Title: a simple 2D game engine
1a simple 2D game engine
- input handling and collision detection
2Getting input from the user
- We want to keep track of
- Where the mouse is
- Whether a mouse button has been pressed
- What keys have been pressed
- Well do this by storing the information in
global variables - For mouse position and state
- And a list of states (up/down) for each key
- define mouse-location point 0 0
- define mouse-in-window? false
- define mouse-pressed? false
- define key-states
- This just makes a list of 256 elements, all
set to false - make-list 256 false
- define key-pressed? Keyvalue
- get key-states keyvalue
3Event handling
- The operating system tells you what the user is
doing by signaling events - KeyDown/KeyUp
- A key went down/up on the keyboard
- MouseDown/MouseUp
- A button went up/down on the mouse
- MouseMove
- The mouse moved inside the window
- MouseEnter/MouseLeave
- The user dragged the mouse into/out of the window
- So we need to set up handlers for them
4Setting up input handling
- First, we initialize all those global variables
- Set all the elements of the list of key states to
false (i.e. not pressed) - Assume the mouse buttons are up
- Assume the mouse is out of the window
- define initialize-input form
- up-to 256
- i ? item
key-states i ? false - mouse-location ? point 0 0
- mouse-down? ? false
- mouse-in-window? ? false
5Setting up event handlers
- When the MouseEnter event happens
- Set mouse-in-window? to be true
- When MouseLeave happens
- Set it to be false
- define initialize-input form
-
- form.MouseEnter ? ignore ignore ?
- mouse-in-window? ? true
- form.MouseLeave ?
- form.MouseMove ? ignore e ?
- update-mouse e
- form.MouseDown ? ignore e ?
- mouse-down? ? true
- update-mouse e
- form.MouseUp ?
6Setting up event handlers
- When MouseMove happens
- The OS passes a MouseEventArgs object
- Called e here
- It contains the coordinates of the mouse
- Call update-mouse to update the mouse-location
variable using the MouseEventArgs object
- define initialize-input form
-
- form.MouseEnter ? ignore ignore ?
- mouse-in-window? ? true
- form.MouseLeave ?
- form.MouseMove ? ignore e ?
- update-mouse e
- form.MouseDown ? ignore e ?
- mouse-down? ? true
- update-mouse e
- form.MouseUp ?
7update-mouse
- The .X and .Y fields of the MouseEventArgs object
give the location of the mouse - Make a point out of them and update mouse-location
- define update-mouse emouse-location ?
point e.X e.Y
8Setting up event handlers
- MouseDown/MouseUp events are the same way
- The MouseEventArgs object also has a field called
Button that tells which button was pressed - For simplicity, well ignore that
- Update the mouse-down? Variable
- Call update-mouse to update mouse-location
- define initialize-input form
-
- form.MouseDown ? ignore e ?
- mouse-down? ? true
- update-mouse e
- form.MouseUp ?
9Setting up the keyboard handlers
- The OS passes a KeyEventArgs object to keyboard
handlers - Its KeyValue field has a number corresponding to
the key that was pressed
- define initialize-input form
-
- form.KeyDown ? ignore e ?
set-key-state e.KeyValue
true - form.KeyUp ? ignore e ?
set-key-state e.KeyValue
false
10Implementing set-key-state
- Basically, we
- Take the key number (keyvalue)
- And set the corresponding element of key-states
to state (true or false) - However, we need to do the bitwise-and thingy to
fix the number - Well explain this later
- For now, trust me
- define set-key-state keyvalue state
- set key-states
- bitwise-and keyvalue 255
- state
11Getting the magic key numbers
- Theres an object called Keys
- It has fields with all the key numbers
- Except theyre represented as a funny kind of
object - So you need to do use int (short for integer)
to make them real numbers - You can get any keyboard key you want this way
(e.g. using Keys.A for the A key) - To get a list of all the magic key codes, google
- .NET Keys class members
- define up-arrow int Keys.Up
- define down-arrow int Keys.Down
- define left-arrow int Keys.Left
- define right-arrow int Keys.Right
12Example controlling a car
- A simple car that you can steer with the arrow
keys - Up go forward
- Down go back
- Left, right - steer
13Example controlling a car tank
- A simple car that you can steer with the arrow
keys - Unfortunately, its hard to tell which way the
car is facing - So well use a tank
14The Tank class
- Basically like the Obstacle class, but a slightly
different draw method
- define Tank
- class Tank position
- GameObject
- define-method draw Tank t g
- g.DrawRectangle black-pen
-12 -10 24 20 - g.DrawRectangle black-pen 12 -2 10 4
15Controlling speed
- Simple version
- If they hold down the up-arrow key
- Move right at 10 pixels per second
- define-method tick Tank t ?t
- t.velocity ?
- if key-pressed? up-arrow
- point 10 0
- point 0 0
16Controlling speed
- Simple version
- If they hold down the up-arrow key
- Move right at 10 pixels per second
- Slightly fancier
- Let them move backward
- define-method tick Tank t ?t
- t.velocity ?
- if key-pressed? up-arrow
- point 10 0
- if key-pressed? down-arrow
point -10 0 - point 0 0
17Controlling speed
- Simple version
- If they hold down the up-arrow key
- Move right at 10 pixels per second
- Slightly fancier
- Let them move backward
- More readable
- Turn the two ifs into one cond
- define-method tick Tank t ?t
- t.velocity ?
- cond key-pressed? up-arrow
- point 10 0
- key-pressed? down-arrow
point -10 0 - else point 0
0
18Controlling speed
- Simple version
- If they hold down the up-arrow key
- Move right at 10 pixels per second
- Slightly fancier
- Let them move backward
- Oh, yea. Let them steer.
- define-method tick Tank t ?t
- t.velocity ? rotate-vector-degrees
- cond key-pressed? up-arrow
- point 10 0
- key-pressed? down-arrow
point -10 0
else - point 0 0
t.orientation
19Controlling speed
- Writing it this way makes it easier to change the
speed if we want to - Only one number to change
- define-method tick Tank t ?t
- t.velocity ? 10
- cond key-pressed? up-arrow
1 key-pressed?
down-arrow - -1 else
0 - rotate-vector-degrees
point 1 0 - t.orientation
20Steering
- To steer
- Just do the same trick with the angular velocity
- Only, remember its a number, not a vector
- define-method tick Tank t ?t
- t.velocity ? ...
- t.angular-velocity ? 30
- cond key-pressed? left-arrow
-1 - key-pressed?
right-arrow 1 - else
0
21Sticking to the mouse
- We can force an object to follow the mouse by
just setting its position to the mouse position
- define dragger
- class dragger position
- GameObject
- define-method draw dragger o g
- g.DrawEllipse black-pen -20 -20 40 40
- define-method tick dragger o ?t
- o.position ? mouse-location
22Following the mouse
- We can make the object follow the mouse
- by setting its speed to always be some fraction
of the vector between the object and the mouse
- define Mouser
- class Mouser position
- GameObject
- define-method draw Mouser o g
- g.DrawEllipse black-pen -20 -20 40 40
- define-method tick Mouser o ?t
- o.velocity ? - mouse-location
- o.position
- 0.5
23Making it more interesting
- We can complicate the dynamics of the ball by
- Accelerating it toward the mouse
- define SpringMouser
- class SpringMouser position
- GameObject
- define-method tick SpringMouser o ?t
- o.velocity ? o.velocity
- -
mouse-location
o.position - 0.1
- -0.001
o.velocity
24Making it more interesting
- We can complicate the dynamics of the ball by
- Accelerating it toward the mouse
- Rather than moving straight toward it
- define SpringMouser
- class SpringMouser position
- GameObject
- define-method tick SpringMouser o ?t
- o.velocity ? o.velocity
- -
mouse-location
o.position - 0.1
- -0.001
o.velocity
25Making it more interesting
- We can complicate the dynamics of the ball by
- Accelerating it toward the mouse
- Rather than moving straight toward it
- And adding some damping to slow it down
- define SpringMouser
- class SpringMouser position
- GameObject
- define-method tick SpringMouser o ?t
- o.velocity ? o.velocity
- -
mouse-location -
o.position - 0.1
- -0.001
o.velocity
26Changing the appearance slightly
- We can make a filled circle rather than a normal
circle - By substituting
- FillEllipse
- For DrawEllipse
- And a Brush object
- For a Pen
- define green-brushnew SolidBrush color
green - define-method draw SpringMouser o g
- g.FillEllipse green-brush
- -20 -20 40 40
27Collision handling
- Many games need to notice when two objects
collide - This is an expensive operation
- Its an on-going area of research
- Well just talk about the absolute dumbest
version of it
- define update-objects form
- with current-time DateTime.Now
- ?t current-time.Subtract
last-time.TotalSeconds - for-each-game-object o ? tick o ?t
- for-each-game-object o ?
- o.position ? o.position
-
o.velocity ?t - o.orientation ? o.orientation
-
o.angular-velocity
?t - check-collisions
- last-time ? current-time
- form.Invalidate
28Naïve algorithm
- Compare every object to every object
- Check if theyve collided
- Deal with it if they have
- Notes
- We havent said how to check whether two objects
have collided - Or what to do about it
- define check-collisions
- for-each-game-object
- o1 ? for-each-game-object
- o2 ? if collided? o1 o2
handle-collision o1 o2
29Computational complexity
- Suppose there are n objects in the game
- define check-collisions
- for-each-game-object
- o1 ? for-each-game-object
- o2 ? if collided? o1 o2
handle-collision o1 o2
30Computational complexity
- Suppose there are n objects in the game
- Then this procedure runs n times
- define check-collisions
- for-each-game-object
- o1 ? for-each-game-object
- o2 ? if collided? o1 o2
handle-collision o1 o2
31Computational complexity
- Suppose there are n objects in the game
- Then this procedure runs n times
- But each time it runs, this procedure runs n
times!
- define check-collisions
- for-each-game-object
- o1 ? for-each-game-object
- o2 ? if collided? o1 o2
handle-collision o1 o2
32Computational complexity
- Suppose there are n objects in the game
- Then this procedure runs n times
- But each time it runs, this procedure runs n
times! - So that means we do n2 collision checks
- define check-collisions
- for-each-game-object
- o1 ? for-each-game-object
- o2 ? if collided? o1 o2
handle-collision o1 o2
33Computational complexity
- Suppose there are n objects in the game
- Then this procedure runs n times
- But each time it runs, this procedure runs n
times! - So that means we do n2 collision checks
- Very expensive
- define check-collisions
- for-each-game-object
- o1 ? for-each-game-object
- o2 ? if collided? o1 o2
handle-collision o1 o2
34Computational complexity
- The time complexity of a program is
- The rate at which the running time increases
- With the size of its input
- A linear algorithm increases about as fast as n
- We then say the algorithm is O(n)
- A quadratic algorithm increases as fast as n2
- We then say its O(n2)
- An exponential time algorithm increases
exponentially with n - Exponential algorithms are useless unless n is
very small
35Problems with the algorithm
- This actually has some bugs
- define check-collisions
- for-each-game-object
- o1 ? for-each-game-object
- o2 ? if collided? o1 o2
handle-collision o1 o2
36Problem 1
- This will check whether each object has collided
with itself - It probably has
- define check-collisions
- for-each-game-object
- o1 ? for-each-game-object
- o2 ? if collided? o1 o2
handle-collision o1 o2
37Problem 2
- For any two objects, x and y, it will call both
- collided? x y, and
- collided? y x
- define check-collisions
- for-each-game-object
- o1 ? for-each-game-object
- o2 ? if collided? o1 o2
handle-collision o1 o2
38Fancy version
- This version only compares objects
- Against objects that are later in the list of
game objects - So we only compare each pair once
- define check-collisions
- if collision-detection-enabled?
- with i 0
- while lt i length all-game-objects
- with o1 get all-game-objects i
- j i 1
- while lt j length
all-game-objects - with o2 get
all-game-objects j - if collided? o1 o2
- handle-collision o1
o2 - j ? j 1
- i ? i 1
39Adding collision handling to the SpringBall
example
- Two balls have collided if
- define collided? o1 o2lt magnitude -
o1.position - o2.position
- 10
- define-method handle-collision
SpringBall o1
SpringBall o2 - destroy o1
- destroy o2
40Adding collision handling to the SpringBall
example
- Two balls have collided if
- The length
- define collided? o1 o2lt magnitude -
o1.position - o2.position
- 10
- define-method handle-collision
SpringBall o1
SpringBall o2 - destroy o1
- destroy o2
41Adding collision handling to the SpringBall
example
- Two balls have collided if
- The length
- Of the space between them
- define collided? o1 o2lt magnitude -
o1.position - o2.position
- 10
- define-method handle-collision
SpringBall o1
SpringBall o2 - destroy o1
- destroy o2
42Adding collision handling to the SpringBall
example
- Two balls have collided if
- The length
- Of the space between them
- Is less than 10 pixels
- define collided? o1 o2lt magnitude -
o1.position - o2.position
- 10
- define-method handle-collision
SpringBall o1
SpringBall o2 - destroy o1
- destroy o2
43Adding collision handling to the SpringBall
example
- define collided? o1 o2lt magnitude -
o1.position - o2.position
- 10
- define-method handle-collision
SpringBall o1
SpringBall o2 - destroy o1
- destroy o2
44Adding collision handling to the SpringBall
example
- When two balls collide
- Blow the little buggers away
- define collided? o1 o2lt magnitude -
o1.position - o2.position
- 10
- define-method handle-collision
SpringBall o1
SpringBall o2 - destroy o1
- destroy o2
45Final project
- On blackboard
- Work in teams of 1-3 people
- Make a 2D game of some sort
- Must include
- User input
- At least 2 classes
- At least 6 methods total for tick, draw,
collided?, handle-collision
- Should also include at least one of (or 2 or 3 if
youre working in a group) - Collision handling
- Simple physics
- Sound
- In-game object creation
- Object destruction
- Something else you get me to agree to in advance
- Rough cut due a week from Thursday
- Final version due the Saturday before finals
46Movie today V for Vendetta
- 4pm, Animate Arts studio, Kresge 1-370
- Feel welcome to attend if youre still in town
and youre bored