使用paint组件中的数组来循环Snake的主体

时间:2014-01-13 15:19:01

标签: java runtime-error paintcomponent

数组并不是我的强项,我通常必须经历很多错误,通常是IndexOutOfBoundsException,然后才能正确完成。这次我得到的错误是一遍又一遍。

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at FinalSnake$DrawPanel.paintComponent(FinalSnake.java:272)
at javax.swing.JComponent.paint(JComponent.java:1037)
at javax.swing.JComponent._paintImmediately(JComponent.java:5106)
at javax.swing.JComponent.paintImmediately(JComponent.java:4890)
at javax.swing.RepaintManager$3.run(RepaintManager.java:814)
at javax.swing.RepaintManager$3.run(RepaintManager.java:802)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:802)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:745)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:725)
at javax.swing.RepaintManager.access$1000(RepaintManager.java:46)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1680)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:715)
at java.awt.EventQueue.access$400(EventQueue.java:82)
at java.awt.EventQueue$2.run(EventQueue.java:676)
at java.awt.EventQueue$2.run(EventQueue.java:674)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:685)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

当我在我的程序中使用此代码时,它用于绘制蛇体。

/* Sprite: Snake Body */
        if (length > 0) {
            for (int i = 0; i <= length; i++) {
                g.setColor(Color.darkGray);
                g.fillRect(bodyX.get(i), bodyY.get(i), width, height);
            }
        }

每当我收到这些错误XD

时,我都无法理解程序试图告诉我的内容

这是代码的其余部分

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
import java.util.ArrayList;

public class FinalSnake extends JFrame {

String direction = "right";

//String duration = 
int time = 100;
int start = 0;

/* Sprite: snake head co-ordinates */
int x = 400;
int y = 450;
int width = 10;
int height = 10;

/* Sprite: snake body */
int length = 0;
ArrayList<Integer> bodyX = new ArrayList<Integer>();
ArrayList<Integer> bodyY = new ArrayList<Integer>();

/* Score */
int point = 0;
String p = String.valueOf(point);

/* Sprite: mouse co-ordinates */
Random rand = new Random();
int addx = (rand.nextInt(10)) * 10;
int addy = (rand.nextInt(10)) * 10;
int mx = ((rand.nextInt(5) + 1) * 100) + addx;
int my = ((rand.nextInt(6) + 2) * 100) + addy;

DrawPanel drawPanel = new DrawPanel();
Timer timer;
public FinalSnake() {

    addMouseListener(new MouseListenerfinal());

    timer = new Timer(time, new TimerListener());     ////////////// <<<<<<<<<<<<<<<<<< TIMER
    timer.start();

    /* move snake up */
    Action upAction = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            direction = "up";                       ////////////// <<<<<<<<<<<<<<<<<< direction only change
        }
    };

    /* move snake down */
    Action downAction = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            direction = "down";
        }
    };

    /* move snake left */
    Action leftAction = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            direction = "left";
        }
    };

    /* move snake right */
    Action rightAction = new AbstractAction() {
        public void actionPerformed(ActionEvent e) {
            direction = "right";
        }
    };

    InputMap inputMap = drawPanel
            .getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
    ActionMap actionMap = drawPanel.getActionMap();

    inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "rightAction");
    actionMap.put("rightAction", rightAction);

    inputMap.put(KeyStroke.getKeyStroke("LEFT"), "leftAction");
    actionMap.put("leftAction", leftAction);

    inputMap.put(KeyStroke.getKeyStroke("DOWN"), "downAction");
    actionMap.put("downAction", downAction);

    inputMap.put(KeyStroke.getKeyStroke("UP"), "upAction");
    actionMap.put("upAction", upAction);

    add(drawPanel);

    pack();
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLocationRelativeTo(null);
    setVisible(true);

}// FinalSnake()

private class TimerListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {                /////////////////// <<<<<<<<<<<<<< All logic here
        if ("right".equals(direction)) { 
            x += 10;

            if (x >= mx && x <= mx + 9 && y >= my && y <= my + 9) {
                addx = (rand.nextInt(10)) * 10;
                addy = (rand.nextInt(10)) * 10;
                mx = ((rand.nextInt(5) + 1) * 100) + addx;
                my = ((rand.nextInt(6) + 1) * 100) + addy;
                point += 100;
                p = String.valueOf(point);
                length++;
                time--;
                bodyY.add(0, y);
                bodyX.add(0, x);
                //System.out.println(bodyX + ":" + bodyY);
            }

            if (x > 699) {
                new GameOver();
                dispose();
            }
        } else if ("left".equals(direction)) {
            x -= 10;

            if (x >= mx && x <= mx + 9 && y >= my && y <= my + 9) {
                addx = (rand.nextInt(10)) * 10;
                addy = (rand.nextInt(10)) * 10;
                mx = ((rand.nextInt(5) + 1) * 100) + addx;
                my = ((rand.nextInt(6) + 1) * 100) + addy;
                point += 100;
                p = String.valueOf(point);
                length++;
                time--;
                bodyY.add(0, y);
                bodyX.add(0, x);
            }

            if (x < 99) {
                new GameOver();
                dispose();
            }
        } else if ("up".equals(direction)) {
            y -= 10;

            if (y >= my && y <= my + 9 && x >= mx && x <= mx + 9) {
                addx = (rand.nextInt(10)) * 10;
                addy = (rand.nextInt(10)) * 10;
                mx = ((rand.nextInt(5) + 1) * 100) + addx;
                my = ((rand.nextInt(6) + 1) * 100) + addy;
                point += 100;
                p = String.valueOf(point);
                length++;
                time--;
                bodyY.add(0, y);
                bodyX.add(0, x);
            }

            if (y < 99) {
                new GameOver();
                dispose();
            }


        } else if ("down".equals(direction)) {
            y += 10;

            if (y >= my && y <= my + 9 && x >= mx && x <= mx + 9) {
                addx = (rand.nextInt(10)) * 10;
                addy = (rand.nextInt(10)) * 10;
                mx = ((rand.nextInt(5) + 1) * 100) + addx;
                my = ((rand.nextInt(6) + 1) * 100) + addy;
                point += 100;
                p = String.valueOf(point);
                length++;
                time--;
                bodyY.add(0, y);
                bodyX.add(0, x);
            }

            if (y > 799) {
                new GameOver();
                dispose();
            }
        } 
        drawPanel.repaint();
    }
}

private class GameOver extends JFrame implements ActionListener {
    JLabel answer = new JLabel("");
    JPanel pane = new JPanel(); // create pane object
    JButton pressme = new JButton("Quit");
    JButton replay = new JButton("Replay?");

    GameOver() // the constructor
    {

        super("Game Over");
        timer.stop();                                           //////////////////////     <<<<<<<<<< Stop TIMER
        setBounds(100, 100, 300, 200);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Container con = this.getContentPane(); // inherit main frame
        con.add(pane);
        pressme.setMnemonic('Q'); // associate hotkey
        pressme.addActionListener(this); // register button listener
        replay.addActionListener(this);
        pane.add(answer);
        pane.add(pressme);
        pane.add(replay);
        pressme.requestFocus();
        answer.setText("You Lose");
        setVisible(true); // make frame visible
    }// GameOver()

    // here is the basic event handler
    public void actionPerformed(ActionEvent event) {
        Object source = event.getSource();
        if (source == pressme)
            System.exit(0);
        if (source == replay) {
            dispose();
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new FinalSnake();
                }
            });
        }
    }// actionPreformed

}// GameOver

private class DrawPanel extends JPanel {

    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        if (start == 1){
          g.setColor(Color.white);

        }

        Font ith = new Font("Ithornît", Font.BOLD, 78);

        /* Background: Snake */
        g.setColor(Color.darkGray);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.gray);
        g.fillRect(100, 100, 600, 700);
        g.setColor(Color.white);
        g.drawRect(99, 99, 601, 701);

        g.drawString("Quit", 102, 86);
        g.drawRect(100, 70, 30, 20);

        //g.drawString("Pause", 152, 86);
        //g.drawRect(150, 70, 40, 20);
        g.drawString("Score: ", 602, 86);
        g.drawString(p, 640, 86);

        g.setFont(ith);
        g.drawString("SNAKE", 350, 60);

        /* Sprite: Mouse */
        g.setColor(Color.black);
        g.fillRect(mx, my, width, height);

        /* Sprite: Snake Body */
        if (length > 0) {
            for (int i = 0; i < length; i++) {
                g.setColor(Color.darkGray);
                g.fillRect(bodyX.get(i), bodyY.get(i), width, height);
            }
        }

        /* Sprite: Snake head */
        g.setColor(Color.white);
        g.fillRect(x, y, width, height);

    }// Paint Component

    public Dimension getPreferredSize() {
        return new Dimension(800, 850);
    }// Dimension

}// DrawPanel

public static void main(String[] args) {
  //new StartScreen();
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            new FinalSnake();
        }
    });
}// main

}// Snake Class

/* Tracks where mouse is clicked */
class MouseListenerfinal extends MouseAdapter {

public void mouseReleased(MouseEvent me) {
    if (me.getX() >= 101 && me.getX() <= 131 && me.getY() >= 94
            && me.getY() <= 115) {
        System.exit(0);
    }
    if (me.getX() >= 151 && me.getX() <= 181 && me.getY() >= 94
            && me.getY() <= 115) {
    }

    String str = "Mouse Released at " + me.getX() + "," + me.getY();
    System.out.println(str);
}
}// MouseAdapter

3 个答案:

答案 0 :(得分:2)

for (int i = 0; i <= length; i++) {更改为for (int i = 0; i < length; i++) {,因为ArrayLists从索引0开始,到size()-1结束。

答案 1 :(得分:1)

好的,发生了奇怪的事!我决定切换&gt;进入&lt;在for循环中,现在它的工作原理!我在嘲笑自己,因为唯一的问题是小于/大于标志。

for (int i = 0; i < length; i++) {

答案 2 :(得分:0)

我发现为什么我在for循环中得到了错误

for (int i = 0; i < length; i++) {

i&lt;长度真的应该是我&gt;长度。我认为这是对的,并没有看清楚 修复之后它仍然没有输出正文,我还没有让它工作,因为当我运行它时我得到一个类似的错误,但它仍然运行程序(不是它应该的方式)

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 64, Size: 64
at java.util.ArrayList.RangeCheck(ArrayList.java:547)
at java.util.ArrayList.get(ArrayList.java:322)
at FinalSnake$DrawPanel.paintComponent(FinalSnake.java:277)
at javax.swing.JComponent.paint(JComponent.java:1037)
at javax.swing.JComponent._paintImmediately(JComponent.java:5106)
at javax.swing.JComponent.paintImmediately(JComponent.java:4890)
at javax.swing.RepaintManager$3.run(RepaintManager.java:814)
at javax.swing.RepaintManager$3.run(RepaintManager.java:802)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:802)
at javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:745)
at javax.swing.RepaintManager.prePaintDirtyRegions(RepaintManager.java:725)
at javax.swing.RepaintManager.access$1000(RepaintManager.java:46)
at javax.swing.RepaintManager$ProcessingRunnable.run(RepaintManager.java:1680)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:209)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:715)
at java.awt.EventQueue.access$400(EventQueue.java:82)
at java.awt.EventQueue$2.run(EventQueue.java:676)
at java.awt.EventQueue$2.run(EventQueue.java:674)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:86)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:685)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)