Velocity Reviews > Java > Collision detection

# Collision detection

Stephen Wolfe
Guest
Posts: n/a

 02-19-2004
Hi,

I am a beginner at the Java Programming language, learning from a
variety of sources i.e part-time University course, books and Sun's
Java Tutorial.

Part of my part-time university course has been to write a Java Applet
(Java v1.1) which should act and behave like a children's sliding
block puzzle. The puzzle consists of 10 blocks of varying sizes which
are inside a 'tray' (5 x 4) and the object is to move the largest
block (2 x 2) from the top right hand corner to the bottom left hand
corner by sliding the other blocks into the available spaces to create
a 'path' for the large block. The blocks are not allowed to move over
each other or be rotated.

The initial code has been written, however this only displays the
blocks in the 'tray' and they can move over each other.

My problem is, I am unsure of how to write collision detection for the
blocks, 'snap' the blocks to the 5 x 4 grid, and finally, stop the
flickering of the applet. I know stopping the flickering involves
some sort of image buffer, however I am unsure as to how implement
this into the code I have already written.

Apologies for the length of this posting.

Here is the code so far:

package blockPuzzle;

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

public class BlockPuzzle extends Applet implements
MouseMotionListener, MouseListener {

int[] xpos = {0, 50, 150, 50, 0, 50, 150, 200, 50, 200}; // Array of
Starting x-positions
int[] ypos = {0, 0, 0, 50, 100, 100, 100, 100, 150, 150}; // Array
of Starting y-positions
int[] width = {50, 100, 100, 100, 50, 50, 50, 50, 50, 50}; // Array
of Block Widths
int[] height = {100, 50, 100, 50, 100, 50, 100, 50, 50, 50}; //
Array of Block Heights

Color[] blockColour = {Color.yellow, Color.blue, Color.green,
Color.red}; // Array of colors 4 Values, 0 - 3

Block[] block = new Block[xpos.length]; // Constructor for 10
different blocks
// Array of blocks 'length of Array "xpos"' values in size, 0 - 9.
i.e 10 Blocks

// Declared Class Variables
int boardHeight = 200, boardWidth = 250;
int grab = -1, margin = 800;
int xMouse, yMouse ;
// final int canvasWidth = 400, canvasHeight = 400 ;

// Image scratch ; Graphics g2 ; // For flicker free operation.

// Initialization Method
public void init() {
Color c;
int index ;

for (int j = 0; j < xpos.length; j++) {

index = (width[j]/50 - 1) * 2 + height[j]/50 - 1; // number
between 0 and 3
block[j] = new Block(xpos[j], ypos[j], width[j], height[j] ,
blockColour[index] );
}

// scratch = createImage(canvasWidth, canvasHeight) ;
// g2 = scratch.getGraphics() ;

}

public void mousePressed(MouseEvent e) {
int px, py, xCentre, yCentre ;
grab = -1 ;
for (int j = 0; j < xpos.length; j++) {

xCentre = Block.xBoard + (block[j].x + width[j]/2) ;
px = xCentre - e.getX() ;
xMouse = e.getX() ;

yCentre = Block.yBoard + (block[j].y + height[j]/2) ;
py = yCentre - e.getY() ;
yMouse = e.getY() ;

if ((px*px + py*py) <= (margin)) {

grab = j;
block[j].setLatch(true) ;
break;
}

}
repaint () ;
}

public void mouseReleased(MouseEvent e) {
grab = -1;

for (int j = 0; j < xpos.length; j++) {
block[j].setLatch(false);
}
repaint();
}

public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseMoved(MouseEvent e) {}

public void mouseDragged(MouseEvent e) {
int dx, dy, xDrag, yDrag ;

xDrag = e.getX() ;
yDrag = e.getY() ;

dx = xDrag - xMouse ;
dy = yDrag - yMouse ;

if ( (grab >=0) ){

block[grab].x += dx ; // block[grab].x = block[grab].x + dx ;
block[grab].y += dy ; // block[grab].y = block[grab].y + dy ;

xMouse = xDrag ;
yMouse = yDrag ;

repaint ();
}
}

public void paint(Graphics g) {
for (int j = 0; j < xpos.length; j++) {
block[j].plot(g);
}
Block.drawBoard(boardWidth, boardHeight, g);
// g.drawImage(scratch, 0, 0, this);
}
}

class Block {
int x, y, width, height;
Color colour;
boolean latch = false, collision = false ;

final static int thick = 4;
final static int xBoard = 20, yBoard = 20;

public Block(int x0, int y0, int width0, int height0, Color
colour0) {
x = x0 ;
y = y0 ;
width = width0 ;
height = height0 ;
colour = colour0 ;
}

public void setLatch (boolean latch0) {
latch = latch0 ;
}

public void plot(Graphics g) {
g.setColor(colour);
g.fillRect(xBoard + x, yBoard + y, width, height);
g.setColor(Color.black);
g.drawRect(xBoard + x, yBoard + y, width -1, height -1);
g.setColor(Color.white);
if (latch) g.fillRoundRect(xBoard + x + width/4, yBoard + y +
height/4, width/2, height/2, 5, 5);}

public static void drawBoard(int bWidth, int bHeight, Graphics g0)
{
for (int j = 0; j <= thick; j += thick / 2) {
g0.setColor(Color.black);
g0.drawRect(xBoard - j, yBoard - j, bWidth + j * 2, bHeight +
j * 2);
}
}
}

Any thoughts on this would be greatly appreciated.

Stephen in Glasgow, UK

Alex Hunsley
Guest
Posts: n/a

 02-20-2004
Stephen Wolfe wrote:
> Hi,
>
> I am a beginner at the Java Programming language, learning from a
> variety of sources i.e part-time University course, books and Sun's
> Java Tutorial.
>
> Part of my part-time university course has been to write a Java Applet
> (Java v1.1) which should act and behave like a children's sliding
> block puzzle. The puzzle consists of 10 blocks of varying sizes which
> are inside a 'tray' (5 x 4) and the object is to move the largest
> block (2 x 2) from the top right hand corner to the bottom left hand
> corner by sliding the other blocks into the available spaces to create
> a 'path' for the large block. The blocks are not allowed to move over
> each other or be rotated.
>
> The initial code has been written, however this only displays the
> blocks in the 'tray' and they can move over each other.
>
> My problem is, I am unsure of how to write collision detection for the
> blocks, 'snap' the blocks to the 5 x 4 grid, and finally, stop the
> flickering of the applet. I know stopping the flickering involves
> some sort of image buffer, however I am unsure as to how implement
> this into the code I have already written.
>
> Apologies for the length of this posting.
>
> Here is the code so far:

[snip]
> Stephen in Glasgow, UK

Hi Stephen
I'm over in Edinburgh!

been set it as a task (stop the the flickering), your tutors probably
aren't that worried about that aspect.

The next thing I would worry about is getting the block to 'snap' to the
nearest whole block location when you drop it. Don't worry about
collision detection for other blocks and deciding what is a legal move -
do that later - for now, just worry about snapping the block into the
right place when the user releases the mouse button after dragging.

As for where to do the code for snapping, I would choose the
mouseReleased(MouseEvent e) method, as this is the logical place (if you
want snapping to occur when the mouse is released).
Hint for snapping: the coords for the block just moved are block[grab].x
and block[grab].y, you want to examine these and change them to snap to
a different coordinate (usually).

alex

alex