java arrayList以不同方式处理不同的元素

时间:2015-07-13 10:32:34

标签: java

所以,我试图制作一个简单的平台游戏,这里是代码:

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)将true打印到屏幕,并且平台的边界将打印到屏幕和控制台)。然后,当我跳到另一个平台上时,跳跃保持为真,player.intersects(plat)将屏幕打印为false,平台的界限仅打印到控制台,而不是屏幕。

我认为我已经将其缩小到与在arrayList中拥有多个元素有关,但我不知道具体问题。

1 个答案:

答案 0 :(得分:0)

有一个简单的原因,为什么跳总是如此 - 在复杂逻辑的最后一行 你写的

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

这将覆盖您之前在循环运行中设置的jumping=false

如果你与一个不是最后一个的平台相交,你就不会 与ArrayList中的最后一个平台相交 - 但是上面的逻辑代码 将在上一次循环运行中将跳转设置为true。

我认为你的播放器只是一次交叉一个平台 - 因此,如果在最后一个之后插入break语句,则代码应该可以正常工作 if(player.intersects(plat)) { ... }代码块中的操作。

你应该重新设计你的逻辑部分并为它编写JUnit测试 - 但是 无论如何你应该重构你的代码。如果你的游戏正在进行中 更复杂的是,您将遇到调整新功能的问题。 请使用常量作为密钥代码,以便更容易 让读者了解你在做什么。