Jump to content
Heaven/TQA

sinistar-like nasty movements-quesion

Recommended Posts

as programming Boinxx i want to code some nasties (enemies) which haunt the player... i was always a fan of kind of dynamic approach and would like to ask you 6502 wizards how would you do that... i am thinking of flying objects like in the arcade game Sinistar by Williams...

 

i would use 8.8 fixed point maths for the dynamics but i am not sure if this is too slow... maybe 4.4 is enough.

 

i would need xp,yp [the positions of the nasty on screen]

vx,vy [velocity]

 

what else do we need? accelerationx,y?

 

maybe there are existing models which i could adapt...

Share this post


Link to post
Share on other sites

I'm not sure exactly what you're asking, so if this isn't it then just ignore :)

 

But for the various things I've done with fractional positioning, this has worked well:

 

Have 8.8 variables for position (x and y) and single bytes (integer) for velocity.

 

Then, every frame (on the 2600) I add velocity to the fractional position and, if the fractional position overflows then I increment/decrement the integer position.

 

Here's a code sample, edited for clarity (from the arkanoid clone I'm working on now):

MoveBallSubroutine
 ;--first add velocity to fractional position
  lda BallX_fraction
  clc
  adc BallVelocityX
  sta BallX_fraction
 ;---now, if we overflowed (result is greater than +127 or less than -128)
 ;   then we want to inc/dec integer position
  bvc NoOverflowBallX
 ;--so, we overflowed; therefore increment or decrement integer position
 ;   (which way depends on carry flag)
  bcc MoveBallRight
  dec BallX
 ;--now, reset the fractional position (not always necessary)
 ;   A still holds fractional position from above
  clc
  adc #120
  sta BallX_fraction
  jmp UpdateBallY
MoveBallRight
  inc BallX
 ;--now, reset the fractional position (not always necessary)
 ;   A still holds fractional position from above
  sec
  sbc #120
  sta BallX_fraction
NoOverflowBallX
UpdateBallY
 ;--and similar for Y position and etc.

This is nice because it handles positive/negative velocity (-128 to +127).

 

Main problem with this method is that it isn't possible to change the integer position by more than 1 per frame; so the upper limit of your speed is 1 pixel/frame.

 

To get higher speeds I guess you would have to use fixed point velocity.

 

Other issue with this is that it takes a little work to get positive and negative speeds to be symmetrical, since fractional position will overflow at -128 and +127.

 

I've never stored acceleration; all velocity changes I've ever coded have been event driven.

Share this post


Link to post
Share on other sites

Hi there!

 

Main problem with this method is that it isn't possible to change the integer position by more than 1 per frame; so the upper limit of your speed is 1 pixel/frame.

 

Just call it twice or thrice per frame... ;)

 

Greetings,

Manuel

Share this post


Link to post
Share on other sites

what about this... sorry. haven't read the source from arkanoid but what about this:

 

1 F=8
5 GRAPHICS 15+16
7 COLOR 1
9 DEG 
10 ------------------------------
20 REM ENEMY
30 ------------------------------
40 PX=80
50 PY=96
60 VPX=0
70 VPY=0
80 ------------------------------
90 EX=RAND(159)
100 EY=RAND(191)
110 VEX=1
120 VEY=1
125 DO 
126   COLOR 1
127   IF PX<0 THEN 135
130   TEXT PX,PY,"P"
135   COLOR 2
140   TEXT EX,EY,"E"
150   EXEC CALC
170   I=I+3
171   C=C+3
175   IF I=180 THEN EX=RAND(159):EY=RAND(160):I=0:CLS #6
180   PX=INT(SIN(C)*80+79)
185   PY=INT(COS(C)*80+95)
999 LOOP 
1000 PROC CALC
1010   VEX=PX-EX
1020   VEY=PY-EY
1040   VEX=(VEX/F)
1050   VEY=(VEY/F)
1060   EX=EX+VEX
1070   EY=EY+VEY
1099 ENDPROC 

 

it's written in atari turbo basic xl for rapid testing... and it was written having 6502 in mind... so don't afraid of the divisions as they are just ASLs... and some lookup tables... ignore the sin,cos there... it's just moving the "P" sprite around on the screen while the "E" sprite is trying to catch it. after 180 degrees (half circle) the enemy is position new.

 

PX,PY = player position on screen

VEX,VEY = velocity x,y enemy

EX,EY = position enemy on screen

 

so very straight forward...should be easy to implement... there is only one thing here... the enemy does not have a "boost" to catch the player.... as the player is moving faster than the enemy could... but i'll show you code how this can be handled....

 

now back to the 2600 arkanoid code in detail.

Share this post


Link to post
Share on other sites
what about this... sorry. haven't read the source from arkanoid but what about this:

I haven't posted the source to my 2600 Arkanoid demo, so don't be sorry :)

it's written in atari turbo basic xl for rapid testing... and it was written having 6502 in mind... so don't afraid of the divisions as they are just ASLs... and some lookup tables... ignore the sin,cos there... it's just moving the "P" sprite around on the screen while the "E" sprite is trying to catch it. after 180 degrees (half circle) the enemy is position new.

 

PX,PY = player position on screen

VEX,VEY = velocity x,y enemy

EX,EY = position enemy on screen

 

so very straight forward...should be easy to implement... there is only one thing here... the enemy does not have a "boost" to catch the player.... as the player is moving faster than the enemy could... but i'll show you code how this can be handled....

 

now back to the 2600 arkanoid code in detail.

Nah, don't go back to the arkanoid code unless you want to.

Share this post


Link to post
Share on other sites
1000 PROC CALC
1010   VEX=PX-EX
1020   VEY=PY-EY
1040   VEX=(VEX/F)
1050   VEY=(VEY/F)
1060   EX=EX+VEX
1070   EY=EY+VEY
1099 ENDPROC 

Won't this make velocity dependent on how far apart the two sprites are from each other? Is this intended?

 

EDIT: And the behavior produced by this will be an enemy sprite who always moves towards the player, right? Something a little more interesting might be better - maybe updating the enemy velocity at infrequent intervals would produce more interesting behavior. ?? Or not allowing the enemy to turn sharply would reward evasive action on the part of the player.

Edited by vdub_bobby

Share this post


Link to post
Share on other sites

Here's another possible enemy behavior...in 6502 assembly.

   lda PX
  sec
  sbc EX
  beq EnemyInLineHorizWithPlayer
  bmi EnemyToRightOfPlayer
 ;--else enemy to the left of the player
  lda VEX
  clc
  adc #VELOCITY_CHANGE_CONSTANT
  sta VEX
  bvc DoneChangingVelocity
 ;--if overflow set, then we increased velocity beyond the maximum, so reset to maximum
  lda #127
  sta VEX
  jmp DoneChangingVelocity
EnemyToRightOfPlayer
  lda VEX
  sec
  sbc #VELOCITY_CHANGE_CONSTANT
  sta VEX
  bvc DoneChangingVelocity
 ;--if overflow set, then we decreased velocity below the minimum, so reset to minimum
  lda #-128
  sta VEX	
DoneChangingVelocity
EnemyInLineHorizWithPlayer
 ;---now change Y component of velocity...etc. etc.
 ;---done changing Y velocity, now:
 ;---apply velocity to position
 ;...

The behavior of this enemy would be something similar to the player-controlled ship in Asteroids.

 

This is set up to use code for applying the velocity to the position similar to the arkanoid code I posted above.

Share this post


Link to post
Share on other sites

as this code is only for one type of enemy... this type is trying to catch you... of course the player can move around and the enemy tries to catch you... this formular is very simple 2 improvements might be to do:

 

1st: the enemy is starting fast and slowing down as near as it gets to the player... maybe it must be the otherway around (start slow, move faster like homing missles)

 

2nd: right now the player is not reached when the enemy gets track of the player movement (as its moving not faster when its near...the max is as fast as the player...) i have some formulars to handle this but we will see... i am glad that i have found even this type... :)

 

next will be to implement this into 6502... good exercise as it must use fixed point maths... and some divisions (ASLs or LSR depending on sign/unsign)

 

i have printed out the numbers of VEX,Y and it never gets bigger than 8...so i could use 3.5 maths f.e. as well... but i never used this since 1986... my fixed point math experience was always 8.8 (8 byte integer, 8 byte fractional)... but i think thomas and the rest will help me ;)

Share this post


Link to post
Share on other sites

vdup... have a look at sinistar in MAME or in any Williams arcade classics where the game is...

 

asteroid is not the right one...but maybe you can imagine if the player ship would hunt you while you turn around and move around...then maybe it's more visible what i want to achive. unfortunatly i just can't remember a 2600 game doing that...

 

what about warhawk on atari800 or zone ranger or crazy comets on c64....

Share this post


Link to post
Share on other sites

Ok; sorry, I misunderstood your question. I played some Sinistar and now I understand what you're asking. I'm not sure exactly how to duplicate that flight pattern, but there is a 2600 rom for Sinistar that you could disassemble.

Share this post


Link to post
Share on other sites

just had a look on the 2600 sinistar....

 

definitly NOT this version... as there is no dynamics. the player ship seems to have 3 speeds (no velocity) and the enemies are flying around like in galaga...as well it seems no velocity...

 

i don't know how you are rating this proto...but imho its ugly crap...

Share this post


Link to post
Share on other sites

Okay...using the method I posted above for changing the velocity, you could then adjust the magnitude of the velocity in this way, so that the enemy ships move slower when they get closer to the player ship:

   lda PX
  sec
  sbc EX              ;A holds PX-EX
  jsr GetAbsoluteValue;A holds abs(PX-EX)
  lsr
  lsr
  lsr
  lsr                 ;A holds abs(PX-EX)/16 -- range: 0 - 8
  sta Temp

  lda PY
  sec
  sbc EY
  jsr GetAbsoluteValue
  lsr
  lsr
  lsr
  lsr
  clc
  adc Temp            ;A holds abs(PX-EX)/16 + abs(PY-EY)/16
                      ;--rough distance between player and enemy, 
                      ;--range: 0 to 16
  tax
  lda VelocityAdjusterTable,X
  tay
  beq DoneAdjustingVelocity
  lda VEX
  sta VEX_Adjusted
  lda VEY
  sta VEY_Adjusted
AdjustVelocityLoop
  lsr VEX_Adjusted
  lsr VEY_Adjusted
  dey
  bne AdjustVelocityLoop
DoneAdjustingVelocity

 ;---now apply VEX_Adjusted and VEY_Adjusted to EX and EY


VelocityAdjusterTable
  .byte 6,6,5,5,4,4,3,3,2,2,1,1,0,0,0,0  ;adjust these values until
                                         ;the effect is what you want

This is untested, so it may not work and it may not do what I think it should do, but I think that this, combined with the method I posted above, will give a quick and dirty approximation of the Sinistar enemy flight patterns.

Share this post


Link to post
Share on other sites

This isn't a full solution but just an alternative calc for distance between two objects.

 

x1,y1 - position of one object

x2,y2 - position of other object

 

dx = abs(x1-x2)

dy = abs(y1-y2)

 

dist = max(dx,dy) + 1/4(min(dx,dy))

 

 

The 6502 is just off the top of my head

 

approxDist:
       lda x1
       sec
       sbc x2
       bcs pdx
       eor #255
       adc #1
pdx:   sta dx
       lda y1
       sec
       sbc y2
       bcs pdy
       eor #255
       adc #1
pdy:   sta dy
       cmp dx
       bcs dyg
       lsr
       lsr
       clc
       adc dx
       rts

dyg:   lda dx
       lsr
       lsr
       clc
       adc dy
       rts

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...