How to use hitboxes on my map
-
I made a map and I made the hitboxes thing in the map editor but I don't know how to use it, when I tried using the detectmapcollision() and all those but when I did the hit boxes of my map were not where I put them in the map editor. I tried to make my character stop when he hits a hitbox but I found a problem, I made it where if my up button is pressed it will increase the y value of my camera and is moves the camera with my player, but when I hit a wall my camera moves but not my player. How do I fix this?
-
When you draw your map, are you doing
drawMap()
on its own or are you using custom draw coordinates? Because doing something likedrawMap(100, 100)
will offset the collision data. Collision data and map drawing are two separate processes to allow for custom drawing effects without interfering with collision data.Make sure you're just using
drawMap()
on its own, and using the sprite camera to move around the map.Secondly,
detectMapCollision()
will only tell you if you are colliding - just a true/false. If you want to enable collision behaviour, you can usecollideMap(sprite)
to make the supplied sprite interact with collision boxes. This will be a default collision behaviour (where the sprite cannot move past the collision boxes), but if you wanted specific custom collision behaviour you can get all the information regarding a collision and perform the operations you want.collideMap()
returns an array of collisions, each one with a bunch of properties to check. You can also say whether you want the sprite to be affected by collisions or not, and still get the same information. Let's imagine you have a sprite called "player":// Get all map collision data and allow it to affect the sprite collisions = collideMap(player) // Get all map collision data but do not allow it to affect the sprite collisions = collideMap(player, false)
Here's an example of using it in a main loop sort of program:
loop clear() // Call collideMap and store the result in a variable collisions = collideMap(player) // Loop over all potential collisions (if there are none, len(c_map) will be Zero and therefore this loop will not happen for i = 0 to len(collisions) loop // We can check the collision properties in this loop. For example, if you are on the left of the collision box: if collisions[i].resolution_b.x > 0.1 then // This tells us that the player sprite is pushing positively on the x axis of the collision box endif // If you are on the right of the collision box: if collisions[i].resolution_b.x < -0.1 then // This tells us that the player sprite is pushing positively on the x axis of the collision box endif repeat drawMap() drawSprites() update() repeat
It's quite tricky-looking at first. But remember these things:
- collideMap() returns an array of collisions, so to avoid errors we must loop over them like in the example above (because there may not be any collisions happening)
- resolution_a describes how the sprite must be pushed out of the collision box to resolve the collision. If your sprite is pushing from the left side of the box, resolution_a.x will be negative (since the sprite must be pushed backwards, to the left, to resolve it.
- resolution_b describes how the sprite is pushing on the box. If your sprite is pushing from the left side again, then resolution_b.x will be positive
- You can get all this information without enabling collision behaviour by using
collideSprites(sprite, false)
(the false tells Fuze to not resolve the collisions, but we still get all the data to do what we want with).
I know this is a lot to take in - but you are asking good questions and you are clearly motivated so I hope this can be useful to you. Keep us posted :)
-
This post is deleted! -
This post is deleted! -
This post is deleted! -
@dave how do I make it where if I enter a specific hitbox it does someone different than one that's just hitting the wall? For instance a hitbox called "wall" makes it where if I hit it, it will stop me, but a hitbox called "shop" will load shop stuff?
-
@soggy-games Great question. For that, you can use named map areas.
In your map, you can name a collision box by pressing X when the cursor is highlighting that box. You can then enter a name - for example "shop" like you said.
Although - for simple walls I would recommend not using named areas - walls should be covered by the default
collideMap()
behaviour. However, named areas is perfect for your shop example!You might want to do all sorts of stuff, like loading a new map or moving the player to a different region or simply just bringing up some menu when the player is on the shop, so I will just show you the basics here of how to interact with a named map area, then you can experiment, get an idea of how you want it to behave and then maybe I can help with more specific stuff.
Simple
The most basic way is to simply just check if your player is on the shop area with
detectMapAreaCollision()
if detectMapAreaCollision("shop", player) then // These instructions will only happen when the player is colliding with a "shop" area endif
This method will not apply any collision behaviour and only returns a
true
/false
so it is quite limited in terms of information, but if all you need to know is whether the player is on the area, it will do fine!More Detailed
To get more detailed information, you can use
collideMapArea()
. By default, this will apply collision behaviour - but you can disable this and get access to all collision data without having the player "pushed" by the collision box:// The "false" parameter below stops the player from being affected by the collision box, but we still keep all the data collisions = collideMapArea("shop", player, false) // Since collideMapArea() returns an array of collisions (there might be more than 1 happening at once), we must loop over the collisions and check them. Inside this loop is where the Area Specific behaviour should be written: for i = 0 to len(collisions) loop // We could check if a collision exists: if collisions[i].exists then // We know that a collision exists here - like doing detectMapAreaCollision() endif // We could check if the player is colliding from below the box, for example: if collisions[i].resolution_b.y < -0.1 then // We know that the player sprite is pushing upwards on the collision box from below endif repeat
Switching Maps
Like I said, if you had a separate shop map and you wanted to load that in then will get a little bit more complicated - not a lot though. It's certainly very doable, you will just need some flags to prevent things from loading/unloading more than once.
Let's imagine your maps are called "main" and "shop".
// We could use a variable to keep track of the current map: current_map = "main"
You could create a function which loads a new map, and is called upon a button press. It would also update the current_map variable so we can check which map we're working on. Something like this:
function loadNewMap(map) unloadMap() loadMap(map) current_map = map return void
You could then call this in your main loop on a particular button press.
A very important concept to use here is the idea of comparing the controls to the previous state of the controls on the frame before. This stops things from repeatedly triggering, and it is very neat. Make sure you have a global controls variable, and a global variable for the previous state:
c = controls(0) c_prev = c
With those, we need to make sure they are set correctly in our main loop:
loop clear() // At the beginning of the loop, we update the current state of the controls c = controls(0) // Your game code goes here drawMap() drawSprites() update() // At the end of the loop, we store that state into the c_prev variable c_prev = c repeat
With that setup, we can use them in if statements to make sure a button press only triggers once by using something like this:
// If A button is breing pressed but WASNT being pressed on the previous frame: if c.a and !c_prev.a then
Right, now we have all the tools we need.
In your main loop, we might have something like the following code to switch between main and shop maps:
// We can now check for collision with certain areas, and make sure that our current map is the one we want: if current_map == "main" then if detectMapAreaCollision("shop", player) then if c.a and ! c_prev.a then // Because of our controls technique - this function is only called once - exactly what we want! loadNewMap("shop") endif endif endif // Then you can have a similar if statement to check for areas inside the shop, for example - an exit: if current_map == "shop" then if detectMapAreaCollision("exit", player) then if c.a and !c_prev.a then loadNewMap("main") endif endif endif
Hope this helps. Well done for persevering. Looking forward to seeing the project.
-
@dave I don't know what I did wrong but I can't exit the shop in my game, here's the download code:
SS3K3MND9D -
@soggy-games I don't see a game with that code on our server - I suspect you may have done the "share program" part but still need to "submit" the program from the Share menu.
- From the Main Menu, go to Share.
- Once it's loaded, press the R button until you see "My Shared Programs"
- Select the program you want to submit with the A button, then select "Submit" from the menu.
Once you've done that we can approve the program and I'll take a look!
-
@dave it should be uploaded now, Thanks!