XNA Game-Themed CS1 Examples (XGC1) | |
Release 2.0 (XNA V3.1) |
References:
Goals:
1. Obtain the example code
When the game starts, you'll see a screen that
looks similar to this:
As you can see, this program animates the movement of two soccer balls from left to right across the screen. When the soccer balls go beyond the end of the screen, they "wrap around" and jump back to the left edge of the screen. The top soccer ball traces out the path of a sine wave, while the bottom soccer ball traces out the path of a cosine wave. (You may find it useful to search the web for terms like "sine wave", or "sine wave animation" if you'd like more information about these mathematical concepts) There are only two ways to interact with the game (not counting the standard "Press the Back button to exit" way):
By pushing the right thumbstick up or down, you can increase or decrease the amplitude of the waves, meaning that you can make the waves (vertically) bigger or smaller.
By pushing the right thumbstick left or right, you can increase or decrease the period of the waves, meaning that you can make the waves (horizontally) longer or shorter.
2. Examining The Program:
Let's examine the
C# source code that produces the behavior we see on-screen
public
class Game1 : XNACS1Base { private XNACS1Circle m_SinSoccer; // soccer ball following the sine function private XNACS1Circle m_CosSoccer; // soccer ball following the cosine function private float m_Frequency; // number of complete oscillations to fit into 0-100 private float m_Amplitude; // amplitude of the oscillations #region Constants for circle/ball definition private const float SINE_BALL_INIT_Y = 35.0f; private const float COSINE_BALL_INIT_Y = 15.0f; private const float BALL_INIT_X = 0.0f; private const float BALL_INIT_RADIUS = 3.0f; private const float X_SPEED = 0.8f; private const float SCALE_FACTOR = 0.1f; #endregion |
private XNACS1Circle m_CosSoccer; // soccer ball following the cosine function
private float m_Frequency; // number of complete oscillations to fit into 0-100
private float m_Amplitude; // amplitude of the oscillations
private const float COSINE_BALL_INIT_Y = 15.0f;
private const float BALL_INIT_X = 0.0f;
private const float BALL_INIT_RADIUS = 3.0f;
private const float X_SPEED = 0.8f;
private const float SCALE_FACTOR = 0.1f;
protected
override
void
InitializeWorld() { World.SetWorldCoordinate(new Vector2(0,0), 100.0f); m_Frequency = 2.0f; // initially fit 2 cycles into 0 to 100 m_Amplitude = 10.0f; ; // initially oscillate from -10 to 10 m_SinSoccer = InitializeSoccer(SINE_BALL_INIT_Y); m_CosSoccer = InitializeSoccer(COSINE_BALL_INIT_Y); } |
m_Amplitude = 10.0f; ; // initially oscillate from -10 to 10
m_CosSoccer = InitializeSoccer(COSINE_BALL_INIT_Y);
///
<summary> /// Allcoate memory and initialize soccer at different y positions /// </summary> /// <param name="yPos">The y-position</param> /// <returns>An initialized Soccer with proper texture</returns> private XNACS1Circle InitializeSoccer(float yPos) { // initialize the soccer ball XNACS1Circle aSoccer = new XNACS1Circle(); aSoccer.Center = new Vector2(BALL_INIT_X, yPos); aSoccer.Radius = BALL_INIT_RADIUS; aSoccer.Texture = "SoccerBall"; return aSoccer; } |
protected
override
void
UpdateWorld() { if (GamePad.ButtonBackClicked()) this.Exit(); // 1. change the period and amplitude according to right thumb stick m_Amplitude += SCALE_FACTOR * GamePad.ThumbSticks.Right.Y; m_Frequency += SCALE_FACTOR * GamePad.ThumbSticks.Right.X; // 2. Compute a new X position based on SinSoccer's centerX float newX = (m_SinSoccer.CenterX + X_SPEED) % World.WorldMax.X; m_SinSoccer.CenterX = newX; m_CosSoccer.CenterX = newX; // 3. convert the newX value into a radian value float xInRad = (newX / World.WorldMax.X) * ((float) Math.PI * 2.0f) * m_Frequency; // 4. compute the y values for the two soccer balls m_SinSoccer.CenterY = SINE_BALL_INIT_Y + (m_Amplitude * (float) Math.Sin(xInRad)); m_CosSoccer.CenterY = COSINE_BALL_INIT_Y + (m_Amplitude * (float) Math.Cos(xInRad)); // 5. after calling the above, the two radii should be the same?! EchoToTopStatus("Amplitude=" + m_Amplitude + " NumPeriod=" + m_Frequency); } |
m_Amplitude += SCALE_FACTOR * GamePad.ThumbSticks.Right.Y;
m_Frequency += SCALE_FACTOR * GamePad.ThumbSticks.Right.X;
float newX = (m_SinSoccer.CenterX + X_SPEED) % World.WorldMax.X;
m_CosSoccer.CenterX = newX;
float xInRad = (newX / World.WorldMax.X) * ((float) Math.PI * 2.0f) * m_Frequency;
m_SinSoccer.CenterY = SINE_BALL_INIT_Y + (m_Amplitude * (float) Math.Sin(xInRad));
m_CosSoccer.CenterY = COSINE_BALL_INIT_Y + (m_Amplitude * (float) Math.Cos(xInRad));
EchoToTopStatus("Amplitude=" + m_Amplitude +
" NumPeriod=" + m_Frequency);
FURTHER EXERCISES::
Kelvin Sung Computing and Software Systems University of Washington, Bothell ksung@u.washington.edu |
Michael Panitz Business And Information Technology Cascadia Community College mpanitz@cascadia.eduu |
This work is supported in part by a grant from Microsoft Research under the Computer Gaming Curriculum in Computer Science RFP, Award Number 15871 and 16531. | |
2/8/2010 |