Week 1 Examples: MVC + Speed + Direction + Velocity + Path SoruceCode zip flie
- EmptyTemplate Project:
- Completely empty
project.
- Good to begin
programming with GTCS1Lib.
- API model: Init,
Update, and Draw
- Assumption on underlying:
there is a "model"
- What is the model?
Well, you game!
- Assets: REQUIREMENT
folder structure
- Resources with three
subfolders: Audio/Fonts/Textures
- Spelling must be
correct, organization is required
- Build property for the asset files!! ß Make sure you know
what this is, otherwise, you will waste a lot of time!! (If you add in a
texture but it does not show in your game, THIS IS THE CAUSE!)
- Things to note:
- Do not create
graphical primitives before InitializeWorld() is called (system
initialization may not be completed)
- Opaque texture on
circle shows rectangle image
- SetWindowPixelDimension():
can only be called from InitalizeWorld() [bad
limitation: cannot toggle full screen during
runtime!]
- Development
environment:
- Solution vs Project
names
- Icon image
- Compile target name
- Default file and class
names
- Default namespace
names
- Default executable
file location and name
- Default game window
title bar name
- GUID name of the app.
- Useless stuff in the
development environment that you should remove before sharing your
source code
- MVC: Model-View-Controller
- Model: user defined,
should be in a separate class representing your game state. Must persist
over Update/Draw cycles. In our case, instance variable of your class
subclassing from XNACS1Base class.
- View: The DrawWorld()
function. By default, drawing happens automatically. No need to do
anything, except when you want to avoid drawing an object
(RemoveFromAutoDrawSet()).
- Controller: The
UpdateWorld() function, accepts user input and modify the Model accordingly.
- In this Examples
- Model: SoccerTarget, you
can create one, update it (moves towards the right), and destroy it.
- Controller: A: to create, B: to
destroy, Right-ThumbStick: to move it.
- Try: press-A button
multiple times. See left over soccer, why? How to handle this?
(RemoveFromAutoDrawSet());
- Speed:
- A-Button to shoot the ball,
- Right-Thumb-Stick-Up/Down to change the speed
- Only function to pay
attention to is: ComputeBallSpeed()
- This example (in fact
most examples) are not designed according to MVC, this is for
illustrating specific concept!
- Note the
World.TicksInASecond constant, this is a not-very accurate approximation
of number of UpdateWorld() functions call in a second.
- Note, it is accurate
that we cover 100 units in exactly 200 updates.
- Our game world is
defined against "Update" calls and not against wall clock.
- Notice:
- ShouldTravel
- Velocity (different
from Speed)
- AutoDrawSet functions:
AddTo and RemoveFrom (default: all created primitives are in
AutoDrawSet)
- Constant speed with changing direction:
- A-Button to assign a new
direction for the ball.
- Only function to pay
attention to is: SetRandomBallVelocityDir()
- Allocate a random
direction (call RandomFloat())
- Normalize the
direction
- Ball's velocity is the
normalized random vector multiplied by the speed
- IMPORTANT: notice the
UseXNACS1Lib compiler directive: the library supports setting velocity
direction (mBall.VelocityDirectoin) and speed separately (mBall.Speed)
- Constant direction with varying speed:
- A-Button to assign a new
direction for the ball.
- Right-Thumb-Stick-Up/Down to change the speed
- Interesting point:
- UseXNACS1Lib: DOES NOT
WORK!! As the speed decreases and approaches zero, the ball starts move
randomly!! (lost direction information when speed is zero).
- Vectors and Seeing Vectors:
- A-Button: to add a new Vector at
the end of the current one
- B-Button: Clear all existing work
- Left-Thumb-Y: increase/decrease
vector size
- Right-Thumb: change current vector
direction
- ShowVector class:
- math: Pay attention to
the UpdateEndPoints() function.
- XGCS1Lib:
RemoveFromAutoDrawSet(),
- Update Vector by right
thumbStick notice: Normalize()
what happens if we don't call this function?
- Button-B:
World.RemoveAllFromDrawSet()!
- Changing velocity and speed:
- B-Button: to change direction of
the ball (with same speed)
- A-Button: will change the speed
without changing the direction
- Now, lets look at the
colorful line again: constant speed (towards the right)
- But, what if instead of
moving towards the right, I want to move in some other directions?
- Roads are now instance
variables (to avoid re-creating rectangles)
- GenerateRandomBallVelocityDirection():
notice:
- RandomFloat function
- Normalize()
- SetEndPoints()
- How we line up the
roads: line equation somewhere?
- The two options in the
for loop for computing nextPos
- Notice:
TopOfAutoDrawSet() (in button B Clicked)
- Ball follow path: Define and implement a soccer ball that continuously
follow the vector-segments defined (follow the direction). The soccer ball
should cover each segment in a fixed amount of time (faster on the short
segments and slower on the longer segments). This goal of this
exercise/example is to demonstrate direction (velocity) and magnitude
(speed) of vectors.
- Left Thumb-Stick-Y: Change current
road segment length
- Left Thumb-Stick-X: Change how much time
the soccer ball has to cover the segment
- Right Thumb-Stick: Change current road
segment direction
- A-Button: Add in new road segment
- Ball follows current segment
of road it is on
- MySoccer class: it has
AI!? no!!
- A Simple Finite State
Machine, treats each "Road Segment" as a distinct state
- mCurrentRoadSegment as indication of which
"state" it is in
- State transitions:
- if travelled distance
> current segment size, transit to next state (next road segment)
- if at the very last
state (last segment), transit to the first state again.
- Road class: simple array
of ShowVector
- Update(): of main program is
simple:
- Handle User: Insert new road
segment
- Handle User: Get new
direction/size for current road segment
- Handle internal
behavior (AI): Tell
ball to update itself (because road's new values)
- Handle boundary
condition (win/loose): Reset if necessary
- If last segment
direction change while the ball is on it, have to make sure the ball
follows!! Can we make the ball “stick” to the road?
- Ball sticking to path using distance travelled: Identical to the above
example, only differences are
- Instead of moving ball from
what every position it is in towards the end of the current road-pathway,
we make sure the ball is actually on the road.
- All the actions are
in MySoccer::UpdateBallDirAndSpeed():
- travelled: distance already
travelled along the road.
- Center = road.StartPos
+ travelled * dirOfRoad
- Notice, we try to
adjust the Speed according to the remaining distance left.
- Ball stick to path using number of ticks left: exactly the same as
above, the only differences here are:
- mNumTicksLeft: this is the instance
variable inside the MySoccer class telling us how many more ticks before
we come to the end of the current road segment.
- Update(): notice the
state transition condition is trivial now! Just check if we have use up
all the ticks.
- Once again, all the
actions are in the MySoccer::UpdateBallDirAndSpeed() function:
- Change mNumTicksLeft
if this is negative (meaning we are beginning a new road segment)
- Center position is now
a percentage of ticks that has happened, percentage of the entire road
length
- User shortening path
may cause ball to travel backwards!
- We still compute speed
according to how much distance left we have to travel.
- General Observation:
- Process
Button-A first or process Button-B first? (try it!)
- Does not really
matter (unless you press both buttons at the same time J).