# How to get one char to chase another?

## Recommended Posts

Some of you may laugh at my demise, but I simply have no clue how to get a character to chase another in Ext . Basic

I'm attempting to write another game, "Texas Oil" .... you've to collect oil whilst avoiding JR Ewing

JR has to chase you .... but how .... what are the best routines to get JR to follow my character around?

(these are chars and not sprites)

##### Share on other sites

Dang deleted the original program can not show it.

Edited by RXB

##### Share on other sites
Some of you may laugh at my demise,

Uh, you're dying?

##### Share on other sites

Do you mean something like this?

X1=X1+SGN(X2-X1)

Y1=Y1+SGN(Y2-Y1)

Where (X1,Y1) are the coordinates of JR and (X2,Y2) are your coordinates.

##### Share on other sites

Let's consider only x-direction. You're at 16, JR's at 10.

JR calculates the difference/distance. "You minus JR" = 16 - 10 = 6.

Let's look at the Signum function.

Format: SGN(numeric-expression).

Description: Returns 1 if positive, 0 if zero and -1 if negative expression.

SGN(6) = 1.

Direct JR to move 1 in the x-direction. JR moves from 10 to 11, hence getting closer.

You're at 10, JR’s at 16. Observe this is the other way around.

Again "You minus JR" = 10 - 16 = -6.

SGN(-6) = -1.

Direct JR to move -1 in the x-direction. JR moves from 16 to 15, getting closer.

You're at 6, JR's at 6.

You minus JR = 6 - 6 = 0.

SGN(0) = 0.

Direct JR to move 0 in the x-direction.

If both calculated movement in x- and y-direction are zero, then you're obviously caught. You might catch this condition prior, but anyway.

##### Share on other sites

Uh, you're dying?

predicament or problem would have been a better word, perhaps.

No. I'm not sat at my desk running a TI emulator whilst dying. I probably WILL die doing this, but not today. I hope not anyway.

##### Share on other sites

Thanks guys,

I'll get busy very soon with the SGN command .... Should have something to show within a couple of days

##### Share on other sites

Here you go. Use ESDX to move the man. JR will follow him, always taking the shortest path. To make things more interesting, I have done it such that JR moves at half the speed of the man. I use a simple toggle to do this. See line 120.

Shout out if anything is un-clear. Though, it's been years since I did XB

```10 CALL CLEAR
20 MAN=42 :: JR=35 ! man and JR ascii characters
30 MX=5 :: MY=5 ! man coordinates
40 JX=30 :: JY=22 ! jr coordinates
50 TOG=1		 ! toggle. JR will move when tog=1
60 CALL HCHAR(MY,MX,MAN):: CALL HCHAR(JY,JX,JR)
70 CALL KEY(0,K,S)
80 IF K=83 THEN CALL LEFT(MY,MX,MAN)
90 IF K=68 THEN CALL RIGHT(MY,MX,MAN)
100 IF K=69 THEN CALL UP(MY,MX,MAN)
110 IF K=88 THEN CALL DOWN(MY,MX,MAN)
120 TOG=-TOG :: IF TOG=1 THEN CALL JR(JY,JX,MY,MX,JR)
130 GOTO 70
140 SUB LEFT(Y,X,C)
150 CALL HCHAR(Y,X,32)
160 IF X>1 THEN X=X-1
170 CALL HCHAR(Y,X,C)
180 SUBEND
190 SUB RIGHT(Y,X,C)
200 CALL HCHAR(Y,X,32)
210 IF X<32 THEN X=X+1
220 CALL HCHAR(Y,X,C)
230 SUBEND
240 SUB UP(Y,X,C)
250 CALL HCHAR(Y,X,32)
260 IF Y>1 THEN Y=Y-1
270 CALL HCHAR(Y,X,C)
280 SUBEND
290 SUB DOWN(Y,X,C)
300 CALL HCHAR(Y,X,32)
310 IF Y<24 THEN Y=Y+1
320 CALL HCHAR(Y,X,C)
330 SUBEND
340 SUB JR(JY,JX,MY,MX,C)
350 CALL HCHAR(JY,JX,32)
360 JX=JX+SGN(MX-JX)
370 JY=JY+SGN(MY-JY)
380 CALL HCHAR(JY,JX,C)
390 SUBEND
```

I've written it to be easy to understand (I hope!) rather than fast/efficient.

##### Share on other sites

Ok ... just ran the program and JR seems to be asleep or he cant move

Thanks for the source code though mate that's gonna come in handy

Scratch that --- my fault !

Tog=-Tog

I wrote something else.

I'm writing the code in manually, no copy/paste with Linux+wine+Classic.

I've just corrected myself and run it again, it works brilliantly, thanks willsy for that

Edited by Retrospect

##### Share on other sites

Much shorter version (faster) without SUBs:

```10 CALL CLEAR
20 MAN=42 :: JR=35 ! man and JR ascii characters
30 MX=5 :: MY=5 ! man coordinates
40 JX=30 :: JY=22 ! jr coordinates
50 TOG=1 ! toggle. JR will move when tog=1
60 CALL HCHAR(MY,MX,MAN) :: CALL HCHAR(JY,JX,JR)
70 CALL KEY(0,K,S)
80 IF K=83 THEN GOSUB 170 :: IF MX>1 THEN MX=MX-1
90 IF K=68 THEN GOSUB 170 :: IF MX<32 THEN MX=MX+1
100 IF K=69 THEN GOSUB 170 :: IF MY>1 THEN MY=MY-1
110 IF K=88 THEN GOSUB 170 :: IF MY<24 THEN MY=MY+1
120 TOG=-TOG :: IF TOG=1 THEN 60
130 ! MOVE JR
140 CALL HCHAR(JY,JX,32)
150 JX=JX+SGN(MX-JX) :: JY=JY+SGN(MY-JY)
160 GOTO 60
170 CALL HCHAR(MY,MX,32) :: RETURN
```

Edited by Willsy

##### Share on other sites

I'm also thinking of having objects that both myself and JR have to walk around, that may slow JR down in his tracks a little, the occasional wall here and there

This is achieved by the brilliant CALL GCHAR command I believe ....

I'm having fun with the TI again at the moment, and having to enter the code in manually to the emulator takes me back to the old days.

I managed to reset it earlier by accident. I've never been so dis-pleased to hear the BEEP

##### Share on other sites

Try this. JR stops when he hits the wall :-)

```10 CALL CLEAR
15 CALL VCHAR(4,16,ASC("\$"),16)
20 MAN=42 :: JR=35 ! man and JR ascii characters
30 MX=5 :: MY=5 ! man coordinates
40 JX=30 :: JY=22 ! jr coordinates
50 TOG=1 ! toggle. JR will move when tog=1
60 CALL HCHAR(MY,MX,MAN) :: CALL HCHAR(JY,JX,JR)
70 CALL KEY(0,K,S)
80 IF K=83 THEN GOSUB 180 :: IF MX>1 THEN MX=MX-1
90 IF K=68 THEN GOSUB 180 :: IF MX<32 THEN MX=MX+1
100 IF K=69 THEN GOSUB 180 :: IF MY>1 THEN MY=MY-1
110 IF K=88 THEN GOSUB 180 :: IF MY<24 THEN MY=MY+1
120 TOG=-TOG :: IF TOG=1 THEN 60
130 ! MOVE JR
140 CALL HCHAR(JY,JX,32)
150 TX=JX+SGN(MX-JX) :: TY=JY+SGN(MY-JY)
160 CALL GCHAR(TY,TX,C) :: IF C<>32 THEN 60
170 JY=TY :: JX=TX :: GOTO 60
180 CALL HCHAR(MY,MX,32) :: RETURN
```

Edited by Willsy

##### Share on other sites

Sweet!

I can't thank you guys enough for all the help, Willsy, Sometimes99er, Rasmus, and also RXB ... if he HAD the code to show me, he would of!

I'll work on this code and get a game out probably within a week or so.

##### Share on other sites

Well my original RXB game IN THE DARK was only written in XB but I added Assembly to speed it up and apparently erased the XB one.

Sorry.

##### Share on other sites

if your doing it it xb why not use sprites instead of hchar or vchar. its far more simple

##### Share on other sites

if your doing it it xb why not use sprites instead of hchar or vchar. its far more simple

See below

(these are chars and not sprites)

I agree though. Sprites would remove the need to erase a character before you draw it at the new position. So it might be a little faster.

Does CALL COINC detect a sprite colliding with characters though? (Can't remember).

##### Share on other sites

... Does CALL COINC detect a sprite colliding with characters though? (Can't remember).

Yes, if you call it that way: CALL COINC(#<sprite>,<dot-row>,<dot-col>,<tol>,<var>)—not really "characters", but a spot on the screen.

...lee

##### Share on other sites

Since everyone else did such a good job with code examples, I'll take the non-code approach and give you the design that these examples are based on.

The idea is to move the MOB (a term for any "bad guy" in a game) toward the player. Doing this in a straight-ish line is typically the simplest. The program will have variables to track the player, so you know where the player is, i.e. an x,y location on the screen, as well as the MOB(s). So if the player is at 10,12 and the MOB is at 6,7, to get to the player the MOB needs to move in the positive-X and positive-Y directions *releative to the MOB's location*.

The simplest way to do that is to subtract the MOB's X coordinate from the player's X coordinate, and the same for the Y coordinates. So 10-6=4 and 12-7=5 in this case. This gives you two pieces of information: 1. how far the MOB is from the player in that direction (the magnitude), and 2. in what direction the player is *relative to the MOB* (the sign). This is also known as a "vector". :-) The X difference is 4, which is positive, so you would add to the MOB's X location to get closer to the player. Same for the Y.

In the examples above the SGN function was used to quickly check the sign (hence the function's name) of the result and convert the magnitude into a value of -1, 0, or 1. This is typically called a "unit vector". You would do this if you don't care about moving your MOB faster or slower based on the distance from the player. You just worry about adding or subtracting a unit of 1 from the MOB's location in each coordinate X or Y.

A few notes:

* You can use the magnitude to accelerate the MOB based on the distance, i.e. the larger the magnitude the faster away from the player, and the bigger jump you might make.

* You can use the magnitude as a range of influence, so maybe the MOB is less aggressive, or runs in a random pattern, until the player gets too close. In this case, maybe JR does not start to chase the player until they get too close to an oil well. You can use the calculation for any two objects, i.e. oil wells and the player, MOBs and the player, oil wells and MOBs, etc.

* You can also use some other randomness to modify the direction if you want the MOB to not be so straight-on with the attack.

* Moving the MOB in *both* the X and Y in the same step will make it faster on diagonals, and might also allow it to "jump" on screen obstacle if you are not careful. This also might make the MOB faster than the player, so you might need to restrict the MOB to moving in just the X or Y (based on the greater magnitude) for each "turn".

This is probably the simplest AI (artificial intelligence) method for games, but it can be effective depending on the rest of the game. Tombstone City uses this kind of AI.

##### Share on other sites

How I did it for IN THE DARK was use a sprite but the grid was in lower 8K

This speeded up the program quite a bit as instead of reading and writing to the screen each time I only wrote to the screen and never read it.

Most of the reading and writing was to lower 8K RAM and RAM is always faster to work with then VDP.

100 ! IN THE DARK

110 GOSUB 1110

120 CALL AMSBANK(B,B+1) :: CALL MOVES("RV",768,W,0) :: N=INT(X/256) :: O=X-(N*256) :: CALL LOAD(-12286,N,O)

130 CALL SPRITE(#1,128,5,89,C*8-7)

140 ! KEYS IN Z\$=ARROWS OR Ss Dd Xx Ee SPACE ENTER AID Pp

150 Z\$=CHR\$(&"Ss"&CHR\$(9)&"Dd"&CHR\$(10)&"Xx"&CHR\$(11)&"Ee"&CHR\$(32)&CHR\$(13)&CHR\$(1)&"Pp"

160 ! MAIN LOOP

170 CALL SOUND(50,-6,15)

180 U=W+351+C :: CALL LOAD(U,225)! FOOTSTEPS

190 CALL LOCATE(#1,90,C*8-7) :: CALL MOVES("RV",768,W,0)! SHOW ME

200 ! ARROWS OR L,R,D,U,SPACE,ENTER,FCTN7,P,p

210 CALL ONKEY(Z\$,0,K,Z)GOTO 370,370,370,410,410,410,450,450,450,510,510,510,580,690,810,1590,1590

220 ! ENEMY MOVEMENTS

230 IF F+T<9 THEN 210

240 CALL PEEK(-12276,G) :: IF G=218 THEN E=I*5 :: CALL LOAD(-12276,0)

250 IF M<>B THEN 280

260 IF E=0 THEN 270 ELSE E=E-1 :: GOTO 210

270 IF U-X<256 AND M=B THEN CALL SOUND(-1,2500,2)

280 CALL AMSBANK(M,M+1) :: CALL EXECUTE(-12256)

290 CALL PEEK(-12286,G,H) :: X=(G*256)+H :: IF U=X AND B=M THEN 750! MISSION FAILED

300 IF(U<X AND M>B)OR(X<U AND B>M)THEN M=B :: CALL LOAD(-12286,33,129)

310 IF X<8227 AND M=0 THEN 360

320 IF X>16348 AND M=42 THEN 360

330 IF X<8227 THEN M=M-1 :: X=X+4096

340 IF X>16348 THEN M=M+1 :: X=X-4096 ELSE 360

350 N=INT(X/256) :: O=X-(N*256) :: CALL AMSBANK(M,M+1) :: CALL LOAD(-12286,N,O)

360 CALL AMSBANK(B,B+1) :: GOTO 190

370 ! MOVE LEFT

380 CALL GCHAR(12,C-1,G) :: IF G=143 OR G=119 OR G=111 OR G=103 THEN 640

390 IF G=122 THEN 760

400 C=C-1 :: GOTO 160

410 ! MOVE RIGHT

420 CALL GCHAR(12,C+1,G) :: IF G=143 OR G=119 OR G=111 OR G=103 THEN 640

430 IF G=122 THEN 760

440 C=C+1 :: GOTO 160

450 ! MOVE DOWN

460 IF W=15488 AND B=42 THEN 1020

470 CALL GCHAR(13,C,G) :: IF G=143 OR G=119 OR G=111 OR G=103 THEN 640

480 IF G=122 THEN 760

490 IF W>=15615 THEN B=B+1 :: W=W-4096 :: GOTO 570

500 W=W+32 :: GOTO 160

510 ! MOVE UP

520 IF W=8192 AND B=0 THEN CALL HCHAR(1,1,119,480) :: CALL MOVES("VR",768,0,W) :: GOTO 640

530 CALL GCHAR(11,C,G) :: IF G=143 OR G=119 OR G=111 OR G=103 THEN 640

540 IF G=122 THEN 760

550 IF W=8192 THEN B=B-1 :: W=W+4096 :: GOTO 570

560 W=W-32 :: GOTO 160

570 CALL AMSBANK(B,B+1) :: GOTO 160

580 ! FEEL AROUND ME

590 CALL CHAR(128,"0000187E7E242466")

600 N=INT(U/256) :: O=U-(N*256) :: CALL LOAD(-12282,N,O)

610 CALL EXECUTE(-12034)

620 CALL PEEK(-12288,N,O) :: F=F+N :: S=S+(I*N) :: T=T+O

630 FOR Z=1 TO N+O :: CALL SOUND(1,-5,3) :: NEXT Z :: CALL CHAR(128,"187E5A5A3C242424") :: GOTO 190

640 CALL SOUND(99,200,20,-7,0) :: GOTO 160

650 ! SHOW SCORE

660 CALL MOVES("VR",768,0,W) :: CALL CLEAR :: CALL HPUT(10,1,"TRAPS=",10,7,T,10,13,"SCANS=",10,19,S,10,24,"FOOD=",10,29,F)

670 CALL HPUT(14,1,"YOU ARE INJURED "&STR\$(D)&" TIMES!") :: GOTO 1570

680 ! SHOW AREA SCAN

690 IF S THEN 700 ELSE GOSUB 660 :: GOTO 160

700 CALL CLEAR :: CALL SOUND(10,2E4,6,770,5,440,6,-7,3) :: U=W+352 :: K=U+32 :: N=352 :: O=384 :: FOR Z=1 TO 12

710 CALL MOVES("RV",32,U,N,"RV",32,K,O) :: U=U-32 :: K=K+32 :: N=N-32 :: O=O+32 :: NEXT Z

720 CALL COLOR(11,16,1,12,7,1) :: FOR Z=1 TO 100 :: CALL KEY(0,K,J) :: IF K=13 THEN 740

730 NEXT Z :: GOTO 700

740 CALL COLOR(11,2,1,12,2,1) :: S=S-1 :: GOTO 160

750 ! GAME OVER FAILED

760 FOR Z=1 TO 24 STEP 4 :: CALL SOUND(100,-7,Z) :: NEXT Z

770 D=D+1 :: IF I=0 THEN I=1 ELSE I=I-1 :: E=I

780 GOSUB 660 :: IF U=X AND M=B THEN CALL HPUT(22,5,"REPAIR BOT CAUGHT YOU!",20,12,"YOU DIE!") :: END

790 IF D=25 THEN CALL HPUT(22,2,"YOUR INJURIES ARE TO GREAT...",20,12,"YOU DIE!") :: END

800 GOTO 120

810 CALL CLEAR :: CALL HPUT(1,10,"IN THE DARK",12,2,"SUGGEST YOU SWITCH DISKS NOW!",24,9,"PRESS SPACE KEY") :: CALL KEY(" ",0,K,S)

820 OPEN #1:P\$&"SCORE",OUTPUT

830 PRINT #1:W! 8K ADDRESS

840 PRINT #1:T! TRAPS

850 PRINT #1:S! SCANS

860 PRINT #1:F! FOOD

870 PRINT #1:D! DEAD/FAILED

880 PRINT #1:B! BANKS 4K

890 PRINT #1:I! INCREMENTS

900 PRINT #1:C! COLUMN ME

910 PRINT #1:X! 8K ADDRESS

920 PRINT #1:M! BANKS 4K

930 CLOSE #1

940 FOR BANK=0 TO 84 STEP 2

950 CALL AMSBANK(BANK,BANK+1)

960 CALL BSAVE(P\$&"ITDT"&STR\$(PAGE))

970 PAGE=PAGE+1

980 CALL MOVES("RV",768,8192,0)

990 NEXT BANK

1000 PRINT "GAME SAVED!" :: END

1010 CALL SOUND(99,200,20,-5,0) :: RETURN

1020 ! WE HAVE A WINNER!

1030 CALL CLEAR :: CALL HPUT(12,5,"YOU ARE FREE AT LAST!!",24,7,"< PRESS ANY KEY >")

1040 DIM Y(6) :: RESTORE 1050

1050 DATA 247,262,294,330,349,392,440

1060 FOR Z=0 TO 6 :: READ Y(Z) :: NEXT Z

1070 Z=INT(RND*7) :: N=Z :: O=Z :: GOTO 1090

1080 O=N :: N=Z :: Z=INT(RND*7)

1090 CALL SOUND(-200,Y(Z),0,Y(N),9,Y(O),19)

1100 CALL KEY(0,K,G) :: IF G=0 THEN 1080 ELSE GOSUB 660 :: END

1110 ! TITLE SCREEN

1120 CALL CLEAR :: FOR Z=0 TO 8 :: CALL COLOR(Z,16,1) :: NEXT Z :: CALL SCREEN(2)

1130 FOR Z=9 TO 12 :: CALL COLOR(Z,2,1) :: NEXT Z

1140 CALL CHAR(128,"187E5A5A3C242424") :: CALL COLOR(13,5,1)

1150 CALL CHAR(111,"00003C3C3C000000") :: CALL COLOR(10,8,1)

1160 CALL CHAR(119,"FFFFFFFFFFFFFFFF") :: CALL CHAR(122,"00005A5A5A5A0000") :: CALL DUPCHAR(119,143) :: CALL COLOR(14,15,1)

1170 CALL CHAR(103,"007F7F7F7F7F7F00") :: CALL COLOR(9,12,1) :: RESTORE 1180

1180 DATA 73,78,32,84,72,69,32,68,65,82,75,32

1190 FOR Z=1 TO 12 :: READ K :: CALL SPRITE(#Z,K,15,29,Z*21) :: NEXT Z :: CALL MAGNIFY(2)

1200 CALL HPUT(12,15,"BY",18,8,"RICH GILBERTSON") :: GOSUB 1570

1210 ! LOADER FOR MAP

1220 CALL CLEAR :: CALL HPUT(17,4,"WHERE IS THE MAP?")

1230 CALL HPUT(20,3,"EXAMPLE: 1 OR DSK.VOLNAME.",23,3,"DISK # OR DEVICE PATH:") :: PRINT :: INPUT D\$

1240 IF LEN(D\$)=1 THEN P\$="DSK"&D\$&"." ELSE P\$=D\$

1260 FOR BANK=0 TO 84 STEP 2

1270 CALL AMSBANK(BANK,BANK+1)

1290 PAGE=PAGE+1 :: CALL MOVES("RV",768,8192,0) :: NEXT BANK

1300 PRINT "LOADING ASSEMBLY ROUTINES!" :: GOSUB 1610

1310 ! LOAD OLD GAME

1320 OPEN #1:P\$&"SCORE",INPUT

1330 INPUT #1:W! 8K ADDRESS (ME)

1340 INPUT #1:T! TRAPS

1350 INPUT #1:S! SCANS

1360 INPUT #1:F! FOOD

1370 INPUT #1:D! DEAD/FAILED

1380 INPUT #1:B! BANKS 4K (ME)

1390 INPUT #1:I! INCREMENTS

1400 INPUT #1:C! COLUMN (ME)

1410 INPUT #1:X! 8K ADDRESS (ENEMY)

1420 INPUT #1:M! BANKS 4K (ENEMY)

1430 CLOSE #1 :: E=I

1440 CALL CLEAR :: CALL HPUT(24,2,"DO YOU WANT INSTRUCTIONS? Y/N") :: CALL KEY("YyNn",0,K,Z) :: CALL CLEAR

1450 ! INSTRUCTIONS

1460 CALL MAGNIFY(1) :: CALL DELSPRITE(ALL) :: IF K=78 OR K=110 THEN RETURN

1470 CALL HPUT(1,10,"IN THE DARK",3,1,"YOU HAVE BEEN CAPTURED AND ARE NOW A TEST TEST SUBJECT.")

1480 CALL HPUT(5,1,"YOU HAVE A TOOL TO DISARM TRAPS.BUT YOU MUST GET ON HANDS AND",7,1,"KNEES TO FEEL THEM IN THE DARK.")

1490 CALL HPUT(9,1,"SPACE BAR TO FEEL AROUND YOU. g IS A DISARMED TRAP.",11,1,CHR\$(143)&" ARE WALLS FOUND.")

1500 CALL HPUT(12,1,"o IS FOOD AND SCAN CHIPS.",14,1,"ENTER KEY TO TURN ON SCAN CHIP.")

1510 CALL HPUT(16,1,"FREEDOM IS END OF THE TUNNEL!",18,1,"DO NOT TOUCH THE REPIAR BOT!",20,4,"YOU WILL DIE INSTANTLY!")

1520 CALL HPUT(22,1,"DISARMED TRAPS SLOWS REPAIR BOT!") :: GOSUB 1570

1530 CALL CLEAR :: CALL HPUT(1,10,"IN THE DARK",4,1,"(FNCT 7) SAVES THE GAME PROGRESS",6,1,"ARROWS OR ESDX KEYS ARE MOVEMENT")

1540 CALL HPUT(8,1,"SPACE BAR FEELS AROUND YOU",10,1,"ENTER IS SCAN CHIP (FULL SCREEN)",12,1,"P IS THE PAUSE KEY")

1550 CALL HPUT(14,1,"BY THE WAY THE REPAIR BOT MAKES A SOUND WHEN IT GETS CLOSE.")

1560 CALL HPUT(17,1,"THIS GAME USES 336K OF SAMS MEMORY IN 43 FILES.",20,1,"SEE IF YOU CAN COMPLETE THE GAMEWITHOUT A SINGLE INJURY.")

1570 CALL HPUT(24,8,"<PRESS ANY KEY>") :: CALL KEY(0,K,Z) :: IF Z=0 THEN 1570 ELSE RETURN

1580 FOR Z=1 TO 24 STEP 4 :: CALL SOUND(100,110*Z,30-Z,44000/Z,Z) :: NEXT Z :: RETURN

1590 ! PAUSE KEY

1600 CALL CLEAR :: CALL HPUT(10,13,"PAUSED!") :: GOSUB 1570 :: GOTO 160

1610 ! EXECUTE ASSEMBLY

1620 CALL LOAD(-12288,0) :: CALL MOVES("RR",406,-12288,-12287)

1800 RETURN

This program ran 360K of AMS memory as a map and worked out pretty well.

##### Share on other sites

I like In the Dark, it's kind of like Gauntlet Of Death was for the old TRS-80, only much more advanced and bigger.....

Here's what I've done so far, with the existing code .... I've electrified the wall .... only it's JR's wall, so he won't get electrocuted ... just me

1 DIM SC(24,32)::! THIS WILL DETERMINE WALLS & OIL TO COLLECT

2 FOR L=4 TO 19::SC(L,16)=1::NEXT L

10 CALL CLEAR

15 CALL VCHAR(4,16,ASC("\$"),16)

20 MAN=42 :: JR=35

30 MX=5 :: MY=5

40 JX=30 :: JY=22

50 TOG=1

60 CALL HCHAR(MY,MX,MAN) :: CALL HCHAR(JY,JX,JR)

61 DISPLAY AT(24,1):MY,MX

65 IF SC(MY,MX)=1 THEN 200

70 CALL KEY(0,K,S)

80 IF K=83 THEN GOSUB 180 :: IF MX>1 THEN MX=MX-1

90 IF K=68 THEN GOSUB 180 :: IF MX<32 THEN MX=MX+1

100 IF K=69 THEN GOSUB 180 :: IF MY>1 THEN MY=MY-1

110 IF K=88 THEN GOSUB 180 :: IF MY<24 THEN MY=MY+1

120 TOG=-TOG :: IF TOG=1 THEN 60

130 ! MOVE JR

140 CALL HCHAR(JY,JX,32)

150 TX=JX+SGN(MX-JX) :: TY=JY+SGN(MY-JY)

160 CALL GCHAR(TY,TX,C) :: IF C<>32 THEN 60

170 JY=TY :: JX=TX :: GOTO 60

180 CALL HCHAR(MY,MX,32) :: RETURN

200 FOR L=1 TO 8

210 CALL HCHAR(MY,MX,MAN)::CALL SOUND(100,-7,1)

220 CALL HCHAR(MY,MX,32)::CALL SOUND(100,-7,10)

230 NEXT L

240 STOP

Line 61 can be left out, it will be in the end when the game is up and running, it was just for me really, to show me where the wall ended and started, make sure I had the right parameters for the 'electric shock'

That wall won't be there in the finished game, but there will be walls elsewhere and there's going to be a boxed-off section with only one way in and one way out , that contains something you have to collect to progress or complete the game.... theres a risk of JR following you into the box.

What I really need is a decent GCHAR routine to determine the wall tile, for the player as well as JR .... I can't fathom where to put the gchar command for the player, 'cos it's got to detect the tile BEFORE the player steps onto it and turns the tile into himself ..... confusion!

Edited by Retrospect

##### Share on other sites

You could do like IN THE DARK and use the Lower 8K as screen buffer then make changes to it before putting it on screen.

It occurred to me that a CALL PEEK or CALL LOAD is much faster then CALL GCHAR or CALL HCHAR as VDP slows down all execution by quite a bit.

Strings and variable being stored in VDP is also one of the reasons that slows XB. RAM is so much faster.

I forgot to take out the GCHAR and HCHAR in my game IN THE DARK and replace them with CALL PEEK and CALL LOAD.

##### Share on other sites

TEXASOIL.zip

Okay, here's what I've come up with so far

the scoring system does NOT work yet, and there's only two screens, but it's fun nonetheless, hey, try tricking JR into staying still because he cant see you whilst you steal all his oil!

Edited by Retrospect

##### Share on other sites

Yes, if you call it that way: CALL COINC(#<sprite>,<dot-row>,<dot-col>,<tol>,<var>)—not really "characters", but a spot on the screen.

...lee

That would mean too many calculations to perform for the game speed to be anything like playable, surely? .... unless you can specify within those parameters on the CALL COINC command a large area of the screen, but then that would only ever be a square area .... if you get what I mean? .... no good for long walls etc

##### Share on other sites

That would mean too many calculations to perform for the game speed to be anything like playable, surely? .... unless you can specify within those parameters on the CALL COINC command a large area of the screen, but then that would only ever be a square area .... if you get what I mean? .... no good for long walls etc

I speeded up RXB game IN THE DARK by making some Assembly Language portions to speed up slow sections.

##### Share on other sites

What I really need is a decent GCHAR routine to determine the wall tile, for the player as well as JR .... I can't fathom where to put the gchar command for the player, 'cos it's got to detect the tile BEFORE the player steps onto it and turns the tile into himself ..... confusion!

You mean, like this:

1 DIM SC(24,32)::! THIS WILL DETERMINE WALLS & OIL TO COLLECT

2 FOR L=4 TO 19::SC(L,16)=1::NEXT L

10 CALL CLEAR

15 CALL VCHAR(4,16,ASC("\$"),16)

20 MAN=42 :: JR=35

30 MX=5 :: MY=5

40 JX=30 :: JY=22

50 TOG=1

60 CALL HCHAR(JY,JX,JR)

61 DISPLAY AT(24,1):MY,MX

65 IF SC(MY,MX)=1 THEN 200

70 CALL KEY(0,K,S)

80 IF K=83 THEN IF MX>1 THEN GOSUB 260

90 IF K=68 THEN IF MX<32 THEN GOSUB 290

100 IF K=69 THEN IF MY>1 THEN GOSUB 320

110 IF K=88 THEN IF MY<24 THEN GOSUB 350

120 TOG=-TOG :: IF TOG=1 THEN 60

130 ! MOVE JR

140 CALL HCHAR(JY,JX,32)

150 TX=JX+SGN(MX-JX) :: TY=JY+SGN(MY-JY)

160 CALL GCHAR(TY,TX,C) :: IF C<>32 THEN 60

170 JY=TY :: JX=TX :: GOTO 60

200 FOR L=1 TO 8

210 CALL HCHAR(MY,MX,MAN)::CALL SOUND(100,-7,1)

220 CALL HCHAR(MY,MX,32)::CALL SOUND(100,-7,10)

230 NEXT L

240 STOP

250 ! MOVE MAN LEFT

260 CALL HCHAR(MY,MX,32) :: TEMP=MX :: MX=MX-1 :: CALL GCHAR(MY,MX,C):: IF C<>32 THEN MX=TEMP

270 CALL HCHAR(MY,MX,MAN) :: RETURN

280 ! MOVE MAN RIGHT

290 CALL HCHAR(MY,MX,32) :: TEMP=MX :: MX=MX+1 :: CALL GCHAR(MY,MX,C):: IF C<>32 THEN MX=TEMP

300 CALL HCHAR(MY,MX,MAN) :: RETURN

310 ! MOVE MAN UP

320 CALL HCHAR(MY,MX,32) :: TEMP=MY :: MY=MY-1 :: CALL GCHAR(MY,MX,C):: IF C<>32 THEN MY=TEMP

330 CALL HCHAR(MY,MX,MAN) :: RETURN

340 ! MOVE MAN DOWN

350 CALL HCHAR(MY,MX,32) :: TEMP=MY :: MY=MY+1 :: CALL GCHAR(MY,MX,C):: IF C<>32 THEN MY=TEMP

360 CALL HCHAR(MY,MX,MAN) :: RETURN

I have moved the man-move routines into their own subroutines (250-36- inclusive) as they are quite like to expand.

Here’s how it works (I’ll use move man RIGHT as an example):

• Erase the man at the current MY/MX coordinate
• Store the current MX coordinate in TEMP in case the move is illegal
• Adjust the MX coordinate by 1
• Using GCHAR, check the character at the new position
• If the character at the new position is NOT a space, then the move is not allowed, so adjust the MX coordinate back to its original value (which was stored in TEMP)
• Draw the man

And that’s it. Hope this helps.

## Join the conversation

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

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

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