我正在开发一款仅用于学习目的的Java游戏。 我希望玩家选择对象。选定的对象可以移动,但其他对象(未选择的对象)不能移动。
Game.java:
import javax.swing.JFrame;
public class Game {
public static void main(String[] args) {
JFrame frame = new JFrame("Kibe");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(new GamePanel());
frame.pack();
frame.setVisible(true);
}
}
GamePanel.java:
import javax.swing.JPanel;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.util.*;
public class GamePanel extends JPanel implements Runnable, KeyListener {
// fields
public static final int WIDTH = 640, HEIGHT = 480;
private Thread thread;
private boolean running;
private int FPS = 30;
private double averageFPS;
private BufferedImage image;
private Graphics2D g;
public ArrayList<Circle> circles;
private int selectedCircle;
// constructor
public GamePanel(){
super();
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
requestFocus();
}
// functions
public void addNotify(){
super.addNotify();
if(thread == null){
thread = new Thread(this);
thread.start();
}
addKeyListener(this);
}
public void run(){
running = true;
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
circles = new ArrayList<Circle>();
long startTime;
gameUpdate();
gameRender();
gameDraw();
long URDTimeMillis;
long waitTime;
long totalTime = 0;
int frameCount = 0;
int maxFrameCount = 30;
long targetTime = 1000 / FPS;
while(running){ // the game loop
startTime = System.nanoTime();
gameUpdate();
gameRender();
gameDraw();
URDTimeMillis = (System.nanoTime() - startTime) / 1000000;
waitTime = targetTime - URDTimeMillis;
try{
Thread.sleep(waitTime);
}catch(Exception e){
e.printStackTrace();
}
frameCount++;
if(frameCount == maxFrameCount){
averageFPS = 1000.0 / ((totalTime / frameCount) / 1000000);
frameCount = 0;
totalTime = 0;
}
}
}
private void gameUpdate(){
circles.get(selectedCircle).update();
}
private void gameRender(){
g.setColor(Color.BLACK);
g.fillRect(0, 0, WIDTH, HEIGHT);
for(int i = 0; i < circles.size(); i++){
circles.get(i).draw(g);
}
}
private void gameDraw(){
Graphics g2 = this.getGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
}
// key functions
public void keyTyped(KeyEvent e){
int keyCode = e.getKeyCode();
}
public void keyPressed(KeyEvent e){
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_SPACE){
circles.add(new Circle());
}
else if(keyCode == KeyEvent.VK_Z){
selectedCircle = (selectedCircle + 1) % circles.size();
}
}
public void keyReleased(KeyEvent e){
int keyCode = e.getKeyCode();
}
}
Circle.java:
import java.awt.*;
public class Circle {
// fields
private double x;
private double y;
private int speed;
private int dx;
private int dy;
private int r;
private boolean up;
private boolean down;
private boolean left;
private boolean right;
private Color color;
// constructor
public Circle(){
x = Math.random() * GamePanel.WIDTH / 2 + GamePanel.HEIGHT / 4;
y = -r;
speed = 5;
dx = 0;
dy = 0;
r = 5;
color = Color.WHITE;
}
// functions
public void setUp(boolean b) { up = b; }
public void setDown(boolean b) { down = b; }
public void setLeft(boolean b) { left = b; }
public void setRight(boolean b ) { right = b; }
public void update(){
if(up)
dy = -speed;
else
dy = 0;
if(down)
dy = speed;
if(left)
dx = -speed;
else
dx = 0;
if(right)
dx = speed;
color = Color.RED;
}
public void draw(Graphics2D g){
g.setColor(Color.WHITE);
g.fillOval((int) x - r, (int) y - r, 2 * r, 2 * r);
}
}
我尝试运行时出错:
线程中的异常&#34;线程-2&#34; java.lang.IndexOutOfBoundsException:Index:0,Si 泽:0 在java.util.ArrayList.rangeCheck(未知来源) at java.util.ArrayList.get(Unknown Source) 在GamePanel.gameUpdate(GamePanel.java:102) 在GamePanel.run(GamePanel.java:51) 在java.lang.Thread.run(未知来源)
答案 0 :(得分:2)
错误消息很明确:
IndexOutOfBoundsException: Index: 0, Size: 0
您尝试从大小为0的ArrayList中获取第0项,这意味着 没有第0项(第一项)。
这一行:
private void gameUpdate(){
circles.get(selectedCircle).update(); // here ****
}
这是在圈子ArrayList保存任何Circle对象之前的游戏开始时发生的。
一种解决方案是在尝试提取不存在的内容之前进行有效性检查,例如,
private void gameUpdate() {
if (selectedCircle < circles.size()) {
circles.get(selectedCircle).update();
}
}
当然,这不会阻止您很快遇到的其他问题,包括
getGraphics()
获得的Graphics对象进行绘制