2016-03-04 4 views
0

Я делаю космический шутер в java. Когда я запускаю программу и играть на минуту, она работает, но часть пути через, как только пуля вступает в контакт с противником, программа аварий и дает мне следующее сообщение об ошибке:Java-программа продолжает сбой

Exception in thread "Thread-1" java.lang.IndexOutOfBoundsException: Index: 1, Size: 1 
at java.util.ArrayList.rangeCheck(ArrayList.java:638) 
at java.util.ArrayList.get(ArrayList.java:414) 
at main.Game.checkCollisions(Game.java:185) 
at main.Game.tick(Game.java:118) 
at main.Game.run(Game.java:95) 
at java.lang.Thread.run(Thread.java:745) 

Что вызывает этот крах? Как я могу это исправить?

Вот область кода, где происходит ошибка:

void checkCollisions() { 
     for(int i = 0; i < Shoot.allBullets.size(); i++){ 
      for(int j = 0; j < Enemy.allEnemies.size(); j++){ 
       if(new Rectangle((int)Shoot.allBullets.get(i).x, (int)Shoot.allBullets.get(i).y, 23, 48).intersects(new Rectangle((int) Enemy.allEnemies.get(j).x, (int) Enemy.allEnemies.get(j).y, 64, 64))) { 
        bulletIntersectsEnemy(i, j); 
       } 
      } 
     } 
    } 

Вот остальная часть кода:

Game.java

package main; 

import java.awt.Canvas; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Rectangle; 
import java.awt.event.KeyEvent; 
import java.awt.event.KeyListener; 
import java.awt.image.BufferStrategy; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 

import javax.imageio.ImageIO; 
import javax.swing.JFrame; 

public class Game extends Canvas implements Runnable, KeyListener { 

    //declare values 
    private static final long serialVersionUID = 1L; 
    public static final int WIDTH = 800; 
    public static final int HEIGHT = 600; 
    public static final String TITLE = "Space Shooter"; 

    private boolean running = false; 
    private Thread thread; 

    private Player player; 

    private BufferedImage playerImage; 
    private BufferedImage bulletImage; 
    private BufferedImage enemyImage; 

    int playerx; 
    int playery; 

    int round = 1; 

    public Game() { 
     // 
     player = new Player((WIDTH/2)-32, HEIGHT-200); 

     //allocates all file resources 
     try { 
      playerImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/player.png")); 
      bulletImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/bullet.png")); 
      enemyImage = ImageIO.read(this.getClass().getResourceAsStream("/resources/enemy.png")); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     addKeyListener(this); 
     setFocusable(true); 
     requestFocusInWindow(); 
    } 

    //starts thread 
    private synchronized void start() { 
     if (running) 
      return; 

     running = true; 
     thread = new Thread(this); 
     thread.start(); 
    } 

    //stops thread 
    private synchronized void stop() { 
     if (!running) 
      return; 

     running = false; 
     try { 
      thread.join(); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
     System.exit(1); 
    } 

    @Override 
    //game loop 
    public void run() {  
     long lastTime = System.nanoTime(); 
     final double amountOfTicks = 60.0; 
     double ns = 1000000000/amountOfTicks; 
     double delta = 0; 
     int updates = 0; 
     int frames = 0; 
     long timer = System.currentTimeMillis(); 
     while (running) { 
      long now = System.nanoTime(); 
      delta += (now - lastTime)/ns; 
      lastTime = now; 
      if (delta > 1) { 
       tick(); 
       updates++; 
       delta--; 
      } 
      render(); 
      frames++; 

      if (System.currentTimeMillis() - timer > 1000) { 
       timer += 1000; 
       System.out.println(updates + " TICKS, " + frames + " FPS"); 
       updates = 0; 
       frames = 0; 
      } 
     } 
     stop(); 
    } 

    //updates sprite locations 
    public void tick() { 
     playerx = player.getX(); 
     playery = player.getY(); 
     Shoot.updateBullets(); 
     Enemy.updateEnemies(); 
     checkCollisions(); 
    } 

    //renders sprites 
    public void render() { 
     //setting up triple-buffering 
     BufferStrategy bs = this.getBufferStrategy(); 
     if (bs == null) { 
      createBufferStrategy(3); 
      return; 
     } 
     Graphics g = bs.getDrawGraphics(); 

     ////////////////////////////////// 

     g.setColor(Color.BLACK); g.fillRect(0,0,getWidth(), getHeight()); 
     g.drawImage(playerImage, playerx, playery, this); 

     if (Shoot.allBullets.size() != 0) { 
      for (int i = 0; i < Shoot.allBullets.size(); i++) { 
       int bulletx = (int) Shoot.allBullets.get(i).x; 
       int bullety = (int) Shoot.allBullets.get(i).y; 
       g.drawImage(bulletImage, bulletx + 21, bullety, this); 
      } 
     } 

     if (Enemy.allEnemies.size() != 0) { 
      for (int i = 0; i < Enemy.allEnemies.size(); i++) { 
       int enemyx = (int) Enemy.allEnemies.get(i).x; 
       int enemyy = (int) Enemy.allEnemies.get(i).y; 
       g.drawImage(enemyImage, enemyx, enemyy, this); 
      } 
     } else { 
      Enemy.createEnemies(round); 
      round++; 
     } 

     ////////////////////////////////// 

     g.dispose(); 
     bs.show(); 
    } 

    @Override 
    public void keyReleased(KeyEvent e) { 
     int key = e.getKeyCode(); 
     if (key == KeyEvent.VK_SPACE) { 
      Shoot.addBullet(player.getX(), player.getY()); 
     } 
    } 

    public void keyPressed(KeyEvent e) { 
     int key = e.getKeyCode(); 
     if (key == KeyEvent.VK_UP) { 
      player.setY(playery -= 20); 
     } else if (key == KeyEvent.VK_DOWN) { 
      player.setY(playery += 20); 
     } else if (key == KeyEvent.VK_RIGHT) { 
      player.setX(playerx += 40); 
     } else if (key == KeyEvent.VK_LEFT) { 
      player.setX(playerx -= 40); 
     } 
    } 

    void checkCollisions() { 
     for(int i = 0; i < Shoot.allBullets.size(); i++){ 
      for(int j = 0; j < Enemy.allEnemies.size(); j++){ 
       if(new Rectangle((int)Shoot.allBullets.get(i).x, (int)Shoot.allBullets.get(i).y, 23, 48).intersects(new Rectangle((int) Enemy.allEnemies.get(j).x, (int) Enemy.allEnemies.get(j).y, 64, 64))) { 
        bulletIntersectsEnemy(i, j); 
       } 
      } 
     } 
    } 

    void bulletIntersectsEnemy(int bulletIndex, int enemyIndex) { 
     Shoot.allBullets.remove(bulletIndex); 
     Enemy.allEnemies.remove(enemyIndex); 
    } 

    /* 
    public void manageCollisions() { 
     for (int i = 0; i < Shoot.allBullets.size(); i++) { 
      for (int e = 0; e < Enemy.allEnemies.size(); e++) { 
       if (Shoot.allBullets.get(i).x > Enemy.allEnemies.get(e).y) { 
        if (Shoot.allBullets.get(i).x < Enemy.allEnemies.get(e).y) { 
         if (Shoot.allBullets.get(i).y == Enemy.allEnemies.get(e).y + 64) { 
          System.out.println("Collision Detected!"); 
         } 
        } 
       } 
      } 
     } 
    } 
    */ 

    public void keyTyped(KeyEvent e) {} 

    public static void main(String[] args) { 

     Game game = new Game(); 
     JFrame frame = new JFrame(TITLE); 

     frame.setSize(WIDTH, HEIGHT); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setResizable(false); 
     frame.add(game); 
     frame.getContentPane().setBackground(Color.BLACK); 
     frame.setVisible(true); 

     game.start(); 

    } 

} 

Enemy.java

package main; 

import java.util.ArrayList; 

public class Enemy { 

    static ArrayList<Point> allEnemies = new ArrayList<Point>(); 

    public static ArrayList<Point> createEnemies(int round) { 
     for (int i = 0; i < round; i++) { 
      Point newEnemyLocation = new Point((int) (Math.random()*Game.WIDTH), 0); 
      double newx = validate(newEnemyLocation.x); 
      newEnemyLocation.x = newx; 
      allEnemies.add(newEnemyLocation); 
     } 
     return allEnemies; 
    } 

    private static double validate(double x) { 
     for (int i = 0; i < allEnemies.size();i++) { 
      Point otherEnemy = allEnemies.get(i); 
      if (x > otherEnemy.x) { 
       if (x < (otherEnemy.x - 64)) { 
        x += 200; 
       } 
      } 
     } 
     if (x > Game.WIDTH - 64) { 
      x -= 64; 
     } 
     if (x < 64) { 
      x += 64; 
     } 
     return x; 
    } 

    public static ArrayList<Point> updateEnemies() { 
     if (allEnemies.size() != 0) { 
      for (int i = 0; i < allEnemies.size(); i++) { 
       Point enemyLocation = allEnemies.get(i); 
       if (enemyLocation.y <= Game.HEIGHT) { 
        allEnemies.get(i).y += 1; 
       } else { 
        allEnemies.remove(i); 
       } 
      } 
     } 
     return allEnemies; 
    } 

} 

Стрелять .java

package main; 

import java.util.ArrayList; 

public class Shoot { 

    static ArrayList<Point> allBullets = new ArrayList<Point>(); 

    public static void addBullet(int x, int y) { 
     allBullets.add(new Point(x, y)); 
    } 

    public static ArrayList<Point> getAllBulletPosistions() { 
     return allBullets; 
    } 

    public static void updateBullets() { 
     if (allBullets.size() != 0) { 
      for (int i = 0; i < allBullets.size(); i++) { 
       allBullets.get(i).y -= 5; 
      } 
     } 
    } 

} 

Player.java

package main; 

public class Player { 

    int x, y; 

    public Player(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 

    public void setX(int x) { 
     this.x = x; 
    } 

    public void setY(int y) { 
     this.y = y; 
    } 

} 
+0

необходимо указать какой-то код, просто причина исключения не достаточно –

+0

я сделал, я дал ссылку, где вы можете скачать мой код от –

+1

Вы должны предоставить код - только соответствующий фрагмент кода, который вы должны выработайте обычную диагностику, отладку и т. д. - * в вопросе *. –

ответ

2
void checkCollisions() { 
    for(int i = 0; i < Shoot.allBullets.size(); i++){ 
     for(int j = 0; j < Enemy.allEnemies.size(); j++){ 
      if(new Rectangle((int)Shoot.allBullets.get(i).x, (int)Shoot.allBullets.get(i).y, 23, 48).intersects(new Rectangle((int) Enemy.allEnemies.get(j).x, (int) Enemy.allEnemies.get(j).y, 64, 64))) { 
       bulletIntersectsEnemy(i, j); 
      } 
     } 
    } 
} 

void bulletIntersectsEnemy(int bulletIndex, int enemyIndex) { 
    Shoot.allBullets.remove(bulletIndex); 
    Enemy.allEnemies.remove(enemyIndex); 
} 

Проблема заключается в том, что вы на самом деле удалить ваши пули преждевременно. Допустим, вы стреляете только одной пулей, и есть три врага. Он попадает в первую.

Теперь вы удаляете пулю из списка Shoot.allBullets, но внутренний цикл for еще не закончен. Он все равно будет пытаться увидеть,

Shoot.allBullets.get(0) 

(i по-прежнему 0) пересекается с другими врагами. За исключением того, что Bullet больше не существует, вы получите это исключение.

+0

Я исправил это, и теперь он работает! Благодаря! –

+0

Рад, что я мог помочь. Я был бы признателен, если бы вы отметили это как правильный ответ;) – Mark

Смежные вопросы