2

Im doing an assignment for school. I have to create 30 randomly colured GameObjects in random locations. I have to use 2 classes, a GameObject class which contains the GameObject data, x and y co-ordinates and colour, plus the move and paint method... and a main MovingSquaresApplication which puts the GameObjects into an array and calls the paint() and move() methods... the current program compiles, runs, paints 60 squares (paint() and repaint()) but no animation. I've looked at a lot of different posts but still cant get it right. Any help would be great. Here is the code.....

*edited new code

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

public class MovingSquaresApplication extends JFrame implements Runnable {


//member data
private static final Dimension WindowSize = new Dimension(600,600);
private static final int NUMGAMEOBJECTS = 30;
private GameObject[] gameObjectsArray = new GameObject[NUMGAMEOBJECTS];
private int i,j;

//constructor
public MovingSquaresApplication(){


            this.setTitle("MovingSquaresApplication");
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);


            //Display the window, centered on the screen
            Dimension screensize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
            int x = screensize.width/2 - WindowSize.width/2;
            int y = screensize.height/2 - WindowSize.height/2;
            setBounds(x, y, WindowSize.width, WindowSize.height);
            setVisible(true);           


            for (i=0; i<gameObjectsArray.length; i++){        //fills array with GameObjects
                GameObject NewSquare = new GameObject();
                gameObjectsArray[i] = NewSquare;
            }

            Thread t = new Thread(this);        //creates and stars a thread
            t.start();              
}

//threads entry point
public void run(){


while (true){
    try {
        Thread.sleep(20);

            for (j=0; j<gameObjectsArray.length; j++){
                gameObjectsArray[j].move();
                repaint();
            }


        } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}
}

//applications paint method
public void paint (Graphics g){

    super.paintComponents(g);
    for (i=0; i<gameObjectsArray.length; i++){
        gameObjectsArray[i].paint(g);
    }

    }

//applications entry point
public static void main(String[] args){
    MovingSquaresApplication w = new MovingSquaresApplication();

}

}

and the GameObject class

import java.awt.*;

public class GameObject {

//member data
private int x,y,xvel=2,yvel=2;
private Color c;

public GameObject(){

    x = (int) (Math.random( )*600);
    y = (int) (Math.random( )*600);

    int R = (int) (Math.random( )*256);
    int G = (int)(Math.random( )*256);
    int B= (int)(Math.random( )*256);

    c = new Color (R, G, B);
}

//public interface
public void move(){
    x += xvel;
    y += yvel;

    if(x<10)
    {
        xvel = 2;
    }

    else if(y<30)
    {
        yvel = 2;
    }

    else if(x>=560)
    {
        xvel = -2;
    }

    else if(y>=560)
    {
        yvel = -2;
    }
}


public void paint(Graphics g){
    g.setColor(c);
    g.fillRect(x, y, 30, 30);
}


}

Thanks for all the help, much appreciated

Thanks for the help, I didnt create a class that extends JPanel, i simply put

super.paintComponent(g);

in the paint method, not sure if thats good practice but it worked....also on a sidenote i haven't seen this before

for (GameObject gameObject : gameObjectArray)

what exactly does this do compared to the loop i've used?

7
  • 3
    Im doing an assignment for school. - then you should be using proper variable names. Variable names should NOT start with an upper case character. Commented Mar 14, 2016 at 20:19
  • You're not updating your game objects in your update loop. You're simply creating a new game object, then looping through your game objects and moving this NEW game object, but it is never displayed and it is then destroyed. Just updated each of your game objects in your loop through them and you should be close to achieving your goal. Commented Mar 14, 2016 at 20:23
  • then you should be using proper variable names I second that. It kinda irks me when people tells me their school teacher don't bother about naming conventions. Commented Mar 15, 2016 at 12:50
  • Sorry, i was aware of that, but they were the variable names given to us, i meant to change them. thanks for the help Commented Mar 15, 2016 at 13:56
  • 1
    No, don't call paintComponent within the paint method, yes, extend JPanel for your animation, not JFrame, and please don't try to edit my answer. Commented Mar 15, 2016 at 15:16

1 Answer 1

4

You need to paint within the paintComponent method of a JPanel (as I'm sure that you've read,.... and so I recommend that you do just that. That you

  • Fill your GameObjectsArray with GameObjects, and do so not within any painting method, but on GUI construction
  • Create a JPanel and override its paintComponent method just as the Swing painting tutorials tell you to do
  • Call the super's paintComponent method within your override (again as the tutorials will tell you to do)
  • iterate through your GameObjectsArray (but rename it gameObjectsArray since its a variable not a class) within the paintComponent method
  • call each GameObject's paint method within that same for loop.

edit: check out this code of yours:

GameObject MoveSquare = new GameObject();
for (y = 0; y < GameObjectsArray.length; y++) {
    MoveSquare.move();
}

What you're doing is creating a completely new GameObject object, MoveSquare, and are trying to move it within the for loop, meanwhile you're not touching any of the GameObjects held within the gameObjectsArray. Do you see your mistake here?


Edit 2
Also you're using the y variable as the array index, the same variable that you're using to figure out the y-axis bounds of your GUI -- don't do this. Use a completely independent variable.

Edit 4
And here:

public void paint(Graphics g) {
    for (y = 0; y < GameObjectsArray.length; y++) {
        GameObject NewSquare = new GameObject();
        if (GameObjectsArray[y] == null) {
            GameObjectsArray[y] = NewSquare;
            NewSquare.paint(g);
        }
    }
}

You're creating new GameObject variables with each call to paint, ignoring any that already may be present in the array(??). Painting methods should be for painting and painting only. Again, fill your GameObject array with new GameObject items once and in your class constructor, not in a painting method.

You're doing a lot of guessing here, and throwing code at the wall and seeing what sticks is not a good heuristic for creating a program. Instead plan each step on paper before committing code to IDE.


Edit 5
Your if conditions within the GameObject move method need to be fixed. But once you get the code running, you'll see exactly what I mean, as you'll see all your GameObjects running off of the page.


Edit 6

I'm not going to show you all your code, but again, you'll want to create a class that extends JPanel, override its paintComponent method, and that method will be quite simple and look like this:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);  // do housekeeping painting

    // note that I've renamed the array to gameObjectArray
    for (GameObject gameObject : gameObjectArray) {
        gameObject.paint(g);  // this is all you need to call
    }
}

Likewise, the run method would be something like:

@Override
public void run() {
    while (true) {
        try {
            Thread.sleep(SLEEP_TIME); // constant for the sleep time
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // again note that the array has been renamed
        for (GameObject gameObject : gameObjectArray) {
            gameObject.move();  // this is all that needs to be called here
        }
        repaint();
    }
}

Edit next :)
You're creating two Thread objects and starting them both -- don't do that. Only one will do.

Sign up to request clarification or add additional context in comments.

1 Comment

I wish I could upvote you more. You've done as fine a job of tutoring as I've seen on a question and answer site.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.