It is currently Fri Oct 20, 2017 9:26 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Mon Jul 10, 2017 3:52 am 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 238
The object moves in a loop from point A to point B and returns. I would like to slow down the movement of the object so that it smoothly slows down the movement at each approach to these points. I tried to do two times slow motion, which will start 8pixels before those points. Ideally, if the slowdown in the direction change was more fluid (like normal speed->slow 2x->slow 4x->reverse movement->slow4x->slow2x->normal speed.


Attachments:
demo.nes [40.02 KiB]
Downloaded 19 times
pict.jpg
pict.jpg [ 15.78 KiB | Viewed 577 times ]
File comment: code
monsterslo.zip [52.33 KiB]
Downloaded 21 times
Top
 Profile  
 
PostPosted: Mon Jul 10, 2017 4:30 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 351
I'd use fixed point math with velocity and acceleration (linear movement equations). I'd calculate the distance to the limit where I have to begin applying deceleration. Then, if suitable, I'd make a LUT with the results.

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Mon Jul 10, 2017 6:47 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5724
Location: Canada
As an alternative to using 16-bit velocity, you could take a random number (0-255) each frame, and compare it against some sort speed throttle value to decide whether or not to move this frame, i.e. "if rand() >= 128" will move at 50% speed, "if rand() >= 64" at 75% speed, etc.

This thread might be of interest, talks about similar ideas: http://forums.nesdev.com/viewtopic.php?f=2&t=12831


Top
 Profile  
 
PostPosted: Mon Jul 10, 2017 6:53 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 351
You don't need 16 bits if the distance for the slowdown is always the same (if I've understood correctly). You can use fp during the calculations, then output a lut with integer pixel increments per frame.

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Mon Jul 10, 2017 12:53 pm 
Offline

Joined: Tue Apr 11, 2006 4:08 am
Posts: 238
I managed to do it the way I wanted it, ie releasing 8pix before points A and B. But the code does not look too good, especially as far as optimizations are concerned, I will be grateful for the improvement of the code.

Code:
ENM_loop:

   LDA ENM_Slow         ;EOR changes the value of one bit per frame
   EOR #%00000001
   STA ENM_Slow

   lda ENM_S
   and #%00000100
   bne ENM_loop_Left      ;Czy bit kierunku jest ustawiony? Skocz, jeśli tak.

   lda ENM_MovePos
   cmp ENM_INC
   beq ENM_loop_chngDir      ;When the max INC is reached, change the direction

   LDA ENM_X
   CMP ENM_SlowDEC
   BCC ENM_Loop_INCslo

   LDA ENM_MovePos
   CMP ENM_SlowINC
   BCC ENM_Loop_INCnoSlo      ;When it will be 8pix before MAX INC. Do not make a branch

ENM_Loop_INCslo:

   LDA ENM_Slow         ;Now it is 8pix or less since max INC - now slow down the movement
   CMP #1
   BNE ENM_Loop_SkipINCFrame

ENM_Loop_INCnoSlo:

   INC ENM_MovePos

ENM_Loop_SkipINCFrame:

   RTS
 
ENM_loop_Left:

   lda ENM_MovePos
   cmp ENM_DEC
   beq ENM_loop_chngDir      ;When the max DEC is reached, change the direction

   LDA ENM_X
   CMP ENM_SlowINC
   BCS ENM_Loop_DECslo

   LDA ENM_MovePos
   CMP ENM_SlowDEC
   BCS ENM_Loop_DECnoSlo      ;When it will be 8pix before MAX DEC. Do not make a branch

ENM_Loop_DECslo:

   LDA ENM_Slow         ;Now it is 8pix or less since max DEC - now slow down the movement
   CMP #1
   BNE ENM_Loop_SkipDECFrame

ENM_Loop_DECnoSlo:

   DEC ENM_MovePos

ENM_Loop_SkipDECFrame:
 
   RTS

ENM_loop_chngDir:         ;CHANGE DIRECTION

   JSR SND1
   lda ENM_S
   EOR #%01000100
   sta ENM_S

ENM_loop_end:

   RTS


I mainly mean that the ENM_INC and ENM_DEC variables can be changed to any value, and the slowdown itself will be executed (without further changes in the ENM_Loop)


EDIT:
I made a slow down consisting of two parts (1x-> 2x-> 4x reverse direction 4x, 2x, 1x)


The code does not look beautiful, but it works. Unfortunately it is quite curly and has a large size ...

Code:
ENM_Slowmo:

   LDA ENM_Slow
   EOR #%00000001
   STA ENM_Slow

   LDA ENM_Slow
   CMP #1
   BNE ENM_Slowmo_Skip

   LDA ENM_Slow2
   EOR #%00000001
   STA ENM_Slow2

ENM_Slowmo_Skip:

   RTS

;------------------------------------

ENM_loop:

   JSR ENM_Slowmo

   lda ENM_S
   and #%00000100
   bne ENM_loop_Left      ;Czy bit kierunku jest ustawiony? Skocz, jeśli tak.

   lda ENM_MovePos
   cmp ENM_INC
   beq ENM_loop_chngDir      ;When the max INC is reached, change the direction

   LDA ENM_X
   CMP ENM_SlowDEC
   BCC ENM_Loop_INCslo

   LDA ENM_MovePos
   CMP ENM_SlowINC
   BCC ENM_Loop_INCnoSlo      ;When it will be 8pix before MAX INC. Do not make a branch

ENM_Loop_INCslo:

   LDA ENM_Slow         ;Now it is 8pix or less since max INC - now slow down the movement
   CMP #1
   BNE ENM_Loop_SkipINCFrame

ENM_Loop_INCnoSlo:

   LDA ENM_MovePos
   CMP ENM_Slow2DEC
   BCC ENM_Loop_INCSlo2

   LDA ENM_MovePos
   CMP ENM_Slow2INC
   BCC ENM_Loop_INCnoSlo2

ENM_Loop_INCSlo2:

   LDA ENM_Slow2
   CMP #1
   BNE ENM_Loop_SkipINCFrame

ENM_Loop_INCnoSlo2:

   INC ENM_MovePos

ENM_Loop_SkipINCFrame:

   RTS
 
ENM_loop_Left:

   lda ENM_MovePos
   cmp ENM_DEC
   beq ENM_loop_chngDir      ;When the max DEC is reached, change the direction

   LDA ENM_X
   CMP ENM_SlowINC
   BCS ENM_Loop_DECslo

   LDA ENM_MovePos
   CMP ENM_SlowDEC
   BCS ENM_Loop_DECnoSlo      ;When it will be 8pix before MAX DEC. Do not make a branch

ENM_Loop_DECslo:

   LDA ENM_Slow         ;Now it is 8pix or less since max DEC - now slow down the movement
   CMP #1
   BNE ENM_Loop_SkipDECFrame

ENM_Loop_DECnoSlo:

   LDA ENM_MovePos
   CMP ENM_Slow2INC
   BCS ENM_Loop_DECSlo2

   LDA ENM_MovePos
   CMP ENM_Slow2DEC
   BCS ENM_Loop_DECnoSlo2

ENM_Loop_DECSlo2:

   LDA ENM_Slow2
   CMP #1
   BNE ENM_Loop_SkipDECFrame

ENM_Loop_DECnoSlo2:

   DEC ENM_MovePos

ENM_Loop_SkipDECFrame:
 
   RTS

ENM_loop_chngDir:         ;CHANGE DIRECTION

   JSR SND1
   lda ENM_S
   EOR #%01000100
   sta ENM_S

ENM_loop_end:

   RTS


Attachments:
demo4.nes [40.02 KiB]
Downloaded 16 times
monsterslo4.zip [51.85 KiB]
Downloaded 14 times
demo2.nes [40.02 KiB]
Downloaded 18 times
Top
 Profile  
 
PostPosted: Wed Jul 12, 2017 10:58 pm 
Offline

Joined: Tue Feb 07, 2017 2:03 am
Posts: 248
While not really the right thing to do.. you can do something like this
Code:
 bit Direction
        bmi Backwards
;Forward
        lda ENM_MovePosHi
        sec
        sbc ENM_EndPos
        lsr a
        lsr a
        cmp #3
        bcc safeF
        lda #2
safeF   
        tax
        lda ENM_MovePosLo
        clc
        adc SpeedTableFLo,x
        sta ENM_MovePosLo
        lda ENM_MovePosHi
        adc SpeedTableFHi,x
        cmp ENM_EndPos
        bcc safeF2
        lda #80
        sta Direction
        lda #0
        sta ENM_MovePosLo
        lda ENM_EndPos
safeF2
        sta ENM_MovePosHi
        rts
       
Backwards
        lda ENM_StartPos
        sec
        sbc ENM_MovePosHi
        lsr a
        lsr a
        cmp #3
        bcc safeB
        lda #2
safeB   
        tax
        lda ENM_MovePosLo
        sec
        sbc SpeedTableFLo ,x
        sta ENM_MovePosLo
        lda ENM_MovePosHi
        sbc SpeedTableFHi,x
        cmp ENM_StartPos
        bcc safeB2
        lda #0
        sta Direction
        sta ENM_MovePosLo
        lda ENM_StartPos
safeB2
        sta ENM_MovePosHi
        rts
       
SpeedTableFLo .db $40,$80,$00
SpeedTableFHi .db $00,$00,$10


Note this is off the top of my head and might have bugs ;)

The idea is you do
EndPos - Pos
Which gives you the number of pixels until the end. Now you want to have 0-3 1 speed, 4-7 another 8+ another, so what I do is a shift right 2 times so
1000 -> 0010 8 = 2
0111 -> 0001 7 = 1
0100 -> 0001 4 = 1
0011 -> 0000 3 = 0
0001 -> 0000 1 = 0
so if the number after shift it higher than 2 I set the index to 2.
Then I use 16 bits maths to add the pixels. This is basically 8.8 fixedpoint, you set sprites based upon the Hi value.
$100 = 1
$080 = 0.5
$040 = 0.25

as in
040 +
040
----
080

080 +
040
----
0C0

0C0 +
040
----
100

so basically you use it to get the 1x,0.5,0.25 speeds but you might want to scale them up so the enemy moves at 2px a frame for example, then 1, then .5 or whatever.

It then checks to see if it has gone over or hit the target, then it snaps to the target and flips the direction. Note I use $80, $00 so I can use BIT instruction to do the test, as BIT will pull bit 7 into the N flag, an LDA will also do the same

Backwards is the same thing, just now you do Pos-Start and then subtract the speeds to go the other way.


Top
 Profile  
 
PostPosted: Fri Jul 14, 2017 9:56 am 
Offline
User avatar

Joined: Wed Sep 21, 2016 8:55 am
Posts: 54
Location: Calgary.Alberta,Canada
How about using tables for you enemy object movement logic,I'm using the stack but you can use temp variables to save the values(NmeXVelocity,NmeYVelocity,NmeMovementPatternTimer) also the tables are integer values(you can add fixed point values like Oziphantom showed you) if you can't understand or have trouble implementing my example private message me and we can modify code that suits your game needs.Best of luck which ever way you decide."Off topic" sdm you have unconventional ways of solving problems and you manage to solve them each time,it's neat to see. :)



Code:
;-------------------------------------------------------
Do_BuildNmeLogicPointer:
  ldy #NmeObjLogicOffset
  lda (_NMEArray),Y
  sta _NmeLogicPointer+0
  iny
  lda (_NMEArray),Y
  sta _NmeLogicPointer+1
  rts
;-------------------------------------------------------
Do_NMEMovementTimers:
  sec
  sbc #1
  sta (_NMEArray),y
  rts
;-------------------------------------------------------
Do_BuildNMEMovementPattern:
  ldy #NmeMovementPatternTimerOffset
  lda (_NMEArray),Y
  bne Do_NMEMovementTimers
  jsr Do_BuildNmeLogicPointer
  ldy #MovementPatternTableOffset
  lda (_NMEArray),Y
  tay
  lda (_NmeLogicPointer),Y
  iny
  pha                                                        ;Push NmeXVelocity to stack
  lda (_NmeLogicPointer),Y
  pha                                                        ;Push NmeYVelocity to stack
  iny
  lda (_NmeLogicPointer),Y
  bpl +                                   
  and #%01111111                                     
  ldy #$FF
+: 
  iny
  pha                                                         ;Push NmeMovementPatternTimer to stack
  tya
  ldy #NMEMovementPatternTableOffset             
  sta (_NMEArray),Y                   
  pla                                                          ;Pull NmeMovementPatternTimer from stack
  ldy #NmeMovementPatternTimerOffset         
  sta (_NMEArray),Y                                            ;Save NmeMovementPatternTimer in EnemyArray
  pla                                                          ;Pull NmeYVelocity from stack
  ldy #NmeYVelocityOffset
  sta (_NMEArray),Y                                            ;Save NmeYVelocity in EnemyArray
  pla                                                          ;Pull NmeXVelocity from stack
  ldy #NmeXVelocityOffset
  sta (_NMEArray),Y                                            ;Save NmeXVelocity in EnemyArray
  rts

;==================================================
;Data Format
;Byte 0 = NmeXVelocity
;Byte 1 = NmeYVelocity
;Byte 2 = NmeMovementPatternTimer
;==================================================
Enemy1PatternLogicTable:
.db $FE,$02,$05 
.db $FE,$02,$05   
.db $FE,$FE,$05 
.db $FE,$FE,$85 
;-------------------------------------------------------
NME2PatternLogicTable:
.db $FE,$00,$0A 
.db $FE,$03,$0A 
.db $FE,$05,$0A 
.db $FE,$09,$0A 
.db $FE,$05,$0A 
.db $FE,$03,$0A 
.db $FE,$00,$0A 
.db $FE,$FD,$0A 
.db $FE,$FB,$0A 
.db $FE,$F7,$0A 
.db $FE,$FB,$0A 
.db $FE,$FD,$8A


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: Google [Bot] and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group