Basic Game

Let’s start with basic.

You want to do a game and don’t know where to start?

A game is usually compose of the following elements :

  • Frame : The window of the game
  • Canvas : The rendering surface
  • GameLoop : Call the rendering and update methods
  • Rendering method : All your drawing here
  • Update method : All your game logic here
  • Mouse and Key input : Add KeyListener, MouseListener and MouseMotionListener to the canvas

Here is a template that I use for my games. To make your own game, you just have to add your code in the render(Graphics2D g) and update(int deltaTime) methods.

I add a little test so you can run this code directly to see what it does.

import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Game implements Runnable{
	
	final int WIDTH = 1000;
	final int HEIGHT = 700;
	
	JFrame frame;
	Canvas canvas;
	BufferStrategy bufferStrategy;
	
	public Game(){
		frame = new JFrame("Basic Game");
		
		JPanel panel = (JPanel) frame.getContentPane();
		panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
		panel.setLayout(null);
		
		canvas = new Canvas();
		canvas.setBounds(0, 0, WIDTH, HEIGHT);
		canvas.setIgnoreRepaint(true);
		
		panel.add(canvas);
		
		canvas.addMouseListener(new MouseControl());
		
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.pack();
		frame.setResizable(false);
		frame.setVisible(true);
		
		canvas.createBufferStrategy(2);
		bufferStrategy = canvas.getBufferStrategy();
		
		canvas.requestFocus();
	}
	
        
	private class MouseControl extends MouseAdapter{
		
	}
	
	long desiredFPS = 60;
    long desiredDeltaLoop = (1000*1000*1000)/desiredFPS;
    
	boolean running = true;
	
	public void run(){
		
		long beginLoopTime;
		long endLoopTime;
		long currentUpdateTime = System.nanoTime();
		long lastUpdateTime;
		long deltaLoop;
		
		while(running){
			beginLoopTime = System.nanoTime();
			
			render();
			
			lastUpdateTime = currentUpdateTime;
			currentUpdateTime = System.nanoTime();
			update((int) ((currentUpdateTime - lastUpdateTime)/(1000*1000)));
			
			endLoopTime = System.nanoTime();
			deltaLoop = endLoopTime - beginLoopTime;
	        
	        if(deltaLoop > desiredDeltaLoop){
	            //Do nothing. We are already late.
	        }else{
	            try{
	                Thread.sleep((desiredDeltaLoop - deltaLoop)/(1000*1000));
	            }catch(InterruptedException e){
	                //Do nothing
	            }
	        }
		}
	}
	
	private void render() {
		Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
		g.clearRect(0, 0, WIDTH, HEIGHT);
		render(g);
		g.dispose();
		bufferStrategy.show();
	}
	
	//TESTING
	private double x = 0;
	
	/**
	 * Rewrite this method for your game
	 */
	protected void update(int deltaTime){
		x += deltaTime * 0.2;
		while(x > 500){
			x -= 500;
		}
	}
	
	/**
	 * Rewrite this method for your game
	 */
	protected void render(Graphics2D g){
		g.fillRect((int)x, 0, 200, 200);
	}
	
	public static void main(String [] args){
		Game ex = new Game();
		new Thread(ex).start();
	}

}

Here is a game that I made with this code : http://www.gudradain.byethost12.com/geomwar.html

NOTE : If you run the code, you probably realize that the square in the animation glitter a little bit. You can remove that effect by increasing the frame rate of the game (change the variable desiredFPS).

WARNING : If you set a too high FPS (frame per second), you might have problem with the game logic.

I will have to say that that is absolutely BEAUTIFUL!!

Very nice tutorial and awesome game to boot!!
Thank you very much for your contribution!!

I got a score over 800,000! :stuck_out_tongue:
It just goes to show how to optimize a simple game engine with a dash of creativity and effort. ;D

EDIT: Ok, I think I have found a good solution. Thanks anyway :slight_smile:

Hi, Gudradain,

I’m new on the forums here, and found the place from a google serch that got me to this tutorial.

I have been playing around with the code for your game loop, and have started working on a basic space RTS where you pilot a space ship around a solar system. At the moment its only a very rudimentary graphics and physics engine based around your code.

I have been up all night implimenting a 2D camera class using AffineTransform that alows zooming and scrolling the map. This works fine programaticaly (i can lock the camera to a moving object in the game world) but i cannot for the life of me figure out how to get mouse input to work (for manual click and drag/wheel zooming).

I muss confess, i’m new to the Java game scene, having come from a few years experience with XNA/C# game programing, and am a little uncerten how all the mouse event listening works in Java.

I would be verry greatfull if you could explain what the MouseControl class is sposed to do, and how to use this to detect dragging and wheel events, and maybe keyPresses?

Thankyou very much for an already fantastic tutorial!

Once i have something close to ready i’ll post screenshots and a demo.

Matt Taylor

My question: how do you get all those moving parts move over the screen so efficiently? In my (tower defence) game I used the following way way to get the monsters moving:

When I need a new monster, I make an instance of the monster class. That starts a swing-timer. Every time that generates an action event, the integer “steps” goes up by one. The path they need to take is set out pizel by pixel into an arrayList. Because the monster class extends JPanel, it can then paint itself based on those coordinates (arrayList.get(steps)). The JPanel is added to a JLayeredPane and repainted each time the timer generates an action event.

For one monster, this works fine, however at 3 monsters it gets to slow to be practical. Your game consists of 50+ moving parts, how do you do that?

Lot of problems here.

First, in a game you only really need 1 timer, just one. This timer send event to all your game object in the update method.
Second, you only need 1 drawing surface in a game. Don’t make a lot of JPanel. That bring up next point
Third, dont make monster extends JPanel. Make Monster a class of his own and use Graphics2D class to draw your monster. The Monster class should only contain information about where the monster is, what it can do and how to draw it.

Oh by the way, there is way more than 50 moving part in this game. Every line of the explosion is a class equivalent to a monster (… ok this must not be the most efficient way, but so far I didn’t get any lag complaint).

Hope it helps.

N.B. Drawing on canvas is suppose to be accelerated (by graphics card?!?). Anyway, not sure if it does any difference as Swing component are suppose to be accelerated too.

This is a great template but I am not sure it counts as a tutorial since nothing is explained. If someone could go back through the op’s code and explain it line by line this would probably make a perfect intro tutorial to gaming.

Maybe this should be moved to “Shared Code”.

Is your goal actually a game or just try to make a good game loop for a couple of week and then give up on game programming? Ok sorry if I sound a bit harsh but something similar happens to me.

I waste a lot of time trying to make a good game loop. First I went with a JPanel and I just let the repaint() method to be called from time to time (not a good idea). Next I tried to use a Timer object with the repaint(). Didn’t really work either. Finally I decide to look around on the forum I saw that many person were using a while(true) loop. So I guess that was not so bad. Unfortunately, there was no place that a specified game loop was propose without having many variation of it. So I wonder, why is there so many variations? Is one better than another? So I decide to try everyone I see and research about every methods (on this forum, on other forum, on google, etc). In the process I also learn about double buffering (drawing to an image before switching it to the screen in one step) and how it improved your rendering.

All of that was a lenghty process and I basically lost 2-3 months doing so just to realize that most of the methods I encounter were excellent or good enough and that I would have saved a lot of time just picking one and getting started in game programming rather than try to understand everything for no particular reason. Maybe it’s just because I’m really stubborn.

Anyway I put this tutorial up this way because I figured that most people only want to get started as soon as possible and really the only thing you really need to start coding your game is an update(deltaTime) method, a render(Graphics2D) and some knowledge about Mouse and keyboard input (check java tutorial for that). The rest is basically your imagination.

Well there is a few technical trick you might need to learn in the way but we have a very good forum for that (Newbie & Debugging Questions)

Man, what you described is exactly what I’ve gone through.

Thanks for sharing this code with us. Very good reference. I have a bit of question.

 protected void update(int deltaTime){
        x += deltaTime * 0.2;
        while(x > 500){
            x -= 500;
        }
    }

Could someone explain me what is this deltaTime for?

The deltaTime is used to know how far update (move, lifespan of an entity etc) should be done on this loop. Each loop takes some amount of time but our update must still go on so we need to update based on deltaTime of previous loop.

[quote]Could someone explain me what is this deltaTime for?
[/quote]
It is the number of milliseconds that have elapsed since the last update.

Thanks for the replies.

I have been trying to calculate FPS using this game loop. I call this method at the end of while loop. For instance, when I set the FPS to 60, it calculates between 62 and 65. Am I still doing this correctly?

public void calcFPS(){
		++frameCount;
		long now = System.nanoTime();
		if (now - base >= 1000000000L){
			frameRate = (float)(frameCount * 1000000000L) / (float)(now - base);
			frameCount = 0;
			base = System.nanoTime();
		}
	}

I’ve extended your game class, but I’m having trouble understanding how to access the MouseControl nested class. I think this is just my limited understanding of java, but if a nested class is declared private, I don’t understand how i access it from the derived class. I’m not supposed to modify it in the superclass, right? That would defeat the purpose of deriving it in the first place.

Halp? :frowning:

I may be wrong,b ut I don’t think that you are supposed to extend, when I took a quick look, it seems like u should use that code directly and just change it to suite ur needs.

His update() and render(g) methods say to override them in a subclass, so it looks like it’s meant to be extended.

EDIT: Although the more i look at it, the more I think you are right. It doesn’t seem like it needs to be derived from. I’ll give it a try without a subclass and see if that works better or not.

Sorry for double-post.

I stopped trying to derive a class from your Game class, but that nested class still gets me. I’ve put system print lines in the MouseControl class to see when an event is being registered, and it doesn’t look like it’s ever getting there. What am I missing?

Here’s the code that I’ve changed/added:

private class MouseControl extends MouseAdapter{
		
		public boolean mouseLeftPressed, mouseRightPressed;
		
		public void MouseClicked(MouseEvent e){}
		public void MouseDragged(MouseEvent e){}
		public void MouseEntered(MouseEvent e){}
		public void MouseExited(MouseEvent e){}
		public void MouseMoved(MouseEvent e){}
		public void MousePressed(MouseEvent e){
			switch(e.getButton()) {
				case MouseEvent.BUTTON1:
					mouseLeftPressed = true;
					System.out.println("mouseLeftPressed");
					break;
				case MouseEvent.BUTTON2:
					mouseRightPressed = true;
					System.out.println("mouseRightPressed");
					break;
			}
		}
		public void MouseReleased(MouseEvent e){
			switch(e.getButton()) {
				case MouseEvent.BUTTON1:
					mouseLeftPressed = false;
					System.out.println("mouseLeftReleased");
					break;
				case MouseEvent.BUTTON2:
					mouseRightPressed = false;
					System.out.println("mouseRightReleased");
					break;
			}
		}
		public void MouseWheelMoved(MouseEvent e){}
		
	}

hmm, I’ve never used mouseAdapter, but in any event did you add it to the frame? like there should be a method in your game class where u add it. for a mouse listener is is something like addListener(whatever class implements the listener). but you use adaper for some reason so it may be different

It’s added to the canvas in the Game() method in the original code, but not to the frame.