java - 在绘制组件中使用数组来循环蛇的 body

标签 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)

当我在程序中使用这段代码时,它用于绘制蛇的 body 。

/* 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

最佳答案

更改for (int i = 0; i <= length; i++) {for (int i = 0; i < length; i++) { ,因为 ArrayList 从索引 0 开始并以 size()-1 结束.

关于java - 在绘制组件中使用数组来循环蛇的 body ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21094816/

相关文章:

java.rmi.UnmarshalException : error unmarshalling arguments; nested exception is: java. lang.ClassNotFoundException:ServicesTableau

java - 如何抓取 HTTPS javascript 网页

java - 调整窗口/JFrame 大小会导致计时器滞后

java - JComponents 未在 JFrame 上正确绘制

java - 平移时创建无限网格

java - 如何在正则表达式的帮助下从字符串中获取年、月和日的值

java - 使用带有 SHA-256 的 KDF 在 ECDHC 之后生成对称 key

java - 在 NetBeans 中找不到主类

visual-studio - 什么是 “Microsoft C++ Visual Runtime Library: Runtime error!”,如何捕获?

ios - 将 UIGestureRecognizer 添加到 UITableViewCell