Examples:
- ScrollAndZoom:
- Left-Thumb-Stick to scroll around the world
- Right-Thumb-Stick-X to zoom in/out (what is the reference
position)? Can you change the reference?
- Zoom with respect to world center:
- Controls are identical to above
- Math: simple!
- user changes: WorldWidth
- SetWorldCoordinate(Org, WorldWidth)
- We need to compute Org such that WorldCenter does not change
- Org needs to be move by half of new worldsize change
- The Camera Class:
- A fake class!! (because we cannot instantiate more than one of these!).
A simple wrapper over XNACS1Base.World.
- A/B Button: to zoom in/out
- Left Thumb Stick: to move the camera, notice, as the soccer
balls gets to the boundary of the camera view, you can't move the camera
anymore! (More about this later)
- Right Thumb Stick: to move the soccer ball. Notice as the soccer
ball gets to the boundary, it "pushes" the application window. Here,
the logic in our code makes sure the camera view always sees the soccer
ball. (Camera Safe Zone).
- Function: MoveCamera() - trivial offset of WorldCoordinate
origin.
- Function: ZoomBy() - changes the width of the camera view, exactly the
same functionality as previous example, just we hide this in a class.
- Function/Attribute: SafeZonePercentage/KeepPointInSafeZone()
- "Safe Zone" is something I kind of invented, this is the area where
you want important positions to stay within. E.g., if your hero moves
beyond "Safe Zone", you will update your camera to "chase after it".
- By default, I define my "Safe Zone" as 90% of the world size.
Whatever works for you.
- KeepPointInSafeZone(): computes input position, makes sure the
position is within 90% of camera view.
- The reason why we cannot "move" our camera to outside of the soccer
ball with LeftThumbStick is because KeepPointInSafeZone() stops us!
- Roll a ball and scroll the world:
- Left Thumb-Stick-X: to zoom with-respect-to center
- Right Thumb-Stick: to change ball velocity
- Small and Large ball rotates at different rate that obeys' their speed
- RollingBall: class. notice:
- All the functions to hide Circle's velocity!!
- VelocityDirection is not hidden, and it is UNUSABLE!!
- Update: angular displacement theta = Speed/R, and
remember to convert to degree for RotateAngle
- Notice: Easy to use with abstraction ... the camera class.
- Simple fake physics:
- Left Thumb-Stick: Set initial velocity
- Right Thumb-Stick X: to change "fake" friction
- Right Thumb-Stick Y: to change "fake" collision
elasticity
- A-Button: To shoot the soccer ball with the velocity defined
by LeftThumbStick
- Press-A to observe:
- Gravitation pull effect: continuously decrease y-velocity by a
constant (deceleration).
- Complex condition for the ball to stop motion!
- onTheFloorHeight: slightly higher than the ball radius
- Notice: the ball is the "RollingBall" from above, where rotation
is controlled by VelocityX only (instead of Speed)
- Friction:
- apply only when ball is in contact with the floor (<onTheFloorHeight).
- Scale the current velocity by "frictional force": here we say,
the faster you travel, the more friction you encounter. May be true?
may not be true. Whatever. Looks cool.
- Elasticity:
- How much "energy" (speed) is lost at a collision.
- Again, we scale: you lost a "proportion" of your energy/speed.
- How accurate? Well, it looks cool.
- Question: How come with elasticity of one, the soccer
ball's y-velocity will go to zero? Great question!!
- Gravity and Parabolic Freefall:
ignore if you want. This is to show, math and physics actually works. But
too tedious for us to care.
- Right-Thumb-Stick: to change the initial projectile velocity
- A-Button: to initial the projectile motion
- To compute gravitational pull, in each update we must:
- Update position by Velocity
- Update Velocity by Acceleration (VelocityY by gravity)
- Notice the order of operation is important because the library always
travels the primitives before calling the UpdateWorld() function:
- Red projectile trace: shows velocity is changed before
position computation
- Green projectile trace: shows position is updated before
velocity is updated (what the library implements).
- Notice the computeTargetPosition() function:
- Our unit is in "Number of Updates"
- Takes the center of an update (by adding 0.5 to the tmToHitYMax)
- add 0.5f when computing the initial y-displacement because position
is changed before the UpdateWorld() function call.
- Remember first day of class?
- I said we don't care about the order of the
updates? Well, I lied!
- We don't care unless we care about any kind of "real
math/physics"!!
- Do we care about math and physics?
- Is the Red-Path more correct or the Green-path? Do you care?
- Answer: whichever one looks better! So: the same! So, we don't
care about "real physics", not in this case/class.
- Collision and Conversation of
Energy:
- A-Button: to shoot the hero towards the target
- B-Button: randomize the target
- Right-thumb-X: controls the hero radius
- Right-thumb-Y: controls the hero speed
- The CircleWithMass class:
- Use area as mass (PI*R*R)
- When collide with another circle with Mass, resolves velocity
correctly in preserving kinetic energy and normal-direction
momentum.
- ClassExample::ComputeHeroVDirection():
use hero Speed and Target velocity to compute a hero velocity such
that hero will collide with target somewhere in the future.
Here is the math, code, and
detailed explanation of the implementation.