0

I will be making a simple game with Timer and thought how I should put everything together. I've just started with Swing and Keyboard controls. I imagine I'll have a class for the main Frame with JFrame, a class for the Board with JPanel and then I'll add all the objects to the Board, like JLabel in this example. I'll use composition to glue everything together. I'll have my methods for keyboard controls in the object classes I want to control.

How good or bad is this design and how could I improve it? Any advice would be great.

import javax.swing.JFrame;

public class Main extends JFrame {

public Board board = new Board();

public Main() {
    add(board);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    pack();
    setVisible(true);
}

public static void main(String args[]) {
    new Main();
}

}

import javax.swing.JPanel;

public class Board extends JPanel {

public TextLabel textLabel1 = new TextLabel("Hi", "Hello", "Bye");
public TextLabel textLabel2 = new TextLabel("Bye", "GoodBye", "Farewell");

public Board() {

    addKeyListener(textLabel1); //this could be a ball in my game
    addKeyListener(textLabel2); //this could be something else...
    add(textLabel1);
    add(textLabel2);
    setFocusable(true);
}

}

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JLabel;

public class TextLabel extends JLabel implements KeyListener {

private String txt1, txt2;

public TextLabel(String text, String txt1, String txt2) {
    setText(text);
    this.txt1 = txt1;
    this.txt2 = txt2;
}
public void keyPressed(KeyEvent e) {
    int key = e.getKeyCode();

    if (key == KeyEvent.VK_A) {
        setText(txt1);
    }

    if (key == KeyEvent.VK_L) {
        setText(txt2);
    }

}
@Override
public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub

}
@Override
public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub

}
}
  • I suggest you take a look at an article/book on game design. A game can be implemented similar to a MVC pattern, where each part is divided into smaller subsections. For example, the main controller would be a loop that is being iterated with each tick of the timer, and this loop would make calls to a physical engine, AI engine etc. Each of those subcontrollers would make appropriate modifications in the Model and in the end of the loop View would be updated according to the Model. Iterations of that loop is sometimes called a Frame (e.g. FPS: Frame Per Second). – mostruash Apr 19 '14 at 17:11

1 Answers1

1

If you want your simple game to be memory/cpu efficient, I suggest taking a totally different route.

  1. Use a GameLoop. It seems as if you aren't using any type of action listener or loop to handle updates. You need something to handle updates, such as when a player moves from point A to point B, you need a way to keep increasing your entity's coordinates until it's at its destination. An ActionListener and using Swing timers will work for simple games, but if you wanna get serious about game dev In the future, start off the right way.

public class Main { public static void main(String[] args) { Game game = new Game(); //init JFrame and add game to it

        game.start();
        while(game.isRunning()) {
            game.update();
            game.repaint();
        }
    }
}

class Game extends Canvas {
    private boolean running = true;
    private Ball ball = new Ball(0, 0, 50, 50);

    public void start() {   
        running = true;
    }

    public void stop() {
        //clean-up
        running = false;
    }

    public void update() { //update game logic
        ball.update();
    }

    @Override
    public void paint(Graphics g) { //render game
        super.paint(g); //clears previous graphics

        ball.render(g); //passes graphics down to entity
    }
}

This will give you a clear view on the design of your game, aswell separate rendering from game logic. Here's what the ball class would look like

class Ball {
    private int currentX, currentY, width, height;

    public Ball(int x, int y, int w, int h) {
        currentX = x; currentY = y;
        width = w; height = h;
    }

    public void update() {
        currentX++; //moves ball to right
    }

    public void render(Graphics g) {
        g.setColor(Color.BLUE);
        g.fillRect(currentX, currentY, width, height);
    }
}

You'll notice that when running something like this, your CPU usage will be rather high. It's because the while loop controlling your game is looping at an extremely fast rate. There are many ways to slow this down in a precisely timed manner. I'll show you a pretty simple way:

int fps = 30;
int oneNanoSec = 1000000000;
int secondsPerLoop = oneNanoSecond/fps; //divide a second into 30 slices
while(game.isRunning()) {
    long start = System.nanoTime(); //see what time it is when we start

    game.update();
    game.render();

    long end = System.nanoTime(); //see what time it is when the game is finished updating/rendering
    long sleepTime = secondsPerLoop - (end-start);

    if(sleepTime > 0) {
        try {
            Thread.sleep(sleepTime);
        }catch(InterruptedException e) {
            e.printStackTrace();
        }
    } else
        Thread.yield();
}

This timer sees how long it took to update and render, then depending on how fast you wanna update/render, the thread running your game will sleep (pause).

Vince
  • 14,470
  • 7
  • 39
  • 84