No sooner had I thought I'd put the rock code 'to bed' for now, I noticed something slightly out of place.
I was running a quick test of the map code (to start on craters) and noticed a graphics glitch - I'd forgot to replace the error check at the end and it was seeing the new map-code as another rock.
Also, there were only 3 rocks on screen at once... not 4 as there should be. I'd realized with some playing that it would be WAY too difficult to shoot down 4 anyways - so hadn't given it much thought past that... nope something was amiss.
Part of me by this stage is saying 'well - it works with 3... that's good enough.. just don't put 4 in the map close together! - problem solved!'.. But I knew that 1) this would sit in the back of my head and annoy me - and 2) EVA isn't so much about 'getting a game done' - it's about solving a specific set of problems with robust and modular code I can use in future project.
If I was trying to just get it working and that was that I would just set them up 'manually' and blit them - done.... instead I've borrowed concepts I've learned in my time away from the Amiga and assembly programming in C and other languages.
Each graphic in EVA has it's info placed in a memory structure (just like a C struct - see below about RS directive and addressing modes) - every graphic, be it a block, a bullet, the buggy - all contains info about how it's to be drawn, it's size, etc. Each structure has the ability to be expanded with specific info to further define it if needed - while retaining all the original info shared by all graphic objects (an oversimplified version of inheritance you find in C++ and other languages).
Further - all are grouped into linked lists. Each graphic element contains a pointer to the next element in it's series. Somewhere this wasn't working as it should.
It brings up the question that I was asked a lot back when all my friends were making demos, 'why? why not just blit it and be done?'
Well, it makes several things possible - automation being one of them, I can feed the address of say, the top level bullet into my draw routine and have it animate and draw ALL them - by simply passing ONE address.
Clarity in code - each routine does one thing, and does it well (or as good as I can make it), and each routine is named for what it does - concepts I learned from UNIX. As you work up from the machine level basics, the code becomes easier to read - 'fetch_next' 'draw_object' 'update_rocks' - each of these routines contains others that break it further, until you hit the bottom line at the machine level - where it's 90% moving to registers and other things. Things learned from programming MOO's and other online games.
Scalability. As it stood a week ago in the 'get it working' stage - to add just a single rock element required changes to 7 different bits of code..... setup, initializing, drawing, clearing, updating,collision detection, and of course allocating memory. Now it only needs one - setup.
Setup creates X amount of objects of that type and links them - every other routine automatically runs down the list - updating what needs updating, drawing what needs drawing, doing collision checks where needed.
And of course - portability. All the graphics routines could be lifted in a single file and used in the next game, and all I'd need do is draw new graphics and fill in the setup data. All basic animation, drawing, moving, etc.
Eventually I found my bug - and fixed it - a mistake in when I was checking for the end of the list... I guess another bonus in taking the long road was that the error itself told me where to look, and although it took me some time to work out what I'd done wrong - it was all fixed by changing just 3 lines of code.
Guess there's some benefit to taking the road less travelled. One of them being that I shouldn't have to travel down it again for some time.
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment