简体   繁体   中英

Java 2d Game: Why is the variable not changing outside of KeyReleased?

I am attempting to create my own version of the well known game Space invaders. I am using zetcode as a point of reference (not a direct copy and paste) http://zetcode.com/tutorials/javagamestutorial/spaceinvaders/

However I seem to be a bit stuck. Namely on the use of KeyAdapters and the MVC design pattern. According to zetcode tutorial, the protected int dx changes when KeyPressed is pressed and once again when it is released, however I not seeing any movement nor value change outside of the KeyPressed and Keyreleased methods.

I carried out some simple checks 1: Does the "player" graphics move without key input at all (basically do graphic updates work)? - Yes, I changed the "move()" method within player to simply do a "x--; " and visibly see movement on screen 2: Does the value "dx" change at all? - Kinda, from Keypressed method, I can use System.out.println(""+dx); to return the value and visibly see, from within the method that dx changes, but not outside of this method, suggesting that the value changes are only occurring local to this method, which in my opinion is bizarre.

My ask from the community is the following: Is this an issue with concurrency (or should I say, 2 references to the "dx" value stored in memory but only 1 reference is getting updated or there something else funky going on in my code that I am missing?

package spaceInvaders;

import java.awt.event.KeyEvent;

public class Player extends  IngameObjects implements Commons {

    private  int startX = 250;
    private final int startY = 150;


    public Player(){
        initPlayer();
    }

    public void initPlayer(){
        this.setX(startX);
        this.setY(startY);
    }

    public int getX() {
        return x;
    }
    public void setX(int x) {
        this.x = x;
    }
    public void move(){     
        this.x += dx;
        if (x <= 2) {
            x = 2;
        }
        if (x >= 400 - 2 * 10) {
            x = 400 - 2 * 10;
        }
    }

    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();


        if(key == KeyEvent.VK_LEFT){
            dx = -1;
            System.out.println(""+dx);
        }
        if(key == KeyEvent.VK_RIGHT){}

        if(key == KeyEvent.VK_ESCAPE){
            System.exit(0);
        }

    }



    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();
        if(key == KeyEvent.VK_LEFT){
            this.x = -1;
        }
        if(key == KeyEvent.VK_RIGHT){}
    }
}

 package spaceInvaders;

    public class IngameObjects {
        protected int x;
        private int y;
        protected int dx;   

        public int getY() {
            return y;
        }
        public void setY(int y) {
            this.y = y;
        }
    }

package spaceInvaders;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;

public class GamePanel extends JPanel implements Runnable{
private Player player;
private Thread animator;
private boolean isRunning;

    public GamePanel(){

        this.setBackground(Color.BLACK);
        this.setDoubleBuffered(true);
        addKeyListener(new TAdapter());
        setFocusable(true);
    }

    public void paintComponent(Graphics g){     
        super.paintComponent(g);
        drawPlayer(g);
        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }

    public void drawPlayer(Graphics g){
        g.setColor(Color.GREEN);
        g.fillRect(player.getX(), player.getY(), 50, 50);
    }

    @Override
    public void run() {
        isRunning = true;
        long startTime, timeDiff, sleepTime; 
        startTime = System.currentTimeMillis();

        while(isRunning){
            repaint();
            gameUpdate();

             timeDiff = System.currentTimeMillis() -  startTime;
             sleepTime = 5 - timeDiff;

            try{
                Thread.sleep(sleepTime);
            }
            catch(InterruptedException ex){
                System.exit(0);
            }
            startTime = System.currentTimeMillis();
        }       
    }


    @Override
    public void addNotify(){
        super.addNotify();
        startGame();
    }


    public void startGame(){
        player = new Player();

        if(animator == null || !isRunning){
            animator = new Thread(this);
            animator.start();

        }
    }

    public void gameUpdate(){
        player.move();
    }

    private class TAdapter extends KeyAdapter{


        @Override
        public void keyPressed(KeyEvent e) {
            System.out.println(""+player.getX());
            player.keyPressed(e);
        }
        @Override

        public void keyReleased(KeyEvent e) {
            player.keyReleased(e);
        }
    }
}

thanks for the swift responses, much appreciated. After x amount of time (leaving it as x due to embarrassment) I have actually found a problem, quite a serious one actually.

1: Duplicated TAdapter on another class which extended the JFrame 2: 2 classes (GamePanel (which extends JPanel) and class (poorly named) Main (which extends JFrame) both have setFocusable(true);

Regarding Vince's reply, yes you are correct, as an attempt to debug my own code I actually replaced what was originally dx, for x. Obviously neither worked which led me to suspect there was a coding issue elsewhere.

Regarding MadProgrammer's reply, thanks, I am not familiar with Key bindings, I have not been programming in a very long time, which is the reason why I am making my own version of space invaders, so I can not only get back into programming but improve my knowledge, I will look at key bindings, even though you don't specify what is wrong with KeyListeners, I will study the differences. Regarding dispose, yep once again, not very familiar with the uses, i thought it was another way of refreshing the graphics, I will look into this.

in summary, where did I go wrong:

  • Duplicated TAdapter in a dedicated class for JFrame and another one in JPanel
  • Duplicated requests for "focus" setFocusable(true);
  • Use KeyListener instead of key bindings (not sure why: research required)
  • Use of the dispose() method
  • Changing value of x rather than dx

This question can be considered resolved at this point, thanks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM