Now with Images
Next up was adding images to the project.
Basically just replacing the letters with AI-generated balls.
Features
Pressing spacebar will spawn new balls with a random velocity.
The balls can bounce off the canvas and each other transfering their impuls.
Restart the app with "CTRL + R".
Upcoming
At this point a bit more gameplay would be nice.
Maybe like Bricks that can be destroyed with a ball while controlling a paddle.
Or we add sound on impact next.
Details
There is now an AssetManager, that can load images, and the AABBPhysicsEngine now supports a "complex" collision solver.
The AssetManager can register new assets, which should be done on game-construct.
After the required images have been registered, they should be loaded with the loadAll function of the AssetManager.
Currently loading new images at runtime is not really supported.
export function registerAssets(asset_manager: AssetManager) { asset_manager.addImage("ball-blue", assets.ball_blue); asset_manager.addImage("ball-red", assets.ball_red); asset_manager.addImage("ball-green", assets.ball_green); asset_manager.addImage("ball-cyan", assets.ball_cyan); asset_manager.addImage("background", assets.background); }
The complex solving for physics solution allows for more dynamic collisions between two colliding objects.
It will take into account the speed and angle the objects hit each other and change there velocities based on their impact force,
instead of simply inverting the speed.
public solveCollisionComplex(collision: AABBCollision) { const { overlap, a, b } = collision; const overlap_rect = Rect.fromBoundingBox(overlap); // calculate the new velocity for each box const a_mass = a.outerBox.size.x * a.outerBox.size.y; const b_mass = b.outerBox.size.x * b.outerBox.size.y; const total_mass = a_mass + b_mass; const impact_vector_a = b.outerBox.center.cpy().sub(a.outerBox.center).normalize(); const impact_vector_b = impact_vector_a.cpy().mul(-1); const a_force = a.velocity.dot(impact_vector_a) * (a_mass); const b_force = b.velocity.dot(impact_vector_b) * (b_mass); const impact_force = a_force + b_force; a.velocity.add(impact_vector_b.cpy().mul(impact_force / a_mass)).mul(0.999); b.velocity.add(impact_vector_a.cpy().mul(impact_force / b_mass)).mul(0.999); if (overlap_rect.w < overlap_rect.h) { // if the overlap is taller than it is wide, then the collision is horizontal const a_direction = (overlap_rect.center.x < a.outerBox.center.x) ? 1 : -1; a.outerBox.center.x += overlap_rect.w / 2 * a_direction; const b_direction = (overlap_rect.center.x < b.outerBox.center.x) ? 1 : -1; b.outerBox.center.x += overlap_rect.w / 2 * b_direction; } else { // if the overlap is wider than it is tall, then the collision is vertical const a_direction = (overlap_rect.center.y < a.outerBox.center.y) ? 1 : -1; a.outerBox.center.y += overlap_rect.h / 2 * a_direction; const b_direction = (overlap_rect.center.y < b.outerBox.center.y) ? 1 : -1; b.outerBox.center.y += overlap_rect.h / 2 * b_direction; } }
Comments