Beginner's Sprite Tutorial
Re: Beginner's Sprite Tutorial
[mention]Seven.FFF[/mention] apart from in your tutorial are there any documents that explains the configuration bits you put before the code?
I suppose I have always used Pasmo because you don't need all that extra stuff, but I should spend some time on Zeus especially as it has an.emulator built in..
I suppose I have always used Pasmo because you don't need all that extra stuff, but I should spend some time on Zeus especially as it has an.emulator built in..
Re: Beginner's Sprite Tutorial
Yes, for sure. The documentation is distributed on a non-linear fashion between here and here.
For a quick start, if you go File >> New ZX Spectrum (48K) you get a commented template. But let's see. This is what I consider to be the minimum configuration for a new project:
Code: Select all
zeusemulate "48K"
A lot of the Zeus options can be specified in the UI or in code. Doing it in the UI is obviously simpler and more intuitive, but doing it in the code has the advantage of being able to open, assemble and run multiple projects without having to tweak settings.
Code: Select all
zoLogicOperatorsHighPri = false
This is also corresponds to one of the many checkboxes on the Config tab.
Code: Select all
zoSupportStringEscapes = false
Code: Select all
Zeus_PC = $nnnn
Stack equ $nnnn
Conceptially, it's more like what happens at the point you finish loading a .z80 or .sna shapshot. The entire state of the machine is restored, before jumping to the entry point.
There are also other directives to set the registers, interrupt mode and enabled state, current 128K page, etc.
Instead of Zeus_PC you can also use the pasmo syntax of END $nnnn at the end of your code. For pasmo, that is an instruction to put a RANDOMIZE USR nnnnn command in the basic loader; for Zeus, it's an instruction for the emulator where to put the entry point.
It might seem like a pointless distinction, but having code injected directly makes 128K development a breeze - literally all eight 16K pages (or in the case of the Spectrum Next, all 223 8K pages!!) are in memory and ready to use right from the getgo, without the user having to write code to export them and merge them with a multipage loader.
Code: Select all
org $nnnn
Code: Select all
org zeuspage(7)
Code: Select all
output_z80"..\bin\blah.z80", $0000, EntryPoint
output_sna"..\bin\blah.sna", $0000, EntryPoint
output_tap"..\bin\blah.tap", "LoaderProgramName", "Comment", StartAddress, BytesToSave, 2, EntryPoint
output_tzx "..\bin\blah.tzx", "LoaderProgramName", "Comment", StartAddress, BytesToSave, 2, EntryPoint
Where this gets interesting is the 128K/sparse memory scatterloader (mode 3) tape files, for example:
Code: Select all
output_tap"..\bin\blah.tap", "LoaderProgramName", "Comment", StartAddressOfBlock, BytesOfBlockToSave, 3, EntryPoint, BorderColours
output_tap_block "..\bin\blah.tap",StartAddressOfSecondBlock, BytesOfSecondBlockToSave
output_tap_block "..\bin\blah.tap",StartAddressOfThirdBlock, BytesOfThirdBlockToSave
If there's a loading screen at $4000-$5AFF (loaded with something like this):
Code: Select all
import_bin "loading.scr", $4000
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Re: Beginner's Sprite Tutorial
I believe we all need some good article about this Zeus
It's seems that it became a serious player among crossassemblers quite recently.
It was always Sjasm or Pasmo before. Okay, maybe not always but last 10 years which seems like always
I'm personally not up to date. When I hear Zeus I think about this thing from 1983
https://spectrumcomputing.co.uk/index.p ... 96&id=9010
It's seems that it became a serious player among crossassemblers quite recently.
It was always Sjasm or Pasmo before. Okay, maybe not always but last 10 years which seems like always
I'm personally not up to date. When I hear Zeus I think about this thing from 1983
https://spectrumcomputing.co.uk/index.p ... 96&id=9010
Re: Beginner's Sprite Tutorial
Just to give a little teaser about another one of my fav Zeus features, I have a USB cable running into to my Spectrum Next, which has an integrated 2Mbps serial port. At the click of a button, Zeus assembles code, loads it down the wire into memory, and executes at the entry point.
It has a command line interface, so by typing my own commands I can list memory, do pokes, write to ports, reset the machine, disassemble any address (including 128K pages that aren't even currently paged in) with the source lines next to them, import files from disk on the PC into memory, and export memory blocks to disk on the PC.
Pretty much what any emulator debugger does - except that none of the emulators for the Next are fully functional yet, and the bits that are functional don't behave the same as they do on the real hardware.
You could get this running on a real Spectrum with a serial or parallel interface too, pretty easily (with some input from Simon).
It has a command line interface, so by typing my own commands I can list memory, do pokes, write to ports, reset the machine, disassemble any address (including 128K pages that aren't even currently paged in) with the source lines next to them, import files from disk on the PC into memory, and export memory blocks to disk on the PC.
Pretty much what any emulator debugger does - except that none of the emulators for the Next are fully functional yet, and the bits that are functional don't behave the same as they do on the real hardware.
You could get this running on a real Spectrum with a serial or parallel interface too, pretty easily (with some input from Simon).
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
SevenFFF / Threetwosevensixseven / colonel32
NXtel • NXTP • ESP Update • ESP Reset • CSpect Plugins
Re: Beginner's Sprite Tutorial
[mention]R-Tape[/mention]. Is there any chance you could do versions of your examples to cover up and down from here please:
viewtopic.php?f=6&t=2575
viewtopic.php?f=6&t=2575
-
- Microbot
- Posts: 105
- Joined: Wed Jul 01, 2020 2:33 pm
Re: Beginner's Sprite Tutorial
Thanks for the code to print a sprite. I've created my own sprite and added to the code. My issue is my sprite is only 2 bytes wide, I have changed everything to allow for this but there is something is the 'yx2pix' call that I think only allows for 3 bytes wide sprites. Does anyone know what the code change would be for just 2 bytes wide? It's a bit complicated for me to follow at the moment. My sprite does move along but only a character at a time, something in that call stops in doing pixel movement.
Re: Beginner's Sprite Tutorial
Cheers. It's good to see the code being useful.Freespirit wrote: ↑Thu Jul 02, 2020 8:41 pm Thanks for the code to print a sprite. I've created my own sprite and added to the code. My issue is my sprite is only 2 bytes wide, I have changed everything to allow for this but there is something is the 'yx2pix' call that I think only allows for 3 bytes wide sprites. Does anyone know what the code change would be for just 2 bytes wide? It's a bit complicated for me to follow at the moment. My sprite does move along but only a character at a time, something in that call stops in doing pixel movement.
"yx2pix" is not the problem, as it only points DE to the top left of the sprite, irrespective of its size.
I've had a look, and if you take the code from here, and change the following subroutines:
This deletes two bytes wide and 16 high.
Code: Select all
;
deletesprite: ;we need to delete the old sprite before we draw the new one. The sprite is 3 bytes wide & 16 pixels high
ld a,(x_coordinate) ;make C=xcor and B=ycor
ld c,a
ld a,(y_coordinate)
ld b,a
call yx2pix ;point DE at the corresponding screen address
ld b,16 ;sprite is 16 lines high
deleteloop: ;NEW!
ld a,0 ;empty A to delete
ld (de),a ;repeat a total of 3 times
inc e ;next column along
ld (de),a
dec e ;NEW
call nextlinedown ;move DE down one line
djnz deleteloop ;repeat 16 times
ret
;
Code: Select all
;
drawsprite:
ld a,(x_coordinate) ;make C=xcor and B=ycor
ld c,a
ld a,(y_coordinate)
ld b,a
call yx2pix ;point DE at corresponding screen position
ld a,(x_coordinate) ;but we still need to find which preshifted sprite to draw
and 00000111b ;we have 8 preshifted graphics to choose from, cycled 0-7 in the right hand 3 bits of the x coordinate
call getsprite ;point HL at the correct graphic
ld b,16 ;sprite is 16 lines high
drawloop: ;NEW
ld a,(hl) ;take a byte of graphic
ld (de),a ;and put it on the screen
inc hl ;next byte of graphic
inc e ;next column on screen
ld a,(hl) ;repeat for 3 bytes across
ld (de),a
inc hl
dec e
call nextlinedown
djnz drawloop ;repeat for all 16 lines
ret
;
Code: Select all
;
getsprite: ;don't worry much about how this works! for an alternative method that
;uses a table see 'getsprite_alternativemethod'
;Arrive A holding which pixel within a byte (0-7), point HL at correct graphic
ld h,0 ;we need to multiply A by 48, do it in HL
ld l,a
add hl,hl ;x2
add hl,hl ;x4
add hl,hl ;x8
add hl,hl ;x16
add hl,hl ;x32
ld bc,spritegraphic0
add hl,bc ;HL now pointing at correct sprite frame
ret
;
Code: Select all
org 32768 ;we can ORG (or assemble) this code anywhere really
;a beginner's, unoptimised sprite routine
main: halt ;this stops the program until the Spectrum is about to refresh the TV screen
;the HALT is important to avoid sprite flicker, and it slows down the program
call deletesprite ;we need to delete the old position of the sprite
call movesprite ;move the sprite! Could be based on player key input or baddy AI
call drawsprite ;get correct preshifted graphic, and draw it on the screen
jr main ;loop!
;
deletesprite: ;we need to delete the old sprite before we draw the new one. The sprite is 3 bytes wide & 16 pixels high
ld a,(x_coordinate) ;make C=xcor and B=ycor
ld c,a
ld a,(y_coordinate)
ld b,a
call yx2pix ;point DE at the corresponding screen address
ld b,16 ;sprite is 16 lines high
deleteloop: ;NEW!
ld a,0 ;empty A to delete
ld (de),a ;repeat a total of 3 times
inc e ;next column along
ld (de),a
dec e ;NEW
call nextlinedown ;move DE down one line
djnz deleteloop ;repeat 16 times
ret
;
movesprite: ;very simple routine that just increases the x coordinate
ld a,(x_coordinate)
inc a
ld (x_coordinate),a
cp 232 ;check if the sprite has moved all the way to the right (256-24)
ret c ;return if not
ld a,0 ;if yes then back to left
ld (x_coordinate),a
ret
;
drawsprite:
ld a,(x_coordinate) ;make C=xcor and B=ycor
ld c,a
ld a,(y_coordinate)
ld b,a
call yx2pix ;point DE at corresponding screen position
ld a,(x_coordinate) ;but we still need to find which preshifted sprite to draw
and 00000111b ;we have 8 preshifted graphics to choose from, cycled 0-7 in the right hand 3 bits of the x coordinate
call getsprite ;point HL at the correct graphic
ld b,16 ;sprite is 16 lines high
drawloop: ;NEW
ld a,(hl) ;take a byte of graphic
ld (de),a ;and put it on the screen
inc hl ;next byte of graphic
inc e ;next column on screen
ld a,(hl) ;repeat for 3 bytes across
ld (de),a
inc hl
dec e
call nextlinedown
djnz drawloop ;repeat for all 16 lines
ret
;
x_coordinate: db 0
y_coordinate: db 0
;
nextlinedown: ;don't worry about how this works yet!
inc d ;just arrive with DE in the display file
ld a,d ;and it gets moved down one line
and 7
ret nz
ld a,e
add a,32
ld e,a
ret c
ld a,d
sub 8
ld d,a
ret
;
yx2pix: ;don't worry about how this works yet! just arrive with arrive with B=y 0-192, C=x 0-255
ld a,b ;return with DE at corresponding place on the screen
rra
rra
rra
and 24
or 64
ld d,a
ld a,b
and 7
or d
ld d,a
ld a,b
rla
rla
and 224
ld e,a
ld a,c
rra
rra
rra
and 31
or e
ld e,a
ret
;
getsprite: ;don't worry much about how this works! for an alternative method that
;uses a table see 'getsprite_alternativemethod'
;Arrive A holding which pixel within a byte (0-7), point HL at correct graphic
ld h,0 ;we need to multiply A by 48, do it in HL
ld l,a
add hl,hl ;x2
add hl,hl ;x4
add hl,hl ;x8
add hl,hl ;x16
add hl,hl ;x32
ld bc,spritegraphic0
add hl,bc ;HL now pointing at correct sprite frame
ret
;
spritegraphic0: ;8 preshifted graphics, each one 3 bytes wide and 16 pixels high, this one a simple square
; ASM data file from a ZX-Paintbrush picture with 16 x 128 pixels (= 2 x 16 characters)
; block based output of pixel data - each block contains 16 x 16 pixels
; block at pixel position (0,0):
db 126, 0, 255, 0, 219, 0, 255, 0
db 189, 0, 195, 0, 255, 0, 126, 0
db 24, 0, 24, 0, 24, 0, 24, 0
db 24, 0, 36, 0, 66, 0, 129, 0
; block at pixel position (0,16):
db 63, 0, 127, 128, 109, 128, 127, 128
db 94, 128, 97, 128, 127, 128, 63, 0
db 12, 0, 12, 0, 12, 0, 12, 0
db 12, 0, 18, 0, 33, 0, 64, 128
; block at pixel position (0,32):
db 31, 128, 63, 192, 54, 192, 63, 192
db 47, 64, 48, 192, 63, 192, 31, 128
db 6, 0, 6, 0, 6, 0, 6, 0
db 6, 0, 9, 0, 16, 128, 32, 64
; block at pixel position (0,48):
db 15, 192, 31, 224, 27, 96, 31, 224
db 23, 160, 24, 96, 31, 224, 15, 192
db 3, 0, 3, 0, 3, 0, 3, 0
db 3, 0, 4, 128, 8, 64, 16, 32
; block at pixel position (0,64):
db 7, 224, 15, 240, 13, 176, 15, 240
db 11, 208, 12, 48, 15, 240, 7, 224
db 1, 128, 1, 128, 1, 128, 1, 128
db 1, 128, 2, 64, 4, 32, 8, 16
; block at pixel position (0,80):
db 3, 240, 7, 248, 6, 216, 7, 248
db 5, 232, 6, 24, 7, 248, 3, 240
db 0, 192, 0, 192, 0, 192, 0, 192
db 0, 192, 1, 32, 2, 16, 4, 8
; block at pixel position (0,96):
db 1, 248, 3, 252, 3, 108, 3, 252
db 2, 244, 3, 12, 3, 252, 1, 248
db 0, 96, 0, 96, 0, 96, 0, 96
db 0, 96, 0, 144, 1, 8, 2, 4
; block at pixel position (0,112):
db 0, 252, 1, 254, 1, 182, 1, 254
db 1, 122, 1, 134, 1, 254, 0, 252
db 0, 48, 0, 48, 0, 48, 0, 48
db 0, 48, 0, 72, 0, 132, 1, 2
;
-
- Manic Miner
- Posts: 205
- Joined: Thu Feb 22, 2018 3:27 pm
- Location: virginias eastern shore
- Contact:
Re: Beginner's Sprite Tutorial
Thanks RTape! FINALLY an explanation that I could at least follow, maybe not understand exactly but its revealing to me why Basic slows the machine down in execution. As far as the question 'did I assume too much?' well yes as far as I'm concerned because I have no idea how to assemble or compile or whatever its called but thats okay. One look at that listing was enough to show me that theres no way I could ever learn all those instruction codes and I don't have the need to use machine code but I'm grateful to you for a lucid explanation and who knows one day I may try it myself just out of curiousity and make my own sprite to do better than just crib your lesson. First explanation thats ever made any sense to me, a sort of Rosetta Stone!
-
- Microbot
- Posts: 105
- Joined: Wed Jul 01, 2020 2:33 pm
Re: Beginner's Sprite Tutorial
Thanks Rtape it works perfectly. If I just have one block of graphics do you know why it's not moving smoothly? I just changed getsprite to point to the first set only.
Code: Select all
; This is a basic template file for writing 48K Spectrum code.
AppFilename equ "Rtape" ; What we're called (for file generation)
AppFirst equ $8000 ; First byte of code (uncontended memory)
zeusemulate "48K","ULA+" ; Set the model and enable ULA+
; Start planting code here. (When generating a tape file we start saving from here)
org AppFirst ; Start of application
;AppEntry halt
;we can ORG (or assemble) this code anywhere really
;a beginner's, unoptimised sprite routine
AppEntry : halt ;this stops the program until the Spectrum is about to refresh the TV screen
;the HALT is important to avoid sprite flicker, and it slows down the program
call deletesprite ;we need to delete the old position of the sprite
call movesprite ;move the sprite! Could be based on player key input or baddy AI
call drawsprite ;get correct preshifted graphic, and draw it on the screen
jr AppEntry ;loop!
;
deletesprite : ;we need to delete the old sprite before we draw the new one. The sprite is 3 bytes wide & 16 pixels high
ld a,(x_coordinate) ;make C=xcor and B=ycor
ld c,a
ld a,(y_coordinate)
ld b,a
call yx2pix ;point DE at the corresponding screen address
ld b,16 ;sprite is 16 lines high
deleteloop : ;NEW!
ld a,0 ;empty A to delete
ld (de),a ;repeat a total of 3 times
inc e ;next column along
ld (de),a
dec e ;NEW
call nextlinedown ;move DE down one line
djnz deleteloop ;repeat 16 times
ret
;
movesprite : ;very simple routine that just increases the x coordinate
ld a,(x_coordinate)
inc a
ld (x_coordinate),a
cp 232 ;check if the sprite has moved all the way to the right (256-24)
ret c ;return if not
ld a,0 ;if yes then back to left
ld (x_coordinate),a
ret
;
drawsprite :
ld a,(x_coordinate) ;make C=xcor and B=ycor
ld c,a
ld a,(y_coordinate)
ld b,a
call yx2pix ;point DE at corresponding screen position
ld a,(x_coordinate) ;but we still need to find which preshifted sprite to draw
and 00000111b ;we have 8 preshifted graphics to choose from, cycled 0-7 in the right hand 3 bits of the x coordinate
call getsprite ;point HL at the correct graphic
ld b,16 ;sprite is 16 lines high
drawloop : ;NEW
ld a,(hl) ;take a byte of graphic
ld (de),a ;and put it on the screen
inc hl ;next byte of graphic
inc e ;next column on screen
ld a,(hl) ;repeat for 3 bytes across
ld (de),a
inc hl
dec e
call nextlinedown
djnz drawloop ;repeat for all 16 lines
ret
;
x_coordinate : db 0
y_coordinate : db 0
;
nextlinedown : ;don't worry about how this works yet!
inc d ;just arrive with DE in the display file
ld a,d ;and it gets moved down one line
and 7
ret nz
ld a,e
add a,32
ld e,a
ret c
ld a,d
sub 8
ld d,a
ret
;
yx2pix : ;don't worry about how this works yet! just arrive with arrive with B=y 0-192, C=x 0-255
ld a,b ;return with DE at corresponding place on the screen
rra
rra
rra
and 24
or 64
ld d,a
ld a,b
and 7
or d
ld d,a
ld a,b
rla
rla
and 224
ld e,a
ld a,c
rra
rra
rra
and 31
or e
ld e,a
ret
;
getsprite : ;don't worry much about how this works! for an alternative method that
;uses a table see 'getsprite_alternativemethod'
;Arrive A holding which pixel within a byte (0-7), point HL at correct graphic
ld bc,spritegraphic0
ld hl,bc ;HL now pointing at correct sprite frame
ret
;
spritegraphic0 : ;8 preshifted graphics, each one 3 bytes wide and 16 pixels high, this one a simple square
; ASM data file from a ZX-Paintbrush picture with 16 x 128 pixels (= 2 x 16 characters)
; block based output of pixel data - each block contains 16 x 16 pixels
; block at pixel position (0,0):
db 126, 0, 255, 0, 219, 0, 255, 0
db 189, 0, 195, 0, 255, 0, 126, 0
db 24, 0, 24, 0, 24, 0, 24, 0
db 24, 0, 36, 0, 66, 0, 129, 0
; ; Replace these lines with your code
jp AppEntry ;
; Stop planting code after this. (When generating a tape file we save bytes below here)
AppLast equ *-1 ; The last used byte's address
; Generate some useful debugging commands
profile AppFirst,AppLast-AppFirst+1 ; Enable profiling for all the code
; Setup the emulation registers, so Zeus can emulate this code correctly
Zeus_PC equ AppEntry ; Tell the emulator where to start
Zeus_SP equ $FF40 ; Tell the emulator where to put the stack
; These generate some output files
; Generate a SZX file
output_szx AppFilename+".szx",$0000,AppEntry ; The szx file
; If we want a fancy loader we need to load a loading screen
; import_bin AppFilename+".scr",$4000 ; Load a loading screen
; Now, also generate a tzx file using the loader
output_tzx AppFilename+".tzx",AppFilename,"",AppFirst,AppLast-AppFirst,1,AppEntry ; A tzx file using the loader
Re: Beginner's Sprite Tutorial
Bonzer.
One block of graphic cannot move smoothly on the speccy—you need to store preshifted graphics.If I just have one block of graphics do you know why it's not moving smoothly? I just changed getsprite to point to the first set only.
In this case, you need to print the same thing 8 times, animated, in the same place, to give the illusion of smoothness. Each animation moves along by a pixel. See the pic below, for horizontal movement, you print a different animation at the same place 8 times, and THEN change the column. This is different to fancier computers like the C64, where you can simply draw the same thing at a different XY.
-
- Microbot
- Posts: 105
- Joined: Wed Jul 01, 2020 2:33 pm
Re: Beginner's Sprite Tutorial
Thanks for your great explanation R-Tape. All makes sense now.
Re: Beginner's Sprite Tutorial
Hello everyone. This is my first approach to software sprites and my first attempts to write something for ZX. I have a question about the example programs for generating Sprite a few posts above - I checked and it works great.
The problem is that the code always "deletes" other elements of the screen when the sprite "passes" here - what needs to be done so that if I have a background element (or two sprites overlapping) they are not deleted but remain on the screen.
You need to somehow check new pixels whether they are set or not and when a new sprite movement is generated in this place, do not delete the already set background bits?
The problem is that the code always "deletes" other elements of the screen when the sprite "passes" here - what needs to be done so that if I have a background element (or two sprites overlapping) they are not deleted but remain on the screen.
You need to somehow check new pixels whether they are set or not and when a new sprite movement is generated in this place, do not delete the already set background bits?
Re: Beginner's Sprite Tutorial
@myduis,
This book by Jonathan Cauldwell goes into software sprites in great detail:
https://jonathan-cauldwell.itch.io/how- ... trum-games
I'm mentioning @R-Tape as he created the thread, and will I'm sure be able to guide you in the right direction.
This book by Jonathan Cauldwell goes into software sprites in great detail:
https://jonathan-cauldwell.itch.io/how- ... trum-games
I'm mentioning @R-Tape as he created the thread, and will I'm sure be able to guide you in the right direction.
Re: Beginner's Sprite Tutorial
Hi @myduis. The example in this thread is one of the simpler ways of doing sprites (LD on and remove with empty space). It would be fine for a game with no background like The Pyramid, or a game with PAPER platforms like Loony Zoo.myduis wrote: ↑Wed Apr 26, 2023 7:29 am The problem is that the code always "deletes" other elements of the screen when the sprite "passes" here - what needs to be done so that if I have a background element (or two sprites overlapping) they are not deleted but remain on the screen.
You need to somehow check new pixels whether they are set or not and when a new sprite movement is generated in this place, do not delete the already set background bits?
Dealing with background is more complicated. There's a lot of ways to do it, but here's a quick summary of the two main methods (that I can think of):
-the XOR method. You XOR the sprite on and you XOR it off later. All AGD games use this method. Pros: simple and no need for a big screen buffer. Cons: pixel clash, and you can make a mess if you're not careful of the order things are drawn and deleted.
Code: Select all
;HL pointing at graphic
;DE pointing at screen
LD A,(DE) ;take a byte from the screen
XOR (HL) ;XOR the graphic onto it
LD (DE),A ;place the combination of background and graphic onto the screen
repeat...
Yep the book that Peter links to book goes into useful detail here.
It all depends on what kind of game you're making and how much experience you have. Could you give a bit more info?
Re: Beginner's Sprite Tutorial
For now, I've made one very simple demo with jumping Willy using the method from the posts above (control keyboard WASD keys).
Thanks for the link to the document, it will help a lot.
TAPE:
https://dl.dropboxusercontent.com/s/r3x ... lytape.tap
CARTRIDGE:
https://dl.dropboxusercontent.com/s/3ry ... lycart.rom
Thanks for the link to the document, it will help a lot.
TAPE:
https://dl.dropboxusercontent.com/s/r3x ... lytape.tap
CARTRIDGE:
https://dl.dropboxusercontent.com/s/3ry ... lycart.rom
Re: Beginner's Sprite Tutorial
That looks great, and you've already done loads of the hard work with the collision and background detection. I'd try out the XOR method.
You need to be very careful of the order of deletion and draw when using XOR, so I'd simplify the main loop to look something like this (and you should delete/draw every pass of the main loop). When you first start, you need to enter the main loop at 'entry', so you miss out the first 'xor_all_sprites_off' (otherwise you will be drawing then deleting and not seeing the sprites).
Code: Select all
main: halt
call xor_all_sprites_off
entry: call xor_all_sprites_on
;...
;other game stuff
;...
jr main
;
Code: Select all
;
xorsprite_off:
ld de,(oldscadd) ;old screen address
ld hl,(oldgraph) ;old graphic address
call xorspr ;use the same code loop as xor on
ret
;
xorsprite_on: ;arrive HL at graphic, DE at screen
ld (oldscadd),de ;store screen address for deletion later
ld (oldgraph),hl ;store graphic address for deletion later
xorspr: ld b,16
xslp: ld a,(de)
xor (hl)
ld (de),a
inc hl
inc e
ld a,(de)
xor (hl)
ld (de),a
inc hl
inc e
ld a,(de)
xor (hl)
ld (de),a
inc hl
dec e
dec e
djnz xslp
ret
;
Re: Beginner's Sprite Tutorial
Ordering isn't too important if you use XOR, as long as you undraw/redraw everything so it may be better to do undraw/redrawn on an individual sprite basis to help reduce flickering.
Draw/erase order becomes much more important if you try to capture and restore sections of the background. It can be more efficient than having an entire back buffer, especially if you don't have many sprites, but requires you to restore the background in the opposite order to the one you drew in originally.
Draw/erase order becomes much more important if you try to capture and restore sections of the background. It can be more efficient than having an entire back buffer, especially if you don't have many sprites, but requires you to restore the background in the opposite order to the one you drew in originally.