It is currently Wed Mar 21, 2018 5:49 am

 All times are UTC - 7 hours

 Page 1 of 1 [ 7 posts ]
 Print view Previous topic | Next topic
Author Message
 Posted: Mon Jul 10, 2017 3:52 am

Joined: Tue Apr 11, 2006 4:08 am
Posts: 261
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 30 times pict.jpg [ 15.78 KiB | Viewed 899 times ] File comment: code monsterslo.zip [52.33 KiB] Downloaded 34 times
Top

 Posted: Mon Jul 10, 2017 4:30 am

Joined: Mon May 27, 2013 9:40 am
Posts: 423
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

 Posted: Mon Jul 10, 2017 6:47 am

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 6120
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.

Top

 Posted: Mon Jul 10, 2017 6:53 am

Joined: Mon May 27, 2013 9:40 am
Posts: 423
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

 Posted: Mon Jul 10, 2017 12:53 pm

Joined: Tue Apr 11, 2006 4:08 am
Posts: 261
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

Top

 Posted: Wed Jul 12, 2017 10:58 pm

Joined: Tue Feb 07, 2017 2:03 am
Posts: 301
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
sta ENM_MovePosLo
lda ENM_MovePosHi
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

 Posted: Fri Jul 14, 2017 9:56 am

Joined: Wed Sep 21, 2016 8:55 am
Posts: 65
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

 Display posts from previous: All posts1 day7 days2 weeks1 month3 months6 months1 year Sort by AuthorPost timeSubject AscendingDescending
 Page 1 of 1 [ 7 posts ]

 All times are UTC - 7 hours

Who is online

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

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

Search for:
 Jump to:  Select a forum ------------------ NES / Famicom    NESdev    NESemdev    NES Graphics    NES Music    Homebrew Projects       2018 NESdev Competition       2017 NESdev Competition       2016 NESdev Competition       2014 NESdev Competition       2011 NESdev Competition    Newbie Help Center    NES Hardware and Flash Equipment       Reproduction    NESdev International       FCdev       NESdev China       NESdev Middle East Other    General Stuff    Membler Industries    Other Retro Dev       SNESdev       GBDev    Test Forum Site Issues    phpBB Issues    Web Issues    nesdevWiki