# Move sprite to X,Y (as LINE) in assembly

Página 2/4
1 | | 3 | 4

yes, I've seen it on the wikipedia page:
But I found a source from the internet a game to 8 tanks (Visual BASIC)

It is not easy to convert to BASIC, but they are quiet.
The calculation is just what I wanted, is not other sources (. ASM) for GAMEBOY, SPECTRUM, COLECO. but the end of the search.

Greetings.
DanySoft

The convertitura from VB to MSX went well ...
only a part of the source is useful for the rotation and the direction of movement is just what I wanted!

Now I put the variables DIM and buttons to change the values ​​of the direction.

Are three types of directions:
8 directions (standard)
16 directions (with my angle.bas to change all 16 directions)
32 directions (as above but adds another 16 directions)

But:
36 directions are one of the game of VB, the original, but the values ​​are not correct, so I keep it for fututro.

Now I also have the DIVIDE function in ASM to calculate and use as a utility for my project.

IN BASIC you can use to change the values​​.
greetings
DanySoft

Hey, this list of BASIC is "correct" to make new direction of move on LINE ?
Is use CALL KANJI (MSX2+) for text graphics to view as debug mode.

```5 REM save "angle.bas
10 DEFINTA-H:SCREEN 5:CALL KANJI
20 DIM I(36),J(36)
30 J(1)=20:I(1)=0
40 J(2)=20:I(2)=100
50 J(3)=25:I(3)=60
60 J(4)=29:I(4)=35
70 X=100:Y=100:N=1:P1=1:P2=0
75 COPY "angle.dat" TO (0,0),3
80 SET PAGE P2,P1:CALL CLS:COPY (0,0)-(60,60),3 TO (100-30,100-30),P1
90 LINE (100,100)-(X,Y),15
100 I\$=INKEY\$
110 IF I\$=CHR\$(28) THEN Q=1:D=D+1:IF D=>5 THEN D=1
120 IF I\$=CHR\$(29) THEN Q=1:D=D-1:IF D=<0 THEN D=4
130 IF I\$=CHR\$(30) THEN N=N+1 AND N<50
140 IF I\$=CHR\$(31) THEN N=N-1 AND N>2
150 IF I\$=CHR\$(27) THEN Q=1:GOTO 80
160 IF I\$="w" OR I\$="W" THEN I(D)=I(D)+N AND I(D)<100
161 IF I\$="q" OR I\$="Q" THEN I(D)=I(D)-N AND I(D)>2
170 IF I\$="p" OR I\$="P" THEN J(D)=J(D)+N AND J(D)<110
171 IF I\$="l" OR I\$="L" THEN J(D)=J(D)-N AND J(D)>59
190 IF I(D)=<0 THEN I(D)=1
200 IF I(D)=>255 THEN I(D)=255
210 IF J(D)=<0 THEN J(D)=1
220 IF J(D)=>192 THEN J(D)=192
230 IF D=1 THEN Y=Y-V/J(D)
240 IF D=2 THEN Y=Y-V/J(D):X=X+V/I(D)
250 IF D=3 THEN Y=Y-V/J(D):X=X+V/I(D)
260 IF D=4 THEN Y=Y-V/J(D):X=X+V/I(D)
270 IF D=5 THEN Y=Y-V/J(D):X=X+V/I(D)
280 V=V+2:IF V=>101 THEN V=0
290 IF INT(X)=<50 THEN X=50
300 IF INT(X)=>180 THEN X=180
310 IF INT(Y)=<50 THEN Y=50
320 IF INT(Y)=>180 THEN Y=180
330 IF Q=1 THEN Q=0:X=100:Y=100
340 GET TIMEA\$
350 LOCATE 0,0:PRINTN;"";D;"Q/W";I(D);"L/P";J(D)
360 LOCATE 0,1:PRINTA\$;"[";X;"] [";Y;"]",INT(X);INT(Y)
365 SWAP P1,P2:REM SET PAGE P1,P2
370 GOTO 80
```

But the D=2 is not correct : move X to RIGHT and not lock the LINE !

This part :

```230 IF D=1 THEN Y=Y-V/J(D)
240 IF D=2 THEN Y=Y-V/J(D):X=X+V/I(D)
250 IF D=3 THEN Y=Y-V/J(D):X=X+V/I(D)
260 IF D=4 THEN Y=Y-V/J(D):X=X+V/I(D)
270 IF D=5 THEN Y=Y-V/J(D):X=X+V/I(D)
```

It used this block from sources of Visual BASIC, (original is 36 direction), the number of bytes is equal on UP, UP/LEFT, UP/LEFT2, UP/LEFT3,...
Why do not you help me to solve this problem?

DanySoft

I don't understand perfectly what you want to do in this program yet.
However....

```225 IF S=1 THEN 280
290 IF INT(X)=<50 THEN X=50:S=1
300 IF INT(X)=>180 THEN X=180:S=1
310 IF INT(Y)=<50 THEN Y=50:S=1
320 IF INT(Y)=>180 THEN Y=180:S=1
330 IF Q=1 THEN Q=0:X=100:Y=100:S=0```

is the better?
Or,

```225 IF X=<50 OR X=>180 OR Y=<50 OR Y=>180 THEN Q=1
```

?

people learn how to program in basic!

x%=25.25
print x%

the % makes x an int by definition.

okey, okey, okey:

but see this example found :

```10 SCREEN 5:GOTO 50
20 X=COS(T/180*3.14)*Z
30 Y=SIN(T/180*3.14)*Z
40 RETURN
50 Z=1:T=90+90+90+21
60 GOSUB 20:PSET(100+X,100+Y)
65 Z=Z+1:FORA=0TO60:NEXTA
70 GOTO 60
```

I put the value 291° (90+90+90+21) and I started the missile!

Thanks to the site: Unit Circle

See the example under "Try It!", Move the blue dot of the circle, gives a value to the COS, SIN, and TAN!

The information from that site with graphics are also very important for those who are not proficient in math.

Thank you.
DanySoft

I think you're approaching this all wrong really. I think you should use an x and y offset per step. This way you can build in gravity and direction. If you want to make it more fun ad in wind-speed too I know Konami does it this way (minus the wind speed calculations)

DanySoft wrote:

okey, okey, okey:

but see this example found :

```10 SCREEN 5:GOTO 50
20 X=COS(T/180*3.14)*Z
30 Y=SIN(T/180*3.14)*Z
40 RETURN
50 Z=1:T=90+90+90+21
60 GOSUB 20:PSET(100+X,100+Y)
65 Z=Z+1:FORA=0TO60:NEXTA
70 GOTO 60
```

I put the value 291° (90+90+90+21) and I started the missile!

Thanks to the site: Unit Circle

See the example under "Try It!", Move the blue dot of the circle, gives a value to the COS, SIN, and TAN!

The information from that site with graphics are also very important for those who are not proficient in math.

Thank you.
DanySoft

COS SIN TAN etc. ARE HEAVY as hell in basic and in ASM, unless you use precalculated tables.

you can't use it.

if you wan a linear trayectory you do:

On the shot:

```Xdistance = ShoterX - TargetX
Ydistance = ShoterY - TargetY
if abs(xdistance) < abs(ydistance) then yStep = 1*sgn(ydistance):XStep = xdistance / abs(ydistance) else xStep = 1*sgn(xdistance):yStep = ydistance / abs(xdistance)
```

THIS CALCULATION es ONLY ONE TIME.

then in each frame you do for the movement. SpeedFactor can be something like = 1 (pixel by pixel movement), or bigger if the draw of the sprite is 4x4 by example you can set a Speed of = 4.

```BulletSpriteX = BulletSpriteX - xStep * SpeedFactor
BulletSpriteY = BulletSpriteY - yStep * SpeedFactor
```

Then in every frame you needs to test if the bullet reached the borders of the screen gameplay.

```if BulletSpriteX < -3 or BulletSpriteY < -3 or BulletSpriteX > 255 or BulletSpriteY > 211 then ' Its out, remove the bullet.
```

And test with ON SPRITE GOSUB for the colission with the target.

EASY!, In assembler you shifts the calculations by an factor of 256 or 512, allowing to use plain integers instead of floats. Then when adding to the sprite current position you shifts back by 256 or 512 the value .

For like a missile guided trayectory you use the same linear model, but improved

Why to go to the BASICS in calculation? Because it is faster, ofcourse is nice the have object and in memory to handle angles, but that sucks in speed and more for a 3.57mhz computer.

So you do the basic in math, is SUM, take aways, divisions and multiplications, nothing more than that. And when less divisions & multiplications, better.

So as if you do it in BASIC or in ASM, to SAVE any value as result of a formula that can be reuse, is better.

Let's see the missile guided approach

On the shot do:

```Xdistance = ShoterX - TargetX
Ydistance = ShoterY - TargetY
if abs(xdistance) < abs(ydistance) then yStep = 1*sgn(ydistance):XStep = xdistance / abs(ydistance) else xStep = 1*sgn(xdistance):yStep = ydistance / abs(xdistance)
```

THIS CALCULATION es ONLY ONE TIME.

then in each frame you do for the movement. SpeedFactor can be something like = 1 (pixel by pixel movement), or bigger if the draw of the sprite is 4x4 by example you can set a Speed of = 4.

```BulletSpriteX = BulletSpriteX - xStep * SpeedFactor
BulletSpriteY = BulletSpriteY - yStep * SpeedFactor
```

Then in every frame you needs to test if the bullet reached the borders of the screen gameplay.

```if BulletSpriteX < -3 or BulletSpriteY < -3 or BulletSpriteX > 255 or BulletSpriteY > 211 then ' Its out, remove the bullet.
```

And test with ON SPRITE GOSUB for the colission with the target.

NOW the added

On each few frames (a planned LAG like emulating a real guided missile) you recalculate the xStep & yStep as the following way.

```Xdistance = ShoterX - TargetX
Ydistance = ShoterY - TargetY
if abs(xdistance) < abs(ydistance) then yStep2 = 1*sgn(ydistance):XStep2 = xdistance / abs(ydistance) else xStep2 = 1*sgn(xdistance):yStep2 = ydistance / abs(xdistance)

' At this point xstep, ystep, xstep2, ystep2 are in the same range from -1 to 1 indication the direction.

InertialForceFactor = 2
Xstep = xstep + (xstep2-xstep) / InertialForceFactor
ystep = ystep + (ystep2-ystep) / InertialForceFactor
```

The inertialforcefactor depends on each how many few frame you do the recalcutation of the direction, if you recalculate like each 4 frames, the inertial factor can be 2 , but if you recalculate faster like each 2 frames, the inertial factor needs to be higher like 4, so it is a matter of LAG in recalculating new direction vs the percentage applied of that new recalculation on the current direction.

EASY!, In assembler you shifts the calculations by an factor of 256 or 512, allowing to use plain integers instead of floats. Then when adding to the sprite current position you shifts back by 256 or 512 the value .

Tip: I think you should take a look at the [url=http://en.wikipedia.org/wiki/Bresenham's_line_algorithm]Bresenham's line algorithm[/url].

Página 2/4
1 | | 3 | 4