How do You Define Sprite Animation?

Are you new to 6502, NES, or even programming in general? Post any of your questions here. Remember - the only dumb question is the question that remains unasked.

Moderator: Moderators

Post Reply
User avatar
Lucradan
Posts: 101
Joined: Wed Sep 21, 2016 12:08 pm

How do You Define Sprite Animation?

Post by Lucradan »

If I want to to define a sprite animation my AMS6 code structure looks like this:

Code: Select all

DAT.Animation.Pacman.Walk:
  .db $08 ; Animation Timer Speed (Number of NMIs before transition)
  .db $03 ; Animation # of Frames
  .dw DAT.Sprite.Pacman.Walk3
  .dw DAT.Sprite.Pacman.Walk2
  .dw DAT.Sprite.Pacman.Walk1
  .dw DAT.Sprite.Pacman.Walk2

DAT.Sprite.Pacman.Walk1:
  .db $04 ; Number of Sprites
  .db $10 ; X Adjustment When Flipped
  .db $F8, $8A, %00000001, $00
  .db $F8, $8B, %00000001, $08
  .db $F0, $9B, %00000001, $00
  .db $F0, $9A, %00000001, $08

DAT.Sprite.Pacman.Walk2:
  .db $04 ; Number of Sprites
  .db $10 ; X Adjustment When Flipped
  .db $F8, $B4, %00000001, $00
  .db $F8, $c4, %00000001, $08
  .db $F0, $B7, %00000001, $00
  .db $F0, $C6, %00000001, $08

DAT.Sprite.Pacman.Walk3:
  .db $04 ; Number of Sprites
  .db $10 ; X Adjustment When Flipped
  .db $F8, $BA, %00000001, $00
  .db $F8, $BB, %00000001, $08
  .db $F0, $BC, %00000001, $00
  .db $F0, $BD, %00000001, $08
The code that manages the player updates is defined here:

Code: Select all

LBL.Draw.Player:

  ; Set the Pointer to the Frame Data
  LDA VAR.Player.Animation.Frame
  ASL
  TAY
  INY
  INY
  LDA (VAR.Player.Animation.Data),Y
  STA VAR.TEMP
  INY
  LDA (VAR.Player.Animation.Data),Y
  STA VAR.TEMP+1

  ; Set the Tile Byte Counter
  LDY #$00
  LDA (VAR.TEMP),Y
  ASL
  ASL
  TAY
  INY
  INY
  STY VAR.TEMP+2

  ; Set the Horizontal Flipping Offset
  LDY #$01
  LDA (VAR.TEMP),Y
  STA VAR.TEMP+3

  LDY #$02
  LDX #$00

LBL.Draw.Player.Loop:

    ; Copy Vertical Position Data
    LDA (VAR.TEMP),Y
    CLC
    ADC VAR.Player.Y
    STA BUF.Sprites,X

    ; Copy Tile
    INY 
    INX
    LDA (VAR.TEMP),Y
    STA BUF.Sprites,X

    ; Copy Tile Attributes
    INY
    INX
    LDA (VAR.TEMP),Y
    STA BUF.Sprites,X

    ; Check if Horizontally Flipped
    LDA VAR.Player.VX.Dir
    BEQ LBL.Draw.Player.SetX
      LDA (VAR.TEMP),Y
      EOR #%01000000
      STA BUF.Sprites,X

    ; Copy Horizontal Position Data
LBL.Draw.Player.SetX:
    INY
    INX
    LDA (VAR.TEMP),Y
    CLC
    ADC VAR.Player.X
    STA BUF.Sprites,X

    ; Check if Flipped
    LDA VAR.Player.VX.Dir
    BEQ LBL.Draw.Player.Loop.Continue
       LDA VAR.Player.X
       SEC 
       SBC (VAR.TEMP),Y
       SEC
       SBC #$08
       CLC
       ADC VAR.TEMP+3
       STA BUF.Sprites,X

LBL.Draw.Player.Loop.Continue:
    INY
    INX
    CPY VAR.TEMP+2
    BNE LBL.Draw.Player.Loop
 
  LDA TRUE
  STA FLAG.UpdateSprites
          
RTS
This works well for most cases, except when I get need to do the following

1. I need to indicate where in the sprite buffer the sprite attributes need to go (since the player can go "behind" other sprites)
2. Indicate where the tile date should be put in CHR-RAM (tile index) when it's loaded.

How do you handle this?
User avatar
Sumez
Posts: 919
Joined: Thu Sep 15, 2016 6:29 am
Location: Denmark (PAL)

Re: How do You Define Sprite Animation?

Post by Sumez »

Unless you hardcode specific positions in the sprite buffer (which is horribly ineffecient when you want to make full use of all 64 hardware sprites, but a lot of old games actually did that), I'd say it's all in the order you decide to write to your buffer.

What I have done previously is two separate solutions:

1. Make a separate "draw" routine at the end of my main loop which reads object information in the order I want to send them to the sprite buffer. Basically, the items I write first get the highest priority. So if a sprite needs to be in front, I'll make a special routine to handle those objects first, and then maybe the player character followed by data from a generic object table, etc., proceeding until no objects are left, or my "X" register (used to index the position in the sprite buffer, same as you do) rolls over.

2. Keep my X index saved to a variable in memory that I dig out whenever I want to draw a sprite during my object update routines. This is less neat to look at, but gives you more freedom to draw different items in different ways. However you'd still have to consider the order you draw them in, if you want to give some of them higher priority.

The biggest issue is of course if you want to have some kind of sprite cycling method to keep your sprites blinking instead of disappearing if you expect to go over 8 on the same scanline. This makes it difficult to always give some objects higher priority, so if that's important to you I'd say it's a good idea to keep a seperate "draw" routine which always draws the high priority sprites first, and then loops through the remaining object in a ways that differs on each frame.
User avatar
rainwarrior
Posts: 8731
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How do You Define Sprite Animation?

Post by rainwarrior »

Yeah, make your sprite drawing routines concatenate to the end of the sprite list, and then it's just a matter of calling the draws in order of priority.

If you have something that does that already, it's not too hard to then randomize or otherwise vary the order to get sprite flickering. (e.g. you could call the draws in reverse order every second frame)
User avatar
Lucradan
Posts: 101
Joined: Wed Sep 21, 2016 12:08 pm

Re: How do You Define Sprite Animation?

Post by Lucradan »

Thanks Everyone! I hadn't though about doing it that way, makes it much easier.
Post Reply