CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 6 of 6
  1. #1
    Join Date
    Jun 2005
    Posts
    3

    Applet ball not moving

    So I wrote an applet Pong game, the paddles move fine, but the ball just stays in the center. I don't understand why, I even have a separate tread for it, and the ball's x and y should change every 100 ms, but they always stay constant (I checked by outputting coordinates to the screen, they stay at 150,100)

    Code:
    import java.awt.*;
    import java.applet.Applet;
    import java.awt.event.*;
    import java.lang.*;
    
    
    
    
    class Ball implements Runnable
    {
    	private int x=0, y=0, size=15, xdir=3, ydir=3, Ymax, Xmax;
    	public int score=0;
    	Paddle P1 = new Paddle();
    	Paddle P2 = new Paddle();
    	Thread T1 = new Thread();
    
    	public Ball(int a, int b)
    	{
    		Xmax = a;
    		Ymax = b;
    		x = Xmax/2;
    		y = Ymax/2;
    		P1.setPaddle(5, (Ymax/2));
    		P2.setPaddle((Xmax-5), (Ymax/2));
    		T1.start();
    	}
    
    	public int getSize()
    	{
    		return size;
    	}
    
    	public int getX()
    	{
    		return x;
    	}
    
    	public int getY()
    	{
    		return y;
    	}
    
    	private void reset()
    	{
    		x=((Xmax-size)/2);
    		y=((Ymax-size)/2);
    	}
    
    	public void end()
    	{
    		T1.stop();
    	}
    
    	public void run()
    	{
    		if((y <= 0) || ((y+size) >= Xmax)) //if ball hits top or bottom edge
    		{
    			ydir = -ydir;
    		}
    		if((P1.hits(x, (y+size)) == true) || (P2.hits((x+size), (y+size)) == true)) //if paddle hits
    		{
    			xdir = -xdir;
    		}
    		if((x) <= 0) //if ball hits left edge
    		{
    			reset();
    			score=1;
    		}
    		else if((x+size) >= Ymax) //if ball hits right edge
    		{
    			reset();
    			score=2;
    		}
    		x += xdir;
    		y += ydir;
    		try
    		{
    			T1.sleep(100);
    		}
    		catch(InterruptedException ie){}
    	}
    }
    
    class Paddle
    {
    	private int x, y, xsize=3, ysize=25;
    
    	public void setPaddle(int a, int b)
    	{
    		x=a;
    		y=b;
    	}
    
    	public void move(int ydir)
    	{
    		y += ydir;
    	}
    
    	public boolean hits(int ballX, int ballY)
    	{
    		int tEdge = y;
    		int bEdge = y+ysize;
    		int lEdge = ballX-x;
    		int rEdge = ballX-x+xsize;
    		//if((((ballX-x) <= 1) && (bEdge < ballY) && (tEdge > ballY)) || (((ballX-x+xsize) <= 1) && (bEdge < ballY) && (tEdge > ballY))))
    		if(((lEdge <= 1) && (bEdge < ballY) && (tEdge > ballY)) || ((rEdge <= 1) && (bEdge < ballY) && (tEdge > ballY)))
    		{
    			return true;
    		}
    		return false;
    	}
    
    	public int getXsize()
    	{
    		return xsize;
    	}
    
    	public int getYsize()
    	{
    		return ysize;
    	}
    
    	public int getX()
    	{
    		return x;
    	}
    
    	public int getY()
    	{
    		return y;
    	}
    }
    
    class Score
    {
    	private int a=0, b=0;
    
    	public int getA()
    	{
    		return a;
    	}
    
    	public int getB()
    	{
    		return b;
    	}
    
    	public void incA()
    	{
    		a++;
    	}
    
    	public void incB()
    	{
    		b++;
    	}
    }
    
    public class Screen extends Applet implements KeyListener, Runnable
    {
    	Thread T0;
    	Color ballC = Color.blue, paddleC = Color.red, C = Color.white, scoreC = Color.black;
    	int Ymax = 200, Xmax = 300;
    	int scoreX = Xmax/2, scoreY = 10;
    	Ball ball = new Ball(Xmax, Ymax);
    	Score score = new Score();
    
    	public void stop()
    	{
    		if(T0!=null)
    		{
    			T0=null;
    		}
    	}
    
    	public void start()
    	{
    		if(T0==null)
    		{
    			T0=new Thread(this);
    			T0.start();
    		}
    	}
    
    	public void run()
    	{
    		try
    		{
    			T0.sleep(100);
    		}
    		catch(InterruptedException ie){}
    		if(ball.score == 1)
    		{
    			score.incA();
    			ball.score = 0;
    		}
    		else if(ball.score == 2)
    		{
    			score.incB();
    			ball.score = 0;
    		}
    		repaint();
    	}
    
    	public void keyPressed( KeyEvent e )
    	{
    		int key = e.getKeyCode();
    		if (key == KeyEvent.VK_UP)
    		{
    			ball.P2.move(-4);
    		}
    		else if (key == KeyEvent.VK_DOWN)
    		{
    			ball.P2.move(4);
    		}
    		else if (key == KeyEvent.VK_Q)
    		{
    			ball.P1.move(-4);
    		}
    		else if (key == KeyEvent.VK_A)
    		{
    			ball.P1.move(4);
    		}
    		else if (key == KeyEvent.VK_0)
    		{
    			ball.end();
    			T0.stop();
    		}
    		repaint();
    	}
    
    	public void keyReleased( KeyEvent e ) {}
    	public void keyTyped( KeyEvent e ) {}
    	
    	public void init()
    	{
    		resize(Xmax, Ymax);
    		setBackground(C);
    		addKeyListener(this);
    	}
    
    	public void paint(Graphics g)
    	{
    		g.setColor(C);
    		g.fillRect(0, 0, Xmax, Ymax);
    		g.setColor(paddleC);
    		g.fillRect(ball.P1.getX(), ball.P1.getY(), ball.P1.getXsize(), ball.P1.getYsize());
    		g.setColor(paddleC);
    		g.fillRect(ball.P2.getX(), ball.P2.getY(), ball.P2.getXsize(), ball.P2.getYsize());
    		g.setColor(ballC);
    		g.fillOval(ball.getX(), ball.getY(), ball.getSize(), ball.getSize());
    		g.setColor(scoreC);
    		g.drawString( ("Player 1: "+score.getA()+"  Player 2: "+score.getB()), scoreX, scoreY);
    	}
    
    	public int Ymax()
    	{
    		return Ymax;
    	}
    
    	public int Xmax()
    	{
    		return Xmax;
    	}
    }
    Last edited by R3N3G4D3; December 3rd, 2005 at 12:34 PM.

  2. #2
    Join Date
    Apr 2003
    Location
    Los Angeles area
    Posts
    776

    Re: Applet ball not moving

    Run is called once and only once. When you start a thread it calls run to get it going. Therefore in your run statement you need to put the code in a while statement so it repeats. The while statement should check a variable that the application can set to false so as to stop the thread.

    An easier approach to this sort of project is to use a Timer object rather than a separate thread.
    "The Chicken and Rice MRE is not a personal lubricant."

  3. #3
    Join Date
    Jun 2005
    Posts
    3

    Re: Applet ball not moving

    Thanks, I didn't know that run() only runs once. But even then, the ball should have moved at least once, and it didn't, so there is something else wrong as well. And indeed, after I tried while(true){} around everything inside run(), there was still no movement.

    Also, as much as I would like to use something else aside from threads (like a timer), I was told to do this with threads so I kind of have to use them.

  4. #4
    Join Date
    Jun 2005
    Posts
    3

    Re: Applet ball not moving

    The problem seems to be that my run() never runs, but I just don't understand why?

  5. #5
    Join Date
    Apr 2003
    Location
    Los Angeles area
    Posts
    776

    Re: Applet ball not moving

    Probably doesn't work because you are using it wrong.

    ALWAYS ALWAYS ALWAYS read the api documentation.

    ALWAYS.

    You can't program anything unless you read the api and know how to use the libraries.
    "The Chicken and Rice MRE is not a personal lubricant."

  6. #6
    Join Date
    Aug 2003
    Posts
    102

    Re: Applet ball not moving

    Quote Originally Posted by R3N3G4D3
    The problem seems to be that my run() never runs, but I just don't understand why?
    run method on the Ball class doesnt get called because you instantiante the class like this Ball ball = new Ball(Xmax, Ymax);

    Since it implements the runnable interface you can do somthing like this
    Ball ball = new Ball(Xmax, Ymax)
    Thread ballThread= new Thread(ball);
    now to move the ball just invoke the start method of the ballThread
    ballThread.start();
    And to keep your ball moving you need a while loop inside the Ball run method to keep updating the ball's x and y coordinates

    Or just try editing the Ball constructor
    Code:
    // just T1 to null;
    Thread T1 = null;
    
    public Ball(int a, int b)
    	{
    		Xmax = a;
    		Ymax = b;
    		x = Xmax/2;
    		y = Ymax/2;
    		P1.setPaddle(5, (Ymax/2));
    		P2.setPaddle((Xmax-5), (Ymax/2));
    		T1 = new Thread(this);
                    T1.start();
    	}
    But this might not be a good idea coz.... the ball is already moving even before your applet is being started.......... I think?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured