Sign in to follow this  

[java] confusing bug

This topic is 4341 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey folks, nice to meet you! I'm trying to program a pong applet in Java, but not object oriented style. I've made a couple simple game clones before, but this is my first Java game and I'm having a bit of trouble. This is also my first time using threads in Java so if I'm doing something wrong let me know. Anyway, the problem is this: the game works fine at first, I can play for maybe 2 minutes without a glitch. Then suddenly it freezes. In the Java Console it stays there is a StackOverflowError, which usually means that there is some sort of recursion happening, but theres no recursion in this program. Here it is:
// PongApplet.java

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

public class PongApplet extends JApplet implements Runnable
{
	//Constants
	private static final int WIDTH = 500;
	private static final int HEIGHT = 350;
	private static final int TOP_PADDING = 30;
	
	private static final int WALL_THICKNESS = 10;

	private static final int PLAYAREA_TOP = TOP_PADDING + WALL_THICKNESS;
	private static final int PLAYAREA_BOTTOM = HEIGHT - WALL_THICKNESS;

	private static final int BAT_THICKNESS = 10;
	private static final int BAT_HEIGHT = 60;
	private static final double BAT_START_Y = PLAYAREA_TOP + (PLAYAREA_BOTTOM-PLAYAREA_TOP)/2 - BAT_HEIGHT/2;
	private static final double BAT_SPEED = .5;
	
	private static final int BALL_SIZE = 10;
	private static final int BALL_START_X = WIDTH / 2;
	private static final int BALL_START_Y = (PLAYAREA_BOTTOM - PLAYAREA_TOP) / 2;

	//ball location and velocity
	private double ballX = BALL_START_X;
	private double ballY = BALL_START_Y;
	private double xVelocity = -0.3;
	private double yVelocity = 0.3;

	//bat locations
	private double bat1Y = BAT_START_Y;
	private double bat2Y = BAT_START_Y;

	//used for getting input
	boolean upPressed = false;
	boolean downPressed = false;
	boolean resetPressed = false;

	private Image buffer;
	private Thread animatorThread;

	public void init() 
	{
	}

	public void start() 
	{			
		buffer = createImage(WIDTH,HEIGHT);
		animatorThread = new Thread(this);
		animatorThread.start();		
	}

	public void stop() 
	{
		buffer = null;
		animatorThread = null;
	}

	public void destroy() 
	{
	}
	
	public void run()
	{
		while(true)
		{
			try {
			requestFocus();
			
			addKeyListener(new KeyAdapter() {
			
			//get input				
			public void keyPressed(KeyEvent e)
			{
				int keycode = e.getKeyCode();
				if(keycode == KeyEvent.VK_UP)
					upPressed = true;
				if(keycode == KeyEvent.VK_DOWN)
					downPressed = true;
				if(keycode == KeyEvent.VK_R)
					resetPressed = true;
			}

			public void keyReleased(KeyEvent e) 
			{			
				int keycode = e.getKeyCode();
				if(keycode == KeyEvent.VK_UP)
					upPressed = false;
				if(keycode == KeyEvent.VK_DOWN)
					downPressed = false;
				if(keycode == KeyEvent.VK_R)
					resetPressed = false;
			}
			});

			if(resetPressed)
			{
				ballX = BALL_START_X;
				ballY = BALL_START_Y;
				resetPressed = false;
			}
							
			//move the left bat	
			if(upPressed)
				bat1Y -= BAT_SPEED;
			if(downPressed)
				bat1Y += BAT_SPEED;

			//move the right bat (until i make the AI)
			if(upPressed)
				bat2Y -= BAT_SPEED;
			if(downPressed)
				bat2Y += BAT_SPEED;

			//correct the position if the bat left the play area
			if(bat1Y < PLAYAREA_TOP)
				bat1Y = PLAYAREA_TOP;
			if(bat1Y + BAT_HEIGHT > PLAYAREA_BOTTOM)
				bat1Y = PLAYAREA_BOTTOM-BAT_HEIGHT;

			//calculate ball's new position
			double newBallX = ballX + xVelocity;
			double newBallY = ballY + yVelocity;			

			//bounce ball off top or bottom of play area
			if(newBallY + BALL_SIZE/2 > PLAYAREA_BOTTOM ||
				newBallY < PLAYAREA_TOP)
				yVelocity = -yVelocity;

			//test for collisions between ball and right bat
			if(xVelocity > 0 && newBallX >= WIDTH-BAT_THICKNESS)
			{
				if(ballX <= WIDTH-BAT_THICKNESS) //bounce off front of bat
				{
					if(ballY > bat2Y && ballY < bat2Y+BAT_HEIGHT)
						xVelocity = -xVelocity;
				}
				else //bounce off top or bottom of bat
				{
					if(ballY < bat2Y && yVelocity > 0 && newBallY > bat2Y)		
						yVelocity = -yVelocity;	
					else if(ballY > bat2Y+BAT_HEIGHT && yVelocity < 0 && newBallY < bat2Y+BAT_HEIGHT)
						yVelocity = -yVelocity;
				}
			}
			//collisions between ball and left bat
			else if(xVelocity < 0 && newBallX <= BAT_THICKNESS)
			{
				if(ballX >= BAT_THICKNESS) //bounce off front of bat
				{
					if(ballY > bat1Y && ballY < bat1Y+BAT_HEIGHT)
						xVelocity = -xVelocity;
				}
				else //bounce off top or bottom of bat
				{
					if(ballY < bat1Y && yVelocity > 0 && newBallY > bat1Y)		
						yVelocity = -yVelocity;	
					else if(ballY > bat1Y+BAT_HEIGHT && yVelocity < 0 && newBallY < bat1Y+BAT_HEIGHT)
						yVelocity = -yVelocity;
				}
			}
			
			//move ball to new position
			ballX = newBallX;
			ballY = newBallY;
			
			//draw to buffer
			//draw background, ball
			Graphics bg = buffer.getGraphics();
			bg.setColor(Color.black);
			bg.fillRect(0,0,WIDTH,HEIGHT);
			bg.setColor(Color.white);
			bg.fillRect((int)(ballX - BALL_SIZE/2), (int)(ballY - BALL_SIZE/2), BALL_SIZE, BALL_SIZE);

			//draw walls
			bg.fillRect(0,PLAYAREA_TOP-WALL_THICKNESS,WIDTH,WALL_THICKNESS);
			bg.fillRect(0,PLAYAREA_BOTTOM,WIDTH,WALL_THICKNESS);

			//draw bats
			bg.fillRect(0,(int)bat1Y,BAT_THICKNESS,BAT_HEIGHT);
			bg.fillRect(WIDTH-BAT_THICKNESS,(int)bat2Y,BAT_THICKNESS,BAT_HEIGHT);
			
			//display buffer in the applet
			Graphics g = this.getGraphics();
			g.drawImage(buffer,0,0,null);	
				
			//let other threads do their thing
			animatorThread.yield();
			} catch (Exception e){}
		}
	}

	public void paint(Graphics g) 
	{
	}
}

If anyone can figure out what I've done wrong, I'd be really pleased. Theres still lots of functionality left to add to the game so try not to let that distract you. ;) Thanks a lot!

Share this post


Link to post
Share on other sites
Maybe its because you're adding the key listener inside the main loop, running that code with everything by the addKeyListener part removed gives me an outofmemory error after a while.

Share this post


Link to post
Share on other sites
So I finished making the pong game, and now I'm thinking about doing it again object oriented style. I've done a bit of research about different ways of designing the game, what classes to build and how they interact with each other.

The main thing that I'm not sure how to do is the collisions between the all and the paddles. Some designs put that in the Ball class, some put it in the Paddle class, and some put it in another higher level class like Playarea or PongGame. Is this a matter of programmer preference? Or is there a certain way that is considered correct in OOP?

To me it seems like the Playarea class would be the place for collision detection. If I put it in the Ball or Paddle class then those classes would have to have intimate knowledge of each other. Another thing I thought of was to make a class that specifically to deal with the collisions.

Anyway, I know theres hundreds of articles out there but I like to hear real peoples opinions on the subject too. If you have any advice to share, please do.

Share this post


Link to post
Share on other sites
Your collision detection code goes into update(), dude. Your Ball class will surely have bounds (Rectangle2D or any other approach), and the logic for changing their directions based on the collision detected goes into the update() method called by the main loop.

Share this post


Link to post
Share on other sites

This topic is 4341 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this