Jump to content
IGNORED

Player movement


Recommended Posts

In the code below is it better to use IF STK<>15 THEN POKE (ME),0 or line 62, to remove the player after movement to a new spot? Also side question: how do I edit lines 50 and 55 to incorporate diagonal movement?

5 GR.17
10 I=0:Y=10:SCRI=19:SCRY=23
15 SCREEN=PEEK(88)+256*PEEK(89)
40 ME=SCREEN+I+20*Y:POKE (ME),202
45 STK=PEEK(632):TR=PEEK(644)
50 DI=(STK=7)-(STK=11)
55 DY=(STK=13)-(STK=14)
60 Y=Y+DY:I=I+DI
62 IF DY=1 OR DI=1 OR DI=-1 OR DY=-1 THEN POKE (ME),0
65 IF I>=SCRI THEN I=SCRI
70 IF I<=0 THEN I=0
75 IF Y>=SCRY THEN Y=SCRY
80 IF Y<=2 THEN Y=2
85 REM IF STK<>15 THEN POKE (ME),0
90 IF TR=0 THEN GOSUB 200
100 GOTO 40
200 POS.5,10:? #6;"TRIGGER"
205 RETURN

Thanks

Link to comment
Share on other sites

You might use binary algebra an check for the bits that represent each of the four joystick positions.

 

 

This is a portion of code from one of my turbo basic tenliners:

 

    t=stick(0)
    j=x+(t&8=0)*(x<39)-(t&4=0)*(x>0)
    k=y+(t&2=0)*(y<3)-(t&1=0)*(y>0)

 

It not only accept each 8 joystick directions, it also checks for valid limits at the same time. X and Y are coordinates for current position, J and K are for the new one.

 

You can keep only X and Y variables if you don't need to do something in the old position like remove something from screen memory, and that will save a couple of assignment statements to update current coordinates.

 

 

  • Like 1
Link to comment
Share on other sites

Oh, you are right. Atari BASIC does not have boolean operators, and it could be "painful" to try to obtain that bits using standard algebra.

 

Before I reply, I should notice that you were using PEEK instead of DPEEK to get the screen data memory address. Almost all other BASIC flavors available have DPEEK function.

 

Instead of adding and substracting the other checks for diagonal movements in line 50 and 55 (to get 6 conditions in each expression), you could initialize two 16-elements arrays with the precalculated deltas, and use the STICK(0) as the array index to get the current delta.

 

You could use a single array for screen positions instead of X and Y coordinates and assign, for instance, -21 for the up-left delta, -20 for the up delta, -19 for the up-right, ... and 21 for the down-right. Of course, this method requires to check for wall collisions (using PEEK) instead of to check for the horizontal and vertical limits, because you should need to compute the modulo 20 of the relative screen position to get the horizontal position and avoid a warp around.

 

Link to comment
Share on other sites

This works well for diagonal. I just recently figured it out.

50 DI=(STK=5 OR STK=6 OR STK=7)-(STK=9 OR STK=10 OR STK=11)
55 DY=(STK=5 OR STK=9 OR STK=13)-(STK=6 OR STK=10 OR STK=14)

 

What I am trying to resolve is,  upon release of an arrow key (using Altirra), more often then most the player does not stop at that spot but usually moves one more space in the direction you were travelling. Thus for my game that requires stopping at exact positions, this problem makes it very difficult.

Link to comment
Share on other sites

Atari BASIC is slow, and you should move your player just after you read the joystick position. If you do many calculations and checks after the read and before the actual player movement, the effect will be a considerable lag.

 

In a simple loop like yours (the one in the original post), you read the joystick immediately after you move the player, so you will get an extra lecture of the unreleased joystick because the player (user) will release the stick just after his eyes see the player (game element) in the place of the screen that he wants to be, advancing one step beyond the required one as a result.

 

BTW, when things goes too fast and you must insert a delay, it cannot be put between the joystick lecture and the player redraw. But in Atari BASIC things never goes too fast!!! ?

 

Link to comment
Share on other sites

I forgot to mention that you also check the trigger between the joystick read and the player draw (longer lag). You should read the trigger and also perform some other activities like the logic for enemies and such after the player is drawed and before the joystick is read for the next iteration.

 

I could rewrite your code to get a better response, but that would take away your fun.

 

 

  • Like 1
Link to comment
Share on other sites

if I understand you correctly, is this the right order of the code?

-I moved the play drawn after the joystick is read, from drawing before reading the joystick.

-I placed the trigger after the player is drawn

5 GR.17
10 I=0:Y=10:SCRI=19:SCRY=23
15 SCREEN=PEEK(88)+256*PEEK(89)
40 STK=PEEK(632):TR=PEEK(644)
45 ME=SCREEN+I+20*Y:POKE (ME),202
47 IF TR=0 THEN GOSUB 200
50 DI=(STK=7)-(STK=11)
55 DY=(STK=13)-(STK=14)
60 Y=Y+DY:I=I+DI
62 IF DY=1 OR DI=1 OR DI=-1 OR DY=-1 THEN POKE (ME),0
65 IF I>=SCRI THEN I=SCRI
70 IF I<=0 THEN I=0
75 IF Y>=SCRY THEN Y=SCRY
80 IF Y<=2 THEN Y=2
85 REM IF STK<>15 THEN POKE (ME),0
100 GOTO 40
200 POS.5,10:? #6;"TRIGGER"
205 RETURN

 

Link to comment
Share on other sites

As stated Atari Basic is next to useless for extracting individual bits from a value with any sort of speed.

There's alternatives - the multiple (S=5 OR S=6 OR S=7) method has the disadvantage of being slow also.

 

As I posted elsewhere, since the paddle buttons are the same as moving the stick left/right you can use PTRIG( to get a quick and easy left/right value of 0 or 1.

 

Another method can be to store all the possible STICK( values in an array for X and Y calculations, since there's only 16 combinations it's not too expensive re memory use.

 

Using logic to limit X/Y values can also be handy but of course you need to be careful there if your positions can change by more than 1 per iteration.

Link to comment
Share on other sites

On 6/21/2019 at 11:30 PM, pmgraphics said:

if I understand you correctly, is this the right order of the code?

-I moved the play drawn after the joystick is read, from drawing before reading the joystick.

-I placed the trigger after the player is drawn


5 GR.17
10 I=0:Y=10:SCRI=19:SCRY=23
15 SCREEN=PEEK(88)+256*PEEK(89)
40 STK=PEEK(632):TR=PEEK(644)
45 ME=SCREEN+I+20*Y:POKE (ME),202
47 IF TR=0 THEN GOSUB 200
50 DI=(STK=7)-(STK=11)
55 DY=(STK=13)-(STK=14)
60 Y=Y+DY:I=I+DI
62 IF DY=1 OR DI=1 OR DI=-1 OR DY=-1 THEN POKE (ME),0
65 IF I>=SCRI THEN I=SCRI
70 IF I<=0 THEN I=0
75 IF Y>=SCRY THEN Y=SCRY
80 IF Y<=2 THEN Y=2
85 REM IF STK<>15 THEN POKE (ME),0
100 GOTO 40
200 POS.5,10:? #6;"TRIGGER"
205 RETURN

 

 

No... the joystick must be read just before the player is drawn, but not immediately after, in the sense that other game logic must be between them, and the trigger subroutine is one of those other logic.

 

This is one alternative of re-ordered code:

5 GR.17
10 I=0:Y=10:SCRI=19:SCRY=23
15 SCREEN=PEEK(88)+256*PEEK(89)
17 ME=SCREEN+200:DI=0:DY=1
30 OLDME=ME:ME=SCREEN+I+20*Y
35 IF DI OR DY THEN POKE OLDME,0:POKE ME,202
40 TR=PEEK(644)
47 IF TR=0 THEN GOSUB 200
49 STK=PEEK(632)
50 DI=(STK=7)*(I<SCRI)-(STK=11)*(I>0)
55 DY=(STK=13)*(Y<SCRY)-(STK=14)*(Y>0)
82 Y=Y+DY:I=I+DI
100 GOTO 30
200 POS.5,10:? #6;"TRIGGER"
205 RETURN

I added OLDME variable to store the previous value of ME, just to perform both the remove of the player from the last position and to put it in the new position as close as posible to avoid a blinking effect.

 

Line 17 initializes the player position and forces a delta asignment at start to draw the player in the first loop.

 

I also simplied the check for a movement of the player in line 35, and included the corresponding screen limit restrictions in lines 50 and 55.

 

Anyway, while this code remains simple, without any other game logic, it will be hard to stop at the desired position. You can simulate more processing with the following line between the player's redraw and the joystick read:

48 FOR X=0 TO 99:NEXT X

Finally, I removed the parentheses from the POKE statements, in order to save a bit of time in the expresion calculation.

 

 

  • Like 1
Link to comment
Share on other sites

The revised player movement routine works great. When checking for a collision with another character I put the peek check at line 48, but there was no detection. After moving the peek check to line 32 it then detected the collision. Is this how it works? Other game logic goes prior to joystick read, but checking for collisions with peek needs to be prior to the poke statement?

5 GR.17
10 I=0:Y=10:SCRI=19:SCRY=23
15 SCREEN=PEEK(88)+256*PEEK(89)
17 ME=SCREEN+200:DI=0:DY=1
30 OLDME=ME:ME=SCREEN+I+20*Y
32 IF PEEK(ME)=39 OR PEEK(ME)=52 THEN POS.2,2:?#6;PEEK(ME)
35 IF DI OR DY THEN POKE OLDME,0:POKE ME,202
40 TR=PEEK(644)
47 IF TR=0 THEN GOSUB 200
48 REM IF PEEK(ME)=39 OR PEEK(ME)=52 THEN POS.2,2:?#6;PEEK(ME)
49 STK=PEEK(632)
50 DI=(STK=7)*(I<SCRI)-(STK=11)*(I>0)
55 DY=(STK=13)*(Y<SCRY)-(STK=14)*(Y>0)
82 Y=Y+DY:I=I+DI
100 GOTO 30
200 POS.5,10:? #6;"TRIGGER"
205 RETURN

 

Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

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...