Skip to content

Instantly share code, notes, and snippets.

@error454
Created March 1, 2014 02:45
Show Gist options
  • Save error454/9284267 to your computer and use it in GitHub Desktop.
Save error454/9284267 to your computer and use it in GitHub Desktop.
Rain of Arrows
// Rain of Arrows
// Author: Zachary Burke
// 5/7/2010
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace rain_of_arrows
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
const int maxArrows = 50;
const int maxArrowDecals = 100;
const int maxEnemies = 10;
const int maxPigs = 1;
const float gravity = 0.4f;
float arrowVelocity = 25;
Texture2D backgroundTexture;
GameObject[] clouds;
GameObject[] backgroundClouds;
Rectangle viewportRect; //used to determine how big the backgroundTexture will be drawn
SpriteBatch spriteBatch;
GameObject hero;
GameObject[] arrows;
GameObject[] arrowDecals;
GameObject[] enemies;
GameObject pigs;
GamePadState previousGamePadState = GamePad.GetState(PlayerIndex.One);
GameTime gameTime = new GameTime();
Random random = new Random();
int score;
SpriteFont font;
Vector2 scoreDrawPoint = new Vector2(0.1f, 0.1f);
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
base.Initialize();
graphics.PreferMultiSampling = true;
graphics.PreferredBackBufferWidth = this.Window.ClientBounds.Width;
graphics.PreferredBackBufferHeight = this.Window.ClientBounds.Height;
graphics.ApplyChanges();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
hero = new GameObject(Content.Load<Texture2D>("Sprites\\hero"));
backgroundTexture = Content.Load<Texture2D>("Sprites\\background");
clouds = new GameObject[4];
clouds[0] = new GameObject(Content.Load<Texture2D>("Sprites\\clouds1"));
clouds[1] = new GameObject(Content.Load<Texture2D>("Sprites\\clouds2"));
clouds[2] = new GameObject(Content.Load<Texture2D>("Sprites\\clouds3"));
clouds[3] = new GameObject(Content.Load<Texture2D>("Sprites\\clouds4"));
backgroundClouds = new GameObject[2];
backgroundClouds[0] = new GameObject(Content.Load <Texture2D>("Sprites\\cloudsback1"));
backgroundClouds[1] = new GameObject(Content.Load <Texture2D>("Sprites\\cloudsback2"));
backgroundClouds[0].position = new Vector2(0, 0);
backgroundClouds[1].position = new Vector2(backgroundClouds[1].position.X + backgroundClouds[0].sprite.Width, 0);
for (int i = 0; i <= 3; i++)
{
//Load clouds
//Set cloud position and link the 4 cloud images together
if(i == 0)
{
clouds[i].position = new Vector2(0,0);
}
else
{
clouds[i].position = new Vector2(clouds[i-1].position.X + clouds[i-1].sprite.Width, 0);
}
}
//hero = new GameObject(Content.Load<Texture2D>("Sprites\\hero"));
hero.Load(Content, "Sprites\\bowMap", 4, 20);
hero.position = new Vector2(34, (graphics.GraphicsDevice.Viewport.Height / 2) - 40 );
arrows = new GameObject[maxArrows];
for (int i = 0; i < maxArrows; i++)
{
arrows[i] = new GameObject(Content.Load<Texture2D>("Sprites\\arrow"));
}
arrowDecals = new GameObject[maxArrowDecals];
for (int i = 0; i < maxArrowDecals; i++)
{
arrowDecals[i] = new GameObject(Content.Load<Texture2D>("Sprites\\arrow"));
}
enemies = new GameObject[maxEnemies];
for (int i = 0; i < maxEnemies; i++)
{
enemies[i] = new GameObject(Content.Load<Texture2D>("Sprites\\enemy"));
}
font = Content.Load<SpriteFont>("Fonts\\GameFont");
pigs = new GameObject(Content.Load<Texture2D>("Sprites\\pig"));
viewportRect = new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height);
// TODO: use this.Content to load your game content here
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
GamePadState gamePadState = GamePad.GetState(PlayerIndex.One);
hero.rotation += gamePadState.ThumbSticks.Left.X * 0.05f;
hero.rotation = MathHelper.Clamp(hero.rotation, -MathHelper.PiOver2, 0);
arrowVelocity += gamePadState.ThumbSticks.Left.Y * 1.0f;
arrowVelocity = MathHelper.Clamp(arrowVelocity, 5.0f, 40.0f);
if (gamePadState.Buttons.A == ButtonState.Pressed && previousGamePadState.Buttons.A == ButtonState.Released)
{
FireArrow();
//Reset the bow animation
hero.Reset();
}
if (gamePadState.Buttons.RightShoulder == ButtonState.Pressed)
{
FireArrow();
}
UpdateArrows();
UpdateEnemies();
UpdateBackground();
// TODO: Add your update logic here
//Play the hero drawing the bow animation
hero.UpdateFrameOnce(3, (float)gameTime.ElapsedGameTime.TotalSeconds);
previousGamePadState = gamePadState;
base.Update(gameTime);
}
public void UpdateBackground()
{
//Wrap any images that have left the screen
for (int i = 0; i <= 3; i++)
{
if (i == 0)
{
if (clouds[0].position.X < -clouds[0].sprite.Width)
{
clouds[0].position.X = clouds[3].position.X + clouds[3].sprite.Width;
}
}
else
{
if (clouds[i].position.X < -clouds[i].sprite.Width)
{
clouds[i].position.X = clouds[i - 1].position.X + clouds[i - 1].sprite.Width;
}
}
}
for (int i = 0; i < 2; i++)
{
if (i == 0)
{
if (backgroundClouds[0].position.X < -backgroundClouds[0].sprite.Width)
{
backgroundClouds[0].position.X = backgroundClouds[1].position.X + clouds[1].sprite.Width;
}
}
else
{
if (backgroundClouds[i].position.X < -backgroundClouds[i].sprite.Width)
{
backgroundClouds[1].position.X = backgroundClouds[0].position.X + backgroundClouds[0].sprite.Width;
}
}
}
//Do the actual cloud moving at a fixed velocity
foreach (GameObject cloud in clouds)
{
//Scroll clouds left
cloud.position += new Vector2(-0.25f, 0);
}
foreach (GameObject cloud in backgroundClouds)
{
//Scroll clouds left
cloud.position += new Vector2(-2, 0);
}
}
public void FireArrow()
{
foreach (GameObject arrow in arrows)
{
if (!arrow.alive)
{
arrow.alive = true;
arrow.position = hero.position;
arrow.velocity = new Vector2((float)Math.Cos(hero.rotation), (float)Math.Sin(hero.rotation)) * arrowVelocity;
return;
}
}
}
public void UpdateArrows()
{
foreach (GameObject arrow in arrows)
{
//Update arrow velocity in Y direction (gravity), position and rotation
if (arrow.alive)
{
arrow.velocity.Y = arrow.velocity.Y + gravity;
arrow.position += arrow.velocity;
arrow.rotation = (float)Math.Atan2(arrow.velocity.Y, arrow.velocity.X);
//Kill arrow if it leaves the screen in X direction
if(arrow.position.X > viewportRect.Width || arrow.position.Y > viewportRect.Height)
{
arrow.alive = false;
continue;
}
Rectangle arrowRect = new Rectangle((int)arrow.position.X, (int)arrow.position.Y, arrow.sprite.Width, arrow.sprite.Height);
//Collision detection of arrows and enemies
foreach (GameObject enemy in enemies)
{
Rectangle enemyRect = new Rectangle((int)enemy.position.X, (int)enemy.position.Y, enemy.sprite.Width, enemy.sprite.Height);
if(arrowRect.Intersects(enemyRect))
{
arrow.alive = false;
enemy.hitPoints--;
//Modify enemy velocity here and then update enemy position in the update enemy routine
//enemy.position.X += arrow.velocity.X;
//Attach a decal arrow to the enemy
foreach (GameObject decal in arrowDecals)
{
if (!decal.alive)
{
decal.position = arrow.position;
decal.velocity = Vector2.Zero;
decal.rotation = arrow.rotation;
decal.alive = true;
enemy.decals.Add(decal);
break;
}
}
if (enemy.hitPoints <= 0)
{
enemy.alive = false;
score += 1;
}
}
}
}
}
}
public void UpdateEnemies()
{
foreach (GameObject enemy in enemies)
{
if (enemy.alive)
{
enemy.position += enemy.velocity;
//Update position of decals
if (enemy.decals.Count > 0)
{
foreach (GameObject obj in enemy.decals)
{
obj.position += enemy.velocity;
}
}
if (!viewportRect.Contains(new Point((int)enemy.position.X, (int)enemy.position.Y)))
{
enemy.alive = false;
}
}
else
{
enemy.alive = true;
enemy.hitPoints = 3;
if (enemy.decals.Count > 0)
{
foreach (GameObject obj in enemy.decals)
{
obj.alive = false;
}
enemy.decals.Clear();
}
enemy.position = new Vector2(viewportRect.Right, viewportRect.Bottom - enemy.sprite.Height);
enemy.velocity = new Vector2(MathHelper.Lerp(-1, -10, (float)random.NextDouble()), 0);
}
}
/*
if (pigs.alive)
{
pigs.position += pigs.velocity;
foreach (GameObject decal in arrowDecals)
{
if (decal.alive)
{
decal.position += pigs.velocity;
}
}
if (!viewportRect.Contains(new Point((int)pigs.position.X, (int)pigs.position.Y)))
{
pigs.alive = false;
}
}
else
{
pigs.alive = true;
pigs.hitPoints = 25;
pigs.position = new Vector2(viewportRect.Right, viewportRect.Height / 2);
pigs.velocity = new Vector2(-1, 0);
}
*/
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(backgroundTexture, viewportRect, Color.White);
foreach (GameObject cloud in clouds)
{
spriteBatch.Draw(cloud.sprite, cloud.position, null, Color.White);
}
foreach (GameObject cloud in backgroundClouds)
{
spriteBatch.Draw(cloud.sprite, cloud.position, null, Color.White);
}
foreach (GameObject arrow in arrows)
{
if (arrow.alive)
{
spriteBatch.Draw(arrow.sprite, arrow.position, null, Color.White, arrow.rotation, arrow.center, 1.0f, SpriteEffects.None, 0);
}
}
Microsoft.Xna.Framework.Graphics.
//spriteBatch.Draw(hero.sprite, hero.position, null, Color.White, hero.rotation, hero.center, 1.0f, SpriteEffects.None, 0);
hero.DrawFrame(spriteBatch, hero.position, 0.5f);
foreach (GameObject enemy in enemies)
{
if (enemy.alive)
{
spriteBatch.Draw(enemy.sprite, enemy.position, null, Color.Red);
}
}
//spriteBatch.Draw(pigs.sprite, pigs.position, null, Color.White);
foreach (GameObject arrow in arrowDecals)
{
if (arrow.alive)
{
spriteBatch.Draw(arrow.sprite, arrow.position, null, Color.White, arrow.rotation, arrow.center, 1.0f, SpriteEffects.None, 0);
}
}
spriteBatch.DrawString(font, "Score: " + score.ToString(),
new Vector2(scoreDrawPoint.X * viewportRect.Width, scoreDrawPoint.Y * viewportRect.Height),
Color.Black);
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
// Rain of Arrows
// Author: Zachary Burke
// 5/7/2010
using System;
using System.Collections.Generic;
using System.Collections;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
namespace rain_of_arrows
{
class GameObject
{
public float rotation;
public Vector2 position, center, velocity;
public Texture2D sprite;
public bool alive;
public int hitPoints;
public ArrayList decals;
private int framecount;
private float TimePerFrame;
private int Frame;
private float TotalElapsed;
private bool Paused;
public GameObject(Texture2D loadedTexture)
{
rotation = 0.0f;
position = Vector2.Zero;
sprite = loadedTexture;
center = new Vector2(sprite.Width / 2, sprite.Height / 2);
velocity = Vector2.Zero;
alive = false;
hitPoints = 0;
decals = new ArrayList();
}
public void Load(ContentManager content, string asset, int frameCount, int framesPerSec)
{
framecount = frameCount;
sprite = content.Load<Texture2D>(asset);
TimePerFrame = (float)1 / framesPerSec;
Frame = 0;
TotalElapsed = 0;
Paused = false;
}
public void UpdateFrame(float elapsed)
{
if (Paused)
return;
TotalElapsed += elapsed;
if (TotalElapsed > TimePerFrame)
{
Frame++;
// Keep the Frame between 0 and the total frames, minus one.
Frame = Frame % framecount;
TotalElapsed -= TimePerFrame;
}
}
public void UpdateFrameOnce(int lastFrame, float elapsed)
{
if (Paused)
return;
TotalElapsed += elapsed;
if (TotalElapsed > TimePerFrame)
{
if (Frame < lastFrame)
{
Frame++;
TotalElapsed -= TimePerFrame;
}
}
}
public void DrawFrame(SpriteBatch batch, Vector2 screenPos, float scale)
{
DrawFrame(batch, Frame, screenPos, scale);
}
public void DrawFrame(SpriteBatch batch, int frame, Vector2 screenPos, float scale)
{
int FrameWidth = sprite.Width / framecount;
Rectangle sourcerect = new Rectangle(FrameWidth * frame, 0,
FrameWidth, sprite.Height);
center = new Vector2(sourcerect.Width / 2, sourcerect.Height / 2);
batch.Draw(sprite, screenPos, sourcerect, Color.White,
rotation, center, scale, SpriteEffects.None, 0);
}
public bool IsPaused
{
get { return Paused; }
}
public void Reset()
{
Frame = 0;
TotalElapsed = 0f;
}
public void Stop()
{
Pause();
Reset();
}
public void Play()
{
Paused = false;
}
public void Pause()
{
Paused = true;
}
}
}
using System;
namespace rain_of_arrows
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment