So currently, I am a newb starting coding in c#. I started making a space game akin to space invaders and ran into an issue, in the draw method, I set it to draw my bullet and head upward on the string as soon as i hit space. But the problem was as soon as I let go of space, my bullet disappeared. I made a work around where as soon as the bullet left the screen it would teleport to the ship. Is there anyway to make the game check if the button has been pressed in the past and make the bullet keep moving until i want it to disappear.
using System;
using System.Collections.Generic;
using System.Linq;
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.Media;
namespace Spaceteroids
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
Texture2D spriteSheet;
Texture2D laser;
Texture2D Enemyship;
spriteAnimation loading;
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
KeyboardState currentKeyboard;
KeyboardState oldKeyboard;
PlayerShip character;
Rectangle characterRectangle;
Bullet bullet;
Bullet bullet2;
bool heightCheck;
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
currentKeyboard = new KeyboardState();
oldKeyboard = new KeyboardState();
//characterRectangle = new Rectangle((int)character.Position.X,(int)character.Position.Y, spriteSheet.Width / 4, spriteSheet.Height);
character = new PlayerShip(new Vector2(GraphicsDevice.Viewport.Width / 2, GraphicsDevice.Viewport.Height - 40));
bullet = new Bullet(new Vector2(character.Position.X, character.Position.Y - 20));
base.Initialize();
}
void Movement()
{
if (IsHeld(Keys.A))
{
character.xSpeed = -6;
}
else if (IsHeld(Keys.D))
{
character.xSpeed = 6;
}
else
{
character.xSpeed = 0;
}
}
void Collision()
{
if (character.Position.X < 0)
{
character.Position.X = 0;
}
else if (character.Position.X + (spriteSheet.Width/4) > graphics.GraphicsDevice.Viewport.Width)
{
character.Position.X = graphics.GraphicsDevice.Viewport.Width - (spriteSheet.Width/4) ;
}
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
laser = Content.Load<Texture2D>("Laser");
Enemyship = Content.Load<Texture2D>("EnemyShip");
spriteSheet = Content.Load<Texture2D>("shipSpriteSheet");
spriteBatch = new SpriteBatch(GraphicsDevice);
loading = new spriteAnimation(Content.Load<Texture2D>("shipSpriteSheet"), 4);
loading.Position = new Vector2(character.Position.X);
loading.IsLooping = true;
loading.FramesPerSecond = 30;
// 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)
{
bullet.Position.X = character.Position.X;
currentKeyboard = Keyboard.GetState();
oldKeyboard = currentKeyboard;
loading.Update(gameTime, character);
bullet.ySpeed = -10;
bullet.UpdateBullet();
Collision();
Movement();
if (NotPressed(Keys.Space))
{
bullet.Position.Y = character.Position.Y - 15;
}
if (bullet.Position.Y < 0)
{
bullet.Position.Y = character.Position.Y - 15;
}
character.UpdateShip();
// TODO: Add your update logic here
base.Update(gameTime);
}
/// <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)
{
GraphicsDevice.Clear(Color.Black);
spriteBatch.Begin();
spriteBatch.Draw(laser, new Vector2(bullet.Position.X, bullet.Position.Y), Color.White);
loading.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
public bool IsHeld(Keys key)
{
if (currentKeyboard.IsKeyDown(key))
{
return true;
}
else
{
return false;
}
}
public bool IsReleased(Keys key)
{
if (currentKeyboard.IsKeyUp(key) && oldKeyboard.IsKeyDown(key))
{
return true;
}
else
{
return false;
}
}
public bool JustPressed(Keys key)
{
if (currentKeyboard.IsKeyDown(key) && oldKeyboard.IsKeyUp(key))
{
return true;
}
else
{
return false;
}
}
public bool NotPressed(Keys key)
{
if (IsHeld(key) != true)
{
return true;
}
else
{
return false;
}
}
public bool HasBeenPressed(Keys key)
{
if (oldKeyboard.IsKeyDown(key))
{
return true;
}
else return false;
}
}
}
If you need any other information, feel free to ask.
No, there is nothing in XNA to track keystroke history (or anywhere else either). You have to do it yourself.
The usual solution to your problem is to maintain state on an object that represents the bullet. The keystroke may go away, but the object remains and keeps the bullet visible and moving until it is destroyed. You appear to have that state in your bullet object, so the likelihood is you just have logic errors in when to update it.
The problem is not instantly obvious from a quick read but your handling of keyboard state seems overly complex. All you need is key down and key up. All the rest you should track for yourself.
Related
So I have a problem that I cant figure out, and that is drawing objects into my main Game1 class from a class of drawablegamecomponent.
I'v been playing around with it for a bit and looking at other examples, but can't figure out the issue. There isn't much code as it is, so I'll just post the two classes I have, the main class Game1 and the class I want to draw, Balloon.
The error is in the draw method I get this...
An unhandled exception of type 'System.NullReferenceException' occurred in Burst.exe
Additional information: Object reference not set to an instance of an object.
Main Class.
using System;
using System.Collections.Generic;
using System.Linq;
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.Media;
namespace Burst
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Rectangle bounds;
Balloon ball;
Diamond dia;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = 1152;
graphics.PreferredBackBufferHeight = 648;
Content.RootDirectory = "Content";
bounds = new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
ball = new Balloon(bounds, 1, this, spriteBatch);
dia = new Diamond(bounds, new Vector2(200, 200), this, spriteBatch);
}
/// <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();
}
/// <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);
// 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();
// TODO: Add your update logic here
ball.Update();
base.Update(gameTime);
}
/// <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)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
// TODO: Add your drawing code here
ball.Draw(gameTime);
dia.Draw(gameTime);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Balloon Class:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Burst
{
public class Balloon : Microsoft.Xna.Framework.DrawableGameComponent
{
Vector2 position;
Vector2 motion;
Texture2D texture;
Rectangle bounds;
Rectangle screenBounds;
Game game;
SpriteBatch spriteBatch;
float balloonSpeed = 4;
int colour = 0;
public Balloon(Rectangle screenBounds, int colour, Game game, SpriteBatch spriteBatch) : base (game)
{
this.colour = colour;
this.game = game;
this.spriteBatch = spriteBatch;
this.screenBounds = screenBounds;
this.position = new Vector2(200,200);
}
protected override void LoadContent()
{
switch (colour)
{
case 1: texture = Game.Content.Load<Texture2D>("Images/BlueBalloon");
break;
case 2: texture = Game.Content.Load<Texture2D>("Images/GreenBalloon");
break;
case 3: texture = Game.Content.Load<Texture2D>("Images/RedBalloon");
break;
case 4: texture = Game.Content.Load<Texture2D>("Images/YellowBalloon");
break;
case 5: texture = Game.Content.Load<Texture2D>("Images/PurpleBalloon");
break;
}
}
public Rectangle Bounds
{
get
{
bounds.X = (int)position.X;
bounds.Y = (int)position.Y;
return bounds;
}
}
public void Update()
{
position += motion * balloonSpeed;
}
private void CheckWallColision()
{
if (position.X < 0)
{
position.X = 0;
motion.X *= -1;
}
if (position.X + texture.Width > screenBounds.Width)
{
position.X = screenBounds.Width - texture.Width;
motion.X *= -1;
}
if (position.Y < 0)
{
position.Y = 0;
motion.Y *= -1;
}
if (position.Y + texture.Height > screenBounds.Height)
{
position.Y = screenBounds.Height - texture.Height;
motion.Y *= -1;
}
}
public void SetStartPosition()
{
Random rand = new Random();
motion = new Vector2(rand.Next(2, 6), -rand.Next(2, 6));
motion.Normalize();
position = new Vector2(200, 300);
}
public void Draw()
{
spriteBatch.Draw(texture, position, Color.White);
}
}
}
"spriteBatch" == null when you create objects "ball" and "dia".
You need move this code:
bounds = new Rectangle(0, 0, graphics.PreferredBackBufferWidth, graphics.PreferredBackBufferHeight);
ball = new Balloon(bounds, 1, this, spriteBatch);
dia = new Diamond(bounds, new Vector2(200, 200), this, spriteBatch);
to method "LoadContent". After creating "spriteBatch".
I am trying to get a list of sprite objects to move randomly across the screen in short linear movements (up, down , left, right). The sprites move randomly, but they all move the same as each other (e.g all move left, all move right, etc), apart from one which moves separately. I want them all to move independently to each other. Code below -
namespace game2
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
/// <summary>
/// Sprite
/// </summary>
List<Sprite> spriteList;
Sprite tempSprite;
private int spriteNum;
/// <summary>
/// General
/// </summary>
Random random;
int randomNum;
Rectangle viewPort;
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
//Initialize Sprites
spriteList = new List<Sprite>();
spriteNum = 4;
for (int i = 0; i < spriteNum; i++) //Load in as many sprites as spriteNum specifies
{
tempSprite = new Sprite();
spriteList.Add(tempSprite); //add in sprites to list
}
//initialise random
random = new Random();
//initialise viewport
viewPort = new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height);
base.Initialize();
}
/// <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);
foreach (Sprite s in spriteList) //for each sprite in spriteList, load content by passing in Game1's content
{
s.LoadContent(this.Content, viewPort, "square");
s.Position = new Vector2(random.Next(0, viewPort.Width), random.Next(0, 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();
//update sprites
foreach (Sprite s in spriteList)
{
s.Update(gameTime);
}
// TODO: Add your update logic here
base.Update(gameTime);
}
/// <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)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
foreach (Sprite s in spriteList)
{
s.Draw(this.spriteBatch);
}
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
And here is the sprite class -
namespace game2
{
class Sprite
{
//Movement
public Vector2 Position = new Vector2(0,0);
private float counter = 0f;
private float range = 100f;
private Random random;
public int randomNum;
//Properties
private Texture2D mSpriteTexture;
//General
private Rectangle viewPort;
public void LoadContent(ContentManager theContentManager, Rectangle tempViewport, string asset)
{
random = new Random();
viewPort = tempViewport;
mSpriteTexture = theContentManager.Load<Texture2D>(asset);
}
public void Update(GameTime gameTime)
{
if (randomNum == 0)
{
if (Position.X + mSpriteTexture.Width < viewPort.Width && counter <= range)
{
Position.X++;
counter++;
}
else
{
randomNum = random.Next(0, 4);
counter = 0;
}
}
if (randomNum == 1)
{
if (Position.X > viewPort.X && counter <= range)
{
Position.X--;
counter++;
}
else
{
randomNum = random.Next(0, 4);
counter = 0;
}
}
if (randomNum == 2)
{
if (counter <= range)
{
Position.Y++;
counter++;
}
else
{
randomNum = random.Next(0, 4);
counter = 0;
}
}
if (randomNum == 3)
{
if (counter <= range)
{
Position.Y--;
counter++;
}
else
{
randomNum = random.Next(0, 4);
counter = 0;
}
}
}
public void Draw(SpriteBatch theSpriteBatch)
{
theSpriteBatch.Draw(mSpriteTexture, Position, Color.White);
}
}
}
You are loading all the sprites very quickly in LoadContent normally, this isn't a problem, but each one has its own Random class.
Because of this, many are getting identical seeds (similar to the problem you see when instantiating Random in a for or while loop). RNGs with the same seed will produce the same sequence of values, thus causing the behavior you are seeing.
Passing a single Random instance to all objects that use it should cause your problem to go away.
I've done some research around the internet including this site but I am still confused about what to do with this error. I have 2 classes I'm using MainSkeleton which is the Game1 class and it has the move method while I also made a class InputSkeleton that handles user inputs. When I try calling the move method I'm getting the error even though I called the class.
MainSkeleton
/// <summary>
/// This is the main type for your game
/// </summary>
public class MainSkeleton: Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
InputSkeleton input;
SpriteBatch spriteBatch;
Color backColor = Color.CornflowerBlue;
public MainSkeleton()
{
input = new InputSkeleton(1);
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();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
// This is a texture we can render.
Texture2D myTexture;
// Set the coordinates to draw the sprite at.
Vector2 spritePosition = Vector2.Zero;
// Store some information about the sprite's motion.
Vector2 spriteSpeed = new Vector2(50.0f, 50.0f);
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
myTexture = Content.Load<Texture2D>("Person");
// 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();
// TODO: Add your update logic here
input.Update();
base.Update(gameTime);
}
/// <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)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// Draw the sprite.
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
public void Move(String direction)
{
int MaxX = graphics.GraphicsDevice.Viewport.Width - myTexture.Width;
int MinX = 0;
int MaxY = graphics.GraphicsDevice.Viewport.Height - myTexture.Height;
int MinY = 0;
if (direction.Equals("up"))
{
if (spritePosition.Y > MinY)
{
spritePosition.Y = spritePosition.Y - 1;
}
else
{
spritePosition.Y = MinY;
}
}
if (direction.Equals("down"))
{
if (spritePosition.Y < MaxY)
{
spritePosition.Y = spritePosition.Y + 1;
}
else
{
spritePosition.Y = MaxY;
}
}
if (direction.Equals("left"))
{
if (spritePosition.X > MinX)
{
spritePosition.X = spritePosition.X - 1;
}
else
{
spritePosition.X = MinX;
}
}
if (direction.Equals("right"))
{
if (spritePosition.X < MaxX)
{
spritePosition.X = spritePosition.X + 1;
}
else
{
spritePosition.X = MinX;
}
}
}
}
InputSkeleton
public class InputSkeleton
{
public KeyboardState newKState;
public KeyboardState oldKState;
public MouseState newMState;
public MouseState oldMState;
public Boolean menuState;
public Boolean gameRun;
public int player;
public InputSkeleton(int p)
{
player = p;
}
public void Update()
{
if (menuState == true && gameRun == false)
{
MenuInput();
}
else if (menuState == false && gameRun == true)
{
PlayerInput();
}
}
public void MenuInput()
{
}
public void PlayerInput()
{
newKState = Keyboard.GetState();
if (newKState.IsKeyDown(Keys.Up))
{
MainSkeleton.Move("up");
}
if (newKState.IsKeyDown(Keys.Down))
{
MainSkeleton.Move("down");
}
if (newKState.IsKeyDown(Keys.Left))
{
MainSkeleton.Move("left");
}
if (newKState.IsKeyDown(Keys.Right))
{
MainSkeleton.Move("right");
}
oldKState = newKState;
}
}
A static method can be called on a class, while a non static method needs to be called on an object. You're trying to call a non static method on a class;
MainSkeleton.Move("up");
Either you need to make the Move() method a static method (which in this case is not an option since you want to call the method on the same object every time), or you need to somehow get to the original MainSkeleton object and call the method on that.
A simple way to get to the original object is to pass it in to the InputObject constructor which you call from MainSkeleton;
input = new InputSkeleton(1, this); // Pass in myself
...and take the object in the constructor;
MainSkeleton mainSkeleton;
public InputSkeleton(int p, MainSkeleton m)
{
player = p;
mainSkeleton = m;
}
...and finally call move() on the object instead;
mainSkeleton.Move("up");
Problem is you are calling the class without creating an instance.
You need to first create an instance to call a non-static method in a class.
Example;
private MainSkeleton _MainSkeleton = new MainSkeleton();
private void Update()
{
// The below is calling a method and telling what object is calling that method.
_MainSkeleton.Move("right");
// The below calls a method but does not link to any object. The below is only able to call non-static methods.
MainSkeleton.Move("right");
}
You should look up more about static vs non-static methods to see what the difference is.
Well first i must say i am a complete noob, I just started with 2d graphics and i experiment on a snake game, in the Update method i call snakeUpdate which updates the position according the keystate the thing is it never updates the position, someone explain a bit please.
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Utilities;
namespace SnakeGame1
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D background;
private Texture2D shuttle;
private Texture2D earth;
KeyboardState newState = new KeyboardState();
KeyboardState oldState = new KeyboardState();
private float angle = 0;
public Vector2 position= new Vector2(480,240);
public Vector2 velocity;
public Game1()
: base()
{
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();
}
/// <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);
// TODO: use this.Content to load your game content here
background = Content.Load<Texture2D>("stars.jpg"); // change these names to the names of your images
shuttle = Content.Load<Texture2D>("shuttle.png"); // if you are using your own images.
earth = Content.Load<Texture2D>("earth.png");
}
/// <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)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
listener();
snakeUp();
// TODO: Add your update logic here
//angle += 0.01f;
base.Update(gameTime);
}
/// <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)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(background, new Rectangle(0, 0, 800, 480), Color.White);
spriteBatch.Draw(earth, new Vector2(400, 240), Color.WhiteSmoke);
Vector2 origin = new Vector2(0, 0);
spriteBatch.Draw(shuttle, position, new Rectangle(0,0, shuttle.Width, shuttle.Height), Color.White, angle, origin, 0.5f, SpriteEffects.None, 1);
spriteBatch.End();
base.Draw(gameTime);
}
public void listener()
{
if (newState.IsKeyDown(Keys.Right) && (oldState.IsKeyUp(Keys.Right)))
velocity = new Vector2(3, 0);
if (newState.IsKeyDown(Keys.Left) && (oldState.IsKeyUp(Keys.Left)))
velocity = new Vector2(-3, 0);
if (newState.IsKeyDown(Keys.Down) && (oldState.IsKeyUp(Keys.Down)))
velocity = new Vector2(0, 3);
if (newState.IsKeyDown(Keys.Up) && (oldState.IsKeyUp(Keys.Up)))
velocity = new Vector2(0, -3);
}
public void snakeUp() {
position += velocity;
}
}
}
You're not assigning oldState and newState correctly: you're initializing those variables (incorrectly) only one time when Game1 is instantiated. You'll need something like this:
public class Game1 : Game {
KeyboardState oldState = Keyboard.GetState();
KeyboardState newState = Keyboard.GetState();
// ...
protected override void Update(GameTime gameTime) {
oldState = newState;
newState = Keyboard.GetState();
// ...
}
}
You are not updating your keyboard state. Write something like this inside your Update method (before listener):
oldState = newState;
newState = Keyboard.GetState();
i want to get the lander of this xna game to successfully touchdown on the landing pad, and then play the sound, however, it passes right through and the sound still plays. the complete code for this is:
namespace MoonLander
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class BasicLunarLander : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
SoundEffectInstance EndGameSoundInstance;
Texture2D BackgroundImage;
Texture2D LandingImage;
SoundEffect EndGameSound;
int LanderPosX;
int LanderPosY;
Texture2D LandingPadImage;
public BasicLunarLander()
{
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
LanderPosX = 100;
LanderPosY = 0;
base.Initialize();
}
/// <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);
// TODO: use this.Content to load your game content here
BackgroundImage = Content.Load<Texture2D>("background");
LandingImage = Content.Load<Texture2D>("lander");
LandingPadImage = Content.Load<Texture2D>("landingpad");
EndGameSound = Content.Load<SoundEffect>("crowdcheer");
EndGameSoundInstance = EndGameSound.CreateInstance();
}
/// <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();
if (Keyboard.GetState().IsKeyDown(Keys.Down))
{
LanderPosY = LanderPosY + 2;
}
if (Keyboard.GetState().IsKeyDown(Keys.Up))
{
LanderPosY = LanderPosY - 2;
}
if (Keyboard.GetState().IsKeyDown(Keys.Left))
{
LanderPosX = LanderPosX - 2;
}
if (Keyboard.GetState().IsKeyDown(Keys.Right))
{
LanderPosX = LanderPosX + 2;
}
// TODO: Add your update logic here
Rectangle rectLander = new Rectangle(LanderPosX, LanderPosY, LandingImage.Width, LandingImage.Height);
Rectangle rectLandingPad = new Rectangle(350, 500, LandingPadImage.Width, LandingPadImage.Height);
if (rectLander.Intersects(rectLandingPad))
{
EndGameSoundInstance.Play();
}
base.Update(gameTime);
}
/// <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)
{
// TODO: Add your drawing code here
spriteBatch.Begin();
spriteBatch.Draw(BackgroundImage, Vector2.Zero, Color.White);
spriteBatch.Draw(LandingImage, new Vector2(LanderPosX, LanderPosY), Color.White);
spriteBatch.Draw(LandingPadImage, new Vector2(350,500), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Hope you can help me with this issue, thank you all for your time.
Its because you're not doing anything about preventing movement after the lander has landed (the condition has been met). The sound plays of course, because that is what you did code.
Add a variable detecting if it has landed and declare it inside your class
bool _hasLanded = false;
then wrap the key detection in your update method (for up, down, left and right keys) inside and if:
if(!_hasLanded)
{
//keypresses go here
}
and finally, inside your if where you check to see if the rectangles intersect, add
_hasLanded = true;
That should prevent you from being able to move the lander once it has touched the landing pad.