GP2X Pssst!


We should spend a bit of time thinking through how all the objects in this game interact and produce a really detailed plan of of what we are going to do. Having played the game, hopefully there is a fuzzy outline in your mind of all the interactions and how the game works. What we need to do is get a writing implement and some paper and clearly establish how things are going to pan out.

Unfortunately the only paper I have is too absorbant for writing on. I have lost all my crayons. My felt tips, like my brain, dried out years ago. So we will just have to go with the fuzzy outline and see how it goes.

No doubt we will all have different degrees of fuzziness in our outlines. Mine goes along the lines of : Stuff collides with other stuff and stuff happens.

If I put my fingers in my ears, squeeze my eyes shut really hard, hold my breath and grimace like a baboon I get a vague inkling that the game revolves around the state of the plant.

As I see it, we need to describe the objects, check if they have hit each other and then do stuff depending on what hit what. Sounds like a plan to me.
 
There are certain common elements that just about all the stuff we want to put on the screen share. Things like a position and a graphic, etc. It seems sensible therefore to have a common layout for all objects so that when we want to check if one object has hit something we can just loop through a list checking it against the position and size of all the other objects. The alternative would mean having to write special checks for each object. It will simplify the whole process and save lots of typing.

So we design a store that will hold all the elements that any of the game items need. Robbie does not have a left and a right graphic but the bugs do, so the store must allow for this. Robbie just will not make use of this storage. Essentially we are simplifying the handling at the expense of a little redundant storage in the odd place.

All objects need a location and size. Most objects have a graphic representation. Most objects are animated - this requires a way of knowing how many frames there are and which frame is the current one. Each object will need a type identifier - if looping through a list of objects, we can check what type each is and carry out an appropriate function. For example if the object is Robbie we need to check the controls, if it is a worm it needs to behave one way and if it is wasp it needs to behave in another and so on. A bug needs to know which direction it is travelling in from one moment to the next.etc. etc.

It is starting to be a bit overwhelming, but If we can knock together an initial storage space design we can always add any features we overlooked at this stage later, when we find we need them. A real programmer would have considered all this before writing a single line of code and have an exact understanding of how it was all going to work. But where is the sense of adventure in that ?

Next : We need a way of creating and accessing these stores that will describe our objects.
 
So far Robbie consists of two rectangles and a graphic. It just does not seem enough, does it ? He needs a little piece of memory to call his own. A place he can hang out in and where we can easily find him.

Such a piece of memory would tell us where his graphic image is stored, his current screen position, his size and other vital information.

But how are we going to know a: where it is and b: what bit of it tells us his position or what bit is his size ?

This is where the mighty structure comes in. Using structures we can grab a chunk of memory and give it a name. We can also divide that memory into as many items as we need and define their types, each with their own name. Once we have a structure it can be declared like any other type.

A simple structure to define a rectangle could be defined thus :
CODE
struct rect {
int iX_pos; // the current x co-ordinate
int iY_pos; // the current y co-ordinate
int iWidth; // the width of our rectangle
int iHeight; // the height of our rectangle
};

And used to define two rectangles like this :

CODE
struct rect YourRect = {
20, // the current x co-ordinate
30, // the current y co-ordinate
32, // the width of our rectangle
32, // the height of our rectangle
};

struct rect MyRect = {
36, // the current x co-ordinate
46, // the current y co-ordinate
32, // the width of our rectangle
32, // the height of our rectangle
};

To look at MyRect's x co-ordinate we can access it as MyRect.iX_pos.
To look at YourRect's y co-ordinate we can access it as YourRect.iY_pos.

SDL has already declared a structure to define a rectangle and called it SDL_Rect. As you know, because you are paying attention, we used it earlier to address Robbie's graphic and to define his position in relation to the screen.

Our sprite structure can have within it other structures. So we can use SDL's rectangle structure in our structure to store Robbie's graphic co-ordinates and his screen destination co-ordinates.

So just as you can reserve space with int iJoy, if you have a structure called sprite, you can declare struct sprite Robbie. Robbie will then have all the attributes of the sprite structure. If it is set up appropriately we will be able to use the sprite structure to define spray-cans, wasps, worms and the other junk that makes up this game.

Now we just have to consider what we will be needing to create our own struct, and use it to describe control blocks for the game objects.
 
Here is a rough outline of how I see this program working :
  • We predefine the game objects - there are not that many and most are always in use, so no faffing about creating stuff on the fly.
  • Make a list of the game objects which we can use to access the objects with a simple loop.
  • Write a simple loop that runs through the list and calls a control function depending on what type the game object is.
  • Throw in another simple loop which runs through the list and slaps the graphics on to the screen.
  • Add the control functions for each the object types at our leisure.
This way we can start with a list just containing Robbie. Once we have him whizzing about we can add a bug(creepy crawly) and get that functioning. Then maybe a spray can, and so on.

So then we will have a program structure we can build on without suffering brain melt down. We only have to grapple with little chunks of the game at a time, while knowing (hoping ?) it is all going to hold together in the end.

I have added a file called objects.h to the project. This contains the proprosed structure for the game objects. I have called it 'object' and hopefully the comments will give you all the information you need to know. I have also created some of the values the objects will use, using good old enum so I don't have to type lots of tedious numbers.
CODE
#include "SDL\SDL.h"

// This holds information to describe and control our objects
struct object {
int iType; // object type identifier
int iSubType; // object subtype identifier
bool bDraw; // only put this on the screen when this true
int iPhase; // the current phase - init, dieing etc.....
int iFacing; // currently facing - east/west
SDL_Rect C_Screen; // current screen position
SDL_Rect G_East; // graphic for east facing object
SDL_Rect G_West; // graphic for west facing object
SDL_Rect C_FrameG; // current animation frame graphic
int iAnimCount; // current animation count
int iAnimFrames; // number of animation frames
int iAnimOffset; // animation offset into graphic
struct object *oEmbed; // if another object is embedded - this points to it
struct object *oAbove; // if another object is above - this points to it
struct object *oBelow; // if another object is below - this points to it
struct object *oRight; // if another object is right - this points to it
struct object *oLeft; // if another object is left - this points to it
};
// used to signal if an object facing east of west
// I envisage using this to determine which side of Robbie his spray can should appear
enum directions {
WEST,
EAST,
};
// object ids so we know what the object is
enum types {
ROBBIE,
STEM,
LEAF,
BUD,
BLOSSOM,
SPRAY,
WORM,
SPIDER,
WASP,
SPRAY_CAN,
BONUS
};
// secondry ids - if the object is a leaf we can generally ignore it but the
// leaf itself will want to know which one it is so it knows where to grow
// The bonus is just a bonus but the bonus itself will want know if it is pretending
// to be an oil can, a ruby or a coin.
// Worms, spiders and wasps are a bad thing. They kill us and in that respect
// are all the same. If we check the subtype and it is a bug we know to die without
// tediously checking for each type - is it a worm ? is it a wasp ? etc....
enum subtypes {
SINE,
CLOUD,
DROPLET,
RED,
WHITE,
BLUE,
RUBY,
COIN,
OIL,
LEAF1,
LEAF2,
LEAF3,
LEAF4,
LEAF5,
BUG
};
// The following are possible states the items will be in at different times
// An object will use a state to behave in a particular way until something happens
// to change its state. It will then behave in the required manner for the new state
// until conditions require it to change state again
enum phases {
INIT,
INACTIVE,
WAIT,
PICKED,
CARRIED,
GO_EAST,
GO_WEST,
GO_UP_EAST,
GO_UP_WEST,
GO_DOWN_EAST,
GO_DOWN_WEST,
GO_TO_PLANT,
GO_TO_ROBBIE,
MOVE,
FIRE,
FROZEN,
EXPIRE,
};

You may have noticed that some of the members in the object structure are themselves struct objects. You may be thinking that when we use it to declare an object we will end up creating an infinite progression of structures of the type 'object'. In fact, what we have here, are pointers to structures of this type, not the actual structures themselves.

A pointer is just the stored memory address of something we want to know the address of. What we are doing is saying we will want to store the addresses of other items that are of the data type 'struct object' in these stores. The asterisk (*) before the name defines it as a pointer to a data type and not an actual data type. Pointers have been known to confuse people (me especially). I have known programmers who avoid using them altogether, but in fact they are pretty handy.

You can fiddle with an object through a pointer to it. Instead of directly addressing a stucture's member as 'struct.member', using a pointer we address it as pointer_to_structure->member. So the '.' becomes'->'. If we were to manipulate the pointer as if it were the actual structure it would be like talking to a 'phone number instead of the person who's number it is.

Confused yet ? You will be. Tune in next time when you can copy and paste more stuff into code::blocks and discover new ways to make real programmers shake their heads and make tutting sounds.
 
All this has been mind numbingly tedious, but there has to be some kind of foundation on which to build. Soon the thrill of seeing something happen on the screen will be ours. But first the foundations must be put in place.

The game objects will be defined in a new file called objects.cpp. For now it just has Robbie in it and a structure that will be used to list the game objects. This also only has Robbie in it, plus a NULL terminator so the loop knows when it has reached the end of the list :
CODE
#include "control.h"

//////////////////////////////////////////////
// describe the game objects //
//////////////////////////////////////////////
struct object Robbie = {
ROBBIE, // object type identifier
ROBBIE, // object subtype identifier
true, // only put this on the screen when this true
INIT, // the current phase - init, dieing etc.....
EAST, // currently facing - east/west
{150, 90, 20, 21}, // current screen position
{ 0,146, 20, 21}, // graphic for east facing object
{ 0,146, 20, 21}, // graphic for west facing object
{ 0,146, 20, 21}, // current animation frame graphic
0, // current animation count
1, // number of animation frames
20, // animation offset into graphic
NULL, // if another object is embedded - this points to it
NULL, // if another object is above - this points to it
NULL, // if another object is below - this points to it
NULL, // if another object is right - this points to it
NULL, // if another object is left - this points to it
};
//////////////////////////////////////////////
// declare the list of game objects //
//////////////////////////////////////////////
struct process_list game_objects[] = {
{&Robbie},
NULL
};

In a new file called control.cpp a simple loop runs through the list, checks what type each object is and calls an appropriate function. Again, we are only checking for Robbie so far. As we add new objects then we will expand this. There is also a function to build the display :
CODE
#include "control.h"
#include "buffers.h"
#include "objfunctions.h"

//////////////////////////////////////////////
// process list of game objects //
//////////////////////////////////////////////
void processObjects(struct process_list *objects) {
int iCount;

iCount = 0;
// the list is terminated by a NULL
while(objects[iCount].item != NULL) {
// call a control function depending on what type it is
switch(objects[iCount].item->iType) {
// call Robbies control function
case ROBBIE:
Robbie_control(objects[iCount].item);
break;
}
iCount++;
}
}

//////////////////////////////////////////////
// run through the list of game objects //
// and display the graphic for each //
//////////////////////////////////////////////
void drawObjects(struct process_list *objects) {
int iCount;
// this is the ZX Spectrum style display area
SDL_Rect dstrect = { 32, 24,256,192};

iCount = 0;
// copy the background to the ZX Spectrum style display area
SDL_BlitSurface(backdrop, NULL, screen, &dstrect );
// the list is terminated by a NULL
while(objects[iCount].item != NULL) {
// put the graphic on the screen
SDL_BlitSurface(images, &objects[iCount].item->C_FrameG, screen, &objects[iCount].item->C_Screen );
iCount++;
}
}

So the compiler can find the new functions we need a new file called control.h :
CODE
#include "object.h"

//////////////////////////////////////////////
// describe an entry in the list of objects //
//////////////////////////////////////////////
struct process_list {
struct object *item;
};
//////////////////////////
// function prototypes //
//////////////////////////
void processObjects(struct process_list *objects);
void drawObjects(struct process_list *objects);

//////////////////////////////////////////////////
// Tell the compiler about the list of objects //
// declared in objects.cpp //
//////////////////////////////////////////////////
extern struct process_list game_objects[];

And I have decided to have a header file that holds all the prototypes for the object's control functions called objfunctions.h :
CODE
//////////////////////////
// function prototypes //
//////////////////////////
int Robbie_control(struct object *);

Robbie gets his own file. As you can see, the code that was in the do....while loop in game.cpp has been just been moved here and adjusted to address his shiny new control structure :
CODE
#include <SDL\SDL.h>
#include "ioBasics.h"
#include "object.h"
#include "gp2x.h"

int Robbie_control(struct object *robbie) {
int iJoy;

iJoy = ReadInput(JOYSTICK, ANY_KEY);
switch(iJoy) {
case GP2X_BUTTON_UP:
robbie->C_Screen.y--;
break;
case GP2X_BUTTON_LEFT:
robbie->C_Screen.x--;
break;
case GP2X_BUTTON_DOWN:
robbie->C_Screen.y++;
break;
case GP2X_BUTTON_RIGHT:
robbie->C_Screen.x++;
break;
}
return iJoy;
}

In game.cpp we can change game_loop() to use the new functionality. The #include statements needed are also shown.
CODE
#include <SDL\SDL.h>
#include <SDL\SDL_rwops.h>
#include "control.h"
#include "game.h"
#include "buffers.h"
#include "ioBasics.h"
#include "gp2x.h"

int game_loop(void) {
int status = 0;

// initialise graphics
status = init_graphics();
// check everything OK
if(status != 0 ) {
// no graphics, no game - so exit
return status;
}
do {
// use the list 'game_objects' to update the status of the game elements
processObjects(game_objects);
// use the list 'game_objects' to update the screen
drawObjects(game_objects);

// make the screen visible
SDL_Flip(screen);
} while(ReadInput(KEYBOARD, ANY_KEY) != GP2X_BUTTON_SELECT);

return status;
}


If I have not forgotten to mention something, the code should build. Rather disappointingly, we still only have a big, Robbie shaped cursor that can not even remain within the playing area. But that's life. One crushing let down after another.
 
Now it is time to think about what Robbie actually does. To me it seems he is, in fact, just an oversized cursor/mouse pointer. Obviously his main purpose is to give the user something to move around the screen. His only characteristics are :
  • He moves in 8 directions.
  • He waits a strangely long time before appearing at the beginning of each level.
  • He vaporises if he touches a bug.
  • His movement is restricted by the playing area and also, rather irritatingly, the ledges that the cans sit on.
The first one is a problem. The input function, only allows four directions. Immediately the cost of poor planning starts to charge interest. So here is an updated ReadInput function that corrects this. Replace the existing one in ioBasics.cpp with this :
CODE
int ReadInput(int iDevice, int iKeyReq) {
SDL_Event event;
static int iKey = NO_INPUT;
static int iJoy = NO_INPUT;

SDL_JoystickUpdate();
while( SDL_PollEvent( &event ) ) {
switch( event.type ) {
case SDL_JOYBUTTONDOWN: // GP2X buttons
switch(event.jbutton.button) {
case GP2X_BUTTON_UP: case GP2X_BUTTON_LEFT:
case GP2X_BUTTON_DOWN: case GP2X_BUTTON_RIGHT:
case GP2X_BUTTON_UPLEFT: case GP2X_BUTTON_UPRIGHT:
case GP2X_BUTTON_DOWNLEFT: case GP2X_BUTTON_DOWNRIGHT:
iJoy = event.jbutton.button;
break;
default:
iKey = event.jbutton.button;
break;
}
break;
case SDL_JOYBUTTONUP: // GP2X buttons
switch(event.jbutton.button) {
case GP2X_BUTTON_UP: case GP2X_BUTTON_LEFT:
case GP2X_BUTTON_DOWN: case GP2X_BUTTON_RIGHT:
case GP2X_BUTTON_UPLEFT: case GP2X_BUTTON_UPRIGHT:
case GP2X_BUTTON_DOWNLEFT: case GP2X_BUTTON_DOWNRIGHT:
if(iJoy == event.jbutton.button) {
iJoy = NO_INPUT;
}
break;
default:
if(iKey == event.jbutton.button)
iKey = NO_INPUT;
break;
}
break;
case SDL_KEYDOWN: // PC buttons
switch(event.key.keysym.sym) {
case GP2X_BUTTON_UP: case GP2X_BUTTON_LEFT:
case GP2X_BUTTON_DOWN: case GP2X_BUTTON_RIGHT:
case GP2X_BUTTON_UPLEFT: case GP2X_BUTTON_UPRIGHT:
case GP2X_BUTTON_DOWNLEFT: case GP2X_BUTTON_DOWNRIGHT:
iJoy = event.key.keysym.sym;
break;
default:
iKey = event.key.keysym.sym;
break;
}
break;
case SDL_KEYUP:
switch(event.key.keysym.sym) {
case GP2X_BUTTON_UP: case GP2X_BUTTON_LEFT:
case GP2X_BUTTON_DOWN: case GP2X_BUTTON_RIGHT:
case GP2X_BUTTON_UPLEFT: case GP2X_BUTTON_UPRIGHT:
case GP2X_BUTTON_DOWNLEFT: case GP2X_BUTTON_DOWNRIGHT:
if(iJoy == event.key.keysym.sym) {
iJoy = NO_INPUT;
}
break;
default:
if(iKey == event.key.keysym.sym)
iKey = NO_INPUT;
break;
}
break;
default:
break;
}
}
switch(iDevice) {
case JOYSTICK:
switch(iKeyReq) {
case ANY_KEY:
return iJoy;
break;
default:
if(iKeyReq == iJoy) {
return iJoy;
} else {
return NO_INPUT;
}
break;
}
break;
case KEYBOARD:
switch(iKeyReq) {
case ANY_KEY:
return iKey;
break;
default:
if(iKeyReq == iKey) {
return iKey;
} else {
return NO_INPUT;
}
break;
}
break;
}
return iJoy;
}

The wait also hi-lights a shortcoming - the control block for the objects would benefit from a couple of extra stores for this sort of thing. Add these on the line after struct object *oLeft; to the struct object in object.h.
CODE
int iTimer1; // general purpose timer 1
int iTimer2; // general purpose timer 2
int iCount1; // general purpose Counter 1
int iCount2; // general purpose Counter 2


Add these on the line after the last NULL, to the object Robbie in objects.cpp.
CODE
0, // general purpose timer 1
0, // general purpose timer 2
0, // general purpose Counter 1
0, // general purpose Counter 2


The bugs and ledges require collision detection and mean we will have to write a function to check whether he has hit any of them. That sounds tricky so let's ignore that for as long as possible.

Instead, the plan is to get Robbie's control states implemented as far as possible, and see if this method of control will actually work. If it doesn't we will have to fall back on Plan B. Plan B is : Formulate a Plan B.

The control function for each type of object will be a switch statement that does something depending on the object's 'phase'. The ill-considered idea is that all objects start off in an INIT phase. So Robbie's INIT phase might set his position at the centre of the screen etc. and then set his phase to WAIT. Next few times through the control, the WAIT phase will check if the wait period is up. When he has waited long enough his graphic will be 'switched on' and his state will be set to MOVE. Then during the MOVE phase, if he collides with a bug, his phase will be set to DIE_HORRIBLY ( or whatever).
 
Last edited by a moderator:
The best part about making a game is working out how to implement stuff. Possibly the most challenging part of this game is how to make Robbie interact with the spray cans. The first thought I had was that when he picks up a can, a second graphic would be used - so the can would become part of him, he would become a larger object and his graphic would change. But I also considered keeping the objects separate and making them interact sensibly.

A big problem with the second method is when the carried can cannot move because of a ledge, how would the Robbie object know not to move ? It would constantly have to be checking to see if the can was blocked from moving as well as checking itself. If it were not for those pesky ledges it would be a breeze.

Using the second method would mean we don't need extra composite 'robbie + can' graphics, but at the cost of some ugly, cumbersome handling code. Compared to the ongoing cross-checking of object positions, changing a few of Robbie's attributes at the point of pickup looks a lot more appealing. I think it is the simpler solution and, for me, simple is good.

What do you think ? How would you do it ? Perhaps you would do it completely differently.
 
I like this thread, all the nuts and bolts laying around for everyone to see as you put everything together!

I'd put the can in Robbie's object just adding additional frames of animation and adding another state to the object. I'd do it that way for laziness as collision detection wouldn't have to change and you are going to have to keep track of the can in Robbie's struct anyway.
 
I would keep the can separate, but extend the collision detection code to include the can. This way you won't have to create lots more sprites. I thought of creating more sprites as mentioned earlier, but then you would have to do that for each coloured can. My method means you would only have to write one extra bit of collision detection regardless of what can you have.
 
Thank you for your thoughts, guys ! Luckily, you have each argued for opposing viewpoints so I am none the wiser :lol: . But as this thread is about introducing the joys of programming, it is serves to show that, at the design level, there is not a 'proper' way to do anything. It just goes to show that programming is not a mechanical process, but a creative art form requiring imagination and individual interpretation.

I still favor the option Vilmos prefers. I see it as involving less code which reduces the potential for bugs and means one less item to process. The cans will just be switches that change Robbie from one state, himself alone, to another, a fearsome warrior armed with a can of insecticide.

The extra graphics are a valid consideration. If this was a large mega game it could be critical in fitting the game into memory. It does not matter so much in this piddly little program. I think it is going to be overly complex for Robbie to have to track the can's collisions as well as his own. (In other words I am too dim to get my head around it).

What I want to try, is to have just one set of 'can carrying' graphics which will have spaces for the cans. At the moment of pick up the correct coloured can will be blitted into the spaces in the graphic data. This means only one set of graphics instead of three, but mostly it just appeals to me as an interesting thing to try.
 
I spent the last week mostly playing Knight Lore and GPrina. GP2X homebrew rocks.

Having eventually got them out of my system, there has been a small development in this, the second 'Jabber's How not to write a game' thread.

Having found it overly complicated to have Robbie and a spray-can interact in a meaningful way as two separate objects, they have been implemented as a single entity. The current state of play is as follows :

Some of Robbie's 'phases' have been implemented. He initialises himself, waits before appearing, collides with the ledges and stays within the playing area. He can also pick up, carry and put down spray-cans. The game now comprises Robbie and the three spray cans.

I have managed to get hours of satisfaction just picking up cans and moving them from ledge to ledge. Unfortunately most people will probably expect more, so there is quite a bit to do yet.

Apart from the small amount of code to make Robbie function, there have been a lot of odd changes in files all over the place. Since it would be tedious for me to type each one, and even more tedious for you to read, I have put the c::b project and files here for those who really want to see how not to write code.

With any luck the whole folder can just be unzipped somewhere and the project should build. I have included Rlyeh's gpe compression program (I hope that is O.K. to do that) and the project has a post build step that compresses the GP2X build.

In the PC build the 'joypad' is now mapped to the numeric keypad instead of the direction keys. This is to allow testing of the diagonals.

Coming next - Will it be the plant ? Will it be the bugs ? Maybe it will be a menu. I don't know how you guys contain your excitement.
 
Today's great leap forward is getting the spray-cans to emit wacky sprays when B is pressed.

Just to clarify what is going on :

We have a Robbie object, 3 spray can objects and now we also have 2 spray objects. When Robbie touches a can, the can is turned off and Robbie becomes a robot/can combo. He adopts the can's colour when he picks it up, and stores it as his subtype. When B is pressed Robbie gets a currently inactive spray object and sets its status to FIRE.

The spray, depending on Robbie's colour subtype, sets the correct graphic. i.e. If Robbie's subtype is yellow, the spray sets its own graphic to the purple droplet. It also adopts its direction from Robbie. After initialising itself the spray object sets its status to MOVE and travels in the direction it was fired until it hits the edge or a ledge. It then turns itself off and waits to be activated again.

All this involves objects peeking at and fiddling with the private parts of other objects. This, apparantly is really bad form and will have real programmers weeping into their coffee.

Now we just need something to poison with insecticide. In the meantime the latest project is here.
 
Last edited by a moderator:
06c49b68ef70e90d5092e2a4a1a8496b4g.jpg


The only important part of the plant is the stem. This controls the level. It's whole function is to grow to its full size and signal the level is completed. The bud is just a decoration, as are the leaves and the blossom. It is the stem that is trying to reach its target and any bugs that attach themselves to the plant, attach to the stem. One bug will counteract the stems attempts to grow. More will cause it to shrink. The more bugs the more alarming the shrinkage.

The program now has two more objects - the stem and the bud. At present when the stem reaches it's full extent everything gets reset and it all starts over. Later, it will need to trigger the blossom and it will be after the plant has flowered that the level will restart.

But the next thing to do is add a bug or two.

These will have to follow a certain movement pattern, depending on type, and detect the plant so they can sit and eat it. Coming soon....etc.

Download the current project by clicking the big red word -> WORD
 
Last edited by a moderator:
I can't wait to play this :) Good work!

Also, my compliments on the graphics. Just one suggestion, how about adding a decorative border instead of the black space?
 
Alex. said:
I can't wait to play this :) Good work!

Also, my compliments on the graphics. Just one suggestion, how about adding a decorative border instead of the black space?
Thanks, Alex ! I had not thought about decorating the Spectrum border. It is something to consider. Perhaps it could display the blue and yellow loading stripes. Great for epileptics ! I might just leave it as an exercise for those who want it to add it themselves. I am so lazy.
 
Last edited by a moderator:
1c41c2da31ced5777bd9c7c947cdbe7f4g.jpg

Finally the moment I have been waiting for is here. I get to KILL things.

There are now six bug objects. Rather than having six of each type of bug I have opted for a tangled web of spaghetti code that has just six objects of type BUG. When a bug starts, it selects what type it is going to be, setting its sub-type to WORM, SPIDER, or WASP. So far just the worms are handled.

The spray object has been expanded to detect bugs and tells any bug it hits to die. This way a spray only kills one bug. If the bugs were to check for sprays, several bugs could all die at once from one spray.

Also the bugs will 'eat' away at the height of the stem if they collide with it.

Only the blue can kills worms, the red can freezes them and the yellow can has no effect on them.

It is starting to look like a game.

Still to do :
  • add the wasps and spiders.
  • some sort of storage for the current level, number of lives and current score etc.
  • Most important - screen you can choose to quit the game from.
  • some sort of text handling for scores, messages and the menu.
  • sound
  • lunch
... more stuff I probably have not even thought of...
 
Last edited by a moderator:
Thanks for taking all the time to post your development here.. It gives me ideas for my own code and is a good refresher for someone coming back into coding after a long break.
 
I am glad it is of use to someone. The GP2X currently seems to be dieing rapidly. I hoped this would renew some interest in it and maybe even persuade a ROMZ whore or two to give devving a bash. But I guess the smell of a new machine has them all to busy downloading more WAREZ. ;)

81a37944a6ec10bee48526b1eb9737522g.jpg


The bees and spiders are now implemented. I also jiggled with picking up and placing the spray-cans. You can now place a can and not be lodged between the ledges, so you no longer have to 'back out' of an alcove after putting a can on it.

The progression from one level to another is implemeted. I have changed the order so that worms and bees come before spiders and bees, since I think the latter is harder.

In my previous estimate of things yet to be done, I totally forgot the bonuses and the frippery i.e. the leaves and the blooming of the plant. Once they are out of the way the most important part, having :
'Mr.Jabberwocky wrote this'
plastered across the screen, can be approached.
 
Last edited by a moderator:
QUOTE
Once they are out of the way the most important part, having :
'Mr.Jabberwocky wrote this'

plastered across the screen, can be approached.


Oddly enough, I've been eagerly reading/downloading and printing off this thread ready to alter the source so it reads 'TheMinder wrote this' at the end !
 
recently i have been superficially following thread and not yet had time to implement and test your recent code.

but i know it is here for me to look at when i have more time.

thanks!
 
Back
Top