Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm making a 2D game similar to mario in Java.

I have some questions about class organization and proper method usage.

I have the following classes:

  • Main: runs the game in a JFrame
  • GamePanel: JPanel with boundary rules, timer, paintComponent, scoring, keyboard input, collision check
  • Player: only knows about its own attributes... has getter and setter methods for x, y location, height, width, weight etc...
  • Item: Same thing as Item class... this class will be used for items in the game, like bullets, cars, etc...
  • Physics: I was going to use this class to contain all actions for all items in the game (items class, player class, etc)... Like the rules for jumping, or running, etc...

Am I using the classes appropriately? I'm not sure whether each class should contain its own unique methods...

For example, only Player class objects will be able to jump and run... So should Player class have jump() and run() methods? Or should it just have setX(), setY() methods which alter its location based on run() from another class like Physics()?

And for a gun, I have shoot() which creates a new Item

 bullet = new Item(this, player.getX(), player.getY()+40, 25, 10, 10, bulletVelX, 0);

But as you can see below, I'm actually moving the bullet via the timer() class by calling the Item class's autoMove() method to change the bullet Item's location.

I'm also confused on the correct usage of timer():

I'm using it to run methods at a certain interval if a given boolean is set true...

public void timer() {
    timer.scheduleAtFixedRate(new TimerTask() {
        public void run() {
            collisionCheck();
            if (jump) {     
                player.jump(velocityX, -velocityY);
                velocityY--;
                checkPlayerBounds(player);
                repaint();                  
            }
            if (shoot) {
                if (!bulletMag.isEmpty()) {
                    for (Item bullet : bulletMag) {
                        bullet.autoMove(bullet.getVelocityX(), bullet.getVelocityY());
                    }
                    if (bulletMag.size() > 30) {
                        bulletMag.clear();
                    }
                    repaint();
                }
            }       
        }
    }, 0, 100); 
}

Is is okay to put all that logic inside the timer class? Or should the timer class be kept as clean and empty as possible? Is that where my main Game loop is?

Lastly, paintComponent():

I put a paintComponent in each class (Player, Item, and GamePanel so far), and paint them by calling them from within the GamePanel's paintComponent. Is that right?

public void paintComponent(Graphics g) {
    g.setColor(Color.white);
    g.fillRect(0, 0, width, height);
    player.paintComponent(g);
    for (Item bullets : bulletMag) {
        bullets.paintComponent(g);
    }
}

So, in summary is my usage of classes, timer, and paintComponent correct?

share|improve this question

1 Answer 1

up vote 2 down vote accepted

Notch actually made a Mario clone in Java and has the source code available for perusal. Notably he has a Sprite class that gets extended by classes named things like Fireball, Enemy, and BulletBill. His Mario class is also a subclass of Sprite but whether that class is called Mario or Player probably won't help or hurt in the whole scheme of building this. Passing the Graphics context to the classes that represent visible constructs so that they can draw themselves will work out nicely and is indeed what Notch has done. However, you will most likely want to control when this happens instead of letting Swing make that choice for you. This would mean calling the equivalent of paintComponent yourself which would then make it unnecessary for these things to be JComponents.

As for the use of TimerTask to update a the state of the game; when the game hits the performance wall you won't be simply dropping to a lower framerate, the game logic itself will slowdown. This will be noticeable even when the drop in framerate on its own would normally not be. What's worse is that the TimerTask schedules will stack up during this time so the player will experience a period of slowdown followed by a fast-forwarding of both the game logic and framerate. When a game drops frames we expect to miss out on things, not for the passage of time in the game world to be altered. It is common to separate the logic and graphics updates into multiple threads for precisely this reason. The thread that controls the rendering could have its core logic look something like the following:

// Inside the run function of a class implementing Runnable
while (running) {
  double lastTime = time; // save the last time the loop ran
  time = getTime();
  if (time - lastTime < TARGET_FPS) {
    // do nothing to avoid being greedy with CPU cycles for no good reason
    Thread.sleep(5);
  } else {
    // draw graphics and process gamelogic with respect to real time, not anything
    // tied to the graphical representation of time
    renderGraphics(time);
    processGameLogic(time);
  }
}
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.