java - 在游戏之间出现 IndexOutOfBoundsException

标签 java exception freeze

我制作了一款游戏,我们控制一艘宇宙飞船,可以发射激光摧毁来自顶部的小行星。但在游戏过程中,每当它抛出 IndexOutOfBoundsException 时,我的游戏就会卡住。我不知道为什么会这样。请任何人告诉我解决方案。提前致谢!这是我的代码(3个类)

第一类:主类

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();
    }
}

第二类:游戏功能

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

    }
}

第 3 课:生成小行星/目标

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.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.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)

最佳答案

在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;
    }
}

您将继续循环,直到原始敌人大小为止,但不要考虑到您实际上同时减少了列表!

要实现这一点,您必须使用迭代器

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;
    }
}

关于java - 在游戏之间出现 IndexOutOfBoundsException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42873615/

相关文章:

java - 从 ListView 到 PDF 的数据

java - iOS 和 Android AES 加密(Java 中没有 UINT)

java - 从哪里获得 rt.jar 的完整源代码?

c++ - OpenCL 文件无法在 OS X 上编译

java - Spring Boot 嵌入式 Tomcat 'allowLinking' 属性

java - JasperReport异常打印

Python异常处理——行号

Android Studio 在启动时卡住

c# - 缺少 DataGridview 滚动条 C# WinForm

c++ - 捕获模板化异常时的编译器错误