Calculator Community > TI-BASIC

Collision Detection Explained

(1/5) > >>

meishe91:
So here I am again explaining another bit of code. This time instead of just basic movement though I will be describing a basic way of collision detection.
Note though that this way is not the most efficient way of doing this and this way only works as long as you have a border all around the outside. If there is a gap and you go off screen it will result in ERR:DOMAIN. (Ztrumpet provided some code that adds in the limitations and if I have time (and his permission) I will post an explanation to that too.)

Ok, so to start lets see the code:

--- Code: ---PROGRAM:MOVE
"//////////////// //I broke this string down into rows of 16 (the first line is 17 though) so it is easier to follow. It would normally be typed on one line.
/___///___///__/
/_///___///__/_/
/______/////___/
/__///__///__/_/
/_////__//__////
/______________/
////////////////?Str1
Output(1,1,Ans
2?A
2?B
Repeat 0
Output(A,B,"*
Repeat Ans
getKey?K
End
Output(A,B,"_
A+(Ans=34 and sub(str1,16A+B,1)="_")-(Ans=25 and sub(Str1,16A-32+B,1)="_?A
B+(K=26 and sub(Str1,16A-15+B,1)="_")-(K=24 and sub(Str1,16A-17+B,1)="_?B
End
--- End code ---

"characters in sting"?Str1: The basic function of this is that we are storing those 128 characters into Str1. What this string is though is our map for what we will be maneuvering around when the program is executed. If you hadn't guessed / are walls while spaces are where you can move. These can be changed for any single slot character (ex. =, +, ?, etc.).
Output(1,1,Ans: Quick explanation of the Output( command. Basically it will display *insert what ever being displayed* in row what ever and how ever many columns out (Output(row number (1-8), column number (1-16), thing to displayed). I explain it much further here. Something I haven't explained though is that if the Output( would (in theory) go offscreen it will wrap around and continue onto the next line. Ok, so the Ans here is the string and it is being placed into row one and in column one too. Since the string is 128 characters long (8*16) it will fill in the whole screen. It will basically display like this:

--- Code: ---////////////////
/___///___///__/
/_///___///__/_/
/______/////___/
/__///__///__/_/
/_////__//__////
/______________/
////////////////
--- End code ---

2?A: Pretty simple, stores a value of 2 to the variable A.
2?B: Again, simple. Stores a value of 2 to the variable B.
Repeat 0: This starts a Repeat loop. As covered here it is the only post test loop. Meaning, I believe, that it checks the statement before running again and will exit once true. To be perfectly honest I'm not entirely sure why Repeat 0 creates an endless loop like While 1 creates a endless While loop. To me it is saying "repeat until false" ("repeat until true" for While loops) but this doesn't make sense to me. If some one can explain that please tell me and I will change this. Anyways, this just creates an endless loop.
Output(A,B,"*: This displays a * in row two in column two. We are displaying it here because our map from Str1 has a border around the outside parimeter. This * is also our object that will be moving.
Repeat Ans: This loop will repeat until key is pressed (the key code is stored to Ans completing the loop).
getKey?K: The getKey command is what will tell the calc to collect the key code of what ever key is pressed. This value is then stored to the variable K.
End: This ends the loop that needs a key to be pressed.
Output(A,B,"_: This will display a space over the * from the previous Output(. It effectively erases it so you don't have a trail.
Now for the doozies...haha.
A+(Ans=34 and sub(str1,16A+B,1)="_")-(Ans=25 and sub(Str1,16A-32+B,1)="_?A: So I already went over boolean logic/piecewise espressions in here so I'll just do a recap. If the statement is true it returns a 1, if false a 0. The only new part here is and and sub( commands. I will explain these independently.
-and: When this is used in a boolean logic/piecewise function expression it means that both conditions must be true to return a 1. If either or both are not true it will return 0. Pretty easy. An example of this would be:

--- Code: ---PROGRAM:TEST
randInt(0,100?A
Disp A>25 and A<75
--- End code ---

-sub(: This itself as a few different uses. I'll explain the one most people use it for, then the one that is used here.
--The usual way sub( is used is to display text. It will pull a certain amount of a string and display just that part. The way this works is there are three arguments: the string or list of characters, the point it is starting at, and how many characters it will go out to. For example:

--- Code: ---PROGRAM:TEST
"ABCDEFGHIJKL?Str1
sub(Str1,3,8 //The string, starts at the third character, goes eight out.

This will display:
prgmTEST
CDEFGHIJ
--- End code ---

Though this command can also be used with things other than just strings. For an example of this we can simply optimize our last code:

--- Code: ---PROGRAM:TEST
sub("ABCDEFGHIJKL",3,8
--- End code ---

It will display the exact same thing.
--The way it is being used here is similar but not quite. We are looking through the string but not to display. We are testing to see if the space to the left, right, above, or below the character that is moving is either a / (a wall) or a space. If it is a space then it will return 1 (assuming the correct button was pressed). (As a side note. You can replace all the ...="_" with ...?"/".) The position of the character you're looking for is done with math which you should be able to decode. I will explain it if you need me too. Just ask.
--So there is a third use that is new to one of the OS updates. If you use sub( with only one argument it will divide it by a hundred. It might save you a byte or two if you need to do that.
Ok, so in essence this line is just testing for the key pressed and if the space to where your moving is a space or not. Phew. Finally haha.
B+(K=26 and sub(Str1,16A-15+B,1)="_")-(K=24 and sub(Str1,16A-17+B,1)="_?B: This works basically the same way as the above line. Just for left and right instead of up and down (which is what the other does).
End: This completes the endless loop.

Yay, finally done :D I hope this makes sense and explains some things. I also hope this helps some of you too :)
If you see any mistakes please let me know and I shall fix them.

Again, this is not the most efficient way of doing this. This is just simply what I had come up with (with some help of the guys over here :)) Enjoy :D

Oh ya, one more thing. I thought I would throw this in here too. If you want to make a little game out of this and have score associated with it you can simply make a few changes to the code:

--- Code: ---PROGRAM:MOVE2
"////////////////
/___///___///__/
/_///___///__/_/
/______/////___/
/__///__///__/_/
/_////__//__////
/______________/
////////////////?Str1
Output(1,1,Ans
DelVarC2?A
2?B
Repeat AB=30
Output(A,B,"*
AB?D
Repeat Ans
getKey?K
End
Output(A,B,"_
A+(Ans=34 and sub(str1,16A+B,1)="_")-(Ans=25 and sub(Str1,16A-32+B,1)="_?A
B+(K=26 and sub(Str1,16A-15+B,1)="_")-(K=24 and sub(Str1,16A-17+B,1)="_?B
If AB<D or AB>D
C+1?C
End
ClrHome
--- End code ---

Hopefully this is pretty self-explanitory. The only part of this that is worth explaining, I think, is the Repeat AB=30 part. This basically means when you move to the spot where that statement is true it will exit the loop.

DJ Omnimaga:
wow very nice, should be very useful for many people starting with RPGs and the like :)

you're pretty good at tutorials btw :)

meishe91:
Thanks :D That is why I kinda made it to help people get ideas going for RPG code.

Thanks, just hoping these are helping people O0

ztrumpet:
Yeah, you are very good at explaining things. ;D

You have my permission to use anything that I've posted. :)

meishe91:
Thanks ztrumpet! :D
Also, thanks. I will probably do that tomorrow then since I'm not going to someones birthday thing...