DMSC Devlog: Week 5 - Special Delivery!
This week’s assignment, originally from March, set me up with bug-fixing puzzles I’m still wrangling with now. The premise: program a robot (affectionately termed “Alfie”) that delivers boxes across the screen and bounces off obstacles. It’s an assignment about collision, and on paper the core of the puzzle is distinguishing “box” from “obstacle”.
Step 1 is to represent Alfie’s movement as a vector. Up to now, we had used individual X and Y variables to represent an object’s position and rates of change, as with Week 2’s iceberg. Switching to vectors allows us to not only store each X and Y coordinate pair as its own p5.Vector object, but also leverage the library’s built-in vector functions, making programming changes in velocity (and, later, acceleration) way easier.
this.position = createVector(width - width/10, height/2);
this.velocity = createVector(random(-1,-0.3), random(-3,3));
Step 2 is to create basic collision between two objects. Using circles for our objects’ hitboxes simplifies this process greatly, as the distance between their centers only has to be less than the sum of their radii for them to be touching. To make Alfie carry one box at a time, we only attach a box to his coordinates if he isn’t holding another box and if the box hasn’t been delivered yet.
if (alfie.position.dist(box.position) < alfie.radius + (box.width/2) && alfie.holding == false) {
if (box.held == false && box.delivered == false) {
alfie.holding = true;
box.held = true;
}
}
// ...
// To help Alfie get stuck less, this preemptively checks if he'll collide with an obstacle on the next frame
let positionNext = p5.Vector.add(alfie.position,alfie.velocity);
if (positionNext.dist(obstacle.position) < this.r+i.r) {
this.position.add(this.velocity)
}
Now we just have him change direction if he hits something else and we’re set, right?
Well, we can’t just reverse course if we hits a round obstacle. We need to distinguish hitting the side of an object (reversing the velocity’s X coordinate) from hitting the top or bottom (reversing the Y coordinate). That means Alfie would need to check the angle of collision with an obstacle to determine where he goes next, and since we’re already doing all this work, we might as well reflect the angle of his velocity over the angle of collision to make it feel satisfying.
Here is a sketch I wrote to make the math easier for myself. The orange line represents the velocity of an approaching Alfie, the red lines show the angle between Alfie’s velocity and the point of collision, and the green line shows Alfie’s resulting trajectory:
Step 3 is translating all this code to collision with multiple objects. Both types of collision need to check Alfie’s position relative to what he collides with, and in my pursuit of efficiency, I figured I could decrease the number of arrays I needed to write if I bundled the loop that checks every object’s relative position into the loop that draws every relative object.
// In the draw function
for (i=0;i<obstructs.length;i++) {
alfie.collision(obstructs[i]);
}
// and in Alfie's collision function
let iDirection = p5.Vector.sub(this.position, i.position);
let vMag = this.velocity.mag();
if (this.position.dist(i.position) < this.r + i.r) {
print("collide!");
}
It’s rough-looking, hard to bugfix, and can’t be translated to sketches with multiple Alfies. But it’s satisfying!
Step 4 is making the obstacles move. This introduced a slew of problems into the way I coded Alfie’s changing direction: I had to adapt if he hit an obstacle at too wide an angle, or two obstacles at once, or obstacles that overlapped, or an obstacle and a wall at the same time to keep him from doing mating dances around whatever he touched. It took WEEKS before I tried the lerp() function and got a reliable fix I could adapt to other projects, and I’m still having issues getting some vector functionality to work. So, this is where I’ve left Alfie. He’s been through a lot and a quarter of his code is commented out (see it here!), but he’s given me a lot of learning experience, and I look forward to what his framework turns into later.
-Rafi
Drawing, Moving, and Seeing with Code Devlogs
Status | In development |
Category | Other |
Author | rafi.pdf |
More posts
- DMSC Devlog: Week 4 - Random Seeding13 days ago
- DMSC Devlog: Week 3 - Class Work66 days ago
- DMSC Devlog: Week 2 - Made for Walking73 days ago
Comments
Log in with itch.io to leave a comment.
Heheh, Alfie really gets knocked around in that last one.
Nice work building little learning modules leading up to the final version. Also, great work integrating lerp() for some more natural movement. Now you have a nice bag of tools. This is some good pre-written code that can be adapted for lots of projects going forward. I think slowing it down and adding your own graphics and more of a procedurally generated environment would be obvious next steps if you wanted to go further with this kind of thing.