简体   繁体   English

Java 2d游戏:为什么变量不在KeyReleased之外更改?

[英]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/ 我使用zetcode作为参考(不是直接复制和粘贴) 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. 即关于使用KeyAdapters和MVC的设计模式。 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. 根据zetcode教程,受保护的int dx会在按下KeyPressed时发生更改,并且在释放时会再次发生变化,但是在KeyPressed和Keyreleased方法之外,我看不到任何移动或值更改。

I carried out some simple checks 1: Does the "player" graphics move without key input at all (basically do graphic updates work)? 我进行了一些简单的检查:1:“播放器”图形是否在完全没有按键输入的情况下移动(基本上图形更新起作用)? - 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? -是的,我将播放器中的“ move()”方法更改为仅执行“ x--;”,并在屏幕2上看到了明显的运动:值“ dx”是否有变化? - Kinda, from Keypressed method, I can use System.out.println(""+dx); -Kinda,从Keypressed方法中,我可以使用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. 返回值并从dx更改的方法中看到该值,而在此方法之外看不到,这表明该值更改仅发生在此方法的本地,我认为这很奇怪。

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? 我从社区中提出的问题如下:这是并发性的问题吗(或者我应该说,对内存中存储的“ dx”值的2个引用,但是只有1个引用正在更新,或者在我的代码中还有其他时髦的地方)我想念吗?

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. 经过x的时间(由于尴尬而保留为x)之后,我实际上发现了一个问题,实际上是一个严重的问题。

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); 1:在扩展JFrame的另一个类上复制TAdapter 2:2个类(GamePanel(扩展JPanel)和类(名称不正确)Main(扩展JFrame))都具有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. 关于文斯的答复,是的,您是正确的,作为调试我自己的代码的尝试,我实际上将原来的dx替换为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. 关于MadProgrammer的回复,谢谢,我不熟悉Key绑定,我已经很长时间没有编程了,这就是为什么我制作自己的版本的Space Invaders的原因,所以我不仅可以重新开始编程,而且可以提高我的知识,我将研究键绑定,即使您没有指定KeyListeners的问题,我也会研究它们之间的区别。 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 在JFrame的专用类中有重复的TAdapter,在JPanel中有另一个
  • Duplicated requests for "focus" setFocusable(true); 对“焦点”的重复请求setFocusable(true);
  • Use KeyListener instead of key bindings (not sure why: research required) 使用KeyListener代替键绑定(不确定原因:需要研究)
  • Use of the dispose() method 使用dispose()方法
  • Changing value of x rather than dx 更改x的值而不是dx

This question can be considered resolved at this point, thanks 这个问题可以认为目前已经解决,谢谢

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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