code to bounce a ball

Hey guys. Im trying to get a ball to bounce off of the walls of my applet. The X direction works fine but I just cant get the Y
direction to work. Any idea what Im doing wrong? By the way, “this” is referring to the applet

//loop to constantly repaint the screen
while(true) {

		/* Collision detections between the ball and all four walls*/
		if(ballXPosition > this.getWidth() - ballRadius) {
			
			//change the direction
			ballXSpeed = -1;
		}
		else if(ballXPosition < ballRadius) {
			
			//change the direction
			ballXSpeed = 1;
		}
		if(ballYPostion > this.getHeight() - ballRadius) {
			
			ballYSpeed = -1;
		}
		else if(ballYPostion < ballRadius) {
			
			ballYSpeed = 1;
		}
		
		ballXPosition += ballXSpeed;
		ballYPostion += ballYSpeed;
		
		
		//repaint
		repaint();

I can’t see anything wrong with your code (apart from the unconventional spelling of ballYPostion :wink: ).

Try printing out the ball’s position and velocity each step (System.out.println(“x=” + ballXPosition + " y=" + ballYPostion + …)) and also printing a message whenever the direction changes (or set break points if you prefer).

Simon

what exacly is not working, could you explain a little more the symptomes ?

well 2 things are happening… With the code like this… the ball just goes straight up through the top of the frame, if I switch the < > signs, it just goes to the bottom and looks like its trying to go through the bottom, but cant. Maybe Im thinking of it the wrong way since the Y coordnates arent like we normally have… (up is negative and Down is positive) Basically, Y direction is never changed

Could you post the complete code (use the

 tag)? That'll help us with figuring out what's going wrong.

sure, I probably should have done this from the start

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;

public class BallApplet extends Applet implements Runnable {
	
	private static final long serialVersionUID = -7570390841627016661L;
	private int ballXPosition = 10;
	private int ballYPosition = 100;
	private int ballRadius = 20;
	private int ballXSpeed;
	private int ballYSpeed;
	private Image dbImage; //an image to use for double buffering
	private Graphics dbGraphics;
	
	
	
	public void init() {
		
	}
	
	public void start() {
		
		Thread myThread = new Thread(this);
		myThread.start();
		
	}

	public void stop() {
		
	}
	
	public void destory() {
		
	}
	
	public void run() {
		
		//lowering the threads priority
		Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
		
		//loop to constantly repaint the screen
		while(true) {
			
			/* Collision detections between the ball and all four walls*/
         if(ballXPosition > this.getWidth() - ballRadius) {
            
            //change the direction
            ballXSpeed = -1;
         }
         else if(ballXPosition < ballRadius) {
            
            //change the direction
            ballXSpeed = 1;
         }
         if(ballYPostion > this.getHeight() - ballRadius) {
            
            ballYSpeed = -1;
         }
         else if(ballYPostion < ballRadius) {
            
            ballYSpeed = 1;
         }
         
         ballXPosition += ballXSpeed;
         ballYPostion += ballYSpeed;
			
			
			//repaint
			repaint();
			
			try {
				//try to stop the thread for 20 ms
				Thread.sleep(20);
			} catch (InterruptedException ex) {
				//do nothing here if we cant
			}
			
			//making the priority max again
			Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
		}
		
	}
	
	public void paint(Graphics g) {
		//set the paint color
		g.setColor(Color.BLUE);
		
		//draw a circle
		g.fillOval(ballXPosition - ballRadius, ballYPosition - ballRadius,
				ballRadius * 2, ballRadius * 2);
	}
	
	public void update(Graphics g) {
		
		//create the buffered image
		if (dbImage == null) {
			dbImage = createImage(this.getSize().width, this.getSize().height);
			dbGraphics = dbImage.getGraphics();
		}
		
		//clear background
		dbGraphics.setColor(getBackground());
		dbGraphics.fillRect(0, 0, this.getSize().width, this.getSize().height);
		
		//draw background
		dbGraphics.setColor(getForeground());
		paint(dbGraphics);
		
		//finally draw this buffered image to the actual screen
		g.drawImage(dbImage, 0, 0, this);
	}
}



I guess you dont see it was not compiling and then you use an older version of your compiled class file

you just mispelled ballYPosition => you use severals time ballYPostion

also you mispelled destroy method of the Applet

corrected code here :

import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;

public class BallApplet extends Applet implements Runnable {
	
	 private static final long serialVersionUID = -7570390841627016661L;
	 private int ballXPosition = 10;
	 private int ballYPosition = 100;
	 private int ballRadius = 20;
	 private int ballXSpeed;
	 private int ballYSpeed;
	 private Image dbImage; //an image to use for double buffering
	 private Graphics dbGraphics;
	
	
	
	 public void init() {
		
	 }
	
	 public void start() {
		
		 Thread myThread = new Thread(this);
		 myThread.start();
		
	 }

	 public void stop() {
		
	 }
	
	 public void destory() {
		
	 }
	
	 public void run() {
		
		 //lowering the threads priority
		 Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
		
		 //loop to constantly repaint the screen
		 while(true) {
			
			 /* Collision detections between the ball and all four walls*/
 if(ballXPosition > this.getWidth() - ballRadius) {
 
//change the direction
 ballXSpeed = -1;
 }
 else if(ballXPosition < ballRadius) {
 
//change the direction
 ballXSpeed = 1;
 }
 if(ballYPosition > this.getHeight() - ballRadius) {
 
ballYSpeed = -1;
 }
 else if(ballYPosition < ballRadius) {
 
ballYSpeed = 1;
 }
 
ballXPosition += ballXSpeed;
 ballYPosition += ballYSpeed;
			
			
			 //repaint
			 repaint();
			
			 try {
				 //try to stop the thread for 20 ms
				 Thread.sleep(20);
			 } catch (InterruptedException ex) {
				 //do nothing here if we cant
			 }
			
			 //making the priority max again
			 Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
		 }
		
	 }
	
	 public void paint(Graphics g) {
		 //set the paint color
		 g.setColor(Color.BLUE);
		
		 //draw a circle
		 g.fillOval(ballXPosition - ballRadius, ballYPosition - ballRadius,
				 ballRadius * 2, ballRadius * 2);
	 }
	
	 public void update(Graphics g) {
		
		 //create the buffered image
		 if (dbImage == null) {
			 dbImage = createImage(this.getSize().width, this.getSize().height);
			 dbGraphics = dbImage.getGraphics();
		 }
		
		 //clear background
		 dbGraphics.setColor(getBackground());
		 dbGraphics.fillRect(0, 0, this.getSize().width, this.getSize().height);
		
		 //draw background
		 dbGraphics.setColor(getForeground());
		 paint(dbGraphics);
		
		 //finally draw this buffered image to the actual screen
		 g.drawImage(dbImage, 0, 0, this);
	 }
}



In case DzzD’s answer doesn’t do the trick…

Initial values for ballXSpeed and ballYSpeed? It looks to me like they’re both initially zero, but the start x-position is sufficiently close to a wall that the ball is immediately given a positive x-speed. I don’t see anything that stops the y-speed from remaining zero (but that may depend on the height of the applet).

Simon

Thanks for the corrections, but thats not whats causing the issue. I am using eclipse anyway so its being recompiled everytime I run an updated version. Its something in my logic thats messed up… something with the collision with the Y direction. Ignore the misspellings, Im 100% sure that its not the problem

ahhh dishmoth, I need to check that out… could be the problem.

THAT WAS IT! Thank you so much… I really appreciate the help

your code was not compiling, so if it execute it can only be an ancient version

My version of the code was fine with spelling. The version I posted was some copying and pasting from my code so theres were pieces of it that were stilll old. The problem was that I never gave Yspeed an initial value so it never actually worked. Thanks for that dishmoth

:persecutioncomplex: :persecutioncomplex: :persecutioncomplex: :persecutioncomplex:

else if(ballXPosition < ballRadius) {
            
            //change the direction
            ballXSpeed = 1;
         }

ballRadius is radius of the ball right? if yes it should be (ballXPosition < 0) which bounce on left side, in contradiction to your (ballXPosition > this.getWidth() - ballRadius) which bounce on right side.

ballXPosition and ballYPosition are the coordinates of the ball’s centre (as can be seen from the paint() function), so the original code is correct. The ball bounces when its centre is distance ballRadius from a wall.
Simon