News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

My 2D platformer in BASIC

Started by IndyUK, 22:38, 12 February 22

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

IndyUK

 Hi folks

Just wanted to share something with you all that I've been working on which I'm quite proud of. I know it's not much to look at but being a 100% BASIC program I'm quite chuffed about it. I set myself this challenge after I watched a few videos of C64 games written in BASIC using UDG and thought, I might try something like that on the CPC. The first thing that came to mind was maybe an Invaders clone as that's always a favourite amongst hobbyist but, then I thought, nah, let's do something a bit more challenging and, that's when I came up with the idea of doing a 2D platform game. I'm sure you can all see where the inspiration came from  :D .

It's a bit rough around the edges and not perfect by any means and there's no sound but it does work quite well. It was quite an experience starting from scratch and having to work out how to piece this altogether and challenging at the same time to maintain a decent frame rate. All in all I think it came out quite decent. Due to speed limitations of BASIC I wasn't able to have moving platforms or enemy but, I did get these to work on a different test build, so who knows, if I get the motivation to convert into assembly I may add those features.

As you can see there are no actual sprites, just UDGs. Collision detection is done using the good old bounding rectangle method and works quite well. I use the TEST(x,y) command to test for the player's interaction with the ground. Again not perfect but works well enough for BASIC. The levels are built using simple DATA statements for each character line and, using ASCII characters for the graphics. I've only put a single level together for demo purposes but, the way the level reader is designed, adding a block of 13 data statement lines you can come up with new levels. One thing I was always mindful of was that I would try and keep all the maths simple (pre-calculated if needed, keeping multiplication and division to a complete minimum) so BASIC didn't struggle. This would also be quite useful if I was to ever decide to make an assembly version as we all know how that can drag down performance. Apart from the CPC specific TEST command which I've used, I think this could quite easily be ported to other 8 Bit BASICs as it uses typical commands.

Anyhow, I think I managed to achieve what I set out to with quite a surprising result. Sorry I can't upload a video. The forum only allows MPG and that looks terrible quality.

Thanks

ervin

This looks very cool.
I would love to have a look at the code.
:)

IndyUK

Quote from: ervin on 07:57, 13 February 22
This looks very cool.
I would love to have a look at the code.
:)

Let me tidy up the code a bit and then I'll post it as a TXT file so you can Copy & Paste.

IndyUK

Hi


I have added the code to the orginal post. I tried to tidy up and comment as best as I could but, being BASIC it can start to look quite cluttered if you add too many REM lines. Hopefully there's enough in there to give you some idea of what it's doing. I'm always around here if you need any explanation. Anyway, sorry it took a bit more time than I would have liked to post the code. I started to mess about with adding a ladder and see how that would work. I think it can work. BTW - This needs BASIC 1.1 as I needed the Graphics Pen x command which was only in the 664/6128. I really tried my best to keep it at 464 level but then I would have had to resort to machine code but, at least it's still 100% basic which is all that mattered.


Anyway, have a play everyone and let me know what you think.


Thanks.

AmsAsm

This looks really interesting.

Thanks a lot !

:D

ervin

Quote from: IndyUK on 23:46, 14 February 22
Hi

I have added the code to the orginal post. I tried to tidy up and comment as best as I could but, being BASIC it can start to look quite cluttered if you add too many REM lines. Hopefully there's enough in there to give you some idea of what it's doing. I'm always around here if you need any explanation. Anyway, sorry it took a bit more time than I would have liked to post the code. I started to mess about with adding a ladder and see how that would work. I think it can work. BTW - This needs BASIC 1.1 as I needed the Graphics Pen x command which was only in the 664/6128. I really tried my best to keep it at 464 level but then I would have had to resort to machine code but, at least it's still 100% basic which is all that mattered.

Anyway, have a play everyone and let me know what you think.

Thanks.


This is very cool - thanks for posting the code.  :)
The jumping arc is really well done.
This has a lot of potential!

IndyUK

Quote from: ervin on 12:40, 15 February 22

This has a lot of potential!

I know it's quite sluggish in BASIC but, when this was in it's early stages of development, I ran it through CPCBASIC as an assembly version and it was really fast. Unfortunately, CPCBASIC doesn't cater for arrays so a conversion through that just won't happen. I think it can be converted to assembly fairly easily by hand as I tried to make sure that I avoided anything that would cause machine code to even slow down e.g division/multiplication/16 bit ops. For example, to try and keep a decent frame rate during game play I adopted a method whereby I sectioned the screen off into 16 rectangles so the collision detection routine only had to scan objects in which ever section of the screen the player was currently in. The test screen I have has too many interactable objects, which wouldn't normally be the case. I did that to see how far I could push things before the whole thing became a slideshow. It also forced me to become quite inventive to keep things going. I think the biggest thing I came away from doing this is implementing techniques that could quite easily be adopted in any other languages/platform. I wonder how much work go into a ZX or C64 conversion(?)


I'm not sure if doing this in Mode 0 would have helped with the speed. Personally I like Mode 1's ratio and character rendering proportion so preferred it over Mode 0 but, I did miss the colour selection. The only other obvious missing element is sound. Not something I have any grasp over (yet) so if anyone would like to give me some pointers on say sound during the jump, falling or death sequences I'd be glad to incorporate (or have a go yourselves). Also the player UDG is a bit basic and lacks fluidity during the animation sequence. So that's probably another area for improvement.


BTW - depending on which emulator you're using. If you increase the speed of it this is quite enjoyable. I use WinApe which only has the one turbo mode and that makes it too fast. However, other CPC emulators may have smaller increments that might make it perfectly playable.




ervin

Quote from: IndyUK on 13:59, 15 February 22
I know it's quite sluggish in BASIC but, when this was in it's early stages of development, I ran it through CPCBASIC as an assembly version and it was really fast. Unfortunately, CPCBASIC doesn't cater for arrays so a conversion through that just won't happen. I think it can be converted to assembly fairly easily by hand as I tried to make sure that I avoided anything that would cause machine code to even slow down e.g division/multiplication/16 bit ops. For example, to try and keep a decent frame rate during game play I adopted a method whereby I sectioned the screen off into 16 rectangles so the collision detection routine only had to scan objects in which ever section of the screen the player was currently in. The test screen I have has too many interactable objects, which wouldn't normally be the case. I did that to see how far I could push things before the whole thing became a slideshow. It also forced me to become quite inventive to keep things going. I think the biggest thing I came away from doing this is implementing techniques that could quite easily be adopted in any other languages/platform. I wonder how much work go into a ZX or C64 conversion(?)

I'm not sure if doing this in Mode 0 would have helped with the speed. Personally I like Mode 1's ratio and character rendering proportion so preferred it over Mode 0 but, I did miss the colour selection. The only other obvious missing element is sound. Not something I have any grasp over (yet) so if anyone would like to give me some pointers on say sound during the jump, falling or death sequences I'd be glad to incorporate (or have a go yourselves). Also the player UDG is a bit basic and lacks fluidity during the animation sequence. So that's probably another area for improvement.

BTW - depending on which emulator you're using. If you increase the speed of it this is quite enjoyable. I use WinApe which only has the one turbo mode and that makes it too fast. However, other CPC emulators may have smaller increments that might make it perfectly playable.

In WinAPE' settings, on the General tab, the timing can be set from 5% speed to 1000%.
Your game plays really well at 200%.

VincentGR

#8
Have you tried the "fast basic compiler"?
It's not that fast, but it might give you a proper boost, maybe.

IndyUK

Quote from: VincentGR on 23:32, 15 February 22
Have you tried the "fast basic compiler"?
It's not that fast, but it could give you a proper boost, maybe.

Hi

After lots of messing about, I managed to get the program converted. However, when I run the newly created 'bin' version of the program. It starts of ok then comes up with a "Improper argument in line 100". If that's referring to the line in BASIC then all that reads is;

100 MODE 1:DEFINT a-z:BORDER 5:INK 0,0:INK 2,15:INK 3,14:SYMBOL AFTER 128

Not sure if there is a unsupported command in there. The only BASIC line that is there after the compilation is;

10 CALL &17E

I'm assuming that the address where my assembled version has been loaded and is being called.

As a side note, I have to say that from what it did manage to run, it looks very impressive. If the speed boost is the equivilant of arounf 250%-300% the game will become very playable. I may even be tempted to revist and add some moving characters.

Thanks

IndyUK

From what I could make out when it first runs is. It appeared to error at the stage where the player is first printed to the screen. So as a test I commented out the block of code where the pixel check is made to see if that was the issue (i.e. TEST(x,y)) and lo and behold no error. Of course the player char printed fine but since the logic to determine if it was on solid ground was not being run, it wasn't falling as it should. So basically the TEST command doesn't seem to be handled despite the manual saying it is supported.

I am impressed though at the speed gain. The player animation/movement was a lot faster (probably the equivilant of 200-300% emulation boost). If I can get the TEST command to work I would be very tempted to add moving objects to the game. Speed was the main reason I left them out.

Thanks

SRS

Nice one !

I played a bit with your source and this lines should speed up printing/gameplay without compiling - but i did not test it very long ;)


105 POKE &B941,&C9:REM interupt off
320 POKE &B941,&F3:REM interupt on for keyboard
359 POKE &B941,&C9:REM and off



IndyUK

Quote from: SRS on 20:25, 16 February 22105 POKE &B941,&C9:REM interupt off
320 POKE &B941,&F3:REM interupt on for keyboard
359 POKE &B941,&C9:REM and off

Hi


I'm afraid they didn't appear to do anything. Seemed the same speed. Are these pokes just the Machine code equivilant of BASIC's version DI/EI. I do already have DI/EI within the program. TBH not sure if DI has any affect in BASIC. I did read in a post here that DI/EI are not the same in BASIC and Assembly.


Thanks

andycadley

DI/EI in BASIC control BASIC's interrupts, i.e the AFTER, EVERY and ON SQ GOSUB commands. The idea being you can temporarily prevent one from interrupting another so that variable changes will be atomic. It's not really a performance thing as such.


It doesn't disable actual interrupts, otherwise things like reading the keyboard or flashing INKs would break (since these are implemented on the various ticker lists controlled by the firmware interrupt handler).


I haven't looked, but I suspect those pokes are just fiddling the ticker lists directly, which would speed things up a bit but probably not by any really noticeable factor in most cases (assembly is a lot faster than BASIC and the overhead of parsing commands is vastly larger than that required to perform the general background tasks).

IndyUK

Quote from: andycadley on 00:16, 17 February 22DI/EI in BASIC control BASIC's interrupts, i.e the AFTER, EVERY and ON SQ GOSUB commands. The idea being you can temporarily prevent one from interrupting another so that variable changes will be atomic. It's not really a performance thing as such.

Hi


Thanks for the clarification. I knew I'd read about this somewhere on this forum. It makes sense now why adding those to a BASIC program wont't exhibit any performance gain. I only use them just on the off chance they may give some boost as I needed every ounce of speed I could get. Anyway, all things considered I think I did the best I could and, always knew that you just can't beat machine code. The Free Basic compilier does a very commendable job and bridging the gap between BASIC and M/C. Shame it didn't work out for me.


Thanks for your help.

SRS

Information about the poke can be found here: https://www.cpcwiki.eu/forum/programming/speed-poke/msg208879/#msg208879
And I tested FaBaCom with TEST(x,y) command - in a simple program it works just fine

5 DEFINT t
6 x=1
7 y=100
10 MODE 1
20 PLOT 0,200,3:DRAWR 320,0
30 t=TEST(x*2,y*2)
40 PRINT t
50 CALL &BB18
60 END



IndyUK

Quote from: SRS on 21:24, 18 February 22And I tested FaBaCom with TEST(x,y) command - in a simple program it works just fine

Hi

That's odd. When I skipped the code which checks if the character is on solid ground (line 4400), I got no error. Maybe that's not the problematic line then. I just made an assumption seeing everything else around it was pretty much straight forward code. I'll retry it and this time comment out the TEST command lines and see if I still get the error.

Thanks for checking for me.

IndyUK

Hi Folks,

Hope you're all doing well.

So, it's been quite a while since I last worked on my 2D platformer written entirely in BASIC. I had some time on my hands so thought why not pickup the project again. There is still plenty that's missing from it and so began to ponder over what I could tackle next. As I wanted to make the game a bit more challenging, I thought it might be a good idea to add moving platforms. I knew that if I can add these, then it would open the game up a bit more. So for the last ~2 months I have been working on adding moving platforms and have managed to get something working resonably well. Here's a video of what I managed to put together;


Remember, this is in BASIC running in WinApe using it's Turbo mode so, don't get too excited with the speed.

I have to say that it was quite tricky getting these working as there's so much more that you have to consider. I have begun work on adding platforms moving vertically as the next step, which would really open up the game.

Anyway, hope you like what I've done so far and hope to be back with a demo of vertical ones...oh and may be another screen or two.

See you all later.

Powered by SMFPacks Menu Editor Mod