Today, I will be making a tutorial on how to make a very BASIC homescreen collision detection engine.
I will be breaking the following code into different parts and explain in detail what each bit does.

Here is the code I am going to teach you about.
The matrix's dimension is 8x16, which is the size of the whole homescreen.

Code:
:ClrHome
:2→C:2→D
:[[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2][2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2][2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2][2,0,0,0,2,2,2,2,0,0,0,2,1,2,0,2][2,0,2,0,0,0,0,0,0,2,0,0,0,2,0,2][2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2][2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2][2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]]→[A]
:For(A,1,8)
:For(B,1,16)
:[A](A,B)
:If Ans≠0:Then
:Output(A,B,sub("WX",[A](A,B),1))
:End
:End
:End


Part 1: Displaying a visual of the data for the collision detection.

Here is the segment this part will be over.

Code:
:ClrHome
:2→C:2→D
:[[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2][2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2][2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2][2,0,0,0,2,2,2,2,0,0,0,2,1,2,0,2][2,0,2,0,0,0,0,0,0,2,0,0,0,2,0,2][2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2][2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2][2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]]→[A]
:For(A,1,8)
:For(B,1,16)
:[A](A,B)
:If Ans≠0:Then
:Output(A,B,sub("WX",[A](A,B),1))
:End
:End
:End
:Output(D,C,"θ")
:Repeat [A](D,C)=1
:getKey→K
:If K≠0:Then
:Output(D,C," ")  //1 space
:C-((K=24)([A](D,C-1)≤1))+((K=26)([A](D,C+1)≤1))→C
:D-((K=25)([A](D-1,C)≤1))+((K=34)([A](D+1,C)≤1))→D
:Output(D,C,"θ")
:End
:End
:ClrHome
:Output(1,4,"YOU  WIN")
:Pause
:ClrHome
:Return


The following segment is the matrix that will be holding all of the data for the collision detection.

This is storing your starting location.

Code:
:2→C:2→D


Please note the biggest you should have is a 8x16 matrix, which covers the entire home screen.

Code:
:[[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2][2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2][2,2,2,2,2,2,2,2,2,2,2,2,2,2,0,2][2,0,0,0,2,2,2,2,0,0,0,2,1,2,0,2][2,0,2,0,0,0,0,0,0,2,0,0,0,2,0,2][2,0,2,2,2,2,2,2,2,2,2,2,2,2,0,2][2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2]
[2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2]]→[A]


The 0's represent the empty spaces that nothing will be displayed on showing it is walkable.
The 2's however, are non-walkable positions (I will explain more when we get to the movement engine itself)
And the 1 is the "target" location, which is walkable (I will explain how that is walkable and how to adjust it later also)

Now onto the next area: Displaying the data so that the matrix is visible

This is where you tell the program how to display the matrix, since I have the "For(A,1,8)" before the "For(B,1,16)" it is going to display Left to right, 1 row at a time, now if A was after B, It would display Up to down, 1 column at a time.

Code:
:For(A,1,8)
:For(B,1,16)


This right here is telling the program which position in the matrix it is looking at to see what number it is on.

Code:
:[A](A,B)


This is going to skip over and 0's it finds so that it renders faster, which is mainly what the last segment I pointed out is for.

Code:
:If Ans≠0:Then


Now this is the fun part, and I am going to break it down a bit.

This is going to display on the current location on the Homescreen, and is equivalent to the location in the Matrix.

Code:
:Output(A,B


This is telling the Output() what character to display depending on the number in the current position of the matrix.

Code:
,sub("WX",[A](A,B),1)


Now I will also explain the sub() command for those who don't know how it works.

sub() takes a Strn or text inside quotes, like in this code "WX"
so sub("WX", is going to take the number inside of the current location of the matrix, which is the [A](A,B) bit in it, and in the order of the string, so "WX" is kinda like in the Matrix "12", while the 1 followed by the matrix is telling it to use only 1 character from the string.

This is just closing all the loops that are running as they finish.

Code:
:End
:End
:End


Part 2: The rest of the movement code

Here is where it all starts to work out.

Code:
:Output(D,C,"θ")
:Repeat [A](D,C)=1
:getKey→K
:If K≠0:Then
:Output(D,C," ")  //1 space
:C-((K=24)([A](D,C-1)≤1))+((K=26)([A](D,C+1)≤1))→C
:D-((K=25)([A](D-1,C)≤1))+((K=34)([A](D+1,C)≤1))→D
:Output(D,C,"θ")
:End
:End
:ClrHome
:Output(1,4,"YOU  WIN")
:Pause
:ClrHome
:Return



This is going to put you in the starting location, which was defined in the last part.

Code:
:Output(D,C,"θ")


This is a Repeat Loop, it only ends when the function specified is true, in this case, you standing on the spot where the number 1 is at.

Code:
:Repeat [A](D,C)=1




Code:
:getKey→K


If there is no button pushed, it will keep looping until there is one.

Code:
:If K≠0:Then


Clears your space so that if you moved your guy, he will not stay there and move on, meaning only 1 space will show him at any 1 time.

Code:
:Output(D,C," ")  //1 space


If K is equal to 24(left) 26(right) 25(up) or 34(down) then it will move your character to according to the following algorithm, which I will explain.
I will break these up to make it easier to understand.

Takes your current location for C, and subtracts it from the answer, which I am about to explain

Code:
:C-


Checks if you pressed left, if you did, it would return a 1, if not, a 0

Code:
((K=24)


This checks to see if the space behind you on the matrix is less then or equal to 1, so if that space is a 1 or a 0, then if returns a 1, if not a 0

Code:
([A](D,C-1)≤1))


so far, we have

Code:
C-(0 or 1)*(0 or 1)
in a more simple sense.

Adds the previous answer to the next set of conditions.

Code:
+



Checks if you pressed right, if you did, it would return a 1, if not, a 0

Code:
((K=26)


This checks to see if the space in front of you on the matrix is less then or equal to 1, so if that space is a 1 or a 0, then if returns a 1, if not a 0

Code:
([A](D,C+1)≤1))


Stores your new location to C

Code:
→C


So in a more simple form(won't work, but for visual aid) the code is pretty much


Code:
C-(0 or 1)*(0 or 1)+(0 or 1)*(0 or 1)→C


Now for the second movement conditional.


Code:
:D-((K=25)([A](D-1,C)≤1))+((K=34)([A](D+1,C)≤1))→D


Takes your current location for C, and subtracts it from the answer, which I am about to explain

Code:
:D-


Checks if you pressed up, if you did, it would return a 1, if not, a 0

Code:
((K=25)


This checks to see if the space above you on the matrix is less then or equal to 1, so if that space is a 1 or a 0, then if returns a 1, if not a 0

Code:
([A](D-1,C)≤1))


so far, we have

Code:
D-(0 or 1)*(0 or 1)
in a more simple sense.

Adds the previous answer to the next set of conditions.

Code:
+



Checks if you pressed down, if you did, it would return a 1, if not, a 0

Code:
((K=34)


This checks to see if the space in below you on the matrix is less then or equal to 1, so if that space is a 1 or a 0, then if returns a 1,
if, not a 0

Code:
([A](D+1,C)≤1))


Stores your new location to D

Code:
→D


So in a more simple form(won't work, but for visual aid) the code is pretty much

Code:
D-(0 or 1)*(0 or 1)+(0 or 1)*(0 or 1)→D


Places you on the new location.

Code:
:Output(D,C,"θ")


Closes the If K≠0:Then loop

Code:
:End


Closes the Repeat Loop.

Code:
:End


This is what will display if you get your character to the 1 in the matrix, which will make the Repeat function true, and go to the next line after that Loop is closed.

Code:
:ClrHome
:Output(1,4,"YOU  WIN")
:Pause
:ClrHome
:Return



There is my first tutorial, and I hope this help many of you sometime. :D
I think there should be at least 3 sections:
(1) Initial Values and Initial Display
(2) Movement Code
(3) Collision Detection
MufinMcFlufin wrote:
I think there should be at least 3 sections:
(1) Initial Values and Initial Display
(2) Movement Code
(3) Collision Detection


But the thing is, the Collision detection needs to be taught with the Movement, as it is part of the Movement Code itself. :/
*EDIT* Would it be possible for me to not be forgetful and stupid?
Beta7 wrote:
Would it be possible to make it go up to 4 or 5 in the matrix, and then have separate conditions for various numbers in the matrix (so there's more than just walls, open spots, and goal)?
Of course; you can have an arbitrary number of values, to indicate things like different objects and sprites, things that can be picked up, things that trigger events, things (people? NPCs?) with which you can interact, and lots more.
Beta7 wrote:
Would it be possible to make it go up to 4 or 5 in the matrix, and then have separate conditions for various numbers in the matrix (so there's more than just walls, open spots, and goal)?


The number's in the matrix can go up as far as you need it, and for it to do things, that will have to be triggered if you are on that particular spot, so lets say you wanted it to change matrices like a warp, after the movement, if you are on that number, you would either call a subroutine that will change it for you, or even store a premade one to the one you use to display, and redisplay it, does that make enough sense?
I prefer to use lists, matrics are hard to expand, collapse, are sizely, and hard to make permanent changes to in basic...
Basically my idea is to have 2 list. the first list is list XC and the second is list YC.List XC contains the x coordinates of all the collisions and YC all the Y collisions, so say there were only collisions at (3,4), (5,2), and (7,5).The lists would look like...

Code:
XC = {3,5,7}
YC = {4,2,5}

you can easily add more collisions by using the augment( command.
this is an example of checking for events depending on a location...

Code:
:Repeat sum(X=LXC) and sum(Y=LYC)
:getKey -> K
:if Ans text(Y,X,"   [three spaces here]
:X+(Ans=26)-(Ans=24 -> X
:Y+(K=34)-(K=25 -> Y
:text(Y,X,"R
:End
:[the rest of the code if there was a collision
Anakclusmos wrote:
I prefer to use lists, matrics are hard to expand, collapse, are sizely, and hard to make permanent changes to in basic...
Basically my idea is to have 2 list. the first list is list XC and the second is list YC.List XC contains the x coordinates of all the collisions and YC all the Y collisions, so say there were only collisions at (3,4), (5,2), and (7,5).The lists would look like...

Code:
XC = {3,5,7}
YC = {4,2,5}

you can easily add more collisions by using the augment( command.
this is an example of checking for events depending on a location...

Code:
:Repeat sum(X=LXC) and sum(Y=LYC)
:getKey -> K
:if Ans text(Y,X,"   [three spaces here]
:X+(Ans=26)-(Ans=24 -> X
:Y+(K=34)-(K=25 -> Y
:text(Y,X,"R
:End
:[the rest of the code if there was a collision




DO you read anything whatsoever?!?!?! READ THE a TITLE, IT IS A MATRIX COLLISION DETECTION TUTORIAL, NOT HOW THE HELL CAN YOU MAKE IT SOMETHING ELSE!! >.>
gah, was just offering an alternative Razz
Anakclusmos wrote:
I prefer to use lists, matrics are hard to expand, collapse, are sizely, and hard to make permanent changes to in basic...
Basically my idea is to have 2 list. the first list is list XC and the second is list YC.List XC contains the x coordinates of all the collisions and YC all the Y collisions, so say there were only collisions at (3,4), (5,2), and (7,5).The lists would look like...

Code:
XC = {3,5,7}
YC = {4,2,5}

you can easily add more collisions by using the augment( command.
this is an example of checking for events depending on a location...

Code:
:Repeat sum(X=LXC) and sum(Y=LYC)
:getKey -> K
:if Ans text(Y,X,"   [three spaces here]
:X+(Ans=26)-(Ans=24 -> X
:Y+(K=34)-(K=25 -> Y
:text(Y,X,"R
:End
:[the rest of the code if there was a collision

The large problem with this is that it has to go through very many checks if there are many objects on the map. Along with there isn't much of an easy way to have it check. Yes you can have your X check if it equals any of the x coordinates, then Y with the Y coordinates, but then you have to be sure that the same x coordinate is with the same y coordinate, otherwise you run into some weird situations. Along with, you'll then have to have another method for it to remember different objects. i.e. if you have blocks and walls, then you have to have a walls x, and a walls y, then a blocks x, and a blocks y list. Then it has to check if your coordinates are the same with any of those, and then do a check to be sure that the same x is equal to the same y coordinates. With matrices, you can simply the coordinates at a specific place, little more than that is ever needed.
dunno. Usually use strings since you make the background with em anyway. I just was playing around yesterday when I realized the speed of lists.If guess matrices would be a great thing to use if you dont require many changes to the map...
Anakclusmos wrote:
matrics are hard to expand, collapse, are sizely
No more sizely than lists. A 100-element list is the exact same size as a 10x10 matrix.

Also, Sonlen, chill dude.
KermMartian wrote:
Anakclusmos wrote:
matrics are hard to expand, collapse, are sizely
No more sizely than lists. A 100-element list is the exact same size as a 10x10 matrix.

Also, Sonlen, chill dude.


Kerm, sorry, but 2 retarded posts in a row, within 5 minutes, first FFME, then here, and because he doesn't read anything....

It just gets annoying......
i was more pointing along the lines of expanding, collapsing, and providing permanent changes too.
Anakclusmos wrote:
i was more pointing along the lines of expanding, collapsing, and providing permanent changes too.



Entirely outside the point of this tutorial.....
I recommend you give up in this tutorial, as it seems you don't understand what it is about......
The tutorial was pretty much coverered in Sonlen's first post, I was just trying to point out the ups and downs of using the method and offer alternatives
Anakclusmos wrote:
The tutorial was pretty much coverered in Sonlen's first post, I was just trying to point out the ups and downs of using the method and offer alternatives


Then make another topic about that, not flood my tutorial with things I was not even talking about, nor going to.
Sonlen - you should add a part about how to make multiple maps without taking up 500 bytes per map. Razz
Beta7 wrote:
Sonlen - you should add a part about how to make multiple maps without taking up 500 bytes per map. Razz


Well it isn't quite 500 bytes per map, but I am still working on that one >.<.
Its very good that you learned how to do that. Now you should figure out how to do it with strings Smile
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement