Sprites management

Page 1/3
| 2 | 3

By thegeps

Master (254)

thegeps's picture

07-02-2019, 01:06

Well, sprites ara acting as expected. 2 sprites per spaceship, so 24 sprites for 12 enemies, 2 sprite for player1 and 3 sprites for shots=29 sprites on video. I know I have to reduce enemy quantity or put some onecoloured enemies to leave room for enemy fires


Now I need some hints:
1) can someone teach (or explain clearly) me a "flickering" routine (maybe someone has a snippet?)
2) How can I check when a sprite goes out of the screen and safely disable it? I attempted to do a CP, but with poor results (cause obviously often the sprite doesn't have that x or y value but is one ore some pixels near...
3)any hints on how implement enemy fire?

Login or register to post comments

By santiontanon

Paladin (821)

santiontanon's picture

07-02-2019, 05:09

Really nice video, so many sprites!!!

I don't know what are the "best" ways to do any of these, but I can tell you the way I do them in my games Smile

For flickering, this is what I do:
- I have a mirror of the sprite attribute table (4 bytes per sprite) in memory. Then, in the "even" frames, I upload it to the VDP "as is", and in the "odd" frames, I upload it in reverse order (the first sprite is uploaded to the last position, the second to the second to last, etc.). This changes the order of the sprites, and thus achieves a flickering effect, in case there are more than 4 sprites in line. Upside: this is a very easy solution, Downside: it only works well if there are at most 8 sprites in a single line, if there are 9, then the 5th sprite will never be drawn (since there will always be 4 sprites before it). I know other people have implemented this by doing more of a "rotating buffer", etc. You can also give "preference" to sprites, e.g. if you want the enemy bullets (which are the most important thing to see, other than your ship) to always be on top, you can make those always be the first sprites to be drawn, and make your own bullets be later on the list. Or even have your ship always the first (and thus never flicker), and only make the other sprites flicker, etc. it all depends on the game Smile

For "sprites out of the screen", again there might be better solutions. But in XSpelunker, and in my current game XRacing, I have the coordinates of the enemies/player as a 2byte word. So, I can check easily if this coordinate is higher or lower than the current coordinates of the edge of the screen, e.g.:

    ld hl,(screen_top_y_coordinate)
    ld bc,(enemy_y)
    sbc hl,bc
    jp p,enemy_outside_of_screen
   ; ...

With the left/right edges it's a bit more complicated, since you would need to control the "early clock bit" to make the sprite appear nicely from the left or from the right of the screen, but it's basically the same.

As for enemy fire, I am assuming that you are asking about how to make enemies "aim" at your ship. There are 2 easy solutions for this:
1) You can use the arctangent function (see Artrag's implementation here: https://www.msx.org/forum/msx-talk/development/8-bit-atan2 ), and get the angle from the enemy to the player to use it to move the bullet using a sin/cos table.
2) Even easier (and faster), you can just store the "difference in y" (y_diff) and the "difference in x" (x_diff) at the moment of firing, and then use those to move the bullet. You initialize a temporary variable "tmp" to 0, and you can do this (Assuming both positive and "y_diff" > "x_diff"):
tmp += x_diff
if (tmp>y_diff) {
tmp -= y_diff
This will move the bullet smoothly and exactly in the right angle. You just need to have 4 versions of this code for each of the 4 quadrants (it's basically the same idea of the classic Bresenham line drawing algorithm). This also uses very little CPU cycles :)

Again, not sure if those are the best answers, but it's the way I have been doing it :)

By thegeps

Master (254)

thegeps's picture

07-02-2019, 07:48

Thank you Santiago! Can you explain better tmp+=x_diff stuff? I'm not sure to understand it oO but i feel the force flowing through your algorithm...
Another question: obviously I have to write a collision detection routine (I think it have to be based on sprites coordinates, am I right?). How I can be sure of what hit what when rotating the sprite table? oO
The more I go further the more grow problems LOL!

By thegeps

Master (254)

thegeps's picture

07-02-2019, 10:30

to check y coordinate I found another solution by myself. I do this:

ld a,(bc) ;read ypos offset
add a,(hl) ;add it to ramspttbl ypos
sub 192 ;from 192 ycoord on, subtracting 192
bit 7,a ;we have a positive sign if we are out of screen else if we are in screen range(0-191)we have a neg sign
jp z,deactivatespritey ;if out of y coordinates
add a,192 ;else restore a and go on
code for other params

add a,192+16 ; restore a and add 16 (to check if sprite is in the smooth enter zone)
bit 7,a ;if adding 16 we have a positive value then we are in smooth enter zone
jp z,donot ;so do nohting (a small code to restore a adding -16 and jumping back to code for other params)

now let's see other things.. Smile


Enlighted (6236)

ARTRAG's picture

07-02-2019, 11:40

By thegeps

Master (254)

thegeps's picture

07-02-2019, 11:47

Thank you Arturo! I'm happy to study from your code 'cause you are very skilled, as often says your friend Francesco @ MSX italia on facebook Smile

By Grauw

Ascended (8384)

Grauw's picture

07-02-2019, 12:56

    sub 192
    bit 7,a
    jp z,deactivatespritey

    add a,192+16
    bit 7,a
    jp z,donot

In these cases you can omit the bit 7,a and use the sign (m(inus)/p(ositive)) flag:

    sub 192
    jp p,deactivatespritey

    add a,192+16
    jp p,donot

By thegeps

Master (254)

thegeps's picture

07-02-2019, 13:45

Wow, I didn't know! Probably a part of my msx asm book I read just one time ('cause such arguments are boring, lol). But really useful! I must refresh that part for sure!
Thank you as always! (Did you noticed, in the video, the small cmd prompt windows to compile with glass?)

By Grauw

Ascended (8384)

Grauw's picture

07-02-2019, 14:00

Big smile

By PingPong

Prophet (3435)

PingPong's picture

07-02-2019, 21:35

for sprite flickering routine: you can make at same position two sprite planes, while rotating the next each frame like this:

frame 0:
P0 P1 P2 P3 P4 P... P31
frame 1:
P0 P1 P4 P5 P6 P... P2 P3

frame 2:
P0 P1 P6 P7 P8 P... P4 P5

you rotate at steps of two on every frame and then append the first planes that shift out to the left to the rightmost end of the circular queue.

By hit9918

Prophet (2866)

hit9918's picture

07-02-2019, 21:53

@thegeps, I cant see your videos any more, blocked for non facebook users.
what a pity, I heard there is sprite action.


I know I have to reduce enemy quantity

keep the colorsprites.
copy the sprite list reverse every second time. gives 8 sprites per scanline and 64 sprites per screen.

0 - 192 = 0x40
191 - 192 = 0xFF
0 is in the zone, 191 is in the zone, but the bit 7 of the result is different. it does not work.
it is a job for the carry flag

        ld a,(de) ;dx
        add (hl)  ;x
        ld (hl),a
        jr c,destruct

        inc de
        inc hl
        ld a,(de) ;dy
        add (hl)  ;y
        ld (hl),a

        sub 191
        jr c,destruct
Page 1/3
| 2 | 3