====== Physics, Collisions ======
----
===== Basic Physics: Preliminaries =====
* What kinds of games need physics? What games have physics that you know of?
* Angry Birds, Tower/World of Goo, Crayon Physics, platformers
* Assume fixed discrete simulation (constant time step).
* Approximation (This isn't climate modeling or rocket science or something.)
* "If You Can Get Away With it, Fake it" (From [[http://www.gamasutra.com/view/feature/130848/how_to_prototype_a_game_in_under_7_.php?page=2|"How to Prototype a Game in Under 7 Days"]])
* Working with a 2D coordinate system.
* If you need a formula (e.g., that involves forces or mass), look it up.
* Keep it as simple as possible.
* Use the metric system (e.g., m, m/s)
===== Position and Velocity =====
* Question: Where is the object at time t?
* Velocity - "The rate of change of position along a straight line with respect to time"
* Speed and velocity are not the same; velocity is a vector quantity (has direction) while speed is a scalar quantity.
* Given variables: object_x, object_y, speed, angle
* Calculation of an object's next x and y coordinates (in your game loop):
* scale_x = cos(angle)
* scale_y = sin(angle)
* velocity_x = (speed * scale_x)
* velocity_y = (speed * scale_y)
* object_x = object_x + velocity_x
* object_y = object_y + velocity_y
===== Acceleration =====
* Acceleration - "The rate of change of velocity with respect to time"
* When an object moves along at a certain velocity, an amount of acceleration is __continuously__ added to the velocity.
* Given variables: object_x, object_y, speed, acceleration, angle
* Calculation of an object's next x and y coordinates (in your game loop):
* scale_x = cos(angle)
* scale_y = sin(angle)
* __speed = speed + acceleration__
* velocity_x = (speed * scale_x)
* velocity_y = (speed * scale_y)
* object_x = object_x + velocity_x
* object_y = object_y + velocity_y
===== Gravity =====
* acceleration that only acts downward in the game window
* Earth's gravity constant = 9.81 meters per second squared
* In a game world, the gravity constant will be different, depending on the frame rate.
* Given variables: object_x, object_y
* Calculation of an object's next x and y coordinates (in your game loop; assuming that the object is moving):
* velocity_y = velocity_y - gravity (gravity is a drag on vertical velocity)
* object_y = object_y + velocity_y (if the object has not hit the ground yet)
* object_x = object_x + velocity_x
* Where gravity computation might be useful
* a character jumping in a sidescroller (a "platformer"), games that involve firing projectiles
----
====== Collisions ======
===== Collision detection =====
==== Bounding box method ====
* Problem: often have irregularly shaped objects (thus wasted space).
* However, empirically, less space will be wasted using the bounding box method over bounding sphere method.
=== Collision test, two methods: ===
* 1. if (object.x >= box.min_x && object.x < = box.max_x && object.y >= box.min_y && object.y < = box.max_y) then collision occurred
* Use same approach for mouse choosing in game menus.
* In your ''mouseClicked()'' or equivalent method, check to see if the object was picked via x-y coordinates.
* 2. Use shapes in Graphics or Graphics2D and see if two intersect. Example:
public boolean collidesWith (Entity other)
{
if (other instanceof RectEntity) {
Rectangle him = new Rectangle();
me.setBounds((int) x, (int) y, sprite.getWidth(), sprite.getHeight());
him.setBounds((int) other.x, (int) other.y, other.sprite.getWidth(), other.sprite.getHeight());
return me.intersects(him);
}
else if (other instanceof CircleEntity) {
Ellipse2D him = new Ellipse2D.Double();
me.setBounds((int) x, (int) y, sprite.getWidth(), sprite.getHeight());
him.setFrame((int) other.x, (int) other.y, other.sprite.getWidth(), other.sprite.getHeight());
return him.intersects(me);
}
else if (other instanceof TriangleEntity) {
boolean collided = false;
Point2D p1 = ((TriangleEntity)other).p1;
Point2D p2 = ((TriangleEntity)other).p2;
Point2D p3 = ((TriangleEntity)other).p3;
collided = me.intersectsLine(p1.getX(), p1.getY(), p2.getX(), p2.getY()) ||
me.intersectsLine(p2.getX(), p2.getY(), p3.getX(), p3.getY()) ||
me.intersectsLine(p3.getX(), p3.getY(), p1.getX(), p1.getY());
return collided;
}
else {
System.out.println("Other Entity's shape is ambiguous!");
return false;
}
}
===== Collision response =====
* Different objects respond differently to collisions
* Some collisions will resemble that of balls on a billiards table (elastic collision).
* Angle of incidence - The angle between the ball movement vector and the plane of the billiards rail that it strikes when the ball moving in a straight line collides with it. {{ https://upload.wikimedia.org/wikipedia/commons/thumb/3/30/Angle_of_incidence.svg/200px-Angle_of_incidence.svg.png|(angle of incidence)}}
* Remember, when the ball hits the rail, it will bounce away from the rail at the same angle that it strikes the rail. (assumes no spin on ball)
* In other words, the angle of reflection = angle of incidence
* Calculation (adapted from [[http://rockhopper.monmouth.edu/~jchung/cs498gd/fa15/labs/animation/gamesprite/GameSprite.java|GameSprite.java]]):
if ((ballPoint.x + ballSpeed.x) <= plane.x) {
ballSpeed.x = (ballSpeed.x * -1);
}
if ((ballPoint.x + ballSpeed.x) >= (plane.width)) {
ballSpeed.x = (ballSpeed.x * -1);
}
if ((ballPoint.y + ballSpeed.y) <= plane.y) {
ballSpeed.y = (ballSpeed.y * -1);
}
if ((ballPoint.y + ballSpeed.y) >= (plane.height)) {
ballSpeed.y = (ballSpeed.y * -1);
}
----
===== Java 2D Gravity and Collision Examples: =====
* Gravity and collision example: CannonFireTest
* Gravity example: Lander
* Collision example: Pong
* Get all 3 Eclipse projects at https://cssegit.monmouth.edu:2443/jchung/JavaPhysicsCollisionExamples.git
----