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.
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
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
Code:
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?
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)
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.
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());
}
}
}
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
I feel like an idiot... 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.
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 = 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.
Last edited by Wizard1988; 11-24-2005 at 08:59 PM.
Bookmarks