Writing my first (simple) game in assembly

Pagina 1/5
| 2 | 3 | 4 | 5

Door Pbk71

Expert (101)

afbeelding van Pbk71

23-05-2021, 08:10

Hi all,

After my first tests with a bouncing sprite and some pattern table scrolling in screen 1 I have now started writing my first (simple) game in assembly. It's going to be a simple run ad jump game like the dinosaur game in Chrome.

What I want is:

  • an animated character that can jump variable heights
  • a score and a highscore visible on screen
  • a few random chosen different moving obstacles to jump over or run under
  • an increasing speed for the obstacles, determined by the score
  • some obstacles that only appear at a certain minimum score
  • sound effects for walking, jumping, scoring points and crashing into an obstacle
  • an intro tune before the game starts and an outro tune when the game is over

The first thing I've done is writing a test for letting my character jump:
https://msxpen.com/codes/-MaMlna6aeEs6ekh9ic8

Pressing the spacebar makes the character jump. A longer press makes the character jump higher to a certain maximum. I've implemented gravity for a smooth jump.
This time I've put my game logic in a main loop and only the update of the sprite(s) in the timer hook.
I've created a flag that is set every time the timer hook runs. I use this for 'timed instructions' in my main loop so that the test runs at a fixed speed.

I wonder what your thoughts are about this first experiment. Next thing I am testing is a scrolling floor using pattern tables that can scroll at a variable speed.

Aangemeld of registreer om reacties te plaatsen

Van Daemos

Paragon (1949)

afbeelding van Daemos

23-05-2021, 09:41

Jumping feels good. You can tweak it until it feels perfect but its definetly very good. I would build a simple testmap first that contains all the requirements for your game engine with loader and everything else. You can then build objects starting with the main character. First jump,excellent then do a tilecheck code for your gravity then let the ultimate frustration begin Wink

Van ToriHino

Paladin (710)

afbeelding van ToriHino

23-05-2021, 10:46

Good improvement indeed to only keep the updates towards VDP in the interrupt. You could even go a step further and let the main loop set the sprite attributes in RAM immediately instead of a separate RAM value, that way the interrupt routine really only updates towards VRAM.

In general its better to keep current content of a VDP register if you only want to modify a single setting. Also good to use BIOS when performance is not (yet) an issue.

Initialize of the sprite could look something like:

LDIRVM:			equ 0x005C		; bios call to block transfer RAM to VRAM

RG1SAV:			equ #F3E0		; mirror of VDP register #1

; --- INITIALIZE SPRITE ---	                
  ld HL,sprite0              ; select sprite pattern address in memory
  ld DE,SPRITEPT          ; VRAM address to write attributes
  ld BC,32		           ; 32 bytes of patterns (1x32)
  call LDIRVM

  ld A,(RG1SAV)	          ; use current content of VDP reg #1
  or 0x02                     ; sets sprites to 16x16
                
  ld B,A
  ld C,1
  call WRTVDP

Also check for the jumpstate can be a bit easier:

  ; --- CHECK IF JUMPSTATE=0 ---		
  ld hl,jumpState
  ld a,(hl)			; check if jumpState=0
  cp 0
  jr nz, ml_endcheckspacepressed

  ; --- START JUMP ---		
  ld (hl),1			; set jumpStat to 1

And the end of the interrupt routine can look like this:

  ld hl,sprattr0                  ; start of buffer for sprite attributes
  ld de,SPRITEAT		; VRAM address to write attributes
  ld bc,4                           ; 4 bytes of attributes for sprite 0
  jp LDIRVM			; write to VRAM	and return

One final thing, but that's my personal taste, I don't like the use of 'magic numbers' in the code so I tend to use a lot of EQU values to keep it readable.

For example something like

VDP_SI_16x16         EQU 02     ; Sprite size 16x16
NR_OF_SPRITES        EQU 03     ; Nr of sprites to update
SPRITE_ATTR_SIZE     EQU 04     ; Attribute size of single sprite

  ld a,(RG1SAV)
  or VDP_SI_16x16

  ld   hl,RAM_SPRITE_ATTR_0
  ld   de,SPRITE_ATTR
  ld   bc,SPRITE_ATTR_SIZE * NR_OF_SPRITES
  call LDIRVM

Van ToriHino

Paladin (710)

afbeelding van ToriHino

23-05-2021, 10:54

Btw, a good start to have all default EQU's defined (BIOS, Hooks, System variables, ...) is using these include files as provided on FRS's home page, but you probably need to switch to an offline assembler then.

Van Daemos

Paragon (1949)

afbeelding van Daemos

23-05-2021, 12:05

Also avoid doing tons of things on interrupt. Better set a flag and wait for that flag during your loop. As soon as your loop starts, first output all your data, then do calculations and read controls in the end.

Van Pbk71

Expert (101)

afbeelding van Pbk71

23-05-2021, 14:36

Daemos wrote:

Jumping feels good. You can tweak it until it feels perfect but its definetly very good. I would build a simple testmap first that contains all the requirements for your game engine with loader and everything else. You can then build objects starting with the main character. First jump,excellent then do a tilecheck code for your gravity then let the ultimate frustration begin Wink

I'm not going to make a complete tilemap. My plan is to work with sprites for the obstacles that move from right to left and as soon as one disappears a new obstacle is random chosen.

Daemos wrote:

Also avoid doing tons of things on interrupt. Better set a flag and wait for that flag during your loop. As soon as your loop starts, first output all your data, then do calculations and read controls in the end.

Yeah, I'm trying to do this now. I've written a mainloop with al the logic in it and the timer hook sets a flag for that I use in my main loop. The order you suggest is a good one, thanks.

Van Pbk71

Expert (101)

afbeelding van Pbk71

23-05-2021, 14:40

ToriHino wrote:

Good improvement indeed to only keep the updates towards VDP in the interrupt. You could even go a step further and let the main loop set the sprite attributes in RAM immediately instead of a separate RAM value, that way the interrupt routine really only updates towards VRAM.

In general its better to keep current content of a VDP register if you only want to modify a single setting. Also good to use BIOS when performance is not (yet) an issue.

Thanks for the register-tip I'm going to use that. I was also thinking to adjust the sprite attributes in RAM in the mainloop. Don't think that this has much advantage at the moment but it will make the timer hook routine cleaner.
Thanks for the other tips, I will study them and implement it in my code.

Van Pbk71

Expert (101)

afbeelding van Pbk71

23-05-2021, 14:42

ToriHino wrote:

Btw, a good start to have all default EQU's defined (BIOS, Hooks, System variables, ...) is using these include files as provided on FRS's home page, but you probably need to switch to an offline assembler then.

Thanks for this tip. For my game I am using Sjasm. MSXPen comes in handy to create seperate tests that I can share here. Later on I combine these tests in my 'real' program.

Van Pbk71

Expert (101)

afbeelding van Pbk71

23-05-2021, 15:11

I've implemented the tips of ToriHino. Here is the new version:
https://msxpen.com/codes/-MaOL4ZKhkYFSA2N95iU

Van Pbk71

Expert (101)

afbeelding van Pbk71

23-05-2021, 23:18

Hi all,

I've extended my test. There is a moving floor now (screen 1 pattern table scrolling).
I made the scrolling speed variable. In this test every time you jump the speed is increased a little. You have to restart the emulator to start a the lowest speed again. Pressing jump to often creates strange effects as the speed gets much to high.
It is just to test to see what happens when the speed changes.

Sometimes the scrolling is smooth but at some speeds it is a bit choppy. See result here: https://msxpen.com/codes/-MaQ3Rzatk_WJoqWjX5f

I'm not sure how I will use this yet. Maybe I only use a few speeds where the scrolling is smooth. In the real game the speed will be adjusted when a certain score is reached with a fixed maximum speed.

Van santiontanon

Paragon (1420)

afbeelding van santiontanon

24-05-2021, 05:35

Nice and smooth! Are you considering the MSXDev if you finish a game on time? Smile

Pagina 1/5
| 2 | 3 | 4 | 5