Java - Removing object from array when it collides with player - java

Im working on a falling blocks game in java where you have to move the player around the screen to dodge the blocks. Whenever you get hit by a block, depending on the block type, it will either decrease or increase a int in the player class. Im having the problem that when the player is hit by the block the int keeps going down until the now invisible block is offscreen. Basically I just need a way to check through a object array and when a object meets a specified condition such as (delete == true) it will set the current position of that block in the array to null.
Method for updating the block position:
public void dropFoods(int speed) {
for (int x = 699 - speed; x >= 0; x--) {
for (int y = 0; y < 7; y++) {
if(x > (699 - GUI.HEIGHT) - 10) {
food[y][x] = null;
continue;
}
food[y][x + speed] = food[y][x];
food[y][x] = null;
}
}
}
Method for drawing the blocks (the food are the different types of blocks):
for(int x = 0; x < food.length; x++) {
for(int y = 0; y < food[x].length; y ++) {
Object o = food[x][y];
if(o instanceof Apple) {
new Apple(x * 100, y - Apple.HEIGHT, g);
}
if(o instanceof Burger) {
new Burger(x * 100, y - Burger.HEIGHT, g);
}
}
}
Method for detecting collision with player:
if(Food.getHitBox().intersects(Player.hitBox())) {
willDraw = false;
Player.weight -= 1;
}

You should provide more code and debugging result first.
if(Food.getHitBox().intersects(Player.hitBox())) {
willDraw = false;
Player.weight -= 1;
}
So when something gets hit by player, do you remove the Food object off the map? Because according to this code, you are not.

Related

Method to find if a snake in a snake game has made a loop

I am relatively new to java, and I have an idea for a mechanic I want to implement in to my game. However, I have no idea how to go about solving this problem. My snake game works on a basic coordinate system. I want it to be so that when the snake makes a closed loop (a rectangle or square) the game will detect it has made a loop. I have tried writing a method to locate the part of the snake's body that is the most upper-left, and then checking from there, but it seems to not work very well. Here is the method I attempted to write, if It helps at all. Thank you for any help!!
public boolean checkRing()
{
int topLeftX = 5000;
int topLeftY = 5000;
for(int i = bodyParts;i>0;i--)
{
// Finds coordinates of top left box
if(x[i] < topLeftX)
{
topLeftX = x[i];
}
if(y[i] < topLeftY)
{
topLeftY = y[i];
}
}
// Use isBody() method below (not bug tested) to check for rectangle
boolean lineFoundVert = false;
int checkingX = topLeftX;
int checkingY = topLeftY;
int vertCounter = 1;
while(!lineFoundVert)
{
if(isBody(checkingX, checkingY))
{
vertCounter++;
checkingX++;
}
else
lineFoundVert = true;
}
boolean lineFoundHori = false;
checkingX = topLeftX;
checkingY = topLeftY;
int horiCounter = 1;
while(!lineFoundHori)
{
if(isBody(checkingX, checkingY))
{
horiCounter++;
checkingY++;
}
else
lineFoundHori = true;
}
debug1X = topLeftX + 1;
debug1Y = topLeftY + vertCounter;
debug2X = topLeftX + horiCounter;
debug2Y = topLeftY + 1;
if(isBody(topLeftX + 1, topLeftY + vertCounter) && isBody(topLeftX + horiCounter, topLeftY + 1))
{
return true;
}
return false;
}```
Here is an approximate solution:
private boolean isEdgeCoordinate(Coordinate[] bodyparts, int index) {
// for every bodypart check that its neighbours (bodypart one before and
// bodypart one after) dont share X axis and dont share Y axis. As long
// as that is the case it is an edge.
//additionally for the last bodypart you needto check that it has first
// bodypart as a neighbour and check them as neighbours otherwise no
// rectangle to begin with
}
using this method check the amount of edges in your bodyparts array. If the total number of edges == 4 you have got a square/rectangle

How to detect if two sprites are being touched at the same time?

I tried this:
if(spr.getBoundingRectangles.contain(x,y)){
//do this
}
but how to detect if the other sprite is touched by the second pointer?
EDIT:
for(int i = 0; i < Constants.MAX_POINTERS; i++){
if(Gdx.input.isTouched(i)){
xy.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
xy1.set(Gdx.input.getX(i), Gdx.input.getY(i), 0);
WorldRenderer.camera.unproject(xy);
WorldRenderer.camera.unproject(xy1);
if(Spr.getBoundingRectangle().contains(xy.x, xy.y) &&
Spr1.getBoundingRectangle().contains(xy.x, xy.y))
score += 1;
}
}
What happens is that xy and xy1 are always the same, when I touch the screen with the second pointer they will just both switch to the new coordinates instead of having two different x,y for both xy and xy1.
you can iterate over all pointers checking whether they are touching the screen and then check if positions overlapping sprites position
final int MAX_POINTERS = 5;
...
for(int i = 0; i < MAX_POINTERS; i++)
{
if( Gdx.input.isTouched(i) )
{
int x = Gdx.input.getX(i);
int y = Gdx.input.getY(i);
if( sprite.getBoundingRectangle().contains(x, y) ) //instead of checking one sprite iterate over sprites array
{
System.out.println("The sprite is touched!");
}
//if... - or just add more ifs
}
}
you need to define max count of pointers to iterate over it - as far as I know Libgdx supports up to 20 pointers
ABOUT EDIT:
Of course they are the same... :) You are placing the same value to vetors. My example above is far more generic that you need - if you know that you have two pointers you can just use:
if( Gdx.input.isTouched(0) && Gdx.input.isTouched(1) ) //because if two pointers are touching screen there is a chance that they are touching two sprites
{
xy.set(Gdx.input.getX(0), Gdx.input.getY(0), 0);
xy1.set(Gdx.input.getX(1), Gdx.input.getY(1), 0);
//checking if pointer 1 is touching sprite 1 and pointer 2 is touching sprite 2 OR VICE VERSA
if( (Spr.getBoundingRectangle().contains(xy.x, xy.y) && Spr1.getBoundingRectangle().contains(xy1.x, xy1.y))
||
(Spr.getBoundingRectangle().contains(xy1.x, xy1.y) && Spr1.getBoundingRectangle().contains(xy.x, xy.y))
)
{
score += 1;
}
}
or just create the function that will return true if all sprites you will pass to it are touched (which actually will can handle more than two sprites)
boolean allTouched(Array<Sprite> sprites)
{
int spritesCount = sprites.size;
int spritesTouched = 0;
for(int i = 0; i < MAX_POINTERS; i++)
{
if( Gdx.input.isTouched(i) )
{
for(Sprite sprite : sprites)
{
if( sprite.getBoundingRectangle().contains(Gdx.input.getX(i), Gdx.input.getY(i)) )
{
spritesTouched++;
sprites.removeValue(sprite, true); //to not doubling the same sprite
}
}
}
}
return spritesCount == spritesTouched ;
}

.intersects always returning true?

I've been working on a game with a mix of awt and slick2d (Rendering is done via awt). Anyway, i'm having a problem with collision. Inside of entity class, I have a collision method:
public boolean colidesWithWall(int idx, int idy) {
//if(Level.solid)
wall = new Rectangle(idx, idy, Tile.Size, Tile.Size);
if (this.getBoundingBox() == null) {
return false;
}
return this.getBoundingBox().intersects(wall);
}
Outside of this in my "Core.java" file, I have a for loop iterate the tiles through the colidesWithWall method. I also have an if statement in here so it will only check the tiles that are on the collision layer. (My map has four layers, Background, Collision, Items and Enemies).
for (int i = 0; i < entities.size(); i++) {
Entity me = entities.get(i);
for (int k = 0; k < 100; k++) {
for (int l = 0; l < 100; l++) {
if (Level.getColision(k, l)) {
Entity entity = entities.get(i);
if (entity.colidesWithWall(k, l)) {
entity.collidedWithWall();
frameCounter = 0;
}
}
}
}
}
Well anyway, what happens is, the game always detects a collision going on. Also, the players X&Y coordinates are defined by this:
((int) ((rouge.screenSize.width) / 2 - Tile.Size / 2 + rouge.oX)) / Tile.Size, ((int((rouge.screenSize.height) / 2 - Tile.Size / 2 + rouge.oY))/Tile.size
rouge.oY and rouge.oX are my camera offsets
Tile.Size is the size of my Tiles: 32
Here's a Screenshot of what happens: http://i.imgur.com/zYONBOC.png
The grey tiles and the tree are supposed to be causing collision, where as the brown ones are not.
Here is what I have for my game. I hope it somehow helps you as I'm not sure how I can help with just what you've given.
Getting the player's bounds:
private static Rectangle getPlayerBounds() {
return new Rectangle((int)player.getPositionX(), (int)player.getPositionY(), playerTexture.getImageWidth(), playerTexture.getImageHeight());
}
Getting the entity(in my case enemy)'s bounds:
private static Rectangle getEnemyBounds(Enemy e) {
return new Rectangle(e.getEnemyPosX(), e.getEnemyPosY(), enemyTexture.getImageWidth(), enemyTexture.getImageHeight());
}
then I have my checkCollision():
public static void checkCollisions() {
for(int i = 0; i < getEnemyList().size(); i++) {
Enemy tempEnemy = getEnemyList().get(i);
if (getPlayerBounds().intersects(getEnemyBounds(tempEnemy))) {
getEnemyList().remove(tempEnemy);
}
}
}
and in the end I just call it in my Movement.java:
MovementChecks.checkCollisions();

Unreachable Code in Tic Tac Toe Program

I've been researching "dead code" and "unreachable code" for awhile now and I still can't seem to figure out what's going on with this problem in my program. This is a snippet of what I have; the method "gameEnd()" which checks for winners in Tic Tac Toe:
private boolean gameEnd() {
// Setting local variables
int x = xMouseSquare;
int y = yMouseSquare;
int[][] g = gameBoard;
int c = CPU;
int h = HUMAN;
// Checking for a winner
/* Checking columns (xMouseSquare)
* Enter the y value, the vertical value, first; then x, the horizontal value, second
*/
// Set y equal to 0 and then add 1
for (y = 0; y < 3; y++) {
// Set CPU c equal to 0
c = 0;
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
// Add CPU's value to the game board
c += g[x][y];
// If statement returning the absolute value of CPU
if (Math.abs(c) == 3) {
// If these values are correct, return true; the game ends with CPU win horizontally
return true;
}
}
}
// If not, return false; game continues until all marks are filled
return false;
// Set y equal to 0 and then add 1
for (y = 0; y < 3; y++) {
// This time, however, set HUMAN h equal to 0
h = 0;
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
// Then add HUMAN's value to the game board
h += g[x][y];
// If statement returning the absolute value of HUMAN
if (Math.abs(h) == -3) {
// If these values are correct, return true; the game ends with HUMAN win horizontally
return true;
}
}
}
// If not, return false; game continues until all marks are filled
return false;
{
/* Checking rows (yMouseSquare)
* Enter the x value, the horizontal value, first; then y, the vertical value, second
*/
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
// Set CPU equal to 0
c = 0;
// Set y equal to 0 and then add 1
for (y = 0; y < 3; y++) {
// Add CPU's value to the game board, but with y and then x
c += g[y][x];
// If statement returning the absolute value of CPU
if (Math.abs(c) == 3) {
// If these values are correct, return true; the game ends with CPU win vertically
return true;
}
}
}
// If not, return false; game continues until all marks are filled
return false;
{
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
// This time, however, set HUMAN h equal to 0
h = 0;
// Set y equal to 0 and then add 1
for (y = 0; y < 3; y++) {
// Then add HUMAN's value to the game board
h += g[x][y];
// If statement returning the absolute value of HUMAN
if (Math.abs(h) == -3) {
// If these values are correct, return true; the game ends with CPU win vertically
return true;
}
}
}
// If not, return false; game continues until all marks are filled
return false;
}
}
}
} // error on this bracket; but when I remove it, some of the code above becomes unreachable. Can anyone point to what I'm doing wrong?
If it was indented properly, I think it would show that the first occurrence of 'return false' will always be executed if the first instance of 'return true' was not hit, hence all remaining code is never reached.
Here is your problem right here
// If not, return false; game continues until all marks are filled
return false; <-- code exits here, everything below will not run.
{
// Set x equal to 0 and then add 1
for (x = 0; x < 3; x++) {
...

java: tetris random block generated upon row clear

I'm trying to make the game Tetris in java.
I've gotten it to the point where:
a new block is generated when it hits the floor or its y+1 is not null (meaning there's another block under it)
public void collisionCheck(int x, int y) {
if (activetile.getY() == this.height-2 || getTileAt(x, y+1) != null) {
activetile = new Tile(this, 0, 0);
}
}
A row clears when the bottom row is full of non-null values, or the Tetris pieces (for y = 4 (the floor), loop through x till x = 4 and check if all non-null)
public void checkBottomFull(int x, int y) {
while (getTileAt(x,y) != null) {
say("(" + x + ", " + y +")");
if (x == 3) {
say("row is full");
//replace full row with tiles from above
for (int i = 0; i < 4; i++) {
for (int j = 5; j > 0; j--) {
grid[j][i] = getTileAt(i,j-1);
grid[j-1][i] = null;
}
}
break;
}
x++;
}
}
Right now, I'm using keys to move the block:
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_DOWN) {
activetile.setLocation(activetile.getX(), activetile.getY()+1);
System.out.println("coordinates: " + activetile.getX() + ", " + activetile.getY());
collisionCheck(activetile.getX(),activetile.getY());
checkBottomFull(0,4);
repaint();
}
}
There's two issues I'm having:
1) In the picture you'll notice I've dropped the block all the way to the floor... and the row cleared. After it's cleared, it will generate a block to the top left (x=0, y=1) which I have no control over.
2) On the floor there seems to be a red line... which I'm assuming is a row of blocks hidden by the JFrame... I'm not sure why that's there.
FYI: If you're wondering why grid[j][i] has the rows and columns flipped (aka, why it's not grid[i][j]) is because I instantiated it as grid = new Tile[height][width];
Any thoughts?
Thanks!
It is hard to say what is wrong without actually debugging your app.
But maybe try this one:
public void checkBottomFull(int x, int y) {
while (getTileAt(x,y) != null) {
say("(" + x + ", " + y +")");
if (x == 3) {
say("row is full");
//replace full row with tiles from above
for (int i = 0; i < 4; i++) {
for (int j = 4; j >= 0; j--) {
grid[j][i] = getTileAt(i,j-1);
grid[j-1][i] = null;
}
}
break;
}
x++;
}
}
You have 5 rows (indexed from 0 to 4) and 4 columns (indexed from 0 to 3).
What values of height and width do you pass to:
grid = new Tile[height][width];
Because from what I see you should do something like that:
grid = new Tile[5][4];
Bah,
Turns out in the key event, I needed to check if the bottom was full before checking if there is a collision.
I guess what was happening is, when I was checking collisionCheck(activetile.getX(),activetile.getY()); before checkBottomFull(0,4);, when the bottom was full, it would clear the row and set the current row equal to the row above it: grid[j][i] = getTileAt(i,j-1);, the problem was that collisionCheck was generating a new piece and the that newly generated piece was getting cleared and replaced by checkBottomFull.
Putting the collision check after the checkBottomFull ensures that the newly generated piece won't be replaced if bottom is full.

Categories

Resources