2017-03-18 70 views
0

我做了一個遊戲,我們在遊戲中控制一個飛船,並且可以拍攝激光來摧毀來自頂端的小行星。但是在遊戲過程中,任何時候它都會拋出IndexOutOfBoundsException,並且我的遊戲會凍結。我不知道它爲什麼會發生。請任何人告訴我解決方案。提前致謝!這是我的代碼(3類)在遊戲之間獲得IndexOutOfBoundsException

1類:主類

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

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 

    } 
} 

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) 
+0

請附上你得到的異常 –

+0

ArrayIndexOutOfBoundsException和IndexOutOfBoundsException之間有區別 –

+0

這個錯誤很可能是因爲你在迭代時從'enemies'列表中刪除元素, enemies.remove(enemies.get(I));'。使用'Iterator'而不是普通的'for'循環。 – Titus

回答

2

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

我覺得這條線是給你一個問題:

enemies.remove(enemies.get(i)); 

在某些情況下,你已經刪除了所有的敵人,它再次嘗試刪除。每次訪問enemies時,務必檢查它是否爲空的元素或者是否有值。

感謝, 維諾德

0
for(int i=0;i<enemies.size();i++){ 
      (...) 
      if(bullet.intersects(enemies.get(i).getEnRect())){ 
       enemies.remove(enemies.get(i)); 

這裏是你的主要事件處理一些代碼。當您通過從列表中刪除項目來遍歷它時,您正在改變敵人陣列。這將導致IndexOutOfBounds異常。