Picaxe Game System

knight

Member
Merry Christmas everyone.

In the spirit of giving and Christmas I'd like to share a project i've been working on recently with the community.

I'm referring to the project as a Picaxe Game System. In short terms think of it like a gameboy or similar.

The system consists of
-A 4D systems uLCD for display (serial version)
-6 Buttons (Up, Down, Left, Right, Start, Select)
-A 5v regulator.
The game consists of
-A 28x2 containing the current game
-A 24LC256 providing the memory for the game.

As you can see the system itself contains no brains, i did contemplate including brains, but decided that would simply slow the system down and add unnecessary overheads.

Anyway, the game:
The first game I have implemented is a recreation of the old Lunar Lander game, 2D landscape, have to land the LEM on a specific spot, not too fast or you crash, you know the sort of thing.

The landscape is stored in the attached EEPROM. It is known that the display is 320 px wide, well in the eeprom positions 0-320 each have a height value stored in them. This height value is then read by the 28X2 one at a time, and then used to turn on one px at a given height. Once all 320 px are on the terrain is generated. The landing pad is stored after the terrain height values by storing the starting X position and the width of the pad.

The lander's speed is stored as a word with values over 32768 being speed upwards (that is rising) and values below 32768 being speed downwards or falling.

The lander's change is speed if the engine is not on is just speed = speed - gravity, if the main engine is on then it becomes speed = (speed - gravity) + engine Power.
This is done to allow different levels simply by varying the gravity and engine power ratio. It also allows inertia by taking several updates to return to a positive speed after an extended fall.

Variable acceleration is nessescary to give the appearance of gradually speeding up, as would happen in the real world. This is achieved through a loop that controls the frequency of updates in position depending on the lander's speed.

Finally collision detection is achieved by storing the height of the 15 pieces of terrain under the lander in 15 variables (lemLand0...) If the yPosition of the lander is greater than any of these variables a crash is detected (greater as 0,0 is the top left corner of the display)

Once a collision is detected checks are conducted to determine if the landing was in the correct position and below a certain speed a safe landing and congratulations is displayed.
Otherwise a crash has occured and the screen is turned red to simulate this.

Anyway after that long explanation here is some code, and some pictures. I intend to make some other games and will let you all know how those progress. In the mean time, any questions would be warmly welcomed.

Regards and Merry Christmas
Knight.
 

Attachments

westaust55

Moderator
Well done knight

I may not get around to downloading or trying out today myself
between other activities but a great Christmas gift to the PICAXE community

Have a great Christmas
 

westaust55

Moderator
@knight,

downloaded and had a first look at you program.
Have sent you a PM with some code thoughts if you are interested.
 

westaust55

Moderator
Following some discussions with knight, the decision is to post some recommendations here on the forum for all to be able to take advantage of in their programming. The primary aims here are to achieve improved speed and reduce code size and hopefully maintain readability

So here goes:
1. By using the MIN and MAX functions in the level selection routine there is no need to chick the values and further adjust in the movebutton routine which becomes
Code:
moveButton:
'Don't let someone choose a value that isn't a menu choice

[COLOR="Blue"]; following lines are superceded by use on MIN and MAX functions in the ChooseLevel routine
;	if levelChoice = 0 then
;		levelChoice = 4
;	elseif levelChoice = 5 then
;		levelChoice = 1
;	endif[/COLOR]
and
Code:
:chooseLevel:
	if pinB.7 = 1 then
		dec levelChoice
		levelChoice = levelChoice MAX 4 
		goto moveButton
	elseif pinB.6 = 1 then
		inc levelChoice
		levelChoice = levelChoice MIN 1
		goto moveButton
	elseif pinB.2 = 1 then 
		if levelChoice = 1 or levelChoice = 2 or levelChoice = 3 then setLevelValues ; level choice 4 (instructions) be be implemented later
	endif
	goto chooseLevel

2. Alter the LoadLanderValues routine near the bottom, use of a single hi2cin command and remove the many hi2cin commands and incrementing the EEPROM address. This will reduce program size and potentially increase speed.
Code:
'This loads the values of the height of the land below the LEM from the eeprom to easily accessible variables

loadLandValues:
eepromAddr = xPos
hi2cin eepromAddr, (lemLand0,lemLand1,lemLand2,lemLand3,lemLand4,lemL and5,lemLand6,lemLand7,lemLand8,lemLand9,lemLand10 ,lemLand11,lemLand12,lemLand13,lemLand14)
3. Change the program structure in the move: routine for the lines:
Code:
	if leftThrusterStatus = 1 or rightThrusterStatus = 1 then
		gosub loadLandValues
	endif
	return
we can use
Code:
	if leftThrusterStatus = 1 or rightThrusterStatus = 1 [COLOR="Red"]goto[/COLOR] loadLandValues
	return [COLOR="SeaGreen"]; default return to calling point if side thrusters are not in use[/COLOR]
Because the LoadLandValues: routine has a return on the end, rather than save return address to stack to go to that routine and then have two returns in sequence, we can rely upon the return at the end of the LoadLandValues: routine to return program control back to the calling point for the routine move:
 

knight

Member
Well this last week has seen the project evolve significantly. If you have a look at the photo you will see that instead of a collection of wires the project looks significantly more like a game system.

To put the system in a case necessitated rebuilding both circuit boards, to fit the limited space constraints and redoing most of the cabling to make it longer.

The 'inside' of the project has had significant work done too with several features being added to the code.

First and most importantly. The game no longer relies on using a separate EEPROM for each terrain. Originally that wasn't written in as a space constraint but made the initial coding easier. Now every access of the eeprom is done using the expected address + a level offset. The level offset system allows approximately 100 separate levels per eeprom.

Secondly the game has been made slightly harder through the addition of fuel. If you run out of fuel naturally your motor turns off and you will probably crash. The current fuel level is indicated on the lower right hand of the display as 4 green dots 100%, 75%, 50% 25% with each dot dissapearing as you reach the next fuel level. When your fuel gets below 25% the last remaining dot goes yellow. When your fuel gets critical the last dot goes red before finally turning off at 0%

Finally the lower left of the display there is a speed indicator, green if safe, red if unsafe.

So there you have it, the (nearly) finished product. (Still havn't written the instructions)

As always comments and critisim is welcomed. (Be warned, the fuel display code is not particularly clean)
 

Attachments

womai

Senior Member
Nice project, nicely done! I have been considering a Picaxe based game system for a while, a bit more elaborate since I'd like to add a PIC providing sprite routines, driving the display, producing sound etc, controlled by a user-programmable Picaxe 28X2, but haven't found the time to even start - so great to see you have something up and running. Lunar lander used to be one of my early favorites on my old Commodore C64 (and I even wrote one similar program on a TI-66 programmable calculator around ~1983 - of course that one did not have any graphics!).

One suggestion - you could add a Picaxe 08M as a slave, connected to a Piezo speaker - that way you could add sounds! (white noise when the rocket fires, crash = loud white noise when the ship crashes, a melody when landing succeeds, beeps when fuel gets low, and so on. The 28X2 could send simple commands to the 08M - easiest would be to have two lines, one triggering an interrupt on the 08M that makes it wait for a serial receive in the interrupt routine, and a second line which sends the actual data.

Wolfgang
 

westaust55

Moderator
4D systems themselves have recently (or maybe still about to) release their PoGa (Portable Game) console which is based on little more than a 128 x 128 OLED using the 4DGL programming system as opposed to the serial OS we PICAXE users normally use.

The 4DGL system from a read of the OS manual can accept analogue inputs and create sounds etc.

I have wondered if it would be possible to (easily) program some such data in the 4DGL system but still impliment a serial or other comms line to a PICAXE for other/additional user input.
 

graynomad

Senior Member
I have wondered if it would be possible to (easily) program some such data in the 4DGL system but still impliment a serial or other comms line to a PICAXE for other/additional user input.
4DGL is a full on language with support for SPI/USART/I2C comms so I'd say that would be easy to do.
 
Top