# CALL LOCATE

## Recommended Posts

I forgot to mention this is an arc jump, and I was planning to change it to a slow, floating, high, "Major Havoc" style jump if I can figure out how to do it. It would keep jumping so long as the button was pressed, and hit the "ceiling", like Lunar Lander.

James

##### Share on other sites

It works great. The man wraps around on screen. Why does it work?

640 CALL SPRITE(#1,96,16,DR,DC) :: CALL MAGNIFY(4)

660 ANIM=ABS(ANIM-4) :: CALL JOYST(1,X,Y) :: DR=DR-Y*0 :: DC=DC+X*4 :: CALL LOCATE(#1,(DR AND 255)+1,(DC AND 255)+1)

What does the +1 do?

I am somewhat familiar with AND since I read The Power of AND by Craig Miller from "Night Mission". I think whatever you AND something with, the answer can't be higher than whatever number you ANDed with. The bit "mask" in assembly. I don't fully understand it, but I ANDed some numbers at work just to get familiar with it. I think 9 is 1001. 1 is 0001. 9 AND 1 would be 0001=1 then I think. Can you actually do AND 1, AND 7, etc. or was it some number AND 1, DC, DR, or some number AND 7, etc. that you meant above?

The "AND 255" gets whatever value into the range 0-255. The "+1" moves the range from 0-255 to 1-256. The latter being exactly the range CALL LOCATE will accept.

Yep, bit masking is what it is. And yes, "9 AND 1" equals 1.

##### Share on other sites

Do you have any idea why my jump won't work?

810 SUB JUMP(DR,DC)

830 DR=DR-Y*4

DR was something about row (=vertical) position of the sprite ? And Y was the joystick direction (=vertical) ? Is Y then -4, 0 or 4 here, or has it been changed before getting here ?

It looks like, initially in the jump, you want the man to, more or less instantly, move up, down or not by 16 pixels based on the joystick input ?

Here's some Major Havoc jumping for reference.

##### Share on other sites

The video/Major Havoc jumping.

Looks like joystick input is only left, right and fire.

When you hit the fire button, the man jumps. If you hold the fire button, he continues to elevate. Looks like he gains speed to reach maximum speed quite fast.

When leaping off a structure or releasing the fire button while jumping, it looks like gravity takes over, and downward decent then reaches a maximum speed.

Is this correct ?

Edited by sometimes99er

##### Share on other sites

At first I had 8 directions and center, Diagonals and LeftRightUpDown. It took almost all the character sets and I thought to try only Left, Right, and Fire for the jump. In the game it seems he doesn't actually need to move up or down, the diagonal jump looked cool..but ya can't have everything. So, yes, left, right, orange button k=18.

My thought or wish on the Major Havoc jump would be to try and emulate this jump but then slow it down a bit. I wanted the man to run at ground level left or right and wrap around the screen.(which he now does) He would jump in a tad slow floating movement as long as the button was held down, or until he hit the "ceiling". I was inspired by Major Havoc and Lunar Lander to have a space man with super high jumps, maybe on a planetoid..

There are about 4 subroutines of enemies that keep re-appearing until the game ends, and they only partially work.

##### Share on other sites

DR=Dot Row DC=Dot Column Y= Horizontal X=Vertical(whatever JOYST uses)

I think Y*4 is added to DR or subtracted. Line 660.

635 DR=130 :: DC=1

640 CALL SPRITE(#1,96,16,DR,DC) :: CALL MAGNIFY(4)

660 ANIM=ABS(ANIM-4)::CALL JOYST(1,X,Y)::DR=DR-Y*4 :: DC=DC+X*4::CALL LOCATE(#1,DR,DC)

663 IF X<>0 THEN CALL PATTERN(#1,ANIM+X*2+108)::FACE=SGN(X+4)::GOTO 660

16 pixels?

##### Share on other sites

Do you have to put several CALL COINC statements in to make it catch a coincidence? Or do you generally just write one CALL COINC and loop back to it?

Do you need to CALL subrprograms in the same loop as CALL JOYST(main program)?

I suppose the CALL JOYST would be the main game loop. How do I work in the Subprograms without making the JOYST loop way too lengthy?

I was planning to have a few separate subroutines CALL enemies(Subprograms) one at a time in a loop continuously until the game ends. I think this would cause a similar effect to the recurring and annoying bouncing Spider in Centipede.

THe JUMP was written by my friend who was also experimenting with PI. We wanted to make a jump using CALL LOCATE instead of the normal CALL MOTION, primarily because I heard using locate is much better for coincidence checking. Instead of the internet, most of my news and information comes from rumor and small children, so I'm not sure about that.

##### Share on other sites

I couldn't get CALL COINC to work with my subprograms, but it worked here in this test on line 365.

100 !TEST PROGRAM-USE CALL LOCATE WITH JOYST

110 P1=15 :: P2=10

120 CALL CLEAR :: CALL SCREEN(6)

130 A\$=RPT\$("F",16) :: CALL CHAR(96,A\$)

140 CALL SPRITE(#1,96,2,89,121)

143 S\$=RPT\$("F",16) :: CALL CHAR(104,S\$)

145 CALL SPRITE(#2,104,16,57,223)

150 DR=100 :: DC=100

160 CALL HCHAR(1,16,104)!UP

170 CALL HCHAR(24,16,112)!DOWN

180 CALL HCHAR(12,3,120)!LEFT

190 CALL HCHAR(12,30,128)!RIGHT

200 CALL JOYST(1,X,Y)

210 CALL COLOR(10,P1,P1,11,P1,P1,12,P1,P1,13,P1,P1)

220 R=R-Y/4 :: C=C+X/4

230 DR=DR-Y*4 :: DC=DC+X*4

260 CALL LOCATE(#1,DR,DC)

270 CALL KEY(1,K,S)

280 DISPLAY AT(16,1):"SAME KEY=0 NEW KEY=1 NO KEY PRESS=-1"

290 DISPLAY AT(18,5):"KEY= ";K;"STATUS= ";S

300 DISPLAY AT(20,1):"X= ";X;"Y= ";Y

310 DISPLAY AT(21,1):"R= ";R;"C= ";C

320 DISPLAY AT(22,1):"DR= ";DR;"DC= ";DC

330 IF Y=4 AND X=0 THEN CALL COLOR(10,P2,P2)

340 IF Y=0 AND X=4 THEN CALL COLOR(13,P2,P2)

350 IF Y=-4 AND X=0 THEN CALL COLOR(11,P2,P2)

360 IF Y=0 AND X=-4 THEN CALL COLOR(12,P2,P2)

365 CALL COINC(#1,#2,10,C) :: IF C THEN CALL SOUND(300,-2,10)

368 DISPLAY AT(14,12):"C= ";C

370 GOTO 200

##### Share on other sites

You have way to much stuff in the loop between 370 and 200. It makes the chance of getting a COINC very slow.

If you watch my Videos on RXB 2012 you will see this demo, the lower half requires RXB but the top half is XB.

My point is the more between each line and number of lines the slower XB gets.

Just a matter of distance or up hill if you are walking. More line numbers is farther and more calculations is up hill.

Reduce the number of lines in a loop and it speeds up, reduce the complications and it gets faster.

```100 ! RUN FOR 1 HOUR AND	 AND PRINT X FOR XB VS RXB
110 ! NORMAL XB COINC
120 CALL CLEAR :: X=190
130 CALL SPRITE(#1,65,2,9,X,20,0,#2,66,2,9,X,30,0,#3,67,2,9,X,-20,0)
140 CALL COINC(ALL,A)
150 CALL COINC(#1,#2,12,B)
160 CALL COINC(#1,#3,12,C)
170 CALL COINC(#2,#3,12,D)
180 X=X+1 :: PRINT A;B;C;D
190 GOTO 140
200 !
210 ! RXB COINC
220 CALL CLEAR :: X=190
230 CALL SPRITE(#1,65,2,9,X,20,0,#2,66,2,9,X,30,0,#3,67,2,9,X,-20,0)
240 CALL COINC(ALL,A,#1,#2,12,B,#1,#3,12,C,#2,#3,12,D)
250 X=X+1 :: PRINT A;B;C;D
260 GOTO 240
```

##### Share on other sites

Do you have any idea why my jump won't work?

810 SUB JUMP(DR,DC)

830 DR=DR-Y*4

It looks like, initially in the jump, you want the man to, more or less instantly, move up, down or not by 16 pixels based on the joystick input ?

16 pixels?

If Y can be -4, 0 or 4 then (it will always be 0 inside this SUB since Y is not passed)

Y*4

becomes

-16, 0 or 16

The line

830 DR=DR-Y*4

must then change the "Dot Row" of the sprite by 16 pixels, if you were pulling the joystick in the Y direction.

Obviously the confusion is almost complete.

##### Share on other sites

Do you have to put several CALL COINC statements in to make it catch a coincidence? Or do you generally just write one CALL COINC and loop back to it?

If you use CALL MOTION, there's always the possibility of missing a coincidence. You have to make CALL COINC often with the right amount of tolerance. Yes, CALL COINC can be in a loop, and yes, one can make several CALLs - it depends. I guess it's a bit of trial and error.

If you use one CALL LOCATE and one CALL COINC in your loop, you should be able to catch everything. Of course with the right amount of tolerance.

Do you need to CALL subrprograms in the same loop as CALL JOYST(main program)?

No.

There's no general rule to the use of subrprograms, but of course it depends on what your subrprograms are doing.

I suppose the CALL JOYST would be the main game loop. How do I work in the Subprograms without making the JOYST loop way too lengthy?

Subprograms take some overhead. Calling a subprogram, using local variables and returning takes computer time.

RXB suggested having many statements on a single line, so XB does not have to do too much searching for linenumbers, I think this is very true, when it comes to optimization and saving computer time.

I was planning to have a few separate subroutines CALL enemies(Subprograms) one at a time in a loop continuously until the game ends. I think this would cause a similar effect to the recurring and annoying bouncing Spider in Centipede.

You have to try it out. Using subroutines can help sort out some logic errors and enhancing readability. However - XB can not control a hole lot of action and check for coincidences with an overall nice arcade quality. Take a simple OUTLAW situation. One player shooting at a computer controlled player shooting back at you. This quickly becomes the limit of XB speed. But then again, sometimes things like INACCURATE INVADERS kinda surprises you (and then done in 29 lines with 7 data). Bottomline, you can't have a lot of stuff happening at the same time, but you can take things through different stages (levels).

##### Share on other sites

I removed line 830 which removed the variable Y from the jump. It now does a jumping effect always going to the right. I would use FACE to tell the program to jump left or right. Line 850 .....IF FACE=1 THEN DC=DC+(A*PI/45)*5 :: IF FACE=0 THEN DC=DC-(A*PI/45)*5?

635 DR=130 :: DC=1

640 CALL SPRITE(#1,96,16,DR,DC) :: CALL MAGNIFY(4)

660 ANIM=ABS(ANIM-4) :: CALL JOYST(1,X,Y) :: DR=DR-Y*0 :: DC=DC+X*4 :: CALL LOCATE(#1,(DR AND 255)+1,(DC AND 255)+1)

662 CALL KEY(1,K,S) :: IF K=18 THEN CALL JUMP(DR,DC)

663 IF X<>0 THEN CALL PATTERN(#1,ANIM+X*2+108) :: FACE=SGN(X+4) :: GOTO 660

665 CALL PATTERN(#1,FACE*16+96) :: GOTO 660

670 IF DC<2 THEN DC=240 ELSE IF DC>240 THEN DC=2

810 SUB JUMP(DR,DC)

815 !ALL COINC(#1,ALL,C)

820 CALL SOUND(150,-2,4)

840 SDR=DR :: A=1

845 IF DC<2 THEN DC=240 ELSE IF DC>240 THEN DC=2

850 CALL KEY(1,K,S) :: IF K=18 THEN DR=DR-4 :: DC=DC+(A*PI/45)*5 :: IF DC>240 THEN DC=1

860 !DISPLAY AT(23,1):A;" ";SIN(A*PI/45)

870 IF DR<8 THEN 890

880 CALL LOCATE(#1,DR,DC) :: IF S<0 THEN A=A+1 :: GOTO 850

890 IF DR<SDR THEN DR=DR+4 :: DC=DC+1 :: CALL LOCATE(#1,DR,DC) :: IF DC>240 THEN DC=1

900 IF DR<SDR THEN 890

910 SUBEND

##### Share on other sites

Also tried changing line 850 which makes it jump straight up and to the right on the way down. Misunderstanding is complete again.

635 DR=130 :: DC=1

640 CALL SPRITE(#1,96,16,DR,DC) :: CALL MAGNIFY(4)

660 ANIM=ABS(ANIM-4) :: CALL JOYST(1,X,Y) :: DR=DR-Y*0 :: DC=DC+X*4 :: CALL LOCATE(#1,(DR AND 255)+1,(DC AND 255)+1)

662 CALL KEY(1,K,S) :: IF K=18 THEN CALL JUMP(DR,DC,FACE)

663 IF X<>0 THEN CALL PATTERN(#1,ANIM+X*2+108) :: FACE=SGN(X+4) :: GOTO 660

665 CALL PATTERN(#1,FACE*16+96) :: GOTO 660

670 IF DC<2 THEN DC=240 ELSE IF DC>240 THEN DC=2

810 SUB JUMP(DR,DC,FACE)

815 !ALL COINC(#1,ALL,C)

820 CALL SOUND(150,-2,4)

840 SDR=DR :: A=1

845 IF DC<2 THEN DC=240 ELSE IF DC>240 THEN DC=2

850 CALL KEY(1,K,S) :: IF K=18 THEN DR=DR-4 :: IF FACE=1 THEN DC=DC+(A*PI/45)*5 :: IF FACE=1 THEN DC=DC-(A*PI/45)*5 :: IF DC>240 THEN DC=1

860 !DISPLAY AT(23,1):A;" ";SIN(A*PI/45)

870 IF DR<8 THEN 890

880 CALL LOCATE(#1,DR,DC) :: IF S<0 THEN A=A+1 :: GOTO 850

890 IF DR<SDR THEN DR=DR+4 :: DC=DC+1 :: CALL LOCATE(#1,DR,DC) :: IF DC>240 THEN DC=1

900 IF DR<SDR THEN 890

910 SUBEND

##### Share on other sites

850 CALL KEY(1,K,S) :: IF K=18 THEN DR=DR-4 :: IF FACE=1 THEN DC=DC+(A*PI/45)*5 :: IF FACE=1 THEN DC=DC-(A*PI/45)*5 :: IF DC>240 THEN DC=1

First of all there's two "IF FACE=1" in the line above ?

Also, if an "IF" is met, then the rest of the line is only executed if the "IF" was true, otherwise it jumps to the next line in the program.

```100 A=A+1::CALL JOYST(1,X,Y)
110 IF X=4 THEN A=A+100::PRINT A
120 GOTO 100
```

The above is a test. The value is only printed, when you move the joystick to the right.

Edited by sometimes99er

##### Share on other sites

It was supposed to be :

850 CALL KEY(1,K,S) :: IF K=18 THEN DR=DR-4 :: IF FACE=1 THEN DC=DC+(A*PI/45)*5 :: IF FACE=0 THEN DC=DC-(A*PI/45)*5 :: IF DC>240 THEN DC=1

I remember changing 1 line to FACE=1 and one to FACE=0 and it still didn't come out right. Wow. If this isn't murphy's law, it's definitely what happens when it gets late at night. Some days I can't do this till night and am fighting sleep.

##### Share on other sites

I remember changing 1 line to FACE=1 and one to FACE=0 and it still didn't come out right.

As I tried to explain in post #39,

What comes after an "IF" is only executed, including multiple statements, if the "IF" is true/the condition is met.

Program pointer will never ever get to the things after FACE=0. Why ? It will only get to "FACE=0" if the previous condition "FACE=1" is met. Obviously FACE can't be both 1 and 0, so 0 it will never be (when and if the program pointer gets there).

One solution is to split it up, ending up with only ONE "IF" on each program line. Another a bit more dangerous path/solution is to use ELSE.

Edited by sometimes99er

##### Share on other sites

```850 CALL KEY(1,K,S) :: IF K=18 THEN DR=DR-4 :: IF FACE=1 THEN DC=DC+(A*PI/45)*5 :: IF FACE=0 THEN DC=DC-(A*PI/45)*5 :: IF DC>240 THEN DC=1
```

Should be:

```850 CALL KEY(1,K,S) :: IF K=18 THEN DR=DR-4 :: IF FACE=1 THEN DC=DC+(A*PI/45)*5 ELSE DC=DC-(A*PI/45)*5
851 IF DC>240 OR DC<1 THEN DC=1
```

##### Share on other sites

My friend also has a question about using call locate with joyst.

CALL LOCATE(#1,(DR AND 255)+1,(DC AND 255)+1) I am not sure that I understand what you are trying to do here. (DR AND 255) and (DC AND 255) will return -1 if DR=255 or DC=255 thus only acting if either is 255 and then it changes the statement to be CALL LOCATE(#1,-1+1,-1+1) making either parameter zero which will cause an error. Since DR never changes I would rewrite as CALL LOCATE(#1,DR,(DC AND 255)+2)

##### Share on other sites

(DR AND 255) and (DC AND 255) will return -1

No, or that depends on what and how you extract from the original line.

"AND 255" is a bitwise operation. It takes a value, DR or DC, and only allow the least 8 bits to pass thru, effectively forcing any value into the range 0-255 (what 8 bits can represent). Here I list the value of DR, and the result after doing "DR AND 255" to try and illustrate without using bit graphics. Maybe you get the idea.

```DR (DR AND 255)
0 0
1 1
17 17
255 255
256 0
257 1
-1 255
-244.4 12
30000 48```

Mind you the max range of DR must be -32768.5 - 32767.4999 (floating point range accepted into the 16 bit range).

Here's a program to test what's going to happen

```100 INPUT A
110 PRINT (A AND 255)
120 GOTO 100```

Edited by sometimes99er

##### Share on other sites

Since DR never changes I would rewrite as CALL LOCATE(#1,DR,(DC AND 255)+2)

DR, yep you could do that, as long as DR is in the 1-256 range (what CALL LOCATE likes).

"DC AND 255" forces DC into the 0-255 range. "(DC AND 255)+2" would then result in the possible range of 2-257, which is outside the range of CALL LOCATE, and could cause your program to end with an ERROR.

Edited by sometimes99er

##### Share on other sites

Hmm. Does this solve the negative non integer number, and out of range error? Or merely "patch" it? I know not what I do...

```810 SUB JUMP(DR,DC,FACE)
840 SDR=DR :: A=1
844 DISPLAY AT(16,12):"DC= ";DC
850 CALL KEY(1,K,S) :: IF K=18 THEN DR=DR-4 :: DC=ABS(DC)+ABS(INT(A*PI/45)*5) :: IF DC>240 THEN DC=17
855 CALL COINC(#1,#2,10,CO) :: IF CO THEN CALL SOUND(150,-2,4) :: CALL DELSPRITE(#1)
860 !DISPLAY AT(23,1):A;" ";SIN(A*PI/45)
870 IF DR<8 THEN 890
875 IF DR=126 THEN M=DC
880 CALL LOCATE(#1,DR,DC) :: IF S<0 THEN A=A+1 :: GOTO 850
890 IF DR<SDR THEN DR=DR+4 :: DC=DC+1 :: CALL LOCATE(#1,DR,DC) :: IF DC>240 THEN DC=17
900 IF DR<SDR THEN 890
910 SUBEND
```

I changed line 850 stop negative and non-integer numbers. The error I continually got under these conditions - when the man was at the rightmost corner of the screen, DR=126, and pressed the jump button- stopped after this. The error was always at line 880 If I remember right.

880error.tiff

ERROR_880.tiff

ERRORDC.tiff

##### Share on other sites

Sometimes, what is your private e-mail?

At 23 seconds in this video, there is a dot chasing routine. I have a subprogram to place a random dot on screen. Like the car, the man would touch the dot, and it would disappear only to present itself again somewhere else on screen. The Man would have to touch the dot a certain number of times, say 25. How could this subprogram be called, and simultaneously have another subprogram of an "enemy" running at the same time? I thought the pesky enemies would make it harder for the man to get the dot.

##### Share on other sites

Well, I don't know. Give me a complete working example, and maybe I can tell you how to fix it. It's too easy for me to add confusion, if I have to set up my own test environment. Simply to ensure we're talking about the same thing.

If you want, can you mail me privately here at AtariAge (using their system). But I'd rather communicate publicly, giving people a chance to come with ideas, learn and/or try and do better. My time is also limited, so ...

I think you're very much answering it yourself concerning the dot. Pseudo code would maybe be something like below. Pseudo code is excellent for getting what you have in your head down on paper. It will actually help. I guess moving the enemy is going to be the challenge, if it's not just going to stand there and move like, one right, one left, one right, one up, one left, one down - simple erratic behaviour.

Setup things

Loop start

Move enemy

Move man

Check collision between man and enemy

Check collision between man and dot

Loop end

Sub Move enemy

Subend

Sub Move man

Subend

Man and enemy collided

Do whatever

Go somewhere

Man and dot collided

All 25 dots taken ? Go do something special

Set new dot location

Go back to loop

Edited by sometimes99er

##### Share on other sites

Well, my thought for my first game was to finish it completely, then dish out a free game to the community as a surprise. I figure it putting it all on here would blow the surprise, even though the game is probably no big deal. It does make it easier to learn with the public forum, with trial and error and different input instead of trying to finish it in private. I put most of the code on the CALL COINC thread. Not sure how to do 3 things at once. It seems like the program can CALL JOYST, CALL DOT, and CALL enemies one at a time in a sequence, but it needs to be done simultaneously. When you have to wait for all the enemies to go by before you can move the joystick again, it's not working right.

It seems to be like this

CALL JOYST

CALL DOT

CALL ENEMIES

REPEAT

instead of CALL JOYST- CALL DOT - CALL ENEMIES , where you can move around, touch the dot, jump out of the way of an enemy all in "real time". When I call the subprograms, it seems to be just a stack of tasks that are completed in order, so I have to do all of them before I can start over, preventing the program from doing several things at once. I don't know if the structure is call all subprograms in the game loop and make the game loop too long and slow, or make a short fast game loop and not be able to call the subprograms. Catch-22.

Edited by orion1052003

##### Share on other sites

The game loop allows you to "do multiple things" at one moment in "game time". If the game is running fast enough, then game time is very close to "real time". In BASIC or XB, you are going to have a hard time keeping the game running anywhere close to real time.

```while game is running
get player input
update location player according to input
update "bad guy" locations according to game AI
update other objects (animation frames, explosions, backgrounds, etc.)
resolve collisions
update score and game status
draw objects (new player location, bad guys, other objects, etc.)
wend
```

Notice where "resolve collisions" is placed, i.e. after the player AND AI have had a chance to move. The player moves, the AI moves, then you check if anything collided. If you are using sprite "auto motion" in XB then you will probably end up having a hard time with resolving collisions if the sprites are moving too fast. Everything in the game gets a chance to change every time through the game loop, which is how you create the illusion that multiple things are happening at the same time.

Also notice that "updating" the player and "bad guy" locations is separate from "drawing" them. If in the current "tick" of game time the player was hit by a bad guy (or a bullet, or whatever), you would probably start an explosion animation at the player's location instead of drawing the player.

Edited by matthew180

## Join the conversation

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

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