Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java-KeyListener无法检测碰撞(platformer游戏)_Java_Swing_Keylistener - Fatal编程技术网

java-KeyListener无法检测碰撞(platformer游戏)

java-KeyListener无法检测碰撞(platformer游戏),java,swing,keylistener,Java,Swing,Keylistener,我正在制作一个Java游戏,完全没有任何外部库或引擎。一切都很好,但是我遇到了KeyListener的问题。我不明白为什么会这样 每当我设置角色的动画时,它会使用velX扩展对象(我编码的另一个自定义类),并使用自定义碰撞检测,它工作正常,当字符对象与块对象碰撞时,字符停止移动;i、 e 对象控制器 Character c = new Character(); 字符(扩展对象) KeyListener(此版本有效,动画在按下键时开始,在释放键时停止,但碰撞检测不起作用) 我对每一门课都进行了正

我正在制作一个Java游戏,完全没有任何外部库或引擎。一切都很好,但是我遇到了KeyListener的问题。我不明白为什么会这样

每当我设置
角色
的动画时,它会使用
velX扩展
对象
(我编码的另一个自定义类),并使用自定义碰撞检测,它工作正常,当
字符
对象
对象
碰撞时,
字符
停止移动;i、 e

对象控制器

Character c = new Character();
字符(
扩展对象

KeyListener(此版本有效,动画在按下键时开始,在释放键时停止,但碰撞检测不起作用)

我对每一门课都进行了正确的编程,至少我感觉如此。左右碰撞矩形正确放置在所有
对象上

那么这为什么不起作用呢?我做错了吗?还是Swing的KeyListener的错

任何帮助都将不胜感激。如果您需要更多信息,请在下面发表评论,我很乐意提供更多信息

谢谢,节目主持人杜德

编辑-更新1

有一个名为
Panel的类。class
,基于
JPanel
,它是所有面板的主容器

还有一个
子面板类
,它也扩展了
JPanel
。它是一个抽象类,在该类中调用
tick()

package com.platformer.main;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

public abstract class Subpanel extends JPanel implements Runnable{
    private static final long serialVersionUID = 1L;

    public boolean loaded = false;
    public Thread loop = null;

    public Subpanel(){
        this.setFocusable(true);
        this.requestFocusInWindow();

        init();

        loop = new Thread(this);
        loop.start();
    }

    public void init(){
        load();
        loaded = true;
    }

    public abstract void load();

    public void run(){
        while(loaded){
            tick();
            repaint();
            try{
                Thread.sleep(17);
            }catch(InterruptedException e){

            }
        }
    }

    public abstract void tick();

    BufferedImage buffer;
    Graphics bg;

    public void paint(Graphics g){
        buffer = (BufferedImage) this.createImage(Start.WIDTH,    Start.HEIGHT);
        bg = buffer.getGraphics();
        paintComponent(bg);
        g.drawImage(buffer, 0, 0, null);
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        if(loaded){
            render(g2);
        }
    }

    public abstract void render(Graphics2D g);
    }
}
Gamepanel.class的内部如下所示:

package com.platformer.subpanels;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import com.platformer.input.GameKeys;
import com.platformer.main.Start;
import com.platformer.main.Subpanel;
import com.platformer.objects.ObjectController;

public class Gamepanel extends Subpanel{
    private static final long serialVersionUID = 1L;

    ObjectController objectController;

    GameKeys key;

    public void load(){
        objectController = new ObjectController();
        this.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e){
                objectController.character.setVelX(1);
            }
            public void keyReleased(KeyEvent e) {
                objectController.character.setVelX(0);
            }
        });
    }

    public void tick(){
        objectController.tick();
    }

    public void render(Graphics2D g){
        g.setColor(Color.black);
        g.fillRect(0, 0, Start.WIDTH, Start.HEIGHT);

        objectController.render(g);
    }
}
package com.platformer.input;
import java.awt.event.KeyEvent;
import com.platformer.objects.ObjectController;
import com.platformer.subpanels.Gamepanel;

public class GameKeys extends KeyInput{

    private ObjectController objectController;
    private com.platformer.objects.Character character;

    public GameKeys(Gamepanel panel, ObjectController objectController){
        super(panel);
        this.objectController = objectController;
        this.character = this.objectController.character;
    }

    public void keyPressed(KeyEvent e){
        switch(e.getKeyCode()){
        case KeyEvent.VK_ESCAPE:
            System.exit(0);
        case KeyEvent.VK_RIGHT:
            character.setVelX(1);
        }
    }

    public void keyReleased(KeyEvent e){
        switch(e.getKeyCode()){
        case KeyEvent.VK_RIGHT:
            character.setVelX(0);
        }
    }

    public void keyTyped(KeyEvent e) {

    }
}
GameKeys
是我以前使用的KeyListener。现在,在您看到的代码中,我使用一个定制的KeyAdapter来测试它。它仍然不起作用

GameKeys.class
如下所示:

package com.platformer.subpanels;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import com.platformer.input.GameKeys;
import com.platformer.main.Start;
import com.platformer.main.Subpanel;
import com.platformer.objects.ObjectController;

public class Gamepanel extends Subpanel{
    private static final long serialVersionUID = 1L;

    ObjectController objectController;

    GameKeys key;

    public void load(){
        objectController = new ObjectController();
        this.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e){
                objectController.character.setVelX(1);
            }
            public void keyReleased(KeyEvent e) {
                objectController.character.setVelX(0);
            }
        });
    }

    public void tick(){
        objectController.tick();
    }

    public void render(Graphics2D g){
        g.setColor(Color.black);
        g.fillRect(0, 0, Start.WIDTH, Start.HEIGHT);

        objectController.render(g);
    }
}
package com.platformer.input;
import java.awt.event.KeyEvent;
import com.platformer.objects.ObjectController;
import com.platformer.subpanels.Gamepanel;

public class GameKeys extends KeyInput{

    private ObjectController objectController;
    private com.platformer.objects.Character character;

    public GameKeys(Gamepanel panel, ObjectController objectController){
        super(panel);
        this.objectController = objectController;
        this.character = this.objectController.character;
    }

    public void keyPressed(KeyEvent e){
        switch(e.getKeyCode()){
        case KeyEvent.VK_ESCAPE:
            System.exit(0);
        case KeyEvent.VK_RIGHT:
            character.setVelX(1);
        }
    }

    public void keyReleased(KeyEvent e){
        switch(e.getKeyCode()){
        case KeyEvent.VK_RIGHT:
            character.setVelX(0);
        }
    }

    public void keyTyped(KeyEvent e) {

    }
}
它基于
keyinport.class

package com.platformer.input;
import java.awt.event.KeyListener;
import javax.swing.JPanel;

public abstract class KeyInput implements KeyListener{
    public KeyInput(JPanel panel){
        panel.addKeyListener(this);
    }
}

我找到了一种解决办法。我添加了一个简单的布尔值

public void isCollision(){
    return collision;
}
以及符合以下条件的
碰撞
对象:

for (int i = 0; i < objects.size(); i++) {
    if(this.bounds.getRCol().intersects(objects.get(i).bounds.getLCol())){
       collision = true;
       setVelX(0);
    }else{collision = false;}
}

你把一个类命名为“对象”?不要这样做。只是想澄清一下:问题是添加
c.setVelX(0)中断冲突检测?请发布一个小的可运行示例,如前所述。@programmersdude我认为代码片段没有提供足够的上下文来帮助您进行调试,这就是我建议使用的原因。好的,现在定义“不起作用”。你的检测是否完全停止,你的角色通过对象和屏幕(或其他)运行,或者角色在对象的中间停留某处?
public void isCollision(){
    return collision;
}
for (int i = 0; i < objects.size(); i++) {
    if(this.bounds.getRCol().intersects(objects.get(i).bounds.getLCol())){
       collision = true;
       setVelX(0);
    }else{collision = false;}
}
public void keyPressed(KeyEvent e){
    if(!objectController.character.isCollision()){
        objectController.character.setVelX(1);
    }
}