在游戏之间获取 IndexOutOfBoundsException
getting IndexOutOfBoundsException in between the game
我做了一个游戏,我们控制一艘宇宙飞船,可以发射激光摧毁从顶部飞来的小行星。但是在游戏过程中,只要它抛出 IndexOutOfBoundsException 并且我的游戏就会冻结。我不知道为什么会这样。请任何人告诉我解决方案。提前致谢!这是我的代码(3 类)
Class 1: 主要 Class
import javax.swing.JFrame;
public class Spacewar {
Spacewar(){
JFrame main=new JFrame();
Gamefunction game=new Gamefunction();
main.setTitle("SpaceWar");
main.setVisible(true);
main.setSize(1024,700 );
main.setResizable(false);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.add(game);
}
public static void main(String[] args) {
new Spacewar();
}
}
Class 2:游戏运行
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.Timer;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Gamefunction extends JPanel implements ActionListener,MouseListener,MouseMotionListener{
private static final long serialVersionUID = 1L;
private static int width=1024;
private static int height=700;
private int time=5;
private int score=0;
private boolean play=false, gamestart=false, gameover=false ;
private boolean shoot=false;
Image bg,player,start;
Timer timer;
Rectangle bullet,ship;
Random rand;
ArrayList<Enemy> enemies;
private int playerX = width/2-100;
private int playerY = height-180;
private int bulletX=playerX+45;
private int bulletY=playerY-10;
int total_enemies=190;
Gamefunction(){
//Loading Images
ImageIcon ibg=new ImageIcon("E:\spacewar\bg.jpg");
bg=ibg.getImage();
ImageIcon play=new ImageIcon("E:\spacewar\player.png");
player=play.getImage();
ImageIcon st=new ImageIcon("E:\spacewar\Start.jpg");
start=st.getImage();
//Main settings
timer=new Timer(time,this);
setFocusable(true);
setFocusTraversalKeysEnabled (false );
addMouseListener(this);
addMouseMotionListener(this);
rand=new Random();
enemies = new ArrayList<Enemy>();
timer.start();
for(int i=0;i<total_enemies;i++){
addEnemy(new Enemy(rand.nextInt(900),-rand.nextInt(1000)));
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
//background
g.drawImage(bg, 0, 0, width, height, Color.black, this);
//ship
g.drawImage(player, playerX,playerY,100, 100, this);
for(int i=0;i<enemies.size();i++){
Enemy en =enemies.get(i);
en.draw(g);
}
if(!gamestart){
g.drawImage(start, 0, 0, width, height, Color.black, this);
}
if(play){
if(shoot==true){
g.setColor(Color.green.brighter().brighter().brighter());
g.fillRoundRect(bulletX, bulletY,6 , 15, 50, 100);
}
//score
g.setColor(Color.white);
g.setFont(new Font("Times new Roman",1,40));
g.drawString("Score: "+score, 820, 50);
}
if(gameover){
g.setColor(Color.white);
g.setFont(new Font("Arial",1,150));
g.drawString("Gameover", 150, 200);
g.setColor(Color.white);
g.setFont(new Font("Times new Roman",1,70));
g.drawString("Your Score: "+score, 270, 280);
g.setColor(Color.cyan);
g.setFont(new Font("Times new Roman",1,100));
g.drawString("Click to Restart", 200, 390);
}
}
@Override
public void actionPerformed(ActionEvent ae) {
if(play){
for(int i=0;i<enemies.size();i++){
Enemy en =enemies.get(i);
en.update();
}
for(int i=0;i<enemies.size();i++){
bullet = new Rectangle(bulletX,bulletY,6,15);
ship = new Rectangle(playerX,playerY,100,100);
if(bullet.intersects(enemies.get(i).getEnRect())){
enemies.remove(enemies.get(i));
score++;
shoot=false;
bullet= new Rectangle(0,0,0,0);
}
if(ship.intersects(enemies.get(i).getEnRect())){
gameover=true;
play=false;
}
}
if(playerX<0){
playerX=0;
}
if(playerX>(width-100)){
playerX=width-100;
}
if(shoot==true){
bulletY-=30;
if(bulletY<0){
shoot=false;
bulletY=playerY-10;
bulletX=playerX+50;
}
}
}
repaint();
}
public void shoot(){
shoot=true;
bullet = new Rectangle(bulletX,bulletY,6,15);
}
public void addEnemy(Enemy e){
enemies.add(e);
}
public void reset(){
gameover=false;
shoot=false;
play=true;
playerX = width/2-100;
playerY = height-180;
new Gamefunction();
}
@Override
public void mouseClicked(MouseEvent me) {
if(!gamestart){
gamestart=true;
play=true;
}
if(play){
shoot=true;
}
if(gameover){
reset();
}
}
@Override
public void mouseMoved(MouseEvent me) {
if(play){
playerX=me.getX();
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent me) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
}
Class 3:生成Asteroids/Targets
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.util.Random;
import javax.swing.ImageIcon;
public class Enemy {
Random rand;
int ex,ey;
Enemy(int a, int b){
ex=a;
ey=b;
rand=new Random();
}
public void update(){
ey++;
}
public Image generateEnemy(){
ImageIcon ast =new ImageIcon("E:\spacewar\ast.png");
return ast.getImage();
}
public void draw(Graphics g) {
g.drawImage(generateEnemy(), ex,ey, 80, 65, null, null);
}
public Rectangle getEnRect(){
return new Rectangle(ex,ey,80,65);
}
}
这是长错误或异常
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 170, Size: 170
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at Gamefunction.actionPerformed(Gamefunction.java:132)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
我认为这条线给你带来了问题:
enemies.remove(enemies.get(i));
在某些情况下,您已经移除了所有敌人,它会再次尝试移除。每次访问 enemies
时,请确保检查该元素是空的还是其中有值。
在for循环中
for(int i=0;i<enemies.size();i++){
bullet = new Rectangle(bulletX,bulletY,6,15);
ship = new Rectangle(playerX,playerY,100,100);
if(bullet.intersects(enemies.get(i).getEnRect())){
enemies.remove(enemies.get(i));
score++;
shoot=false;
bullet= new Rectangle(0,0,0,0);
}
if(ship.intersects(enemies.get(i).getEnRect())){
gameover=true;
play=false;
}
}
你继续循环直到原来的敌人大小,但不要考虑你实际上同时减少了列表!
为此,您必须使用 Iterator
for(Iterator<Enemy> iterator = enemies.iterator(); iterator.hasNext();){
Enemy e = iterator.next();
bullet = new Rectangle(bulletX,bulletY,6,15);
ship = new Rectangle(playerX,playerY,100,100);
if(bullet.intersects(e.getEnRect())){
iterator.remove();
score++;
shoot=false;
bullet= new Rectangle(0,0,0,0);
}
if(ship.intersects(e.getEnRect())){
gameover=true;
play=false;
}
}
for(int i=0;i<enemies.size();i++){
(...)
if(bullet.intersects(enemies.get(i).getEnRect())){
enemies.remove(enemies.get(i));
这是您的主事件处理程序中的一些代码。通过从列表中删除项目来循环遍历敌人数组时,您正在改变它。这将导致 IndexOutOfBounds 异常。
我做了一个游戏,我们控制一艘宇宙飞船,可以发射激光摧毁从顶部飞来的小行星。但是在游戏过程中,只要它抛出 IndexOutOfBoundsException 并且我的游戏就会冻结。我不知道为什么会这样。请任何人告诉我解决方案。提前致谢!这是我的代码(3 类)
Class 1: 主要 Class
import javax.swing.JFrame;
public class Spacewar {
Spacewar(){
JFrame main=new JFrame();
Gamefunction game=new Gamefunction();
main.setTitle("SpaceWar");
main.setVisible(true);
main.setSize(1024,700 );
main.setResizable(false);
main.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
main.add(game);
}
public static void main(String[] args) {
new Spacewar();
}
}
Class 2:游戏运行
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.Timer;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class Gamefunction extends JPanel implements ActionListener,MouseListener,MouseMotionListener{
private static final long serialVersionUID = 1L;
private static int width=1024;
private static int height=700;
private int time=5;
private int score=0;
private boolean play=false, gamestart=false, gameover=false ;
private boolean shoot=false;
Image bg,player,start;
Timer timer;
Rectangle bullet,ship;
Random rand;
ArrayList<Enemy> enemies;
private int playerX = width/2-100;
private int playerY = height-180;
private int bulletX=playerX+45;
private int bulletY=playerY-10;
int total_enemies=190;
Gamefunction(){
//Loading Images
ImageIcon ibg=new ImageIcon("E:\spacewar\bg.jpg");
bg=ibg.getImage();
ImageIcon play=new ImageIcon("E:\spacewar\player.png");
player=play.getImage();
ImageIcon st=new ImageIcon("E:\spacewar\Start.jpg");
start=st.getImage();
//Main settings
timer=new Timer(time,this);
setFocusable(true);
setFocusTraversalKeysEnabled (false );
addMouseListener(this);
addMouseMotionListener(this);
rand=new Random();
enemies = new ArrayList<Enemy>();
timer.start();
for(int i=0;i<total_enemies;i++){
addEnemy(new Enemy(rand.nextInt(900),-rand.nextInt(1000)));
}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
//background
g.drawImage(bg, 0, 0, width, height, Color.black, this);
//ship
g.drawImage(player, playerX,playerY,100, 100, this);
for(int i=0;i<enemies.size();i++){
Enemy en =enemies.get(i);
en.draw(g);
}
if(!gamestart){
g.drawImage(start, 0, 0, width, height, Color.black, this);
}
if(play){
if(shoot==true){
g.setColor(Color.green.brighter().brighter().brighter());
g.fillRoundRect(bulletX, bulletY,6 , 15, 50, 100);
}
//score
g.setColor(Color.white);
g.setFont(new Font("Times new Roman",1,40));
g.drawString("Score: "+score, 820, 50);
}
if(gameover){
g.setColor(Color.white);
g.setFont(new Font("Arial",1,150));
g.drawString("Gameover", 150, 200);
g.setColor(Color.white);
g.setFont(new Font("Times new Roman",1,70));
g.drawString("Your Score: "+score, 270, 280);
g.setColor(Color.cyan);
g.setFont(new Font("Times new Roman",1,100));
g.drawString("Click to Restart", 200, 390);
}
}
@Override
public void actionPerformed(ActionEvent ae) {
if(play){
for(int i=0;i<enemies.size();i++){
Enemy en =enemies.get(i);
en.update();
}
for(int i=0;i<enemies.size();i++){
bullet = new Rectangle(bulletX,bulletY,6,15);
ship = new Rectangle(playerX,playerY,100,100);
if(bullet.intersects(enemies.get(i).getEnRect())){
enemies.remove(enemies.get(i));
score++;
shoot=false;
bullet= new Rectangle(0,0,0,0);
}
if(ship.intersects(enemies.get(i).getEnRect())){
gameover=true;
play=false;
}
}
if(playerX<0){
playerX=0;
}
if(playerX>(width-100)){
playerX=width-100;
}
if(shoot==true){
bulletY-=30;
if(bulletY<0){
shoot=false;
bulletY=playerY-10;
bulletX=playerX+50;
}
}
}
repaint();
}
public void shoot(){
shoot=true;
bullet = new Rectangle(bulletX,bulletY,6,15);
}
public void addEnemy(Enemy e){
enemies.add(e);
}
public void reset(){
gameover=false;
shoot=false;
play=true;
playerX = width/2-100;
playerY = height-180;
new Gamefunction();
}
@Override
public void mouseClicked(MouseEvent me) {
if(!gamestart){
gamestart=true;
play=true;
}
if(play){
shoot=true;
}
if(gameover){
reset();
}
}
@Override
public void mouseMoved(MouseEvent me) {
if(play){
playerX=me.getX();
}
}
@Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
@Override
public void mousePressed(MouseEvent me) {
}
@Override
public void mouseReleased(MouseEvent arg0) {
}
@Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
}
Class 3:生成Asteroids/Targets
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.util.Random;
import javax.swing.ImageIcon;
public class Enemy {
Random rand;
int ex,ey;
Enemy(int a, int b){
ex=a;
ey=b;
rand=new Random();
}
public void update(){
ey++;
}
public Image generateEnemy(){
ImageIcon ast =new ImageIcon("E:\spacewar\ast.png");
return ast.getImage();
}
public void draw(Graphics g) {
g.drawImage(generateEnemy(), ex,ey, 80, 65, null, null);
}
public Rectangle getEnRect(){
return new Rectangle(ex,ey,80,65);
}
}
这是长错误或异常
Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 170, Size: 170
at java.util.ArrayList.rangeCheck(Unknown Source)
at java.util.ArrayList.get(Unknown Source)
at Gamefunction.actionPerformed(Gamefunction.java:132)
at javax.swing.Timer.fireActionPerformed(Unknown Source)
at javax.swing.Timer$DoPostEvent.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access0(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.awt.EventQueue.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
我认为这条线给你带来了问题:
enemies.remove(enemies.get(i));
在某些情况下,您已经移除了所有敌人,它会再次尝试移除。每次访问 enemies
时,请确保检查该元素是空的还是其中有值。
在for循环中
for(int i=0;i<enemies.size();i++){
bullet = new Rectangle(bulletX,bulletY,6,15);
ship = new Rectangle(playerX,playerY,100,100);
if(bullet.intersects(enemies.get(i).getEnRect())){
enemies.remove(enemies.get(i));
score++;
shoot=false;
bullet= new Rectangle(0,0,0,0);
}
if(ship.intersects(enemies.get(i).getEnRect())){
gameover=true;
play=false;
}
}
你继续循环直到原来的敌人大小,但不要考虑你实际上同时减少了列表!
为此,您必须使用 Iterator
for(Iterator<Enemy> iterator = enemies.iterator(); iterator.hasNext();){
Enemy e = iterator.next();
bullet = new Rectangle(bulletX,bulletY,6,15);
ship = new Rectangle(playerX,playerY,100,100);
if(bullet.intersects(e.getEnRect())){
iterator.remove();
score++;
shoot=false;
bullet= new Rectangle(0,0,0,0);
}
if(ship.intersects(e.getEnRect())){
gameover=true;
play=false;
}
}
for(int i=0;i<enemies.size();i++){
(...)
if(bullet.intersects(enemies.get(i).getEnRect())){
enemies.remove(enemies.get(i));
这是您的主事件处理程序中的一些代码。通过从列表中删除项目来循环遍历敌人数组时,您正在改变它。这将导致 IndexOutOfBounds 异常。