I have an error when I shorten 3 lines of code to one.

How come this code works

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import java.util.Vector;

public class Draw extends JPanel implements KeyListener, Runnable, ActionListener{

	Vector<Wall> walls = new Vector<Wall>();
	Vector<Enemy> enemy = new Vector<Enemy>();
	Player p = new Player();
	Vector<Bullet> pBullets = new Vector<Bullet>();
	Timer t = new Timer (20,this);
	Rectangle mobRect;
	
	
	Draw (){
		
	}
	public void getFocus(){
		grabFocus();
		for (int i = 0; i < 28; i++){
			enemy.add(new Enemy (i)); // 7 * 4
		}
		for (Enemy e : enemy){
			e.passInDraw(this);
		}
		for (int i = 0; i < 5; i++){
			walls.add(new Wall (i));
		}
		
		
		addKeyListener(this);
		t.setInitialDelay(500);
		t.start();
		repaint();
	}
	
	public void paintComponent (Graphics g){
		super.paintComponent (g);
		
		g.drawImage(p.playerShip, p.px, p.py, 40, 40, this);
		
		for (Enemy e : enemy){
			g.drawImage(e.enemy, e.x, e.y, 40, 40, this);
		}
		
		for (Bullet b : pBullets){
			g.drawImage (b.bullet, b.bX, b.bY, 4, 4, this);
		}
		
		for (Wall w : walls){
			g.drawImage(w.wallImage, w.wallX, w.wallY, 50, 50, this);
		}
		
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		// animate player & check if player collided with wall
		
		if (right && p.px + 40 <= 495){
			p.px += 2;
		}
		if (left && p.px >= 5){
			p.px -= 2;
		}
		// animate enemy
		for (Enemy en : enemy){
			en.animate();
		}
		// animate player bullets
		for (Bullet b : pBullets){
			b.bY -= 2;
		}
		
		// animate enemy bullet
		
		
		// check collision enemy and wall
		for (Enemy e : enemy){
			if (e.x + 40 == 496){
				changeDirection('l');
			}
			if (e.x == 4){
				changeDirection('r');
			}
		}
		
		// check if player bullet collides with enemy
		int removalBullet = -1;
		for (Bullet b : pBullets){
			int removalElement = -1;
			for (Enemy e : enemy){
				if (e.enRect.contains(b.bX, b.bY)){
					removalElement = enemy.indexOf(e);
					removalBullet = pBullets.indexOf (b);
				}
			}
			if (removalElement != -1){
				enemy.remove(removalElement);
				removalElement = -1;	
			}
			
		}// remove bullets that collided
		if (removalBullet != -1){
			pBullets.remove(removalBullet);
			removalBullet = -1;
		}
		// check bullet to wall
		for (Bullet b : pBullets){
			if (b.bY + 4 <= 0){
				removalBullet = pBullets.indexOf(b);
			}
		}
		removeBullet(removalBullet);
		// bullet to barrier
		int removalWall = -1;
		for (Bullet b : pBullets){
			for (Wall w : walls){
				if (w.wallRect.contains(b.bX + 2,b.bY)){
					w.wallHit();
					removalBullet = pBullets.indexOf(b);
					if (w.wallLife == 0){
						removalWall = walls.indexOf(w);
					}
				}
			}
		}
		removeBullet(removalBullet);
		removeWall(removalWall);
		
		repaint();
		
		
		
	}
	
	private void removeBullet(int removalBullet) {
		// TODO Auto-generated method stub
		if (removalBullet != -1){
			pBullets.remove(removalBullet);
			removalBullet = -1;
		}
	}
	private void removeWall (int removalWall){
		if (removalWall != -1){
			walls.removeElementAt(removalWall);
			removalWall = -1;
		}
	}
	
	private void changeDirection(char c) {
		// TODO Auto-generated method stub
		if (c == 'r'){
			for (Enemy e : enemy){
				e.right = true;
				e.y += 1;
			}
		}
		else if (c == 'l'){
			for (Enemy e : enemy){
				e.right = false;
				e.y += 1;
			}
		}
	}

	boolean right = false, left = false;
	
	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();
		if (key == KeyEvent.VK_LEFT){
			left = true;
		}
		if (key == KeyEvent.VK_RIGHT){
			right = true;
		}
		if ((key == KeyEvent.VK_SPACE || key == KeyEvent.VK_UP) && p.canShoot){
			System.out.println("Shot");
			p.canShoot = false;
			p.shootTimer.start();
			addPlayerBullet();
		}
		
	}
	
	private void addPlayerBullet() {
		pBullets.add(new Bullet ('p',(p.px + 18), p.py));
		
		
	}
	public void keyReleased(KeyEvent e) {
		int key = e.getKeyCode();
		if (key == KeyEvent.VK_LEFT){
			left = false;
		}
		if (key == KeyEvent.VK_RIGHT){
			right = false;
		}
		
	}
	public void keyTyped(KeyEvent e) {}
	@Override
	public void actionPerformed(ActionEvent arg0) {
		System.out.println ("Timer");
		Thread t = new Thread(this);
		t.run();
	}
	
	
}

and this one doesn't?

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;
import java.util.Vector;

public class Draw extends JPanel implements KeyListener, Runnable, ActionListener{

	Vector<Wall> walls = new Vector<Wall>();
	Vector<Enemy> enemy = new Vector<Enemy>();
	Player p = new Player();
	Vector<Bullet> pBullets = new Vector<Bullet>();
	Timer t = new Timer (20,this);
	Rectangle mobRect;
	
	
	Draw (){
		
	}
	public void getFocus(){
		grabFocus();
		for (int i = 0; i < 28; i++){
			enemy.add(new Enemy (i)); // 7 * 4
		}
		for (Enemy e : enemy){
			e.passInDraw(this);
		}
		for (int i = 0; i < 5; i++){
			walls.add(new Wall (i));
		}
		
		
		addKeyListener(this);
		t.setInitialDelay(500);
		t.start();
		repaint();
	}
	
	public void paintComponent (Graphics g){
		super.paintComponent (g);
		
		g.drawImage(p.playerShip, p.px, p.py, 40, 40, this);
		
		for (Enemy e : enemy){
			g.drawImage(e.enemy, e.x, e.y, 40, 40, this);
		}
		
		for (Bullet b : pBullets){
			g.drawImage (b.bullet, b.bX, b.bY, 4, 4, this);
		}
		
		for (Wall w : walls){
			g.drawImage(w.wallImage, w.wallX, w.wallY, 50, 50, this);
		}
		
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		// animate player & check if player collided with wall
		
		if (right && p.px + 40 <= 495){
			p.px += 2;
		}
		if (left && p.px >= 5){
			p.px -= 2;
		}
		// animate enemy
		for (Enemy en : enemy){
			en.animate();
		}
		// animate player bullets
		for (Bullet b : pBullets){
			b.bY -= 2;
		}
		
		// animate enemy bullet
		
		
		// check collision enemy and wall
		for (Enemy e : enemy){
			if (e.x + 40 == 496){
				changeDirection('l');
			}
			if (e.x == 4){
				changeDirection('r');
			}
		}
		
		// check if player bullet collides with enemy
		int removalBullet = -1;
		for (Bullet b : pBullets){
			int removalElement = -1;
			for (Enemy e : enemy){
				if (e.enRect.contains(b.bX, b.bY)){
					removalElement = enemy.indexOf(e);
					removalBullet = pBullets.indexOf (b);
				}
			}
			if (removalElement != -1){
				enemy.remove(removalElement);
				removalElement = -1;	
			}
			
		}// remove bullets that collided
		removeBullet (removalBullet);
		// check bullet to wall
		for (Bullet b : pBullets){
			if (b.bY + 4 <= 0){
				removalBullet = pBullets.indexOf(b);
			}
		}
		removeBullet(removalBullet);
		// bullet to barrier
		int removalWall = -1;
		for (Bullet b : pBullets){
			for (Wall w : walls){
				if (w.wallRect.contains(b.bX + 2,b.bY)){
					w.wallHit();
					removalBullet = pBullets.indexOf(b);
					if (w.wallLife == 0){
						removalWall = walls.indexOf(w);
					}
				}
			}
		}
		removeBullet(removalBullet);
		removeWall(removalWall);
		
		repaint();
		
		
		
	}
	
	private void removeBullet(int removalBullet) {
		// TODO Auto-generated method stub
		if (removalBullet != -1){
			pBullets.remove(removalBullet);
			removalBullet = -1;
		}
	}
	private void removeWall (int removalWall){
		if (removalWall != -1){
			walls.removeElementAt(removalWall);
			removalWall = -1;
		}
	}
	
	private void changeDirection(char c) {
		// TODO Auto-generated method stub
		if (c == 'r'){
			for (Enemy e : enemy){
				e.right = true;
				e.y += 1;
			}
		}
		else if (c == 'l'){
			for (Enemy e : enemy){
				e.right = false;
				e.y += 1;
			}
		}
	}

	boolean right = false, left = false;
	
	public void keyPressed(KeyEvent e) {
		int key = e.getKeyCode();
		if (key == KeyEvent.VK_LEFT){
			left = true;
		}
		if (key == KeyEvent.VK_RIGHT){
			right = true;
		}
		if ((key == KeyEvent.VK_SPACE || key == KeyEvent.VK_UP) && p.canShoot){
			System.out.println("Shot");
			p.canShoot = false;
			p.shootTimer.start();
			addPlayerBullet();
		}
		
	}
	
	private void addPlayerBullet() {
		pBullets.add(new Bullet ('p',(p.px + 18), p.py));
		
		
	}
	public void keyReleased(KeyEvent e) {
		int key = e.getKeyCode();
		if (key == KeyEvent.VK_LEFT){
			left = false;
		}
		if (key == KeyEvent.VK_RIGHT){
			right = false;
		}
		
	}
	public void keyTyped(KeyEvent e) {}
	@Override
	public void actionPerformed(ActionEvent arg0) {
		System.out.println ("Timer");
		Thread t = new Thread(this);
		t.run();
	}
	
	
}

All I changes was these lines

if (removalBullet != -1){
	pBullets.remove(removalBullet);
	removalBullet = -1;
}

to this one

removeBullet (removalBullet);

the method has the exact same code, but the first one doesn't cause an error.

The second one causes this error.

Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 0
	at java.util.Vector.remove(Unknown Source)
	at Draw.removeBullet(Draw.java:139)
	at Draw.run(Draw.java:127)
	at java.lang.Thread.run(Unknown Source)
	at Draw.actionPerformed(Draw.java:205)
	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$000(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.awt.EventQueue$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.AccessControlContext$1.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)

The second code works when the bullet hits a wall, or goes off the frame, but not when it hits the enemy. Why is this, and how can I fix it?

Thanks for any help.

Recommended Answers

All 4 Replies

The error message is caused by you trying to remove something from a Vector that is empty (has no elements in it). Presumably the -1 value for removalBullet is some kind of flag, so in the first version you set that value after removing and it stops you trying to remove next time. Without that flag value you presumably try to remove too many times.

is there a way to prevent it from removing the item twice, when it is only supposed to remove it once?

Safest way is to check whether it's present before trying to remove it (there's a method for that).

it is a vector. if I remove it the elements will just slide over one.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.