2017-04-16 78 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:我看到你的問題......請掛上 –