2017-04-16 34 views
-2

所以这里是将提示考虑在内后的代码。 地图不断被重新绘制,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(); 
    } 

} 
+0

呃我的格式不好,我很抱歉。 –

+2

寻求调试帮助的问题(“为什么不是这个代码工作?”)真的应该包括所需的行为,以及*在问题本身*中重现*所需的最短代码。请创建并发布您的[mcve],以便我们可以使用一个小型可编译和可运行的程序,以便我们可以自己测试您的代码,并希望对其进行修改以使其可以正常工作。请注意,我们不希望看到您的整个程序**,也不应该发布指向代码库的链接。相反,保持它小,保持简单,并使其运作。运气。 –

+0

我也会帮忙解释一下当你尝试运行你的创作时发生了什么。例外?还是不按预期工作? – strash

回答

0

正如在评论中提到,你有你的球员,在Speler类,扩展JPanel并连线使用的KeyListener,但要注意,它没有被用来作为一个JPanel,所以KeyListener的是非功能,因为只有当它们被添加到具有焦点的可见的组件时,它们才起作用。

建议:

  • 再按照意见,使Speler非GUI 逻辑类。意思是没有扩展JPanel或任何其他Swing组件,并且肯定不会向其添加KeyListener。
  • 取而代之的是为玩家的行为和让玩家自己绘制代码,就是这样。我所建议的是,你试图在这里将你的“模型”的一部分从“视图”中的玩家与Swing GUI分开。
  • 有一个JPanel,只有一个绘图。重写paintComponent(不要忘记调用其中的super的paintComponent),并通过在其paintComponent方法中调用逻辑组件的绘制方法(public void verf(Graphics2D g2)?或public void teken(Graphics2D g2)?)来绘制每个逻辑组件。
  • 作为一般规则,您也不希望您的GUI组件类(这里是JPanel)直接实现监听器接口(如KeyListener),但希望将它们分开。
  • 要么让该图形JPanel可以聚焦,要给它关注点,并将KeyListener(一个单独的类)添加到它。
  • 或者更好,使用键绑定按照教程:Key Bindings

例如简单的[MCVE]以下不使用摇摆定时器或改变速度,而是它使用一个KeyListener的改变位置Speler2对象只使用一个绘图JPanel和一个KeyListener。如果我使这个更健壮和更大,我会使用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实例,其中斯派勒实例,因为它扩展了Blokken,另一个是由包含的,因为它也有一个Blokken字段。

您更新第一个的x/y状态,但您使用第二个绘制,这就是为什么没有运动显示。解决方案是显而易见的:使用一个或另一个,但不是两个。要么让Speler扩展Blokken,要么让它包含一个Blokken实例,但不要两者兼而有之。

+0

我们已经将您的提示考虑在内,但仍然存在问题,我已经重新编辑了我的问题,现在可以复制并粘贴一次,然后运行代码 –

+0

我可以' t upvote bec因为我的评分太低。我已阅读您发送给我的链接,我在阅读后立即尝试。同时我也很抱歉,我不想重新发布这个问题,并且关注那些已经在努力的事情。 –

+0

@OguzKh:我看到你的问题......请挂上 –