人物不能再动了

时间:2017-04-16 13:20:25

标签: java swing animation keylistener

所以这里是考虑了提示之后的代码。 地图被重新粉刷,keylistener已经改变,但似乎仍有问题。

问题是,左上角的小方块不会移动,这是理想的结果。

package schoolgamev2;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Spel {

    public static void main(String[] args) {
        Speelveld map = new Speelveld();
        map.Speelveld();
        map.GenerateMap();
    }
}

class Speelveld extends JPanel {

    final int rijen = 16;
    final int kolommen = 16;
    Speler speler = new Speler();
    Loopgebied loopgebied = new Loopgebied();
    Blokken blok = new Blokken();

    int[][] coordinaten = new int[rijen][kolommen];

    public void Speelveld() {
        JFrame frame = new JFrame();
        frame.setSize(500, 500);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLayout(new BorderLayout());
        frame.add(this);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        setFocusable(true);
        addKeyListener(new KeyListener(this));

    }

    //genereer map
    public void GenerateMap() {
        Random random = new Random();
        int x;
        int y;
        for (y = 0; y < rijen; y++) {  //scan langs y
            for (x = 0; x < kolommen; x++) { //scan langs x
                //selecteert type blok voor coordinaten x y
                coordinaten[x][y] = random.nextInt(4);
                //debugprint
            }
            //debugprint
        }
        coordinaten[0][0] = 4; //speler begint altijd links boven
        coordinaten[15][15] = 5; //finish is altijd rechts onder
    }

    public int[][] getCoordinaten() {
        return coordinaten;
    }

    public Speler getSpeler2() {
        return speler;
    }

    public int getSpelerX() {
        return speler.getX();
    }

    public int getSpelerY() {
        return speler.getY();
    }

    public void setSpelerX(int x) {
        speler.setX(x);
    }

    public void setSpelerY(int y) {
        speler.setY(y);
    }

    //@Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        int x;
        int y;
        for (y = 0; y < rijen; y++) {  //scan langs y
            System.out.println("");
            for (x = 0; x < kolommen; x++) { //scan langs x
                blok.setX(x);
                blok.setY(y);
                blok.setType(coordinaten[x][y]);
                System.out.print(coordinaten[x][y] + " ");
                switch (blok.getType()) {

                    case 0:
                        loopgebied.teken(g);
                        break;
                    case 4:
                        speler.teken(g);

                    /*case 5:
                        eindveld.teken(g);
                        break;*/
                    default:
                        break;
                }
            }

        }

    }

}

class Speler extends Blokken {

    Blokken blok = new Blokken();

    public void teken(Graphics g) {

        g.drawRect(blok.getX(), blok.getY(), 10, 10);
    }

}

class Loopgebied extends Blokken {

    Blokken blok = new Blokken();

    public void teken(Graphics g) {
        g.drawRect(blok.getX() * size, blok.getY() * size, size, size);
    }
}

class Blokken {

    private static int x;
    private static int y;
    private static int type;
    public int size = 16;

    //setters voor x y en type
    public void setX(int xIn) {
        x = xIn;
    }

    public void setY(int yIn) {
        y = yIn;
    }

    public void setType(int typeIn) {
        type = typeIn;

    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public int getType() {
        return type;
    }

}

class KeyListener extends KeyAdapter {

    private static final int SCALE = 3;
    private Speelveld speelveld;

    public KeyListener(Speelveld speelveld) {
        this.speelveld = speelveld;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        int deltaX = 0;
        int deltaY = 0;
        if (key == KeyEvent.VK_LEFT) {
            deltaX = -1 * SCALE;
            deltaY = 0;
        } else if (key == KeyEvent.VK_UP) {
            deltaX = 0;
            deltaY = -1 * SCALE;
        } else if (key == KeyEvent.VK_RIGHT) {
            deltaX = 1 * SCALE;
            deltaY = 0;
        } else if (key == KeyEvent.VK_DOWN) {
            deltaX = 0;
            deltaY = 1 * SCALE;
        } else {
            return;
        }

        int x = speelveld.getSpelerX() + deltaX;
        int y = speelveld.getSpelerY() + deltaY;

        speelveld.setSpelerX(x);
        speelveld.setSpelerY(y);
        speelveld.repaint();
    }

}

1 个答案:

答案 0 :(得分:0)

正如评论中所提到的,你得到了你的播放器,Speler类,它扩展了JPanel并连线使用KeyListener,但请注意它没有被用作JPanel,因此KeyListener无效,因为它们仅在已添加到具有焦点的可见组件时才起作用。

建议:

  • 再次根据评论,使Speler成为非GUI 逻辑类。意思是没有扩展JPanel或任何其他Swing组件,当然也没有添加KeyListener。
  • 相反,为玩家的行为提供代码,让玩家自己画画,这就是它。我建议的是你试图分离你的&#34;模型&#34;这里的玩家来自&#34; View&#34;这里是Swing GUI。
  • 有一个JPanel,只有一个可以绘图。让它覆盖paintComponent(不要忘记在其中调用super的paintComponent),并让它通过调用逻辑组件的绘制方法(public void verf(Graphics2D g2)?或者绘制每个逻辑组件? {paint}中的public void teken(Graphics2D g2)?)。
  • 作为一般规则,您也不希望您的GUI组件类(此处为JPanel)直接实现侦听器接口(如KeyListener),但希望将它们分开。
  • 要么使这个绘图JPanel可聚焦,给它焦点,并添加KeyListener,一个单独的类。
  • 或者更好,根据教程Key Bindings
  • 使用键绑定

例如,下面的简单[MCVE]不使用Swing Timer或更改速度,而是使用KeyListener仅使用一个绘图JPanel和KeyListener来更改Speler2对象的位置。如果我让它更强大和更大,我会使用Swing Timer,使用Key Bindings,并使用键绑定来改变速度。

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class Spel2 {

    private static final int VELD_WIDTH = 500;

    private static void createAndShowGui() {
        Speelveld2 speelveld2 = new Speelveld2(VELD_WIDTH, VELD_WIDTH);

        JFrame frame = new JFrame("Spel2");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(speelveld2);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        speelveld2.requestFocusInWindow();
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

class MyKeyListener extends KeyAdapter {
    private static final int SCALE = 3;
    private Speelveld2 speelveld2;

    public MyKeyListener(Speelveld2 speelveld2) {
        this.speelveld2 = speelveld2;
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        int deltaX = 0;
        int deltaY = 0;
        if (key == KeyEvent.VK_LEFT) {
            deltaX = -1 * SCALE;
            deltaY = 0;
        } else if (key == KeyEvent.VK_UP) {
            deltaX = 0;
            deltaY = -1 * SCALE;
        } else if (key == KeyEvent.VK_RIGHT) {
            deltaX = 1 * SCALE;
            deltaY = 0;
        } else if (key == KeyEvent.VK_DOWN) {
            deltaX = 0;
            deltaY = 1 * SCALE;
        } else {
            return;
        }

        int x = speelveld2.getSpelerX() + deltaX;
        int y = speelveld2.getSpelerY() + deltaY;

        speelveld2.setSpelerX(x);
        speelveld2.setSpelerY(y);
        speelveld2.repaint();        
    }

}

@SuppressWarnings("serial")
class Speelveld2 extends JPanel {
    private int prefW;
    private int prefH;
    private Speler2 speler2 = new Speler2();

    public Speelveld2(int prefW, int prefH) {
        this.prefW = prefW;
        this.prefH = prefH;

        setFocusable(true);
        addKeyListener(new MyKeyListener(this));
    }

    public Speler2 getSpeler2() {
        return speler2;
    }

    public int getSpelerX() {
        return speler2.getX();
    }

    public int getSpelerY() {
        return speler2.getY();
    }

    public void setSpelerX(int x) {
        speler2.setX(x);
    }

    public void setSpelerY(int y) {
        speler2.setY(y);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        speler2.teken(g2);
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(prefW, prefH);
    }

}

class Speler2 extends Blokken2 {
    private static final int RECT_W = 10;

    public Speler2() {
        super(BlokkenType.SPELER);
    }

    @Override
    public void teken(Graphics2D g2) {
        int x = getX();
        int y = getY();
        g2.drawRect(x, y, RECT_W, RECT_W);
    }
}

class Blokken2 {
    private int x;
    private int y;
    private int velx = 0;
    private int vely = 0;
    private BlokkenType type;
    private BufferedImage img;

    public Blokken2(BlokkenType type) {
        this.type = type;
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

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

    public int getVelx() {
        return velx;
    }

    public void setVelx(int velx) {
        this.velx = velx;
    }

    public int getVely() {
        return vely;
    }

    public void setVely(int vely) {
        this.vely = vely;
    }

    public BlokkenType getType() {
        return type;
    }

    public void setType(BlokkenType type) {
        this.type = type;
    }

    public void setImg(BufferedImage img) {
        this.img = img;
    }

    public BufferedImage getImg() {
        return img;
    }

    public void teken(Graphics2D g2) {
        if (img != null) {
            g2.drawImage(img, x, y, null);
        }
    }
}

enum BlokkenType {
    LOOPGEBIED, BARRICADE, MUUR, SLEUTEN, SPELER, EINDVELD
}

编辑:您的最新代码在此处出错:

class Speler extends Blokken {

    Blokken blok = new Blokken();

    public void teken(Graphics g) {

        g.drawRect(blok.getX(), blok.getY(), 10, 10);
    }

}

关于你的编辑:

现在,当您创建Speler实例时,您可以创建 TWO Blokken实例,其中 Speler实例,因为它扩展了Blokken而另一个包含通过 Speler实例,因为它还有一个Blokken字段。

您更新第一个的x / y状态,但是您使用第二个进行绘制,这就是为什么没有显示动作的原因。解决方案很明显:使用一个或另一个但不是两个。要么让Speler扩展Blokken,要么让它包含一个Blokken实例,但不要同时执行这两个操作。