2015-07-13 30 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