How come the collision detection only works sometimes? - java

I am creating an android app and I am creating a game and the droid has to be able to bounce off the walls and the edge of the screen. Here is my update method in my MainGamePanel.java file where I call the collision detection.
It works when it just has to bounce off the edge of the screen. However when I try to get it bounce off the wall objects it sometimes works. When it doesn't, it goes through the wall sometimes, although this only happens when it moves up and down. It also sometimes gets stuck in the wall. How would I modify the collision detection so I won't have these issues. Any help would be much appreciated.
public void update()
{
// check collision with right wall if heading right
if (droid.getSpeed().getxDirection() == Speed.DIRECTION_RIGHT
&& droid.getX() + droid.getBitmap().getWidth() / 2 >= getWidth()) {
droid.getSpeed().toggleXDirection();
}
// check collision with left wall if heading left
else if (droid.getSpeed().getxDirection() == Speed.DIRECTION_LEFT
&& droid.getX() - droid.getBitmap().getWidth() / 2 <= 0) {
droid.getSpeed().toggleXDirection();
droid.getSpeed().setYv(0);
}
// check collision with bottom wall if heading down
else if (droid.getSpeed().getyDirection() == Speed.DIRECTION_DOWN
&& droid.getY() + droid.getBitmap().getHeight() / 2 >= getHeight()) {
droid.getSpeed().toggleYDirection();
droid.getSpeed().setXv(0);
}
// check collision with top wall if heading up
else if (droid.getSpeed().getyDirection() == Speed.DIRECTION_UP
&& droid.getY() - droid.getBitmap().getHeight() / 2 <= 0) {
droid.getSpeed().toggleYDirection();
droid.getSpeed().setXv(0);
}
for (int i = 0 ; i < listOfWs.length ; i++)
{
if (droid.getX() +(droid.getBitmap().getWidth()/2)+1 > listOfWs [i].giveLeft ()
&& droid.getX()-(droid.getBitmap().getWidth()/2)-1 < listOfWs [i].giveRight ()
&& droid.getY()+(droid.getBitmap().getHeight()/2)+1 > listOfWs [i].giveTop ()
&& droid.getY()-(droid.getBitmap().getHeight()/2)-1 < listOfWs [i].giveBottom () )
{
if(droid.getSpeed().getYv()==0){
droid.getSpeed().toggleXDirection();//Takes the speed and multiplies it by -1 so it changes direction
}
else{
droid.getSpeed().toggleYDirection();
}
}
}
// Update the lone droid
droid.update();
}
Here is my droid.java file that I used.
public class Droid {
private Bitmap bitmap; // the actual bitmap
private int x; // the X coordinate
private int y; // the Y coordinate
public Speed speed;
public Droid(Bitmap bitmap, int x, int y) {
this.bitmap = bitmap;
this.x = x;
this.y = y;
speed= new Speed();
}
public Bitmap getBitmap() {
return bitmap;
}
public void setBitmap(Bitmap bitmap) {
this.bitmap = bitmap;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void draw(Canvas canvas) {
canvas.drawBitmap(bitmap, x - (bitmap.getWidth() /2), y - (bitmap.getHeight() / 2), null);
}
public void update() {
x += (int)(speed.getXv() * speed.getxDirection());
y += (int)(speed.getYv() * speed.getyDirection());
}
public Speed getSpeed(){
return speed;
}
}
This is the speed.java file.
public class Speed {
public static final int DIRECTION_RIGHT = 4;
public static final int DIRECTION_LEFT = -4;
public static final int DIRECTION_UP = -4;
public static final int DIRECTION_DOWN = 4;
private float xv = 1; // velocity value on the X axis
private float yv = 1; // velocity value on the Y axis
private int xDirection = DIRECTION_RIGHT;
private int yDirection = DIRECTION_DOWN;
public Speed() {
this.xv = 1;
this.yv = 1;
}
public Speed(float xv, float yv) {
this.xv = xv;
this.yv = yv;
}
public float getXv() {
return xv;
}
public void setXv(float xv) {
this.xv = xv;
}
public float getYv() {
return yv;
}
public void setYv(float yv) {
this.yv = yv;
}
public int getxDirection() {
return xDirection;
}
public void setxDirection(int xDirection) {
this.xDirection = xDirection;
}
public void setRight() {
xDirection = DIRECTION_RIGHT;
}
public void setLeft() {
xDirection = DIRECTION_LEFT;
}
public void setUp() {
yDirection = DIRECTION_UP;
}
public void setDown() {
yDirection = DIRECTION_DOWN;
}
public int getyDirection() {
return yDirection;
}
public void setyDirection(int yDirection) {
this.yDirection = yDirection;
}
// changes the direction on the X axis
public void toggleXDirection() {
xDirection = xDirection * -1;
}
// changes the direction on the Y axis
public void toggleYDirection() {
yDirection = yDirection * -1;
}
}

in the update method, in for circulation, it seems you make your logical operation there, would you make it more specific?

Related

Error in setting my character in the right color pixel in java

I am having some issues trying to set my character to spawn in the right color spot in my map sheet in java.
In the vídeos that I am watching to learn this I have every single line code identical to the vídeo but yet my character instead of spawning in the right spot is spawning in the up middle corner of the screen.
I'm using those code lines to make him and all Tiles and Entities spawn in the right spot :
public class World {
private Tile[] tiles;
public static int WIDTH,HEIGHT;
public World(String path) {
try {
BufferedImage map = ImageIO.read(getClass().getResource(path));
int[] pixels = new int[map.getWidth() * map.getHeight()];
WIDTH = map.getWidth();
HEIGHT = map.getHeight();
tiles = new Tile[map.getWidth() * map.getHeight()];
map.getRGB(0, 0, map.getWidth(), map.getHeight(), pixels, 0, map.getWidth());
for(int xx = 0; xx < map.getWidth(); xx++) {
for(int yy = 0; yy < map.getHeight(); yy++) {
int pixelAtual = pixels[xx + (yy*map.getWidth())];
tiles[xx + (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);
if(pixelAtual == 0xFF000000) {
//FLOOR
tiles[xx + (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_FLOOR);
}else if(pixelAtual == 0xFFFFFFFF){
//PAREDE
tiles[xx + (yy * WIDTH)] = new FloorTile(xx*16,yy*16, Tile.TILE_WALL);
}else if(pixelAtual == 0xFF0026FF) {
//Player
Game.player.setX(xx*16);
Game.player.setY(yy*16);
}else if(pixelAtual == 0xFFFF0000){
//Enemy
}else if(pixelAtual == 0xFFFF00DC) {
//WEAPON
}else if(pixelAtual == 0xFFFF7F7F) {
//LIFEPACK
}else if(pixelAtual == 0xFFFFD800) {
//BULLET
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void render(Graphics g) {
for(int xx = 0; xx < WIDTH; xx++) {
for(int yy = 0; yy < HEIGHT; yy++) {
Tile tile = tiles[xx + (yy*WIDTH)];
tile.render(g);
}
}
}
}
But when I use these two code lines that are from my Entity Class that are suposed to make my character spawn in the right place it doesn't work at all!
Game.player.setX(xx16);
Game.player.setY(yy16);
Here's my Entity Class for you to see if i did something wrong, and again, i did everything exactely like int the vídeo an in the vídeo it worked.
public class Entity {
public static BufferedImage LIFEPACK_EN = Game.spritesheet.getSprite(78, 0, 16, 16);
public static BufferedImage WEAPON_EN = Game.spritesheet.getSprite(96, 0, 16, 16);
public static BufferedImage BULLET_EN = Game.spritesheet.getSprite(78, 16, 16, 16);
public static BufferedImage ENEMY_EN = Game.spritesheet.getSprite(96, 16, 16, 16);
protected double x;
protected double y;
protected int width;
protected int height;
private BufferedImage sprite;
public Entity(int x, int y, int width, int height, BufferedImage sprite) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.sprite = sprite;
}
public void setX(int newX) {
this.x = newX;
}
public void setY(int newY) {
this.x = newY;
}
public int getX() {
return (int)this.x;
}
public int getY() {
return (int)this.y;
}
public int getWidth() {
return this.width;
}
public int getHeight() {
return this.height;
}
public void update() {
}
public void render(Graphics g) {
g.drawImage(sprite, this.getX(), this.getY(), null);
}
}
I saw where I was wrong.
public void setY(int newY) {
this.x = newY;
In this line code here, it's suposed to be this.y and I thought that I did that, but I couldn't see.

Can't seem to access the image file in my PlayerClass even though it is properly loaded

I'm creating a 2D java game and ran into a nullpointer exception. Whenever I call my render in the playstate class, it throws the exception. I had previously rendered the Font file and got it to work when commenting out the player object references. The player "linkformatted.png" file is able to load after trying and catching, but the nullpointer exception stays. Changing the values didn't work.
public class PlayState extends GameState {
private Font font;
private Player player;
public PlayState(GameStateManager gsm) {
super(gsm);
font = new Font("font/ZeldaFont.png", 16, 16);
player = new Player(new Sprite("entity/linkformatted.png"), new Vector2f(100, 100), 32);
}
public void update() {
player.update();
}
public void input(MouseHandler mouse, KeyHandler key) {
player.input(mouse, key);
}
public void render(Graphics2D g) {
Sprite.drawArray(g, font, "YOU", new Vector2f(100, 100), 32, 32, 16, 0);
player.render(g);
}
}
public class Sprite {
private BufferedImage SPRITESHEET = null;
private BufferedImage[][] spriteArray;
private final int TILE_SIZE = 32;
public int w;
public int h;
private int wSprite;
private int hSprite;
public Sprite(String file) {
w = TILE_SIZE;
h = TILE_SIZE;
System.out.println("Loading: " + file + "...");
SPRITESHEET = loadSprite(file);
wSprite = SPRITESHEET.getWidth() / w;
hSprite = SPRITESHEET.getHeight() / h;
loadSpriteArray();
}
public Sprite(String file, int w, int h) {
this.w = w;
this.h = h;
System.out.println("Loading: " + file + "...");
SPRITESHEET = loadSprite(file);
wSprite = SPRITESHEET.getWidth() / w;
hSprite = SPRITESHEET.getHeight() / h;
loadSpriteArray();
}
public void setSize(int width, int height) {
setWidth(width);
setHeight(height);
}
public void setWidth(int i) {
w = i;
wSprite = SPRITESHEET.getWidth() / w;
}
public void setHeight(int i) {
h = i;
hSprite = SPRITESHEET.getHeight() / h;
}
public int getWidth() {
return w;
}
public int getHeight() {
return h;
}
private BufferedImage loadSprite(String file) {
BufferedImage sprite = null;
try {
sprite = ImageIO.read(getClass().getClassLoader().getResourceAsStream(file));
} catch(Exception e) {
System.out.println("Error: could not load file: " + file);
}
return sprite;
}
public void loadSpriteArray() {
spriteArray = new BufferedImage[wSprite][hSprite];
for(int x = 0; x < wSprite; x++) {
for(int y = 0; y < hSprite; y++) {
spriteArray[x][y] = getSprite(x, y);
}
}
}
public BufferedImage getSpriteSheet() {
return SPRITESHEET;
}
public BufferedImage getSprite(int x, int y) {
return SPRITESHEET.getSubimage(x * w, y * h, w, h);
}
public BufferedImage[] getSpriteArray(int i) {
return spriteArray[i];
}
public BufferedImage[][] getSpriteArray2(int i) {
return spriteArray;
}
public static void drawArray(Graphics2D g, ArrayList<BufferedImage> img, Vector2f pos, int width, int height, int xOffset, int yOffset) {
float x = pos.x;
float y = pos.y;
for(int i = 0; i < img.size(); i++) {
if(img.get(i) != null) {
g.drawImage(img.get(i), (int) x, (int) y, width, height, null);
}
x += xOffset;
y += yOffset;
}
}
public static void drawArray(Graphics2D g, Font f, String word, Vector2f pos, int width, int height, int xOffset, int yOffset) {
float x = pos.x;
float y = pos.y;
for(int i = 0; i < word.length(); i++ ) {
if(word.charAt(i) != 32); // the space
g.drawImage(f.getFont(word.charAt(i)), (int) x, (int) y, width, height, null);
x += xOffset;
y += yOffset;
}
}
}
public class Animation {
private BufferedImage[] frames;
private int currentFrame;
private int numFrames;
private int count;
private int delay;
private int timesPlayed;
public Animation(BufferedImage[] frames) {
timesPlayed = 0;
setFrames(frames);
}
public Animation() {
timesPlayed = 0;
}
public void setFrames(BufferedImage[] frames) {
frames = frames;
currentFrame = 0;
timesPlayed = 0;
delay = 2;
numFrames = frames.length;
}
public void setDelay(int i) { delay = i;}
public void setFrame(int i) { currentFrame = i;}
public void setNumFrames(int i) { numFrames = i;}
public void update() {
if(delay == -1) return;
count++;
if(count == delay) {
currentFrame++;
count = 0;
}
if(currentFrame == numFrames) {
currentFrame = 0;
timesPlayed++;
}
}
public int getDelay() {
return delay;
}
public int getFrame() {
return currentFrame;
}
public int getCount() {
return count;
}
public BufferedImage getImage() {
return frames[currentFrame];
}
public boolean hasPlayedOnce() {
return timesPlayed > 0;
}
public boolean hasPlayed(int i) {
return timesPlayed == i;
}
}
public class Player extends Entity {
public Player(Sprite sprite, Vector2f origin, int size) {
super(sprite, origin, size);
}
public void move() {
if(up) {
dy -= acc;
if(dy < -maxSpeed) {
dy = -maxSpeed;
}
} else {
if(dy < 0) {
dy += deacc;
if(dy > 0) {
dy = 0;
}
}
}
if(down) {
dy += acc;
if(dy < maxSpeed) {
dy = maxSpeed;
}
} else {
if(dy > 0) {
dy -= deacc;
if(dy < 0) {
dy = 0;
}
}
}
if(left) {
dx -= acc;
if(dx < -maxSpeed) {
dy = -maxSpeed;
}
} else {
if(dx < 0) {
dx += deacc;
if(dx > 0) {
dx = 0;
}
}
}
if(right) {
dx += acc;
if(dx > maxSpeed) {
dy = maxSpeed;
}
} else {
if(dx > 0) {
dx -= deacc;
if(dx < 0) {
dx = 0;
}
}
}
}
public void update() {
super.update();
move();
pos.x = dx;
pos.y = dy;
}
#Override
public void render(Graphics2D g) {
g.drawImage(ani.getImage(), (int) (pos.x), (int) (pos.y), size, size, null);
}
public void input(MouseHandler mouse, KeyHandler key) {
if(key.up.down) {
up = true;
} else {
up = false;
}
if(key.down.down) {
down = true;
} else {
down = false;
}
if(key.left.down) {
left = true;
} else {
left = false;
}
if(key.right.down) {
right = true;
} else {
right = false;
}
if(key.attack.down) {
attack = true;
} else {
attack = false;
}
}
}
Here is what is printed:
Loading: entity/linkformatted.png...
Exception in thread "GameThread" java.lang.NullPointerException
at com.zwellis.game.graphics.Animation.getImage(Animation.java:62)
at com.zwellis.game.entity.Player.render(Player.java:82)
at com.zwellis.game.states.PlayState.render(PlayState.java:34)
at com.zwellis.game.states.GameStateManager.render(GameStateManager.java:71)
at com.zwellis.game.GamePanel.render(GamePanel.java:133)
at com.zwellis.game.GamePanel.run(GamePanel.java:90)
at java.base/java.lang.Thread.run(Thread.java:834)
Here is what happens when I made another file to display the image:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
public class ImageInFrame {
public static void main(String[] args) throws IOException {
String path = "entity/linkformatted.png";
File file = new File(path);
BufferedImage image = ImageIO.read(file);
JLabel label = new JLabel(new ImageIcon(image));
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(label);
f.pack();
f.setLocation(200,200);
f.setVisible(true);
}
}
Here is what happens:
Exception in thread "main" javax.imageio.IIOException: Can't read input file!
at java.desktop/javax.imageio.ImageIO.read(ImageIO.java:1308)
at ImageInFrame.main(ImageInFrame.java:11)
Here is also the github link
https://github.com/xfyktcl/ZwellisKnight.git

Projectiles in my ArrayList are not changed individually upon collision, how can I fix this?

I am trying to make a game. I want the projectiles (balls) that I shoot to each have their own individual collisions with objects and the margins of the game screen, but right now when one ball collides with the game screen margins, every balls' velocity.x or velocity.y is multiplied by -1 to simulate collision rather than just the individual ball that hit's velocity being modified. (When one ball hits, all balls' velocities are affected). The projectiles are stored in an ArrayList in the GameWorld class and are all given an identical velocity when they are shot. You pick a direction to shoot in, then balls are shot every 0.3s in that direction until all balls are shot.
Here is the code from my Projectiles class:
package com.trimble.gameobjects;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Vector2;
import com.trimble.gameworld.GameWorld;
public class Projectile {
private Vector2 velocity, acceleration;
private Vector2 position;
private final float RADIUS = 3f;
private boolean active, shot;
private GameWorld world;
private float theta;
public Projectile(float x, GameWorld world) {
this.world = world;
this.position = new Vector2();
this.position.x = x;
this.position.y = world.getGameRect().y - 3;
// hitbox = new Circle(position, 3f);
this.velocity = new Vector2();
this.acceleration = new Vector2(0, 0.5f);
this.active = false;
this.shot = false;
}
public void update(float delta) {
if (active) {
position.add(velocity.cpy().scl(delta));
velocity.add(acceleration.cpy().scl(delta));
// left
if (this.position.x <= 3) {
Gdx.app.log("hit", " left");
this.position.x = 3;
this.velocity.x *= -1;
}
// right
else if (this.position.x >= world.getGameRect().width - 3) {
Gdx.app.log("hit", " right");
this.position.x = world.getGameRect().width - 3;
this.velocity.x *= -1;
}
// top
if (this.position.y < world.getGameRect().y + world.getGameRect().height + 3) {
Gdx.app.log("hit", " top");
this.position.y = world.getGameRect().y + world.getGameRect().height + 3;
this.velocity.y *= -1;
}
// bottom
else if (this.position.y > world.getGameRect().y - 3 && velocity.y > 0) {
Gdx.app.log("hit", " bottom");
if (!this.world.hasTouched()) {
this.world.getBaseCircle().setPositionX(position.x);
this.world.setTouched(true);
}
zeroVelocity();
this.active = false;
this.position = world.getBaseCirclePos();
this.world.addInactive();
}
}
}
public Vector2 getVelocity() {
return velocity;
}
public float getVelocityX() {
return velocity.x;
}
public float getVelocityY() {
return velocity.y;
}
public void setVelocity(Vector2 velocity) {
this.velocity = velocity;
}
public void setVelocityX(float x) {
this.velocity.x = x;
}
public void setVelocityY(float y) {
this.velocity.y = y;
}
public float getTheta() {
return theta;
}
public void setTheta(float theta) {
this.theta = theta;
}
public void zeroVelocity() {
this.velocity.x = 0;
this.velocity.y = 0;
}
public Vector2 getPosition() {
return position;
}
public void setPositionY(float y) {
this.position.y = y;
}
public void setPositionX(float x) {
this.position.x = x;
}
public void setPosition(Vector2 position) {
this.position = position;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public float getR() {
return RADIUS;
}
public boolean wasShot() {
return shot;
}
public void setShot(boolean shot) {
this.shot = shot;
}
}
Here is the code in GameWorld which is called when the player shoots:
public void transitionHasShot() {
if (currentState == GameState.READY) {
currentState = GameState.HASSHOT;
velocity.y = (float) (-165 * Math.sin(theta));
velocity.x = (float) (165 * Math.cos(theta));
baseCircle.setActive(false);
for (Projectile p : projectiles) {
p.setVelocity(velocity);
}
projectiles.get(0).setActive(true);
}
}
Let me know if you need any more info.
I solved the problem by changing the code in transitionHasShot():
change
for (Projectile p : projectiles) {
p.setVelocity(velocity);
}
to:
for (Projectile p : projectiles) {
p.setVelocity(velocity.cpy());
}

My x and y variables only sometimes change

I am testing out a Player object in a game I am trying to build, and I have begun testing my input using a white rectangle on the screen through OpenGL in LWJGL.
The problem is that when I compile the code and try moving the rectangle using the arrow keys, the rectangle only responds to RIGHT and DOWN. When testing it out in the loop, it appears the dx and dy are changing in the move() method, but the change does not persist into the updateXY() method.
-SNIP- (jump problem has been fixed)
I am completely stumped as to why this could be and I would love to get some help
Thanks in advance
EDIT: Added the AbstractMoveableEntity class
EDIT: Updated the code to reflect the current problem
public class Player extends AbstractMoveableEntity implements MoveableEntity {
MouseHandler m;
private double tx, ty;
private double SPEED;
private enum DIR{
UP, DOWN, LEFT, RIGHT;
}
public Player(double x, double y, MouseHandler m) {
super(x, y, 50, 50);
this.m = m;
this.tx = x;
this.ty = y;
this.ax = 0;
this.ay = 0;
this.SPEED = 5;
}
public void draw() {
glRectd(x,y,x+width,y+height);
}
public void update(int delta) {
updateXY();
draw();
}
public void updateXY(){
input();
//Updating target, velocity and position values
this.tx += this.dx;
this.ty += this.dy;
this.dx += this.ax;
this.dy += this.ay;
this.x += this.dx;
this.y += this.dy;
//Acceleration handling
if(tx > x){
this.ax += 1;
} else if(tx < x) {
this.ax -= 1;
} else {
this.ax = 0;
}
if(ty > y){
this.ay += 1;
} else if(ty < y) {
this.ay -= 1;
} else {
this.ay = 0;
}
}
public void input(){
//Event-Driven input
while(Keyboard.next()){
if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)){
if(ay == 0){
jump();
} else {
x = tx;
y = ty;
ay = 0;
}
}
}
//Polled input
if(Keyboard.isKeyDown(Keyboard.KEY_UP)){
move(DIR.UP);
} else {
stop(DIR.UP);
}
if(Keyboard.isKeyDown(Keyboard.KEY_DOWN)){
move(DIR.DOWN);
} else {
stop(DIR.DOWN);
}
if(Keyboard.isKeyDown(Keyboard.KEY_LEFT)){
move(DIR.LEFT);
} else {
stop(DIR.LEFT);
}
if(Keyboard.isKeyDown(Keyboard.KEY_RIGHT)){
move(DIR.RIGHT);
} else {
stop(DIR.RIGHT);
}
}
public void jump(){
setAY(-10);
System.out.println("JUMP " + ay);
}
public void move(DIR d){
if(d == DIR.UP){
this.dy = -SPEED;
} else if(d == DIR.DOWN){
this.dy = SPEED;
} else if(d == DIR.LEFT){
this.dx = -SPEED;
} else{
this.dx = SPEED;
}
}
public void stop(DIR d){
if(d == DIR.UP || d == DIR.DOWN){
this.dy = 0;
} else {
this.dx = 0;
}
}
}
Public abstract class AbstractMoveableEntity extends AbstractEntity implements MoveableEntity {
protected double dx, dy, ax, ay;
public AbstractMoveableEntity(double x, double y, double width, double height) {
super(x, y, width, height);
this.dx = 0;
this.dy = 0;
this.ax = 0;
this.ay = 0;
}
public double getDX() {
return dx;
}
public double getDY() {
return dy;
}
public void setDX(double dx) {
this.dx = dx;
}
public void setDY(double dy) {
this.dy = dy;
}
public void setAX(double ax){
this.ax = ax;
}
public void setAY(double ay) {
this.ay = ay;
}
}
The problem is the part in the input() function marked //Polled input.
When the user presses the KEY_UP key, the first if-condition calls move(DIR.UP). At this point, dy is set to -SPEED. Then the next if-condition checks whether the user is pressing the KEY_DOWN key, sees that he isn't, and calls stop(DIR.DOWN). This sets dy to 0, effectively overwriting the previous call to move(DIR.UP).
The situation with LEFT/RIGHT is identical.

How to handle the collision between two arraylist objects?

I have a problem with my code here. I want to make a game with thow ball on each side of screen, on ball being controlled by the user and the other one by the computer. Both ball shoot to each other, and if the bullets intersects one with another, i need to make something happen. I managed to do some thing here, and I have two class, one for the player bullets, and the other one for the enemies bullets, and the bullets are created trough arraylists. All works fin until now, but if I try ti make them collision with each other,it doesnt work at all. I've tried a lot of things but none of it worked, and I would really appreciate if someone could help me.
That is the Player Projectile class:
import java.awt.Rectangle;
public class Projectiles {
private int x, y, speedX;
private boolean visible;
private int width = 10;
private int height = 10;
private Rectangle r;
public Projectiles(){
}
public Projectiles(int startX, int startY) {
x = startX;
y = startY;
speedX = 1;
visible = true;
r = new Rectangle(0, 0, 0, 0);
}
public void update(){
x += speedX;
r.setBounds(x, y, width, height);
if (x > 800){
visible = false;
r = null;
}
if (x < 800){
checkCollision();
}
}
private void checkCollision() {
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getSpeedX() {
return speedX;
}
public boolean isVisible() {
return visible;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
public Rectangle getR() {
return r;
}
public void setR(Rectangle r) {
this.r = r;
}
}
And this one is the Enemy_Projectile class:
import java.awt.Rectangle;
public class Enemy_Projectiles {
private int x, y, speedX;
private boolean visible;
private int width = 30;
private int height = 20;
public static Rectangle r;
Projectiles p1;
public Enemy_Projectiles(int startX, int startY) {
x = startX;
y = startY;
speedX = 1;
visible = true;
r = new Rectangle(0, 0, 0, 0);
}
public void update() {
x -= speedX;
r.setBounds(x, y, width, height);
if (x < 0) {
visible = false;
r = null;
}
if (x > 0){
checkCollision();
}
}
private void checkCollision() {
if(r.intersects(p1.getR())){
visible = false;
System.out.println("Coliziune!!");
}
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getSpeedX() {
return speedX;
}
public boolean isVisible() {
return visible;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public void setSpeedX(int speedX) {
this.speedX = speedX;
}
public void setVisible(boolean visible) {
this.visible = visible;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public void setWidth(int width) {
this.width = width;
}
public void setHeight(int height) {
this.height = height;
}
}
Do not check intersection after the frame has been drawn. Let's say you have a slow computer and your bullets intersect, but they have moved out of intersection in one frame.
You need to apply high school physics/geometry. Calculate where the bullet will be well before you render it. Then, calculate where the ball will be, and construct a line segment for each from where they are now, to where they will be on the next frame. Check if these segments intersect. Then you will have a fool-proof method of checking for intersection.
This method is similar to how physics and intersections between objects are handled inside of a game engine like Unity.

Categories

Resources