Advertisement

Position of square is updates, but it isn't repainted

Started by December 31, 2015 08:24 AM
4 comments, last by sn0k3 9 years, 2 months ago

Hello guys,

I was testing Java 2D and I tryed to make a game using Canvas and JFrame.There is interesting thing.For now it is drawing rectangle / square /, but when a key is pressed ( up ), it should be moving that rectangle, but it isn't..The Vector2f, which stores the position of the sprite is updated, but the sprite isn't repainted on a new position..

Code:

Window class:


public class Window extends Canvas implements Runnable {
    
    private boolean isRunning = true;
    private InputHandler inputHandler;
    
    public static Vector2f positionOfTheSquare;
    
    public Window() {
        inputHandler = new InputHandler();
        addKeyListener(inputHandler);
        
        positionOfTheSquare = new Vector2f(675 / 2, 25);
    }
    
    public void paint(Graphics g) {
//        g.drawRect(675 / 2, 25, 25, 25);
        g.drawRect((int)positionOfTheSquare.x, (int)positionOfTheSquare.y, 25, 25);        
    }
    
    public void update() {
        if(inputHandler.keys[0] == true) {
            positionOfTheSquare.y = positionOfTheSquare.y + 25;
        }
    }
    
    public void render(Graphics g) {

    }
    
    public void run() {
        while(isRunning == true) {
            update();
        }
    }
}

InputHandler:


public class InputHandler implements KeyListener {

    public boolean[] keys = new boolean[4];
    
    public void keyPressed(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_UP) {
            keys[0] = true;
            System.out.println("Pressed Up!");
//            Window.positionOfTheSquare.y = Window.positionOfTheSquare.y - 25;
        }
        
//        if(e.getK)
    }

    public void keyReleased(KeyEvent e) {
        if(e.getKeyCode() == KeyEvent.VK_UP) {
            keys[0] = false;
        }
    }

    public void keyTyped(KeyEvent e) {
        
    }

}
 

and the main class is:


public class Main {

    public static void main(String[] args) {

        JFrame frame = new JFrame("Test");

        frame.setSize(new Dimension(640, 480));

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setLocationRelativeTo(null);

        

        Window window = new Window();

        frame.add(window);

        frame.setVisible(true);

    }

}

Any ideas?

Well... To be honest, I don't really know anything about JAVA but from my programming experience, all I seem to understand is that the screen isn't updated after the position is. The 'paint' method in the 'Window' has not been called. Try using it.

Advertisement
Hmm well let's see.

First I'd like to start with this, not that it applies to your problem.

Your Main class has all the JFrame stuff in it. Why? These truly belong in the Window class.
And all the stuff in the window class, (the render and update methods, etc.) should be in your main class.

But to address your issue, it seems you have two methods that do basically the same thing. You have a "paint" and "render" method that both do the same thing (I'm assuming). Therefore you should consider removing one if it isn't used. Secondly, your while loop only ever calls your "update" function but never the render or paint function. This may be your issue.

But as a side note, you are using the Runnable interface and the "run" method should be called by creating a new thread (Thread thread = new Thread() ). And calling thread.start. (This is the Java official way to call that Run method.).

Hope this helps, if you need a better example of how it should look I can quickly throw together some code for you and upload it when I'm on a PC.

Okay, but isn't paint(Graphics g); method called by itself? I mean you shouldn't call it?

Sort of. Java's rendering works using a passive algorithm; paint() is not called unless the window needs to be updated, usually from a change in one of the components (e.g resizing window), which does not work well in games because they need to be repainted at a scheduled interval. In fact you might want to disable this behaviour because Java might decide to call repaint() while your program is calling repaint(); I do not think this algorithm is thread safe. I recommend disabling the ability to resize the window just in case.

Add frame.setResizable(false) in your main method, and add repaint() at the end of the Window class's update() method

one last thing though, in your window class the run() method is calling update() all the time. As soon as you press the key that square is going to fly off the screen. You would want to constrain the calling of update() to a set amount of times per second.

Thank you for the info, and I already did frame.setResizable(false);

Thank you guys!

This topic is closed to new replies.

Advertisement