Ball not moving?

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

30 Replies - 1471 Views - Last Post: 09 August 2012 - 01:32 PM Rate Topic: -----

#1 skymonkier  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 94
  • Joined: 14-July 12

Ball not moving?

Posted 06 August 2012 - 04:11 PM

I've been working continuously on my Pong project, and I've pretty much done everything ball- and movement-wise. The problem comes in at movement. When I build and run my game, the ball doesn't move. It's supposed to begin moving randomly as soon as the game begins to run, but nothing seems to happen. Can anyone look over my code and point out any mistakes that might have caused the ball to not move?

I've looked over it time and time again, but I can't spot any fault in it.

Le Game.java
public class Game extends JFrame {
    
    // Double buffering implementations.
    Image dbImage;
    Graphics dbGraphics;
    
    // Create the instance of the ball.
    static Ball ball = new Ball(239, 175);
    
    // Main game variables.
    int
    GWIDTH = 500,
    GHEIGHT = 400;
    // Game screen dimensions. (GWIDTH*GHEIGHT)
    Dimension screenSize = new Dimension(GWIDTH, GHEIGHT);
    
    
    
    
    
    // Create the game constructor.
    public Game(){
        this.setTitle("SurvivalPong - by GamerStudios");
        this.setSize(screenSize);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setBackground(Color.DARK_GRAY);
        this.addKeyListener(new ActionL());
    }

    public static void main(String[] args) {
        Game survpong = new Game();
        // Create and start the threads.
        Thread ballthread = new Thread(ball);
        ballthread.start();
    }
    
    
    
    
    
    @Override
    public void paint(Graphics g) {
        dbImage = createImage(getWidth(), getHeight());
        dbGraphics = dbImage.getGraphics();
        draw(dbGraphics);
        g.drawImage(dbImage, 0, 0, this);
    }
    
    public void draw(Graphics g) {
        ball.draw(g);
        
        repaint();
    }
    
    
    
    
    
    ///////// ActionListener class. Controls key input. /////////
    public class ActionL extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            
        }
        @Override
        public void keyReleased(KeyEvent e) {
        
        }
    }
    /////////        END OF ActionListener CLASS.        /////////
}



Le Ball.java
public class Ball implements Runnable {
    
    // Global variables.
    int
    xLocation, yLocation,
    xDirection, yDirection;
    
    Rectangle ball;
    
    
    
    
    
    // Begin Ball constructor.
    public Ball(int xLoc, int yLoc) {
        // Set the location.
        this.xLocation = xLoc;
        this.yLocation = yLoc;
        //// Set the ball moving randomly. ////
        // First set the X direction.
        Random randomdir = new Random();
        int xrDir = randomdir.nextInt(2);
        if(xrDir == 0) {
            xrDir--;
            setXDirection(xrDir);
        }
        // Now set the Y direction.
        int yrDir = randomdir.nextInt(2);
        if(yrDir == 0) {
            yrDir--;
            setYDirection(yrDir);
        }
        
        // Create the 'ball'.
        ball = new Rectangle(this.xLocation, this.yLocation, 15, 15);
        
    }
    
    
    
    
    
    ///////// Setting the X and Y directions for the ball. /////////
    // Set the X-Direction of the ball.
    public void setXDirection(int xDir) {
        xDirection = xDir;
    }
    
    // Set the Y-Direction of the ball.
    public void setYDirection(int yDir) {
        yDirection = yDir;
    }
    /////////      End of setting X and Y directions.      /////////
    
    
    
    
    
    // Draw the ball. (Technically a square.)
    public void draw(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(ball.x, ball.y, ball.width, ball.height);
    }
    
    
    
    
    public void move() {
        xLocation += xDirection;
        yLocation += yDirection;
        
        // Collision detection for the edge of the panel.
        if(xLocation <= 0) {
            setXDirection(+1);
            
        }
        if(xLocation >= 485) {
            setXDirection(-1);
            
        }
        if(yLocation <= 0) {
            setYDirection(+1);
            
        }
        if(yLocation <= 385) {
            setYDirection(-1);
            
        }
    }
    
    
    
    
    
    @Override
    public void run() {
        try{
            while(true) {
                move();
                Thread.sleep(4);
            }
        }catch(Exception e){System.err.println(e.getMessage());};
    }
    
    
    
}


Thanks and cheers,
skymonkier

Is This A Good Question/Topic? 0
  • +

Replies To: Ball not moving?

#2 farrell2k  Icon User is offline

  • 1.21 Jiggawatts!
  • member icon

Reputation: 572
  • View blog
  • Posts: 1,752
  • Joined: 29-July 11

Re: Ball not moving?

Posted 06 August 2012 - 07:09 PM

Your game loop should draw(). Only move() is being executed. It should move, draw, sleep, then repeat. I am sure pbl will be in sooner or later to tell you about not using a thread for animation, as well as a 4ms sleep time being a waste. :)
Was This Post Helpful? 0
  • +
  • -

#3 skymonkier  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 94
  • Joined: 14-July 12

Re: Ball not moving?

Posted 07 August 2012 - 05:57 AM

Well, I tried it two different ways. I either added draw(); or draw(g); to the Ball.java run method, and it couldn't recognize draw();, or I put the run loop into Game.java, where it could not recognize the move(); method. I'm lost now... Can anyone help me out? :P
Was This Post Helpful? 0
  • +
  • -

#4 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 9153
  • View blog
  • Posts: 33,962
  • Joined: 27-December 08

Re: Ball not moving?

Posted 07 August 2012 - 09:11 AM

You're over-complicating things. There are a few things here.
  • A static Ball isn't good practice. The Ball should be unique to the Game instance, not global and associated with the class. If you have three instances of Game present, each instance should have its own distinct Ball.

  • You don't need to double-buffer. Extend JPanel to handle your painting, as it is double-buffered by default.

  • A Swing Timer will be sufficient to handle painting, with 20-40 millisecond delays.


A basic sample. Note that I am assuming you will be removing your Threading from the Ball class for this.
class PaintSample extends JPanel implements ActionListener{

    private Ball ball;
    private Timer timer;

    PaintSample(){
        this.x = 50;
        this.y = 50;
        this.timer = new Timer(30, this);
        this.timer.start();
    }

    public void paintComponent(Graphics g){
        super.paintComponent(g); //handle superclass functionality
        ball.draw(g);
    }

    public void actionPerformed(ActionEvent e){ 
         ball.move();
         repaint(); 
    }
}


Was This Post Helpful? 1
  • +
  • -

#5 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8066
  • View blog
  • Posts: 31,309
  • Joined: 06-March 08

Re: Ball not moving?

Posted 07 August 2012 - 10:40 AM

your paint() method cals draw() that calls repaint() which will call paint() .....
you atre in an infinite loop that might not let a lot of time for the actual repaint of your screen by the hardware
Was This Post Helpful? 0
  • +
  • -

#6 skymonkier  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 94
  • Joined: 14-July 12

Re: Ball not moving?

Posted 07 August 2012 - 01:14 PM

Alright... I guess it's time I attempted to move to JPanel to make some of my code easier and more efficient...
How do I convert from JFrame to JPanel? Is there any docs that show the features of JPanel so I can replace the ones that are on JFrame but won't work for JPanel?

Thanks and cheers!
skymonkier
Was This Post Helpful? 0
  • +
  • -

#7 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 9153
  • View blog
  • Posts: 33,962
  • Joined: 27-December 08

Re: Ball not moving?

Posted 07 August 2012 - 01:21 PM

My sample above should be a good guide. Then just add() your JPanel subclass to the JFrame like you would any other JComponent.
Was This Post Helpful? 0
  • +
  • -

#8 skymonkier  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 94
  • Joined: 14-July 12

Re: Ball not moving?

Posted 07 August 2012 - 06:52 PM

View Postmacosxnerd101, on 07 August 2012 - 01:21 PM, said:

My sample above should be a good guide. Then just add() your JPanel subclass to the JFrame like you would any other JComponent.


So, I still use JFrame but implement JPanel? I'm not quite sure I understand...
Was This Post Helpful? 0
  • +
  • -

#9 pbl  Icon User is offline

  • There is nothing you can't do with a JTable
  • member icon

Reputation: 8066
  • View blog
  • Posts: 31,309
  • Joined: 06-March 08

Re: Ball not moving?

Posted 07 August 2012 - 07:59 PM

You will always need a JFrame. This is the base container for every Java application GUI.
Just add a JPanel to it and add everything you added to the JFrame to that JPanel.
Was This Post Helpful? 0
  • +
  • -

#10 skymonkier  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 94
  • Joined: 14-July 12

Re: Ball not moving?

Posted 08 August 2012 - 09:39 AM

View Postpbl, on 07 August 2012 - 07:59 PM, said:

You will always need a JFrame. This is the base container for every Java application GUI.
Just add a JPanel to it and add everything you added to the JFrame to that JPanel.


I looked into this and found a simple doc on JPanel. To which class should I add the JPanel? Game or Ball? Also, I've read that you can create a JPanel with JPanel panel = new JPanel();, but do I need an import or is there a way to extend it to do both JFrame and JPanel? Probably a stupid question, but...

EDIT: One more thing, if I put the JPanel into the Game class, do I make the JPanel with the other variables and then initialize it in my constructor, or do I do both in the constructor or with the other variables?

This post has been edited by skymonkier: 08 August 2012 - 09:42 AM

Was This Post Helpful? 0
  • +
  • -

#11 macosxnerd101  Icon User is online

  • Self-Trained Economist
  • member icon




Reputation: 9153
  • View blog
  • Posts: 33,962
  • Joined: 27-December 08

Re: Ball not moving?

Posted 08 August 2012 - 09:42 AM

You want to extend JPanel to handle your painting like I showed you in my example above. You will then add your JPanel subclass instance to a JFrame.

class MyFrame extends JFrame{

    public MyFrame(){
       this.setSize(400,400); 
       this.add(new PaintSample());
       this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       this.setVisible(true);
    }
}


Was This Post Helpful? 1
  • +
  • -

#12 skymonkier  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 94
  • Joined: 14-July 12

Re: Ball not moving?

Posted 08 August 2012 - 09:44 AM

View Postmacosxnerd101, on 08 August 2012 - 09:42 AM, said:

You want to extend JPanel to handle your painting like I showed you in my example above. You will then add your JPanel subclass instance to a JFrame.


Ah, now I see. Thanks. I'll tinker around with this a bit and see what comes up.
Was This Post Helpful? 0
  • +
  • -

#13 skymonkier  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 94
  • Joined: 14-July 12

Re: Ball not moving?

Posted 08 August 2012 - 10:13 AM

Alright, so I've added JPanel to work with this. I figured that I should add the Timer to Game.class for when it moves, but when I attempt to use the "this.timer = new Timer(30, this);" method in my constructor, it comes up with an error stating that the "actual argument Game cannot be converted to ActionListener by method invocation conversion.' This gave me the question where do I put? So I tried putting it in my Ball.class constructor, but it came up with the same error.

On top of this, I'm also thinking that I messed up the painting somehow. When I attempt to ball.paintComponent(); (or should it be draw()?) in my run method, it can't recognize the 'g' argument in ball.paintComponent(g); and when I remove it, it only creates another error. I tried it with draw(g); but ended up with the same error.

Le Code for the Run method in Game.class.
public void run() {
           try {
               while(true) {
                   ball.paintComponent(g);
                   ball.move();
                   
                   repaint();
               }
           }
           catch(Exception e) {
               
           }
       }


Le painting code in Ball.class.
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        this.draw(g);
    }
    
    public void draw(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(ball.x, ball.y, ball.width, ball.height);
    }


I'm probably making simple mistakes here, so I feel stupid and guilty for wasting peoples' time... :/
Was This Post Helpful? 0
  • +
  • -

#14 g00se  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2146
  • View blog
  • Posts: 8,920
  • Joined: 20-September 08

Re: Ball not moving?

Posted 08 August 2012 - 10:50 AM

If you're now encapsulating the Ball functionality as a JPanel subclass (tell me if not - it's important), you might as well

a. Give it the Swing Timer (You can add Ball.start and Ball.stop methods)
b. Make it an ActionListener

There should be no loop in the code - the Timer is 'its own loop'
In the actionPerformed of b. you want only

move();
repaint();

This post has been edited by g00se: 08 August 2012 - 10:51 AM
Reason for edit:: Ball methods

Was This Post Helpful? 0
  • +
  • -

#15 skymonkier  Icon User is offline

  • D.I.C Head

Reputation: 2
  • View blog
  • Posts: 94
  • Joined: 14-July 12

Re: Ball not moving?

Posted 08 August 2012 - 10:57 AM

Well, I fixed up those errors. Just one problem; the ball still doesn't move when the game begins. Here's the updated code, can anyone point out the mistakes?

Le Game.java
package survivalpong;

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


public class Game extends JFrame {
    
    // Create the instance of the ball.
    private Ball ball;
    
    // Main game variables.
    int
    GWIDTH = 500,
    GHEIGHT = 400;
    // Game screen dimensions. (GWIDTH*GHEIGHT)
    Dimension screenSize = new Dimension(GWIDTH, GHEIGHT);
    
    
    
    
    
    // Create the game constructor.
    public Game(){
        // Add the Ball instance.
        this.add(new Ball(247, 120));
        this.setTitle("SurvivalPong - by GamerStudios");
        this.setSize(screenSize);
        this.setResizable(false);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setVisible(true);
        this.setBackground(Color.DARK_GRAY);
        this.addKeyListener(new ActionL());
        
    }

    public static void main(String[] args) {
        Game survpong = new Game();
        
    }
    
    
    
    
    
    
    public void draw(Graphics g) {
        ball.move();
        ball.draw(g);
        
        repaint();
    }
    
    
    
    
    
    ///////// ActionListener class. Controls key input. /////////
    public class ActionL extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            
        }
        @Override
        public void keyReleased(KeyEvent e) {
        
        }
    }
    /////////        END OF ActionListener CLASS.        /////////
}



Le Ball.java
package survivalpong;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Ball extends JPanel implements ActionListener {
    
    // Global variables.
    int
    xLocation, yLocation,
    xDirection, yDirection;
    
    Rectangle ball;
    
    // Create a swing timer to handle movement timing.
    Timer timer;
    
    
    
    
    
    // Begin Ball constructor.
    public Ball(int xLoc, int yLoc) {
        // Set the location.
        this.xLocation = xLoc;
        this.yLocation = yLoc;
        //// Set the ball moving randomly. ////
        // First set the X direction.
        Random randomdir = new Random();
        int xrDir = randomdir.nextInt(2);
        if(xrDir == 0) {
            xrDir--;
            setXDirection(xrDir);
        }
        // Now set the Y direction.
        int yrDir = randomdir.nextInt(2);
        if(yrDir == 0) {
            yrDir--;
            setYDirection(yrDir);
        }
        
        // Create the 'ball'.
        ball = new Rectangle(this.xLocation, this.yLocation, 15, 15);
        
        // Implement the swing timer for movement timing.
        this.timer = new Timer(30, this);
    }
    
    
    
    
    
    ///////// Setting the X and Y directions for the ball. /////////
    // Set the X-Direction of the ball.
    public void setXDirection(int xDir) {
        xDirection = xDir;
    }
    
    // Set the Y-Direction of the ball.
    public void setYDirection(int yDir) {
        yDirection = yDir;
    }
    /////////      End of setting X and Y directions.      /////////
    
    
    
    
    
    // Draw the ball. (Technically a square.)
    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        this.draw(g);
    }
    
    public void draw(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(ball.x, ball.y, ball.width, ball.height);
    }
    
    
    
    
    public void move() {
        xLocation += xDirection;
        yLocation += yDirection;
        
        // Collision detection for the edge of the panel.
        if(xLocation <= 0) {
            setXDirection(+1);
            
        }
        if(xLocation >= 485) {
            setXDirection(-1);
            
        }
        if(yLocation <= 0) {
            setYDirection(+1);
            
        }
        if(yLocation <= 385) {
            setYDirection(-1);
        
        }
    } 
    
    public void actionPerformed(ActionEvent e){ 
         this.move();
         repaint(); 
    }
}


This post has been edited by skymonkier: 08 August 2012 - 10:57 AM

Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3