I’m making a top down racing/time attack ish game for my APCSP Practice Create Task, and I have the movement pretty decently put together, but when I got to making a script to detect wall collision with the track you race on, I can’t find a way to do it smoothly, as all the “touching” predicates generate obscene amounts of lag on the game. Tried asking my teacher he didn’t rlly have any ideas either lol
touching (color): very laggy, at least it works I guess.
(color) touching (color): very inconsistent for some reason, whether it works or not changes every time I place it inside a script, half the time I’ll make the predicate, and it just reports false no matter what I do? I assume it’s some kind of issue on my end. Generates the same lag as touching (color) though.
touching (sprite): same lag, however, doesn’t allow me to differentiate between walls and obstacles/killzones. If I can get it to work with this that’s still fine, I’ll just remove the killzones, like with the method I saw on another post of cloning the sprite and color coding the costume’s parts
NOTE: This reply was supposed to go underneath the other one below, but due to a quirk in timing it ended up being posted a few seconds before the other one so this is slightly hard to read. Go read my second comment (below) first, then this one will make more sense.
Then each sprite has its own behavior that it does if it receives the “touching player sprite” message (obstacles might make the player sprite stop or bounce (change direction), killzones might set the “player has lost” variable to “true”, and so on).
P.S. Here’s a block image, which might be more helpful than that Lisp code.
The best way to detect collision in Snap! is to check for collision between sprites, because this lets Snap! do several clever tricks to make it faster.
First, all sprites have an invisible box around them called the “bounding box”. It’s the smallest possible rectangle that fits around the entire sprite with no parts sticking out. When Snap! checks whether two sprites are touching, it first checks whether their bounding boxes are overlapping. (This is a VERY fast check). If the bounding boxes aren’t touching, then it’s impossible for the sprites to be touching, so the rest of the checks are skipped.
And there’s another way to speed up collision checks between sprites: the “my neighbors” block in the Sensing category. That block reports a list of the sprites that are close enough that they could POSSIBLY be touching. If you have dozens of sprites, but most of them are far away, then the “my neighbors” block will skip most of them.
So first, you could set up the things that have an effect on the game (obstacles, killzones, etc) as sprites. Then you can use the “my neighbor” block in a loop that checks only the other sprites that can possibly be touching the player’s sprite. That should go a lot faster than using the “touching (color)” block.
That second check (“else if not direction”) is unnecessary: if the “if direction” check fails, then “if not direction” is guaranteed to succeed unless something has changed the value of “direction” in the microseconds between the two checks. So anywhere you’re doing that, you can just write this instead, which will be simpler:
I don’t yet understand the purpose of your “direction” variable since I don’t see anything that changes it, but perhaps it’s going to change in code you haven’t written yet. But even once it does change, the “else if not direction” check is still going to be unnecessary, so your code will be simpler if you leave it out.
the “not direction” is there because for some reason direction=0 registers as direction=true in the code, so I have the not direction in there so the script doesn’t misfire as soon as the program starts
direction controls the direction of the deceleration, and is set by the acceleration block (forwards sets it to true, backwards sets it to false)
basically if you last accelerated forwards then you decelerate forwards as well, and if you last accelerated backwards, then you decelerate backwards
for the collision script this also allows me to detect what direction the player is headed in and reflect the momentum accordingly
I tried this, it does run smoother with the wait block however the script doesn’t actually work because adding any wait block creates blind spots that allow the sprite to phase through the wall, and without the wait block there isn’t a noticable difference
since the track as a sprite has to be very large to fit the player and include a lengthy course within it the bounding box check is pretty much null, and even without adding other sprites to test the neighbors block didn’t have any impact on the performance, but I’d guess if I separated the killzones that would only lag the game further since it’s doing extra checks it doesn’t have to when the track is one sprite
If that’s the case, then the second condition wouldn’t even run. If direction is always going to be greater than 0, then I would suggest doing this for the first condition <(direction :: variables) > [0] @<:> > instead, or if it can be negative, just use <(direction :: variables) != [0] @<:> >