2015-07-13 28 views
0

所以,我試圖做一個簡單的平臺遊戲,這裏是代碼:Java的ArrayList的治療不同的元素不同

package Main; 

import java.applet.Applet; 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.Frame; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Image; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.geom.Rectangle2D; 
import java.util.ArrayList; 

public class Platformer extends Applet implements Runnable, KeyListener{ 

    // buffering variables 
    private Image dbImage; 
    private Graphics dbg; 

    // running boolean 
    private boolean running = true; 

    // Player coords 
    private int rectX = 100; 
    private int rectY = 420; 

    // initialise dx and dy at zero 
    private double dx = 0; 
    private double dy = 0; 

    private boolean jumping = false; 

    //debug Strings 
    private String inter = new String(); 
    private String coords = new String(); 

    //for background scrolling 
    private int worldShift; 

    //sprites 
    Rectangle2D player = new Rectangle2D.Double(rectX, rectY, 10, 10); 
    Rectangle2D ground = new Rectangle2D.Double(0, 420, 800, 150); 
    int[][] platforms = { {300 + worldShift, 300, 100, 20}, { 450 + worldShift, 200, 100, 20 },  { 500 + worldShift, 250, 100, 20 }, { 100 + worldShift, 200, 100, 20 } }; 
    ArrayList<Rectangle2D> platformList = new ArrayList<Rectangle2D>(); 

    int level = 1; 

    @Override 
    public void init() { 

     setSize(800, 480); 
     setFocusable(true); 
     addKeyListener(this); 
     Frame frame = (Frame) this.getParent().getParent(); 
     frame.setTitle("Test"); 
     setVisible(true); 

     for (int i = 0; i < platforms.length; i++){ 
      // platforms 
      Rectangle2D platform = new Rectangle2D.Double(); 
      platform.setRect(platforms[i][0] + worldShift, platforms[i][1], platforms[i][2], platforms[i][3]); 
      platformList.add(0, platform); 
     } 
    } 

    @Override 
    public void start() { 
     Thread thread = new Thread(this); 
     thread.start(); 
    } 

    @Override 
    public void stop() { 
     // TODO Auto-generated method stub 
    } 

    @Override 
    public void destroy() { 
     // TODO Auto-generated method stub 
    } 

    public void paint(Graphics g) { 
     //Double Buffering 
     Graphics2D g2 = (Graphics2D) g; 
     dbImage = createImage(getWidth(), getHeight()); 
     dbg = dbImage.getGraphics(); 
     paintComponent(dbg); 
     g2.drawImage(dbImage, 0, 0, this); 
    } 

    // Paint objects 
    public void paintComponent(Graphics g) { 
     Graphics2D g2 = (Graphics2D) g; 

     g2.setColor(Color.white); 
     g2.draw(player); 
     g2.fill(player); 

     if (level == 1) { 
      g2.setColor(Color.blue); 
      g2.draw(ground); 
      g2.fill(ground); 

      for (Rectangle2D plat : platformList){ 
       g2.setColor(Color.red); 
       g2.draw(plat); 
       g2.fill(plat); 
      } 

      //debug printouts 
      g.drawString(inter, 400, 30); 
      g.drawString(coords, 20, 150); 

      Font bold = new Font("Liberation Sans", Font.BOLD, 36); 
      setFont(bold); 
      g.drawString("dx, dy: (" + dx + ", " + dy + ")", 30, 30); 
      g.drawString("x, y: (" + player.getX() + ", " + player.getY() + ")", 30, 60); 
     } 
    } 

    @Override 
    public void run() { 
     while (running) { 

      update(); 
      repaint(); 

      try { 
       Thread.sleep(17); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 

    public void update() { 
     worldShift = 0; 

     rectX += dx; 
     rectY += dy + 1; 

     // set sprite coords 
     player.setRect(rectX, rectY, 10, 10); 
     ground.setRect(0, 420, 800, 480); 

     // stops player running off screen 
     if (rectX < 1) rectX = 0; 
     if (rectX > 790) rectX = 790; 

     // collision detection 
     if (player.intersects(ground)) { 
      rectY = (int) (ground.getY() - player.getHeight()); 
      jumping = false; 
      dy = 0; 
     } 

     for (int i = 0; i < platformList.size(); i++){ 
      Rectangle2D plat = platformList.get(i); 

      //sets platform's coordinates 
      plat.setRect(plat.getX() + worldShift, plat.getY(), plat.getWidth(), plat.getHeight()); 

      //sets debug Strings 
      coords = "Not on platform"; 
      inter = " " + player.intersects(plat); 

      //for moving the world 
      if (rectX > 700 && dx == 5) 
       worldShift = -5; 
      if (rectX < 100 && dx == -5) 
       worldShift = 5; 

      //collision detection 
      if (player.intersects(plat)) { 
       System.out.println(plat); 
       jumping = false; 
       dy = 0; 
       coords = " " + plat.getBounds(); 
       System.out.println(platformList.indexOf(plat)); 
       // if player coming from top 
       if (rectY < plat.getY()) 
        rectY = (int) (plat.getY() - player.getHeight()); 
        // if player coming from bottom 
       else if (rectY > plat.getY() + plat.getHeight()) 
        rectY = (int) (plat.getY() + plat.getHeight()); 
      } 
      else if (!player.intersects(plat) && !player.intersects(ground)) jumping = true; 
     } 

     //implements falling 
     if (jumping) 
      dy += 1; 
    } 

    //button presses 
    @Override 
    public void keyPressed(KeyEvent e) { 
     System.out.println("Key pressed code=" + e.getKeyCode() + ", char="+ e.getKeyChar()); 
     if (e.getKeyCode() == 37) 
      dx -= 5; // 37 is left 
     if (e.getKeyCode() == 39) 
      dx += 5; // 39 is right 
     // if (e.getKeyCode() == 40) dy -= 5; //40 is down 
     if (e.getKeyCode() == 38 && jumping == false){ 
      // if on the ground, 
      // i.e. only jump if on the ground 
      dy -= 20; // 38 is up 
      jumping = true; 
      System.out.println("Jumping"); 
     } 
    } 

    //key release 
    @Override 
    public void keyReleased(KeyEvent e) { 
     if (e.getKeyCode() == 37) 
      dx = 0; // 37 is left 
     if (e.getKeyCode() == 39) 
      dx = 0; // 39 is right 
     if (e.getKeyCode() == 40) 
      dy = 0; // 40 is down 
     // if (e.getKeyCode() == 38) 
    } 

    @Override 
    public void keyTyped(KeyEvent e) { 
     // TODO Auto-generated method stub 

    } 

} 

的問題是,當玩家在平臺上跳,平臺的行爲不同,具體取決於在平臺上。如果我跳到最後一個畫出來的畫面上,它就會按照我想要的方式操作(跳躍設置爲falseplayer.intersects(plat)顯示爲真,屏幕和平臺的邊界都會打印到屏幕和控制檯上)。然後,當我跳到不同的平臺上時,跳躍保持不變,player.intersects(plat)將打印爲屏幕,平臺的邊界僅打印到控制檯,而不是屏幕。

我想我已經縮小到與arrayList中有多個元素有關,但我不知道具體問題。

回答

0

有一個簡單的原因,跳躍總是如此 - 你寫

if (!player.intersects(plat) && !player.intersects(ground)) jumping = true; 

這將覆蓋jumping=false你在一個循環中運行之前設置 在複雜邏輯的最後一行。

如果你有一個平臺,這是不是最後的,那麼你不會 相交ArrayList中的最後一個平臺相交 - 但邏輯代碼上面 將在最後一個循環運行設置跳轉到真。

我假設你的播放器只相交一個平臺,一次 - 所以,如果你在if(player.intersects(plat)) { ... }代碼塊中的最後 手術後插入break聲明你的代碼應該工作。

你應該重新設計你的邏輯部分並編寫JUnit測試 - 但無論如何你應該重構你的代碼 。如果你的遊戲變得更加複雜,你將會遇到適應新功能的問題。 請使用常量作爲關鍵代碼,以便讀者更容易理解你在做什麼 。

+0

爲什麼這行覆蓋跳躍,不應該只在玩家不與平臺或地面相交時纔會運行?還有其他奇怪的事情發生,例如將界限打印到控制檯而不是屏幕上,或者將'player.intersects(plat)'打印爲假,但其行爲就像是真實的。 – foopydoop

+0

嗯,這正是問題 如果你的播放器與你的第一個平臺相交,他或她 不與最後一個或地面相交 因此,當上一次循環運行時,你的表達式將被評估爲真。 – Coder55

+0

噢,我的上帝啊,非常感謝你,這讓我堅持了大約3天。 – foopydoop