I am a beginner Android developer and I am trying to make a game where you move a bat (catcher) along the bottom of the screen and you have to catch falling blocks.
I am struggling currently with the collision detection. The collision detection itself is working correctly but when I then try to remove the block that is falling the game crashes.
The problem code is the line under the “remove block” comment in the checkCollisions() method but I have posted the whole GameView below for clarity.
Here is the code:
package com.mattdrewery.supercatch;
import android.view.View;
import android.view.MotionEvent;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Rect;
import java.util.Random;
import java.util.ArrayList;
public class GameView extends View
{
private Catcher catcher;
private ArrayList<NormalBlock> blocks;
private Random rand;
private int screenWidth;
private int screenHeight;
private boolean gameOver;
private int updateCount;
public GameView(Context context)
{
super(context);
setFocusable(true);
updateCount = 1;
// Set gameOver to false
gameOver = false;
// Create the ArrayList of normal blocks
blocks = new ArrayList<NormalBlock>();
// Create a random number generator
rand = new Random();
// Create the catcher
catcher = new Catcher(context, R.drawable.catcher, 230, 250);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh)
{
screenWidth = this.getWidth();
screenHeight = this.getHeight();
}
@Override
protected void onDraw(Canvas canvas)
{
updateCatcher();
checkCollisions();
updateBlocks();
// Draw the catcher to the canvas
canvas.drawBitmap(catcher.getImage(), catcher.getPosX(), catcher.getPosY(), null);
// For each normal block in the block array
for (NormalBlock block : blocks)
{
// Draw block to the canvas
canvas.drawBitmap(block.getImage(), block.getPosX(), block.getPosY(), null);
}
// Redraw the screen
invalidate();
}
@Override
public boolean onTouchEvent(MotionEvent event)
{
// Get the action from the touch screen
int eventAction = event.getAction();
int X = (int) event.getX();
// If the user presses on the screen....
if (eventAction == MotionEvent.ACTION_DOWN)
{
if (X < screenWidth / 2)
{
catcher.setMovingLeft(true);
catcher.setMovingRight(false);
}
else
{
catcher.setMovingLeft(false);
catcher.setMovingRight(true);
}
}
if (eventAction == MotionEvent.ACTION_MOVE)
{
if (X < screenWidth / 2)
{
catcher.setMovingLeft(true);
catcher.setMovingRight(false);
}
else
{
catcher.setMovingLeft(false);
catcher.setMovingRight(true);
}
}
if (eventAction == MotionEvent.ACTION_UP)
{
catcher.setMovingLeft(false);
catcher.setMovingRight(false);
}
return true;
}
private void updateCatcher()
{
// Check whether the catcher is moving and update position accordingly
if (catcher.isMovingLeft())
{
catcher.moveLeft();
if (catcher.getPosX() < 0)
{
catcher.setPosX(0);
}
}
else if (catcher.isMovingRight())
{
catcher.moveRight();
if (catcher.getPosX() > (screenWidth - catcher.getImage().getWidth()))
{
catcher.setPosX(screenWidth - catcher.getImage().getWidth());
}
}
}
private void updateBlocks()
{
updateCount++;
if (updateCount >= 100)
{
updateCount = 1;
blocks.add(new NormalBlock(getContext(), R.drawable.nblock,
rand.nextInt(screenWidth - 20), 0));
}
// For each normal block in the block array
for (NormalBlock block : blocks)
{
// Check if block has hit the bottom of the screen
if (block.getPosY() + block.getImage().getHeight() > screenHeight)
{
gameOver = true;
}
else
{
// Drop the block down
block.dropDown();
}
}
}
private void checkCollisions()
{
// Get Rectangle for the catcher
Rect catcherRect = new Rect(catcher.posX, catcher.posY,
catcher.posX + catcher.image.getWidth(),
catcher.posY + catcher.image.getHeight());
// For each block in the array
for (NormalBlock block : blocks)
{
// Get Rectangle for the current block
Rect blockRect = new Rect(block.posX, block.posY,
block.posX + block.image.getWidth(),
block.posY + block.image.getHeight());
if (Rect.intersects(catcherRect, blockRect))
{
// Remove block
blocks.remove(block);
}
}
}
public int getScreenHeight()
{
return screenHeight;
}
public int getScreenWidth()
{
return screenWidth;
}
}
Thanks in advance,
Try replacing
for (NormalBlock block : blocks)with this:int count = blocks.size();
for (int i=0;i<count;i++){
Block block = blocks.get(i);
I’m guessing you were getting a
ConcurrentModificationExceptionthere.