XXXconanXXX
Cocktails anyone?
- Reaction score
- 284
Long time no see, eh?
Got a question for you guys in this fine establishment. I've been working on a very simple, bare-bones 2D shooting game in Java that's reminiscent of Pong, and am having a rather unsightly bug with the collision detection.
Seems that whenever either player gets any closer than about 30 pixels from the bullet about to hit, they still get hit. Odd thing is, it only happens when the player is below the bullet and not above.
Here's the code:
Shooter.java
Bullet.java
Player.java
GameObject.java
Any ideas on what may be causing this? I've been scouring the code for quite some time and have tried a multitude of techniques but nothing seems to be alleviating the problem.
The collision detection for the bullets is nested in the Bullet.update method, and there seems to be no discernible reason as to what is causing this. Is it because of the use of a Rect object to draw the players/bullets? Should I delete that and simply stick with the fillRect/clearRect methods and a slightly more convoluted collision detection system by cross-checking the coordinates of the bullets and players for added precision?
Got a question for you guys in this fine establishment. I've been working on a very simple, bare-bones 2D shooting game in Java that's reminiscent of Pong, and am having a rather unsightly bug with the collision detection.
Seems that whenever either player gets any closer than about 30 pixels from the bullet about to hit, they still get hit. Odd thing is, it only happens when the player is below the bullet and not above.
Here's the code:
Shooter.java
Code:
//x coordinates starts at left side and increases to the right, y coordinates start at top and increase going down
import javax.swing.JFrame;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import java.util.concurrent.CopyOnWriteArrayList;
public class Shooter extends JFrame implements KeyListener {
//double buffer vars
private Graphics bufferGraphics;
private Image offscreen;
//end double buffer vars
private Player player1;
private Player player2;
public boolean player1Up = false;
public boolean player1Down = false;
public boolean player2Up = false;
public boolean player2Down = false;
CopyOnWriteArrayList<Bullet> bullets = new CopyOnWriteArrayList<Bullet>();
//Used solely for displaying player winnings
private String win1 = "Player 1 has won the game!";
private String win2 = "Player 2 has won the game!";
private int length = win1.length();
public Shooter() {
setTitle("2D Java Shooter");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setSize(400,800);
setLocation(100,100);
setBackground(Color.BLACK);
setVisible(true);
addKeyListener(this);
player1 = new Player(20, (getHeight()/2)-20, 20, 90, 10);
player2 = new Player(getWidth()-40, (getHeight()/2)-20, 20, 90, 10);
}
public void paint(Graphics g) { //All used for double buffering
offscreen = createImage(getWidth(),getHeight());
bufferGraphics = offscreen.getGraphics();
paintComponent(bufferGraphics);
g.drawImage(offscreen,0,0,null);
repaint();
}
public void paintComponent(Graphics g) { //Actual drawing goes here
if (player1.getHealth() > 0 && player2.getHealth() >0) {
for (Bullet bullet : bullets) {
bullet.draw(g);
bullet.update(this, 0);
}
} else if (player1.getHealth() == 0) {
g.setColor(Color.WHITE);
g.drawString(win2,125,400);
} else if (player2.getHealth() == 0) {
g.setColor(Color.WHITE);
g.drawString(win1,125,400);
}
player1.draw(g);
player1.update(this, 1);
player2.draw(g);
player2.update(this, 2);
g.drawString("P1 HEALTH: "+player1.getHealth(),20,50);
g.drawString("P2 HEALTH: "+player2.getHealth(),getWidth()-100,50);
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) { //player 2
player2Up = true;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
player2Down = true;
} else if (e.getKeyCode() == KeyEvent.VK_W) { //player 1
player1Up = true;
} else if (e.getKeyCode() == KeyEvent.VK_S) {
player1Down = true;
}
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_UP) { //player 2
player2Up = false;
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
player2Down = false;
} else if (e.getKeyCode() == KeyEvent.VK_W) {
player1Up = false;
} else if (e.getKeyCode() == KeyEvent.VK_S) {
player1Down = false;
} else if (e.getKeyCode() == KeyEvent.VK_SPACE) { //Player 1 shooting
Bullet player1Bullet = new Bullet(player2, 1, player1.getXPos()+20,player1.getYPos()+45,6,4,0);
bullets.add(player1Bullet);
} else if (e.getKeyCode() == KeyEvent.VK_ENTER) { //Player 2 shooting
Bullet player2Bullet = new Bullet(player1, -1, player2.getXPos()-4,player2.getYPos()+45,6,4,0);
bullets.add(player2Bullet);
}
}
@Override
public void keyTyped(KeyEvent e) {
}
public static void main(String[] args) {
new Shooter();
}
}
Bullet.java
Code:
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Rectangle;
public class Bullet extends GameObject {
private int deltaX; //Determines which way the bullets shooting, 1 to go right and = -1 to go left
private Player player;
public Bullet(Player player, int deltaX, int xPos, int yPos, int width, int height, int health) {
this.player = player;
this.deltaX = deltaX;
this.xPos = xPos;
this.yPos = yPos;
this.width = width;
this.height = height;
this.health = health;
this.rect = new Rectangle(xPos, yPos, width, height);
}
@Override
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(xPos, yPos, width,height);
}
@Override
public void update(Shooter shooter, int id) {
if(rect.intersects(player.rect)) { //collision detection for bullets
player.setHealth(player.getHealth()-1);
shooter.bullets.remove(this);
} else if (xPos < 1 || xPos > 390) {
shooter.bullets.remove(this);
} else {
xPos += deltaX;
rect.x += deltaX;
}
}
}
Player.java
Code:
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Rectangle;
public class Player extends GameObject {
public Player(int xPos, int yPos, int width, int height, int health) {
this.xPos = xPos;
this.yPos = yPos;
this.width = width;
this.height = height;
this.health = health;
this.rect = new Rectangle(xPos, yPos, width, height);
}
@Override //instructs compiler that we intend to override superclass (This case, GameObject)
public void draw(Graphics g) {
g.setColor(Color.WHITE);
g.fillRect(xPos, yPos, width,height);
}
@Override
public void update(Shooter shooter, int id) {
if(id ==1){
if(shooter.player1Up) {
if(!(yPos < 27)){
yPos = yPos-4;
rect.y--;
}
} else if(shooter.player1Down) {
if(!(yPos > shooter.getHeight() - 96)){
yPos = yPos+4;
rect.y++;
}
}
}else if (id == 2){
if(shooter.player2Up) {
if(!(yPos < 27)){
yPos = yPos-4;
rect.y--;
}
} else if(shooter.player2Down) {
if(!(yPos > shooter.getHeight() - 96)){
yPos = yPos+4;
rect.y++;
}
}
}
}
}
GameObject.java
Code:
import java.awt.Graphics;
import java.awt.Rectangle;
public abstract class GameObject {
protected Rectangle rect;
protected int xPos;
protected int yPos;
protected int width;
protected int height;
protected int health;
abstract void draw(Graphics g);
void update(Shooter shooter, int id) {
}
public int getXPos() {
return xPos;
}
public void setXPos(int pos) {
this.xPos = pos;
}
public int getYPos() {
return yPos;
}
public void setYPos(int pos) {
this.yPos = pos;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
}
Any ideas on what may be causing this? I've been scouring the code for quite some time and have tried a multitude of techniques but nothing seems to be alleviating the problem.
The collision detection for the bullets is nested in the Bullet.update method, and there seems to be no discernible reason as to what is causing this. Is it because of the use of a Rect object to draw the players/bullets? Should I delete that and simply stick with the fillRect/clearRect methods and a slightly more convoluted collision detection system by cross-checking the coordinates of the bullets and players for added precision?