ArrayList:列表中找不到coords

时间:2013-11-11 19:57:29

标签: java swing

最近,在Stack Overflow的人们的帮助下(我非常感谢),我在java中完成了我自己重拍的Tron游戏。然而,发生了一些事情,现在游戏将不会结束,因为我测试的是否是玩家穿越路径的列表在路径交叉时没有返回x和y坐标。这是代码(问题区域评论):

        package tron;
import javax.swing.*;
import java.util.Random;
import java.awt.Graphics2D;
import java.awt.*;
import java.awt.BasicStroke;
import java.awt.event.*;
import java.awt.geom.Path2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

public class Tron extends JPanel{

    private static Point player = new Point(40, 40);
    private static Point lastTurn = new Point(player);
    private static Point cpu = new Point(360, 330);
    private static Point cpuTurn = new Point(cpu);
    static int timer = 0;
    static Point RANGE = new Point(400, 400);
    public static int size = 1;
    public static int move = 1;
    public static int dir = 1;
    public static int cpu_dir = 2;
    public static Path2D path;
    public static Path2D path2;
    public Random random = new Random();
    public Random random2 = new Random();
    static List playerlist = new ArrayList();
    static List cpulist = new ArrayList();
    static final Tron m = new Tron();
    static final JFrame frame = new JFrame("1P Tron");

    public static void main(String[] args){

        frame.setSize(RANGE.x,RANGE.y);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().add(m);
        m.setBackground(Color.black);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
        path = new Path2D.Float();
        path2 = new Path2D.Float();
        path.moveTo(player.x, player.y);
        path2.moveTo(cpu.x, cpu.y);

        Action actionRight = new AbstractAction(){
            public void actionPerformed(ActionEvent actionRightEvent){
                dir = 1;
                lastTurn = new Point(player);
            };
        };

        Action actionLeft = new AbstractAction(){
            public void actionPerformed(ActionEvent actionLeftEvent){
                dir = 2;
                lastTurn = new Point(player);
            };
        };

        Action actionUp = new AbstractAction(){
            public void actionPerformed(ActionEvent actionUpEvent){
                dir = 3;
                lastTurn = new Point(player);
            };
        };

        Action actionDown = new AbstractAction(){
            public void actionPerformed(ActionEvent actionDownEvent){
                dir = 4;       
                lastTurn = new Point(player);
            };
        };


        KeyStroke right = KeyStroke.getKeyStroke("RIGHT");
        KeyStroke left = KeyStroke.getKeyStroke("LEFT");
        KeyStroke up = KeyStroke.getKeyStroke("UP");
        KeyStroke down = KeyStroke.getKeyStroke("DOWN");

        InputMap inputMap = m.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        inputMap.put(right, "RIGHT");
        inputMap.put(left, "LEFT");
        inputMap.put(up, "UP");
        inputMap.put(down, "DOWN");
        m.getActionMap().put("RIGHT", actionRight);
        m.getActionMap().put("LEFT", actionLeft);
        m.getActionMap().put("UP", actionUp);
        m.getActionMap().put("DOWN", actionDown);

    }

    public void endGame(){ //problems with "if, else if" statements
        Component temporaryLostComponent = null;
        if(cpulist.contains(player)){
            dir = 0;
            JOptionPane.showMessageDialog(temporaryLostComponent, "You Lose");
            WindowEvent close = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(close);
        }else if(playerlist.contains(cpu)){
            dir = 0;
            JOptionPane.showMessageDialog(temporaryLostComponent, "You Win!");
            WindowEvent close = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(close);         
        }else if(player.x == cpu.x && player.y == cpu.y){
            dir = 0;
            JOptionPane.showMessageDialog(temporaryLostComponent, "Game Over");
            WindowEvent close = new WindowEvent(frame, WindowEvent.WINDOW_CLOSING);
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(close);
        }
    }

    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        draw(g);
        try{
            p1_move(m);
            cpu_move();
        }catch(InterruptedException jk){
            Component temporaryLostComponent = null;
            JOptionPane.showMessageDialog(temporaryLostComponent, "Timer exception, Thread.sleep()");
        }
    }

    @SuppressWarnings("unchecked")
    public void p1_move(Tron m) throws InterruptedException{
        if(dir == 1){
            if(player.x > 390){
                player.x = -5;
                path.moveTo(0, player.y);
            };
            Thread.sleep(27);
            player.x += 5;
            playerlist.add(player);
            path.lineTo(player.x, player.y);
            path.moveTo(player.x, player.y);
            m.repaint();
            endGame();
        }else if(dir == 2){
            if(player.x < 0){
                player.x = 395;
                path.moveTo(400, player.y);
            };
            Thread.sleep(27);
            player.x -= 5;
            playerlist.add(player);
            path.lineTo(player.x, player.y);
            path.moveTo(player.x, player.y);
            m.repaint();
            endGame();
        }else if(dir == 3){
            if(player.y < 0){
                player.y = 370;
                path.moveTo(player.x, 400);
            };
            Thread.sleep(27);
            player.y -= 5;
            playerlist.add(player);
            path.lineTo(player.x, player.y);
            path.moveTo(player.x, player.y);
            m.repaint();
            endGame();
        }else if(dir == 4){
            if(player.y > 369){
                player.y = 0;
                path.moveTo(player.x, 0);
            };
            Thread.sleep(27);
            player.y += 5;
            playerlist.add(player);
            path.lineTo(player.x, player.y);
            path.moveTo(player.x, player.y);
            m.repaint();
            endGame();
        }
    }

    @SuppressWarnings("unchecked")
    public void cpu_move() throws InterruptedException{
        if(cpu_dir == 1){
            if(cpu.x > 390){
                cpu.x = -5;
                path2.moveTo(0, cpu.y);
            };
            cpu.x += 5;
            cpulist.add(cpu);
            path2.lineTo(cpu.x, cpu.y);
            path2.moveTo(cpu.x, cpu.y);
            timer += 1;
        }else if(cpu_dir == 2){
            if(cpu.x < 0){
                cpu.x = 395;
                path2.moveTo(400, cpu.y);
            };
            cpu.x -= 5;
            cpulist.add(cpu);
            path2.lineTo(cpu.x, cpu.y);
            path2.moveTo(cpu.x, cpu.y);
            timer += 1;
        }else if(cpu_dir == 3){
            if(cpu.y < 0){
                cpu.y = 370;
                path2.moveTo(cpu.x, 400);
            };
            cpu.y -= 5;
            cpulist.add(cpu);
            path2.lineTo(cpu.x, cpu.y);
            path2.moveTo(cpu.x, cpu.y);
            timer += 1;
        }else if(cpu_dir == 4){
            if(cpu.y > 369){
                cpu.y = 0;
                path2.moveTo(cpu.x, 0);
            };
            cpu.y += 5;
            cpulist.add(cpu);
            path2.lineTo(cpu.x, cpu.y);
            path2.moveTo(cpu.x, cpu.y);
            timer += 1;
        }else{
            cpu_dir = random.nextInt(4) + 1;
        };
        if(timer == ((cpu_dir * 4) + 25)){
            if(cpu_dir == 1){
                cpu_dir = random.nextInt(2) + 3;
                cpuTurn = new Point(cpu);
                timer = 0;
            }else if(cpu_dir == 2){
                cpu_dir = random.nextInt(2) + 3;
                cpuTurn = new Point(cpu);
                timer = 0;
            }else if(cpu_dir == 3){
                cpu_dir = random.nextInt(2) + 1;
                cpuTurn = new Point(cpu);
                timer = 0;
            }else if(cpu_dir == 4){
                cpu_dir = random.nextInt(2) + 1;
                cpuTurn = new Point(cpu);
                timer = 0;
            }else{
                cpu_dir = random.nextInt(4) + 1;
                cpuTurn = new Point(cpu);
                timer = 0;
            };
        }
    }

    public void draw(Graphics g){
        Graphics2D g2 = (Graphics2D) g.create();
        g.setColor(Color.BLUE);
        g.fillRect(player.x, player.y, size, size);
        g2.setColor(Color.BLUE);
        g2.setStroke(new BasicStroke(5));
        g2.draw(path);
        g2.draw(new Line2D.Float(lastTurn, player));
        g.setColor(Color.ORANGE);
        g.fillRect(cpu.x, cpu.y, size, size);
        g2.setColor(Color.ORANGE);
        g2.draw(path2);
        g2.draw(new Line2D.Float(cpuTurn, cpu));
    }
}

我根据您的建议和其他人对我的代码做了一些(好的,很多)更改:

    //package Tron.Stable;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Tron {

    public static void main(String[] args) {
        new Tron();
    }

    public Tron() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Tron");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestPane extends JPanel {
        private int cpu_xVelocity;
        private int cpu_yVelocity;
        private int xVelocity;
        private int yVelocity;

        protected static int CPU_DIR = 1;
        protected static final int PLAYER_SIZE = 0;
        protected static final int DELTA = 4;
        protected static int CPU_DELTA = -4;
        public static int timer = 0;

        private Point player;
        private Point cpu;
        private Point lastTurn;
        private Point cpuTurn;
        private Path2D playerPath;
        private Path2D cpuPath;
        private final Random random = new Random();
        static CpuVelocityAction cpu_Vel;

        public TestPane(){
            setBackground(Color.BLACK);
            InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
            ActionMap am = getActionMap();

            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
            im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "down");

            am.put("left", new VelocityAction(-DELTA, 0));
            am.put("right", new VelocityAction(DELTA, 0));
            am.put("up", new VelocityAction(0, -DELTA));
            am.put("down", new VelocityAction(0, DELTA));
            cpu_xVelocity = CPU_DELTA;
            xVelocity = DELTA;

            player = new Point(40, 40);
            cpu = new Point(360, 360);
            lastTurn = new Point(player);
            cpuTurn = new Point(cpu);
            playerPath = new Path2D.Float();
            cpuPath = new Path2D.Float();
            playerPath.moveTo(40, 40);
            cpuPath.moveTo(360, 360);


            Timer playerTimer = new Timer(20, new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent e){
                    player.x += xVelocity;
                    if (player.x > getWidth()){
                        playerPath.lineTo(getWidth(), player.y);
                        playerPath.moveTo(0, player.y);
                        player.x = 0;
                        lastTurn = new Point(player);
                    }
                    if (player.x + PLAYER_SIZE < 0){
                        playerPath.lineTo(0, player.y);
                        playerPath.moveTo(getWidth() - 1, player.y);
                        player.x = getWidth() - 1;
                        lastTurn = new Point(player);
                    }
                    player.y += yVelocity;
                    if (player.y > getHeight()){
                        playerPath.lineTo(player.x, getHeight());
                        playerPath.moveTo(player.x, 0);
                        player.y = 0;
                        lastTurn = new Point(player);
                    }
                    if (player.y + PLAYER_SIZE < 0){
                        playerPath.lineTo(player.x, 0);
                        playerPath.moveTo(player.x, getHeight() - 1);
                        player.y = getHeight() - 1;
                        lastTurn = new Point(player);
                    }

                    if(CPU_DIR == 1){
                        cpu_Vel = new CpuVelocityAction(CPU_DELTA, 0);
                        cpu_xVelocity = cpu_Vel.cpu_xDelta;
                        cpu_yVelocity = cpu_Vel.cpu_yDelta;
                    }else if(CPU_DIR == 2){
                        cpu_Vel = new CpuVelocityAction(-CPU_DELTA, 0);
                        cpu_xVelocity = cpu_Vel.cpu_xDelta;
                        cpu_yVelocity = cpu_Vel.cpu_yDelta;
                    }else if(CPU_DIR == 3){
                        cpu_Vel = new CpuVelocityAction(0, CPU_DELTA);
                        cpu_xVelocity = cpu_Vel.cpu_xDelta;
                        cpu_yVelocity = cpu_Vel.cpu_yDelta;
                    }else if(CPU_DIR == 4){
                        cpu_Vel = new CpuVelocityAction(0, -CPU_DELTA);
                        cpu_xVelocity = cpu_Vel.cpu_xDelta;
                        cpu_yVelocity = cpu_Vel.cpu_yDelta;
                    };

                    if(timer == (CPU_DIR + 25)){
                        if((CPU_DIR == 1) | (CPU_DIR == 2)){
                            CPU_DIR = ((random.nextInt(2)) + 3);
                        }else if((CPU_DIR == 3) | (CPU_DIR == 4)){
                            CPU_DIR = ((random.nextInt(2)) + 1);
                        }
                    };
                    timer += 1;
                    cpu.x += cpu_xVelocity;
                    if (cpu.x > getWidth()){
                        cpuPath.lineTo(getWidth(), cpu.y);
                        cpuPath.moveTo(0, cpu.y);
                        cpu.x = 0;
                        cpuTurn = new Point(cpu);
                    }
                    if (cpu.x + PLAYER_SIZE < 0){
                        cpuPath.lineTo(0, cpu.y);
                        cpuPath.moveTo(getWidth() - 1, cpu.y);
                        cpu.x = getWidth() - 1;
                        cpuTurn = new Point(cpu);
                    }
                    cpu.y += cpu_yVelocity;
                    if (cpu.y > getHeight()){
                        cpuPath.lineTo(cpu.x, getHeight());
                        cpuPath.moveTo(cpu.x, 0);
                        cpu.y = 0;
                        cpuTurn = new Point(cpu);
                    }
                    if (cpu.y + PLAYER_SIZE < 0){
                        cpuPath.lineTo(cpu.x, 0);
                        cpuPath.moveTo(cpu.x, getHeight() - 1);
                        cpu.y = getHeight() - 1;
                        cpuTurn = new Point(cpu);
                    }
                    repaint();
                }
            });
            playerTimer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.setStroke(new BasicStroke(6));
            g2d.setColor(Color.BLUE);
            g2d.draw(playerPath);
            g2d.draw(new Line2D.Float(lastTurn, player));
            g2d.drawRect(player.x - (PLAYER_SIZE / 2), player.y - (PLAYER_SIZE / 2), PLAYER_SIZE, PLAYER_SIZE);
            g2d.setColor(Color.ORANGE);
            g2d.draw(cpuPath);
            g2d.draw(new Line2D.Float(cpuTurn, cpu));
            g2d.drawRect(cpu.x - (PLAYER_SIZE / 2), cpu.y - (PLAYER_SIZE / 2), PLAYER_SIZE, PLAYER_SIZE);

        }

        public class VelocityAction extends AbstractAction{

            private final int xDelta;
            private final int yDelta;

            public VelocityAction(int xDelta, int yDelta){
                this.xDelta = xDelta;
                this.yDelta = yDelta;
            };
            @Override
            public void actionPerformed(ActionEvent e){
                xVelocity = xDelta;
                yVelocity = yDelta;
                lastTurn = new Point(player);
                playerPath.lineTo(player.x, player.y);
            }
        }
        public class CpuVelocityAction extends AbstractAction{  

            private final int cpu_xDelta;
            private final int cpu_yDelta;

            public CpuVelocityAction(int cpu_xDelta, int cpu_yDelta){
                this.cpu_xDelta = cpu_xDelta;
                this.cpu_yDelta = cpu_yDelta;
            };
            @Override
            public void actionPerformed(ActionEvent e){
                cpu_xVelocity = cpu_xDelta;
                cpu_yVelocity = cpu_yDelta;
                cpuTurn = new Point(cpu);
                cpuPath.lineTo(cpu.x, cpu.y);
            }
        }
    }
}

虽然我还没有实现一个系统来测试与对手线的碰撞,但正如我原来问题的主题那样,我在将cpu播放器转换为使用摆动计时器时遇到了一些问题(I讨厌使用那些,顺便说一句,这就是为什么我试图让Thread.sleep()在原始代码中工作的原因)。基本上,cpu只是不起作用。它要么完全吓坏了,要么把所有这些对角线都放在一边,要么只是保持直线而不会转弯。我几乎是肯定的,这与我的随机数发生器无关,我把它设置为使cpu决定如何转动,那么在写这个时我还搞砸了什么呢?谢谢你的帮助。

1 个答案:

答案 0 :(得分:2)

我在endGame例程中放了一个简单的print语句,在任何给定时间打印出CPU的坐标,我发现:

cpu coordiantes = [java.awt.Point[x=340,y=330], java.awt.Point[x=340,y=330],java.awt.Point[x=340,y=330], java.awt.Point[x=340,y=330]]

所有CPU的访问坐标都是当前坐标!这是一个错误。在更新位置的任何情况下,您都可以将其追踪到cpu_move,例如:

else if(cpu_dir == 2){
    if(cpu.x < 0){
        cpu.x = 395;
        path2.moveTo(400, cpu.y);
    }
    cpu.x -= 5;
    cpulist.add(cpu);
    path2.lineTo(cpu.x, cpu.y);
    path2.moveTo(cpu.x, cpu.y);
    timer += 1;

更新X坐标并将其重新添加到列表中。您想要创建一个新的不同Point对象,并为其分配cpu.x - 5的值,并将其添加到列表中。一般来说,这段代码编写得很糟糕,但是如果你解决了这个问题,我认为它应该可行。

值得注意的是,在这种情况下使用Set会更好,因为查找会更快,特别是随着游戏的进行和当前列表的增长。

注意:了解如何在调试器中单步调试代码,否则永远不会成为优秀的程序员。