Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using Microsoft.Xna.Framework;
- using Microsoft.Xna.Framework.Graphics;
- using Microsoft.Xna.Framework.Input;
- namespace BadGame
- {
- public struct PlayerData
- {
- public Vector2 Position;
- public Vector2 Velocity;
- public bool IsAlive;
- public bool Win;
- public bool CanJump;
- }
- public class Game1 : Microsoft.Xna.Framework.Game
- {
- GraphicsDeviceManager graphics;
- GraphicsDevice device;
- SpriteBatch spriteBatch;
- SpriteFont font;
- Texture2D backgroundTexture;
- Texture2D foregroundTexture;
- Texture2D playerTexture;
- Texture2D rect;
- int screenHeight;
- int screenWidth;
- public Game1()
- {
- graphics = new GraphicsDeviceManager(this);
- Content.RootDirectory = "Content";
- IsFixedTimeStep = false;
- }
- protected override void Initialize()
- {
- graphics.PreferredBackBufferWidth = 800;
- graphics.PreferredBackBufferHeight = 400;
- graphics.IsFullScreen = false;
- graphics.ApplyChanges();
- Window.Title = "Terrible Game";
- base.Initialize();
- }
- PlayerData Player = new PlayerData();
- void BuildPlayerData()
- {
- Player.Position = new Vector2(0, 250); // Start them in the air because it looks/feels cool when a player falls at the start
- Player.IsAlive = true;
- Player.Win = false;
- //Player.Velocity = new Vector2(0.3f, 0); // It defaults to Vector2.Zero (stationary)
- Player.CanJump = true;
- }
- List<Rectangle> Platform = new List<Rectangle>();
- void BuildPlatformData()
- {
- Platform.Add(new Rectangle(100, 210, 150, 30));
- Platform.Add(new Rectangle(150, 140, 100, 30));
- Platform.Add(new Rectangle(150, 310, 230, 30));
- Platform.Add(new Rectangle(230, 280, 150, 30));
- Platform.Add(new Rectangle(310, 250, 70, 30));
- Platform.Add(new Rectangle(350, 140, 100, 30));
- Platform.Add(new Rectangle(400, 230, 150, 30));
- Platform.Add(new Rectangle(400, 170, 30, 60));
- Platform.Add(new Rectangle(500, 170, 30, 30));
- Platform.Add(new Rectangle(600, 130, 30, 300));
- Platform.Add(new Rectangle(600, 130, 130, 30));
- Platform.Add(new Rectangle(600, 330, 200, 10));
- Platform.Add(new Rectangle(700, 250, 100, 30));
- Platform.Add(new Rectangle(770, 0, 30, 260));
- // Adding new platforms to keep the player confined within the level
- // These others are positioned right off the screen so you won't see them
- // The only downside would be that these are now DRAWN on the screen (just out of view)
- // However, if you ever expand on the project, you would likely check if an element is visible on the screen, and if not, don't draw it :)
- // You could do this by settings a rectangle that is the size/position of the screen.. and check if the platforms intersect this screen rect
- Platform.Add(new Rectangle(0, 340, 380, 61)); // Bottom boundry (THIS USED TO BE "LEVEL")
- Platform.Add(new Rectangle(0, -30, screenWidth, 30)); // Top boundry
- Platform.Add(new Rectangle(-30, 0, 30, screenHeight)); // Left boundry
- Platform.Add(new Rectangle(screenWidth, 0, 30, screenHeight)); // Right boundry
- }
- List<Rectangle> Hazard = new List<Rectangle>();
- void BuildHazardData()
- {
- Hazard.Add(new Rectangle(380, 340, 420, 61));
- }
- protected override void LoadContent()
- {
- device = graphics.GraphicsDevice;
- spriteBatch = new SpriteBatch(GraphicsDevice);
- backgroundTexture = Content.Load<Texture2D>("background");
- playerTexture = Content.Load<Texture2D>("player");
- foregroundTexture = Content.Load<Texture2D>("foreground");
- font = Content.Load<SpriteFont>("gameFont");
- rect = new Texture2D(GraphicsDevice, 1, 1);
- rect.SetData(new[] { Color.White });
- screenWidth = device.PresentationParameters.BackBufferWidth;
- screenHeight = device.PresentationParameters.BackBufferHeight;
- BuildPlayerData();
- BuildPlatformData();
- BuildHazardData();
- }
- protected override void UnloadContent()
- {
- }
- void CollisionDetection()
- {
- // I removed checking collision with LEVEL and added "LEVEL" as a platform.. there is nothing special about it
- // And it should really just be treated like any other platform
- // I've also removed the screen bounds checking... because if you ever add a camera and have your level "scroll"
- // Your code wouldn't be useful anymore. Just add platforms to the screen edges to prevent movement! Then all your code above works with it :)
- // Less, more generalized code is the way to do things!
- // Figure out the character's destination... collision code will be run based on this position... not the current position!
- Rectangle player = new Rectangle((int)Player.Position.X, (int)Player.Position.Y, 28, 28);
- Player.CanJump = false; // if they're moving they can't jump until they collide with the top of an object (platform/ground)
- // Check horizontal collision
- int finalH = (int)(player.X + Player.Velocity.X);
- while (true)
- {
- // We want to move from point A to point B slowly to check for collisions along the way
- player.X += Interpolate(player.X, finalH, player.Width);
- bool collided = false;
- foreach (Rectangle i in Platform)
- {
- if (player.Intersects(i))
- {
- collided = true;
- if (player.Center.X > i.Center.X)
- player.X = i.Right; // Intersecting right
- else
- player.X = i.Left - player.Width; // intersecting left
- }
- }
- // If we collided with an object or reached our destination with no collision, we're done here
- if (collided || player.X == finalH)
- break;
- }
- // Check Vertical collision
- int finalV = (int)(player.Y + Player.Velocity.Y);
- while (true)
- {
- // We want to move from point A to point B slowly to check for collisions along the way
- player.Y += Interpolate(player.Y, finalV, player.Height);
- bool collided = false;
- foreach (Rectangle i in Platform)
- {
- if (player.Intersects(i))
- {
- collided = true;
- if (player.Center.Y > i.Center.Y)
- player.Y = i.Bottom; // Intersecting bottom
- else
- {
- player.Y = i.Top - player.Height; // Intersecting top
- Player.CanJump = true;
- }
- }
- }
- foreach (Rectangle o in Hazard)
- {
- if (player.Intersects(o))
- {
- Player.IsAlive = false;
- collided = true;
- if (player.Center.Y > o.Center.Y)
- player.Y = o.Bottom; // Intersecting bottom
- else
- {
- player.Y = o.Top ; // Intersecting top
- Player.CanJump = true;
- }
- }
- }
- // If we collided with an object or reached our destination with no collision, we're done here
- if (collided || player.Y == finalV)
- break;
- }
- // Now that the collisions have been figured out, let's update the player's location to where it should be!
- Player.Position = new Vector2(player.X, player.Y);
- }
- void CheckWin()
- {
- if (Player.Position.X >= screenWidth - 28) Player.Win = true;
- }
- int Interpolate(int start, int end, int step)
- {
- // This function just returns a value starting from START and moving towards END in STEP increments
- int difference = Math.Abs(end - start);
- int increment = Math.Min(difference, step);
- if (start > end)
- return -increment;
- else
- return increment;
- }
- // We can make this a const since we won't be changing it
- const float gravity = 1.25f;
- protected override void Update(GameTime gameTime)
- {
- float elapsedTime = (float)gameTime.ElapsedGameTime.TotalMilliseconds;
- float speed = elapsedTime * .3f;
- KeyboardState keyboard = Keyboard.GetState();
- if (Player.IsAlive && !Player.Win)
- {
- // Horizontal movement
- if (keyboard.IsKeyDown(Keys.A))
- Player.Velocity.X += speed*-5;
- else if (keyboard.IsKeyDown(Keys.D))
- Player.Velocity.X += speed*5;
- else
- Player.Velocity.X = 0; // Cancel momentum... Stop moving when they let go
- // Limit their horizontal velocity
- const float maxVelocityH = 5f;
- Player.Velocity.X = MathHelper.Clamp(Player.Velocity.X, -maxVelocityH, maxVelocityH);
- // Vertical movement
- if (keyboard.IsKeyDown(Keys.W) && Player.CanJump)
- Player.Velocity.Y += speed*-15;
- else if (keyboard.IsKeyDown(Keys.S))
- Player.Velocity.Y += speed*1;
- // Limit their vertical velocity
- const float maxVelocityV = 15f;
- Player.Velocity.Y = MathHelper.Clamp(Player.Velocity.Y, -maxVelocityV, maxVelocityV / 2);
- // Apply Gravity (downwards force)
- Player.Velocity.Y += gravity;
- // Collision Detection
- CollisionDetection();
- CheckWin();
- }
- if (keyboard.IsKeyDown(Keys.R)) BuildPlayerData();
- base.Update(gameTime);
- }
- protected override void Draw(GameTime gameTime)
- {
- GraphicsDevice.Clear(Color.CornflowerBlue);
- spriteBatch.Begin();
- DrawLevel();
- DrawText();
- if (!Player.IsAlive) PlayerDead();
- else if (Player.Win) PlayerWin();
- spriteBatch.End();
- base.Draw(gameTime);
- }
- private void PlayerDead()
- {
- //spriteBatch.Draw(rect, new Rectangle(screenWidth / 2, screenHeight / 2, 92, 22), Color.Red);
- spriteBatch.DrawString(font, "YOU DIED!\nPress R to restart.", new Vector2(screenWidth / 2, screenHeight / 2), Color.White);
- }
- private void PlayerWin()
- {
- spriteBatch.DrawString(font, "YOU WON!\nPress R to restart.", new Vector2(screenWidth / 2, screenHeight / 2), Color.White);
- }
- private void DrawText()
- {
- spriteBatch.DrawString(font, String.Format("Position: {0} Gravity: {1} Velocity: {2}", Player.Position, gravity, Player.Velocity), new Vector2(0, 0), Color.White);
- }
- private void DrawLevel()
- {
- Rectangle screenRectangle = new Rectangle(0, 0, screenWidth, screenHeight);
- spriteBatch.Draw(backgroundTexture, screenRectangle, Color.White);
- foreach (Rectangle i in Platform) spriteBatch.Draw(rect, i, Color.Green);
- foreach (Rectangle i in Hazard) spriteBatch.Draw(rect, i, Color.Red);
- DrawPlayer();
- spriteBatch.Draw(foregroundTexture, new Rectangle(0, 0, 380, screenHeight), Color.White);
- }
- private void DrawPlayer()
- {
- spriteBatch.Draw(playerTexture, Player.Position, Color.White);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement