Juce 2D Game Engine

[size=150]Juce 2D Game Engine[/size]

How pointless? Pretty darned pointless! But it’s been fun so far and there’s still a lot to do on it.

It’s a basic 2D game engine, whos elements are Juce Components. The current version of the source code is [size=200]here[/size], and there’s an example windows executable (the source of this is in the archive too) [size=150]here[/size].

The post below explains a bit about some of the features. Some of them haven’t quite been fully tested yet, and i want to make some more systems in there that make creating a game really easy.

There’s little point to this, other than to see what was possible. It’s been a little tricky getting it working, but with this framework it’s actually really easy to get a little game running - have a look at the source for SquaresGame… that’s basically all there is to it.

Would you believe it, this little experiment has spiralled out of control!

What started as a basic ‘lets see how i’d go about making a crude game’ experiment has evolved into a fairly acceptable crude 2D game framework.

It’s definitely bedtime now, but when i get up i’m going to get the system into a deliverable form. I know juce isn’t for games, but it’s fun to mess around coding very basic games just for a laugh. And this GameComponent framework i bashed together actually does make it very very easy…

Here’s a bit of an overview of the features…

  • No need to worry about pixels - everything is measured in ‘units’.

  • Game area is a rectangle of an arbitrary size you specify (e.g. 8x6). The axes have floating point accuracy.

  • All GameElements (component based) have a size and position in this game area (measured in floating point game units).

  • Display and game areas are independant; you can set a display window to show a portion of the game area or the whole thing, and again is measured in units.

  • The aspect ratio of the display area is fixed, and fitted into the actual component face. When this fitting takes place, the unit size (in pixels) is calculated for you, allowing it to convert your game-based coordinates to on-screen positions. The game is therefore automatically scalable.

  • GameElements are based on Component, and can have their positions in the game area set (by corner or centre) using unit-based coordinates.

  • GameElements can be told to move by a particular amount, translating their position in the game area (again, using units). They can also be instructed to ‘startMoving(direction,speed)’ - the speed is measured in game units per second, and this movement will continue automatically until you tell it to stop.

  • Mouse movements on the display are converted into coordinates in the game area, and a special gameMousePositionChanged(float x, float y) callback can be used to do stuff.

  • A ‘SpaceAndTime’ class handles timing and dimensions - the game unit is stored there, and it is used to determine the ‘timeResolution’ of the game (basically the loop cycle duration).

You subclass GameComponent, subclass GameElement to create your elements. Add the elements to the game (using addGameElement()) and define the gameLoop function (return true at the end of the cycle, return false if it’s time to end the loop e.g. game over). All element positioning (to the screen) is handled automatically, so you can just think about basic units.

I’ll put the framework up later today, along with an example. I’m sure someone will be curious about it all! Making rubbish games is a lot of fun.

yet more work done on it (and yet more still to come), including adding sound. it’s actually the first time i’ve ever tried using audio in juce (i know!) so i’ve yet to learn how to make stuff like that efficient (especially in an inefficient system like this!)

to use sound files in a game, you simply make a GameAudio object for the sound file you want to play (and call setFile(…) on it). Then at any time in the game, you can call playSound(&GameAudio). Easy.

Anyway, the code’s at home, but there’s an updated demonstration including sound below. [the slider on this one demonstrates that the view can be set independantly of the game - it just zooms in and out. not particularly good for a dynamic zoom, of course [recalculations aplenty when the unit size changes] but hey. so what. :slight_smile:

http://www.haydxn.net/content/code/gameEngine/Squares2.zip

This one also was a little experiment into using more greedy paint routines and transforms etc… to see how they impacted the performance. [i’ve got the priority set a bit too high in this particular build tho!]

i wonder if anyone cares! :smiley: it’s quite fun. /me ponders just how far he’ll take it before he goes mad

Good job! I’ve wanted to create something similar to Gamemaker (http://www.gamemaker.nl) for a while now, but I need to get a better grasp of c++ and Juce first. I personally think that Juce is an awesome library for creating window-based games. That’s one of the main things I’d like to use it for. Your game seems to be along the line of some of the game ideas I have in mind. You seem to be ripping thoughts right out of my head, as I was planning on doing a quiz/test program also.

I personally think that once more developers get a hold of Juce, more genres of software will be developed using it, games being one of those genres. You’re given that Juce genre a good start here.

Regarding this app, are the hitTests pixel perfect? I mean, are there pixel perfect collision tests being made? It was difficult for me to tell through the game.

not really, i was cheating a bit. the first test version was just squares, so i was testing to see if their rectangles intersected at all [that is their rectangles in the game world, not on the screen]. the second one, because the shapes have changed a little, i thought i’d do something else… but rather than do pixel based testing, i’m doing intersections again, but this time not registering a collision until they’re intersecting by a particular minimum amount.

What a cute little game! Very good!

I’ve always meant to write a “Mornington Crescent” game where you can play against an AI opponent (the game as featured on “I’m Sorry I haven’t a Clue”, which is something only british Radio 4 listeners will be aware of…)

well the game is a total rip-off of a game i played online the other day, so i can take no credit for the idea. i do plan to give it the same features though (it has power ups and stuff, and gets harder as you keep playing), and other stuff (such as a high score table). of course i’ll be giving total credit for the game concept to the original author (Gavin Shapiro)

[play the original game here - although you may not stop playing for a long time]

the game engine’s coming along nicely though :slight_smile: although i think audio may push it a little far… when it’s in full screen mode the audio can suffer a fair few pops and farts. is there any way i can give the audio playback a higher priority than the game thread? i’m sure the whole game system is tremendously inefficient :hihi:

The audio thread always has a higher priority, though you might need to boost the priority of your whole app with Process::setPriority. Don’t set it to real-time, that’s probably a bit much, but “high” is what tracktion uses.

Yeah, i’ve had it set to high priority for the second test build of the game (the one with the bubbles instead of squares), and it seems to help. although going maximised makes it occasionally glitch with the sound, and changing the screen size causes massive windows background redraw delays :hihi:. i guess i could have it momentarily reduce the priority if the app window is resized [after all, the user should expect the game to suffer if they do something silly like resize the window, but they may prefer not to feel like the OS is dying in the process], although i don’t know how ‘instantaneous’ the priority setting is.

It doesn’t glitch on my PC - maybe it’s just your latency settings that aren’t working too well on your machine?

Are the bubbles being cached in images, or drawn as paths each time they move?

currently the GameElements default to having setBufferedToImage(true), so i think they should be buffered internally. The star element isn’t though, as it’s rotating constantly, so it has a timer applying a rotation transform and triggering a repaint.

i’ve not taken any care in configuring my machine for any kind of audio work (setting random values if i remember rightly) since the last reformat [and it’s quite old now anyway!] so you’re probably right.

This is the kind of thing where an opengl rendering context would make a huge difference. The jerkiness in full-screen mode must just be the amount of memory that’s getting shoved around, and the cpu having to do all that compositing.

One possible speed-up might be to also cache the score display - fonts over a certain size get rendered as paths rather than cached in bitmaps, to save memory.

yeah, i’ve always assumed that it would be most efficient using an openGL context. but truth be told i haven’t got a bloody clue how i’d go about doing that!

me neither!

i’d quite like to keep the juce components for the elements, as juce people know how to use them and the Graphics drawing functions. [this is mainly just to give people who know juce a way of making fun simple little games using what they already know]

Is it possible to simply get the Image from the elements and draw them onto the openGLComponent where they should be instead of actually getting the component to draw it automatically? my question isn’t just ‘is it possible’, it’s also ‘is it reasonably straightforward?’ and ‘would it give any benefit?’

do i need to download an OpenGL SDK too?

sure it is possible. and you would gain terrible speedups in doing this since compositing is done directly by the graphics card, if it support the compositing extension and image to texture conversion (with size not fixed to power of two). i’ve been playing a bit with compiz and its plugins on linux and the windows (not that win$) on screen are converted into textures before being composed into the screen… very fast and stunning… i think the approach for a 2D game is the same.
sure is not an easy task, but you can take a look how Amanith framework is implemented, it provides high level graphics objects (path, images, gradients, patterns, animations, vertex…) that are translated into opengl calls. the same as cairo with glitz backend: you have your high level graphics api, that is translated to call openGL directly underneath… here the graphics development is moving along: we all have video cards that have extremely fast processors and memory, 90% of their surfaces is designed to support 3D. why not use 3D even for the 2D ?

sounds like a good idea. i’ll probably implement it once i’ve got the bulk of the features of the game engine done.

right now, the game’s main screen painting is being handled by simply positioning the GameElements (Components) on the main GameComponent, and letting it draw them itself. It should be reasonably straightforward (ignoring for now the actual work involved in doing openGL stuff! :hihi:) to change it to allow an OpenGL drawing system, keeping the rest of the system intact. The only thing that would lose is the option of having the ‘Component’ nature of the elements to work (i mainly mean mouse messages, e.g. if, for some reason, you wanted to have a Juce button as an element, with its normal button behaviour) but seeing as mouse messages are already translated into ‘game world’ coordinates, that can probably be worked out behind the scenes anyway.

it’s definitely something i’m going to attempt at some stage.

Here’s the source for the latest update of the engine…
GameEngine v0.6

This includes the source for the current version of the squares/bubbles game, and demonstrates the ridiculously-simple-to-use audio feature.

There’s a little bit in there that’s a bit naughty, but it makes testing a bit easier - if you include the WindowsXPSounds header, you can access the sounds included with a Windows XP installation directly… that’s what i did with the squares game. Yes, it’s silly because they may not be there (or in the usual place), but it doesn’t really matter because nothing untoward happens if the file isn’t found.

e.g.

XPSounds::getSound(XPSounds::exlamation);

will return a File pointing to that XP sound file (or a nonexistent if it doesn’t exist, naturally).

so, in the SquaresGame, you can see that there are two member GameAudio objects - collectSound and failSound. They are prepared using…

collectSound.setFile (XPSounds::getSound(XPSounds::balloon));
failSound.setFile (XPSounds::getSound(XPSounds::batteryCritical));

and then in the game loop, where needed, they are played using…

playSound (collectSound);

Simple, eh?

It just means you can test having basic sounds that most people will have, to spice it up a little bit without having to package your own samples. Of course I wouldn’t expect anyone to actually use them for a real game! :hihi: … or even make a real game… crumbs! Of course you can indeed point to any file you like. I’ll probably add a ‘setAudioFolder’ function so you can set a place to keep audio files, making finding them a bit easier.

i think the better and straightforward solution is to implement a juce_LowLevelOpenGLRenderer. then with some more tweaks to the opengl component (thus becaming a sort of OpenGLComponentPeer) to let it understood more messages sent to that window, you can probably use transparently a lot of your juce graphics functions. but since gradients, and some other objects don’t have a lowlevel interface, for implementing the whole juce graphics classes to work in opengl you should type a LLLot…
anyway keep up your good work with the engine. could be useful and funny… if it comes to a good point i can embed it into ejuce…

crumbs! i’ve just spent the whole night trying to implement as flexible a high-score-table system as i can, and you’d be surprised just how complex it has been!

i want to have a system that can be handled automatically in the game - i.e. your actual game code should only really require you to indicate that you want a high score table, and to put your game-specific score data into an entry [to be applied to the table automatically]. Thankfully, the squares game i’m making threw up the issue: what if there is more than one type of score? It’s not enough to simply sort by a different type of data (and even that is pretty tricky in a general polymorphic system)… it has taken a lot of work and cunning use of templates, but now i think i have a solution. There’s a basic implementation for simple ‘one relevant score’ tables [i guess a bit like the way there is a SimpleListBox setup for ListBox], but it’s also possible to use the same system to create multiple HighScoreTables for a single class of HighScore data [e.g. a game where you end up with a survival time, a number of points and a number of kills- where any one of those scores could be deemed most relevant to any player]

Sorry that was a pointless rant… i guess i’m sort of using this thread as a blog for the engine. Hopefully i’ll have it working tomorrow to post a new update.