Categories: MSDN / DotNet / Java / Scripts / Linux / PHP Ask - La ask - La Answer

Animation in Java

I was asked to make a hockey game by my Java teacher. I can get the puck to draw, but I'm not sure how to move it. Should I use a thread, or a timer?

Also, how can I check if the puck collides with the outside of the application window? I would like to keep it in the window, and when it hits a window boundary to send it off in another direction.
[364 byte] By [Dark Rain] at [2007-11-11 7:20:40]
# 1 Re: Animation in Java
You should store the (X,Y) position of the puck in variables, and use them for drawing, as in g.drawOval(x,y, height, width) then increment them inside the main loop, to check for collision simply write an if statement checking if it is smaller than 0 or bigger than the height of the window, then compare the y position to 0 and the width. if they collide simply multiply the x, y value by -1 this will reverse the puck

I hope this helps :)
Wizard1988 at 2007-11-11 22:38:41 >
# 2 Re: Animation in Java
I have these two classes:

Hockey.class

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Hockey extends JApplet implements ActionListener
{
private final int WIDTH = 400, HEIGHT = 200;

private JPanel surface = new JPanel();
private HockeyThread thread;

public void init()
{
getContentPane().setLayout(new BorderLayout());
getContentPane().add("Center",surface);
getContentPane().setSize(WIDTH,HEIGHT);

}// init()

public void actionPerformed(ActionEvent e)
{
thread = new HockeyThread(surface);
Thread hockeyThread = new Thread(thread);
hockeyThread.start();
}// actionPerformed()
}//Hockey

HockeyThread.class

import java.awt.*;
import javax.swing.*;

public class HockeyThread implements Runnable
{
private int xCoord = 0;
private int yCoord = 0;

private JPanel surface;

public void run()
{
go();
}

public HockeyThread(JPanel draw)
{
surface = draw;
}

public void go()
{
Graphics g = surface.getGraphics();

Dimension size = surface.getSize();
g.translate(size.width / 2, size.height / 2);

g.fillOval(xCoord,yCoord,20,15);
g.setColor(Color.black);
}// go()
}// HockeyThread

There are no syntatical errors, but for some reason the puck won't draw in the center of the screen like it is supposed to. Anyone know what I could be doing wrong here?
Dark Rain at 2007-11-11 22:39:41 >
# 3 Re: Animation in Java
I think that your problem is in the run() method, the thread runs but go() is called only once.

I usually do all the drawing inside the paint() method

Try this

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Hockey extends JApplet implements ActionListener
{
private final int WIDTH = 400, HEIGHT = 200;

private JPanel surface = new JPanel();
private HockeyThread thread;

public void init()
{
getContentPane().setLayout(new BorderLayout());
getContentPane().add("Center",surface);
getContentPane().setSize(WIDTH,HEIGHT);

}// init()

public void actionPerformed(ActionEvent e)
{
}// actionPerformed()

public void start()
{
thread = new HockeyThread(surface);
Thread hockeyThread = new Thread(thread);
hockeyThread.start();
}
}//Hockey

import java.awt.*;
import javax.swing.*;

public class HockeyThread implements Runnable
{
private int xCoord = 0;
private int yCoord = 0;

private JPanel surface;

public void run()
{
while(true)
{
go();
}
}

public HockeyThread(JPanel draw)
{
surface = draw;
}

public void go()
{
Graphics g = surface.getGraphics();
Dimension size = surface.getSize();
g.translate(size.width / 2, size.height / 2);

g.fillOval(xCoord,yCoord,20,15);
g.setColor(Color.black);
}// go()
}// HockeyThread
Wizard1988 at 2007-11-11 22:40:44 >
# 4 Re: Animation in Java
I changed some things:

HockeyThread.class

import java.awt.*;
import javax.swing.*;

public class HockeyThread extends HockeyOther implements Runnable
{
private static final int XMIN = 0;
private static final int XMAX = 420;
private static final int XSTART = 0;
private static final int YMIN = 0;
private static final int YMAX = 345;
private static final int YSTART = 0;
private static final int SIDE = 5;
private static final int DELTA = 5;
private static final int RANGE = 5;

private Hockey applet;
private Point location;

public HockeyThread(Hockey app)
{
applet = app;
location = new Point(XSTART,YSTART);
state = MOVING;
}

public Point getLocation()
{
return location;
}

public void go()
{
Graphics g = applet.getGraphics();

g.setColor(Color.white);
g.fillRect(location.x,location.y,SIDE,SIDE);

int dx = (int)(DELTA);
int dy = (int)(RANGE);

if (location.x + dx >= XMIN && location.x + dx <= XMAX)
{
location.x = location.x + dx;
} else {
dx *= -1;
}
if (location.y + dy >= YMIN && location.y + dy <= YMAX)
{
location.y = location.y + dy;
} else {
dy *= -1;
}
if (location.x + dx <= XMAX && location.x + dx >= XMIN)
{
location.x = location.x + dx;
} else {
dx *= -1;
}
if (location.y + dy <= YMAX && location.y + dy >= YMIN)
{
location.y = location.y + dy;
} else {
dy *= -1;
}

g.setColor(Color.red);
g.fillRect(location.x,location.y,SIDE,SIDE);
}// go()


Although, I can't seem to get the boundries right. Either the puck flies out of bounds into nowhere, or starts warping around.
Dark Rain at 2007-11-11 22:41:44 >
# 5 Re: Animation in Java
I took some time with MS Paint and explained it a little
Wizard1988 at 2007-11-11 22:42:48 >
# 6 Re: Animation in Java
Thanks for the tutorial. The only problem is the puck stays at 0,0 now. Do I need a loop somewhere to move it?
Dark Rain at 2007-11-11 22:43:47 >
# 7 Re: Animation in Java
You need to do the checking in the main loop, and start with the puck anywhere inbounds

Post your full code again, if ithat doesen't help
Wizard1988 at 2007-11-11 22:44:45 >
# 8 Re: Animation in Java
DarkRain look at your if blocks.
2 of them are same other 2 . you only need 2...
last one reverse the effect of first.
if (location.x + dx >= XMIN && location.x + dx <= XMAX)
if (location.x + dx <= XMAX && location.x + dx >= XMIN)

if (location.y + dy >= YMIN && location.y + dy <= YMAX)
if (location.y + dy <= YMAX && location.y + dy >= YMIN)
mr1yh1 at 2007-11-11 22:45:48 >
# 9 Re: Animation in Java
Here is my code:

import java.awt.*;
import javax.swing.*;

public class HockeyThread extends HockeyOther implements Runnable
{
private static final int XMIN = 0;
private static final int XMAX = 420;
private static final int YMIN = 0;
private static final int YMAX = 345;
private static final int SIDE = 5;
private static final int DELTA = 5;
private static final int RANGE = 5;

private static final int XSTART = (int)Math.random() * SIDE;
private static final int YSTART = (int)Math.random() * SIDE;

private Hockey applet;
private Point location;

public HockeyThread(Hockey app)
{
applet = app;
location = new Point(XSTART,YSTART);
state = MOVING;
}

public Point getLocation()
{
return location;
}

public void go()
{
Graphics g = applet.getGraphics();

g.setColor(Color.white);
g.fillRect(location.x,location.y,SIDE,SIDE);

int dx = (int)(DELTA);
int dy = (int)(RANGE);

// Check x-axis movement
if ((location.x <= XMIN) | (location.x + SIDE >= XMAX))
{
dx *= -1;
} else {
dx += dx;
}

// Check y-axis movement
if ((location.y <= YMIN) | (location.y + SIDE >= YMAX))
{
dy *= -1;
} else {
dy += dy;
}

g.setColor(Color.red);
g.fillRect(location.x,location.y,SIDE,SIDE);
}// go()

public synchronized void die()
{
state = DEAD;
}

public void run()
{
while (state != DEAD)
{
go();
delay(85);
}
}
}// HockeyThread

I call the go() method in the main loop, but it doesn't seem to do any good. Also, I tried setting a random start location with the XSTART,YSTART call but, that also doesn't work.
Dark Rain at 2007-11-11 22:46:51 >
# 10 Re: Animation in Java
Can you post the HockeyOther class?
Wizard1988 at 2007-11-11 22:47:52 >
# 11 Re: Animation in Java
Here you go:

public class HockeyOther
{
protected int state;
public static final int DEAD = -1;
public static final int MOVING = 0;

public HockeyOther()
{
state = MOVING;
}

protected void delay(int N)
{
try {
Thread.sleep(N);
} catch (InterruptedException e) {
System.out.println(e.toString());
}
}

}
Dark Rain at 2007-11-11 22:48:55 >
# 12 Re: Animation in Java
Is there any other code that you didn't post ? because I can't get this to compile...
Wizard1988 at 2007-11-11 22:49:48 >
# 13 Re: Animation in Java
Sorry =p. I forgot the GUI part of it:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Hockey extends JApplet
{
private HockeyThread thread = new HockeyThread(this);

public void init()
{
this.setSize(425,350);

new Thread(thread).start();
}// init()

public void PaintComponent(Graphics g)
{
}
}//Hockey

That's the one you want to compile.
Dark Rain at 2007-11-11 22:50:54 >
# 14 Re: Animation in Java
I feel like an idiot... :o :( My if statements for the collision detection were wrong, so sorry for misleading you there, but I did get this to work.

I think that your problem might have been that you were declaring dx and dy inside the go() method.

import java.awt.*;
import javax.swing.*;

public class HockeyThread extends HockeyOther implements Runnable
{
private static final int XMIN = 0;
private static final int XMAX = 400;
private static final int YMIN = 0;
private static final int YMAX = 200;
private static final int SIDE = 10;
private static final int DELTA = 4;
private static final int RANGE = 3;

private static final int XSTART = 15;
private static final int YSTART = 15;

private Hockey applet;
private Point location;

private int dx;
private int dy;

public HockeyThread(Hockey app)
{
applet = app;
location = new Point(XSTART,YSTART);
state = MOVING;

dx = (int)(DELTA);
dy = (int)(RANGE);
}

public Point getLocation()
{
return location;
}

public void move()
{
location.x += dx;
location.y += dy;
}

public void go()
{
Graphics g = applet.getGraphics();

g.setColor(Color.white);
g.fillRect(location.x,location.y,SIDE,SIDE);

move();

if(location.x + dx >=XMIN && location.x + dx <= XMAX)
{
move();
}
else{
dx*=-1;
}
if(location.y + dy >= YMIN && location.y +dy <= YMAX)
{
move();
}
else{
dy*=-1;
}

g.setColor(Color.blue);
g.fillRect(location.x,location.y,SIDE,SIDE);

}// go()

public synchronized void die()
{
state = DEAD;
}

public void run()
{
while (state != DEAD)
{
go();
delay(50);
}
}
}// HockeyThread

Again sorry for misleading you with the if statements.
Wizard1988 at 2007-11-11 22:51:54 >
# 15 Re: Animation in Java
Thanks for the help.

Everything seems to be working fine. Now the for the next part of the assignment, my teacher wants me to implement the mouse, whatever direction the user clicks that's the direction the puck goes.

Here is my revised HockeyThread class:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class HockeyThread extends HockeyOther implements Runnable,MouseListener,
MouseMotionListener
{
private static final int XMIN = 10;
private static final int XMAX = 760;
private static final int YMIN = 10;
private static final int YMAX = 560;
private static final int SIDE = 10;
private static final int DELTA = 8;
private static final int RANGE = 4;

private static final int XSTART = (int)Math.random() * 15;
private static final int YSTART = (int)Math.random() * 15;

private Hockey applet;
private Point location;
private Point mouse = new Point();

private int dx;
private int dy;

private int timeUntilDie;
private int delay = 50;

public HockeyThread(Hockey app)
{
applet = app;
location = new Point(XSTART,YSTART);
state = MOVING;

dx = (int)(DELTA);
dy = (int)(RANGE);
}

public Point getLocation()
{
return location;
}

public void move()
{
location.x += dx;
location.y += dy;
}

public void go()
{
Graphics g = applet.getGraphics();

g.setColor(Color.white);
g.fillRect(location.x,location.y,SIDE,SIDE);

move();

// Bounds checking
if(location.x + dx >=XMIN && location.x + dx <= XMAX)
{
move();
}
else{
dx*=-1;
timeUntilDie++;
delay += 25;
}
if(location.y + dy >= YMIN && location.y +dy <= YMAX)
{
move();
}
else{
dy*=-1;
timeUntilDie++;
delay += 25;
}
if (timeUntilDie > 5)
{
die();
}

// Mouse position checking
if ((mouse.x < location.x) && (mouse.x > XMIN))
{
location.x += dx;
}
if ((mouse.x > location.x) && (mouse.x < XMAX))
{
dx*=-1;
}
if ((mouse.y > location.y) && (mouse.x < YMAX))
{
dy*=-1;
}
if ((mouse.y < location.y) && (mouse.y > YMIN))
{
location.y += dy;
}
g.setColor(Color.blue);
g.fillOval(location.x,location.y,SIDE,SIDE);

}// go()

/* Mouse Handling Interfaces: MouseMotionListener and MouseListener */
public void mouseDragged(MouseEvent e){}
public void mouseClicked(MouseEvent e)
{
mouse = e.getPoint();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseMoved(MouseEvent e){}

public synchronized void die()
{
state = DEAD;
}

public void run()
{
while (state != DEAD)
{
go();
delay(delay);
}
}
}// HockeyThread

Although, the puck doesn't seem to move after I click around the puck (I implemented a way to slow down and stop the puck, because it is moving initially).
Dark Rain at 2007-11-11 22:52:58 >
# 16 Re: Animation in Java
Sorry about the stream of questions here =p. I have everything I need implemented except the mouse. I tried making the class a JPanel, and tried writing my own mouse code, but to no avail. If someone would look this over and maybe point out where I'm going awry with the code, I would be very grateful.

Here is my revised class code again:

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class HockeyThread extends JPanel implements Runnable , MouseListener
{
private static final int XMIN = 10;
private static final int XMAX = 760;
private static final int YMIN = 10;
private static final int YMAX = 560;
private static final int SIDE = 10;
private static final int DELTA = 8;
private static final int RANGE = 4;
private static final int GOALXMAX = 690;
private static final int GOALYMAX = 310;
private static final int GOALXMIN = 600;
private static final int GOALYMIN = 220;

private static final int XSTART = 25;
private static final int YSTART = 30;

private Hockey applet;
private Point location;
private Point mouse = new Point();

private int dx;
private int dy;

private int timeUntilDie;
private int delay = 50;

protected int state;
public static final int DEAD = -1;
public static final int MOVING = 0;

public HockeyThread(Hockey app)
{
applet = app;
location = new Point(XSTART,YSTART);
state = MOVING;

dx = (int)(DELTA);
dy = (int)(RANGE);

addMouseListener(this);
}

public Point getLocation()
{
return location;
}

public void move()
{
location.x += dx;
location.y += dy;
}

public void go()
{
Graphics g = applet.getGraphics();

g.setColor(Color.white);
g.fillRect(location.x,location.y,SIDE,SIDE);

g.setColor(Color.red);
g.drawRect(600,220,100,100);

//move();

// Bounds checking
if(location.x + dx >=XMIN && location.x + dx <= XMAX)
{
move();
}
else{
dx*=-1;
timeUntilDie++;
delay += 25;
}
if(location.y + dy >= YMIN && location.y +dy <= YMAX)
{
move();
}
else{
dy*=-1;
timeUntilDie++;
delay += 25;
}

if (location.x + dx >= GOALXMIN && location.y + dy >= GOALYMIN &&
location.x + dx <= GOALXMAX && location.y + dy <= GOALYMAX)
{
die();
} else {
move();
}
if (timeUntilDie > 5)
{
die();
}

// Mouse position checking
if ((mouse.x < location.x) && (mouse.x > XMIN))
{
move();
}
if ((mouse.x > location.x) && (mouse.x < XMAX))
{
dx*=-1;
}
if ((mouse.y > location.y) && (mouse.x < YMAX))
{
dy*=-1;
}
if ((mouse.y < location.y) && (mouse.y > YMIN))
{
move();
}
g.setColor(Color.blue);
g.fillOval(location.x,location.y,SIDE,SIDE);

}// go()

/* Mouse Handling Interfaces: MouseMotionListener and MouseListener */
public void mouseDragged(MouseEvent e){}
public void mouseClicked(MouseEvent e)
{
mouse = e.getPoint();
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseMoved(MouseEvent e){}

public synchronized void die()
{
state = DEAD;
}

public void run()
{
while (state != DEAD)
{
go();
delay(delay);
}
}
protected void delay(int N)
{
try {
Thread.sleep(N);
} catch (InterruptedException e) {
System.out.println(e.toString());
}
}
}// HockeyThread

Again, thank you for all of the help, I couldn't have made it this far without it.
Dark Rain at 2007-11-11 22:54:01 >