I am trying to move a sprite but it won't even let me debug.
When i try to debug i get the following error:
Error 1 The name 'keys' does not exist in the current context
What am i doing wrong? or is it something else? According to multiple sources this is one of the ways to make a sprite move.
I've never been able to use keyboard input to move something or make something happen for some reason. Kinda lost here :(
Here's the code:
public class Game1 : Microsoft.Xna.Framework.Game
{
Texture2D myTexture;
Vector2 spritePosition = Vector2.Zero;
Vector2 spriteSpeed = new Vector2(50.0f, 50.0f);
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
KeyboardState keystate;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
myTexture = Content.Load<Texture2D>("sprite");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
keystate = Keyboard.GetState();
if (keystate.IsKeyDown(keys.right))
spritePosition.X += spriteSpeed.X;
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
Use the actual XNA Keys enumeration (MSDN):
protected override void Update(GameTime gameTime)
{
keystate = Keyboard.GetState();
if (keystate.IsKeyDown(Keys.Right))
spritePosition.X += spriteSpeed.X;
}
Remember, C# is case sensitive!
Related
I'm just starting with Monogame and I'm trying to make a simple sprite, which later is meant to be a button. I've searched all around and done several tutorials, but I can't make it work. I just keep getting the blank, blue screen. Here's my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
namespace Test_Game
{
class Main_Menu
{
//setting the variables
public Texture2D button1;
public Vector2 button1Pos;
public GraphicsDevice graphicsDevice;
GraphicsDeviceManager graphics;
public void initialize(Texture2D texture, Vector2 position, ContentManager Content)
{
//Getting the initialized stuff
button1 = Content.Load<Texture2D>("button_temp");
button1Pos.X = 30;
button1Pos.Y = 30;
}
public void Draw(SpriteBatch spriteBatch)
{
graphics.GraphicsDevice.Clear(Color.Black);
spriteBatch = new SpriteBatch(graphicsDevice);
//Just drawing the Sprite
spriteBatch.Begin();
spriteBatch.Draw(button1, new Rectangle(30, 30, 214, 101), Color.White);
spriteBatch.End();
}
}
}
Hope you can find an answer.
I can see many mistakes in your code, I would left a comment pointing all of the, but its too long.
Most of the mistakes come from this: you're not inheriting from Game class. Your line class Main_Menu should be class Main_Menu : Game. Always use this template for a game class:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace MyGame
{
public class MyGame : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
public MyGame()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
}
}
}
From here on, you must fill this template with the following in mind:
Create your memory-only objects in the Initialize method;
Load and create file-related objects in the LoadContent method;
Add your game logic in the Update method;
Add your drawing logic in the Draw method;
Usually, do not bother with the constructor or the UnloadContent method.
Connecting your existing code with the template, we get the following:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace Test_Game
{
public class Main_Menu : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Vector2 buttonPos; // our button position
Texture2D button; // our button texture
public MyGame()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
buttonPos = new Vector2(30, 30); // X=30, Y=30
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
button = Content.Load<Texture2D>("button_temp"); // load texture
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
// here we would add game logic
// things like moving game objects, detecting collisions, etc
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
// draw our button
int buttonWidth = 214;
int buttonHeight = 101;
spriteBatch.Draw(button, new Rectangle(buttonPos.X, buttonPos.Y, buttonWidth, buttonHeight), Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
This template is used in every game for the MonoGame and XNA frameworks, so you should find a LOT of content on the web about what each method of the Game class does.
This is the first time I program a game, I want to creat a sound effect on each time I shot a missile, not playing the sound when the missile is on the screen, just right after the character shooted it. Here is the code. Please help me, I tried to do it the whole night :
class Player
{
Texture2D hero;
Vector2 hero_location;
KeyboardState hero_movement;
int missileREA;
public List<adw> missiles = new List<adw>();
ContentManager takeContent;
public void LoadContent(ContentManager Content)
{
hero = Content.Load<Texture2D>("F5S4");
hero_location = Vector2.Zero;
takeContent = Content;
}
public void ShootMissiles(GameTime gameTime)
{
adw missile = new adw();
missile.LoadContent(takeContent);
missile.missile_location = hero_location + new Vector2(hero.Width /2,-50);
missiles.Add(missile);
shot = missiles;
}
public void Update(GameTime gameTime)
{
hero_movement = Keyboard.GetState();
if (hero_movement.IsKeyDown(Keys.W))
{
hero_location.Y -= 5;
}
if (hero_movement.IsKeyDown(Keys.D))
{
hero_location.X += 5;
}
if (hero_movement.IsKeyDown(Keys.S))
{
hero_location.Y += 3;
}
if (hero_movement.IsKeyDown(Keys.A))
{
hero_location.X -= 5;
}
if (hero_movement.IsKeyDown(Keys.NumPad1))
{
missileREA += gameTime.ElapsedGameTime.Milliseconds;
if (missileREA > 200)
{
missileREA = 0;
ShootMissiles(gameTime);
}
}
foreach (adw missile in missiles)
{
missile.Update(gameTime);
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(hero, hero_location, Color.White);
foreach (adw missile in missiles)
{
missile.Draw(spriteBatch);
}
}
public IEnumerable<adw> ShootMissile { get; set; }
public List<adw> shot { get; set; }
}
This is my Game1.cs, where all of my contents are loaded and drawn to the screen under my control.
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player player;
SoundEffect missile1;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
player = new Player();
graphics.PreferredBackBufferWidth = 1024;
graphics.PreferredBackBufferHeight = 680;
graphics.ApplyChanges();
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
missile1 = Content.Load<SoundEffect>("missile1");
player.LoadContent(Content);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
foreach (adw missile in player.missiles)
{
missile1.Play();
}
player.Update(gameTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
player.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
And if this is not the place to ask things like this, just tell me. I will do as you advice.
protected override void Update(GameTime gameTime)
{
....
foreach (adw missile in player.missiles)
{
missile1.Play();
}
....
}
Every single frame / tick of your game (I assume this is 60 times a second) you are trying to play your sound for every bullet you currently store a reference to. Basically, you're playing a sound 60+ times a second.
Load your sound within your Player class, exactly in the same way you load your texture. Call Play() on it every time you create a new bullet with ShootMissiles(gameTime);
How I can use Exit() in another class? I want to use it in the Intro class, but I always get that „menuinterface.Menu.exit' is never assigned to, and will always have its default value null“ error message. What is wrong?
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private IState currentState;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
currentState = new Intro();
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
currentState.Load(Content);
}
protected override void Update(GameTime gameTime)
{
currentState.Update(gameTime);
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
currentState.Render(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
public interface IState
{
void Load(ContentManager content);
void Update(GameTime gametime);
void Render(SpriteBatch batch);
}
public class Intro : IState
{
private IState currentState;
private Game1 exit;
Texture2D introscreen;
public void Load(ContentManager content)
{
introscreen = content.Load<Texture2D>("intro");
}
public void Update(GameTime gametime)
{
KeyboardState kbState = Keyboard.GetState();
if (kbState.IsKeyDown(Keys.Space))
currentState = new Menu();
if (kbState.IsKeyDown(Keys.Escape))
exit.Exit();
}
public void Render(SpriteBatch batch)
{
batch.Draw(introscreen, new Rectangle(0, 0, 1280, 720), Color.White);
}
}
Here's your problem:
public class Intro : IState
{
private IState currentState;
private Game1 exit;
Texture2D introscreen;
public void Load(ContentManager content)
{
introscreen = content.Load<Texture2D>("intro");
}
public void Update(GameTime gametime)
{
KeyboardState kbState = Keyboard.GetState();
if (kbState.IsKeyDown(Keys.Space))
currentState = new Menu();
if (kbState.IsKeyDown(Keys.Escape))
exit.Exit(); // ---- this object does not exist
}
public void Render(SpriteBatch batch)
{
batch.Draw(introscreen, new Rectangle(0, 0, 1280, 720), Color.White);
}
}
In this class you are declaring an object called exit but this value is never assigned. You need to instantiate the object before you use it. In your case, I would add the following constructor to resolve your problem.
public Intro(Game1 game)
{
exit = game;
}
You do not assign anything to your exit object, which appears to be of type Game, so this is why you get this error. But why do you need this exit object in the first place?
If you want to quit the game after pressing Escape, use Exit() method. It doesn't require you to use it like in your code. It is as simple as this:
public class Game1 : Microsoft.Xna.Framework.Game
{
// ...
protected override void Update(GameTime gameTime)
{
if (kbState.IsKeyDown(Keys.Escape))
Exit();
base.Update(gameTime);
}
// ...
}
this is my code so far:
Game1.cs Class:
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player MyPlayer;
Texture2D Ball;
int GraphicsWidth,GraphicsHeight;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
GraphicsWidth = graphics.PreferredBackBufferWidth;
GraphicsHeight= graphics.PreferredBackBufferHeight;
MyPlayer = new Player(Ball, new Vector2(100, 100), Vector2.Zero);
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
Ball = Content.Load<Texture2D>("Images/ball");
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
MyPlayer.Draw(spriteBatch);
base.Draw(gameTime);
}
}
Player class(The ball):
class Player
{
Texture2D Texture;
Vector2 Positon,Velocity;
public int Height
{
get { return this.Texture.Height; }
}
public int Width
{
get { return this.Texture.Width; }
}
public Player(Texture2D tex, Vector2 position,Vector2 velocity)
{
this.Texture = tex;
this.Positon = position;
this.Velocity = velocity;
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(Texture, Positon, Color.White);
spriteBatch.End();
}
}
When I try to debug the game I have the following error:
This method does not accept null for this parameter.
Parameter name: texture
In that part:
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Begin();
spriteBatch.Draw(Texture, Positon, Color.White);
spriteBatch.End();
}
Btw, I'd like to ask if I can make this code better or something like that.
Thanks alot!
Looks like you create the Player object before you've loaded the Ball content, and thus, the player holds null instead of a texture, but the Ball field in the Game is the real texture.
I would move the creation of Player into LoadContent, after you've assigned the Ball.
Ball = Content.Load<Texture2D>("Images/ball");
MyPlayer = new Player(Ball, new Vector2(100, 100), Vector2.Zero);
I'm going to preface my answer by saying you should call spriteBatch.begin() and spriteBatch.end() in your Game1.cs Draw function instead of your Player.cs Draw function. It's expensive and you shouldn't do it more than once per draw frame, unless it's absolutely necessary (it's not in this case).
With regards to your actual question, you need to load your player in the LoadContent method rather than your Initialize method.
Initialize is happening before your texture is loaded.
try moving MyPlayer = new Player(Ball, new Vector2(100, 100), Vector2.Zero);
into your LoadContent method after you load the texture into Ball.
It looks like you're loading the ball texture after you've already initialized myPlayer with the "NULL" Ball texture
This is because Initialize is called before LoadContent, and at the point you create your Player the Ball texture is still null.
Either create the Player object in LoadContent, after you load the ball, or allow Player to load its own content.
public class Dirt : Tile
{
Vector2 position;
Texture2D texture;
public Dirt(Game game, Vector2 Position)
: base(game)
{
type = "dirt";
textureName = "Textures/Dirt";
position = Position;
}
public override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
texture = Salvage.contentManager.Load<Texture2D>("Textures/Dirt"); // This doesnt work
base.LoadContent();
}
public override void Update(GameTime gameTime)
{
if (InputHandler.KeyDown(Keys.W))
{
position.Y -= 1;
}
else if (InputHandler.KeyDown(Keys.S))
{
position.Y += 1;
}
if (InputHandler.KeyDown(Keys.D))
{
position.X += 1;
}
else if (InputHandler.KeyDown(Keys.A))
{
position.X -= 1;
}
Camera.DesiredPosition = position;
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
Salvage.spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, Camera.Transformation);
Salvage.spriteBatch.Draw(texture, position, Color.White);
Salvage.spriteBatch.End();
base.Draw(gameTime);
}
}
The loading seems to work fine if i load it in the Salvage class(Main game class)
Edit:
The error im getting is:
Salvage.spriteBatch.Draw(texture, position, Color.White);
This method does not accept null for this parameter.
Parameter name: texture
Here is the code for Salvage class:
public class Salvage : Microsoft.Xna.Framework.Game
{
public static GraphicsDeviceManager graphics;
public static SpriteBatch spriteBatch;
public static ContentManager contentManager;
public static SpriteFont spriteFont;
public GameStateManager stateManager;
public Rectangle ScreenRectangle = new Rectangle(0, 0, 1024, 768);
public Salvage()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferHeight = ScreenRectangle.Height;
graphics.PreferredBackBufferWidth = ScreenRectangle.Width;
Content.RootDirectory = "Content";
contentManager = Content;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
spriteFont = Content.Load<SpriteFont>("Fonts/DefaultSpriteFont"); // This works fine
stateManager = new GameStateManager(this);
GameplayState gameplayState = new GameplayState(this, stateManager);
Components.Add(new InputHandler(this));
Components.Add(new Camera(this, ScreenRectangle));
Components.Add(stateManager);
stateManager.ChangeState(gameplayState);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || InputHandler.KeyReleased(Keys.Escape))
this.Exit();
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
base.Draw(gameTime);
}
}
And the code for Tile
public abstract class Tile : Microsoft.Xna.Framework.DrawableGameComponent
{
public string textureName;
public string type;
public Tile(Game game)
: base(game)
{
}
public override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
base.LoadContent();
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
}
}
Edit:
Here is the GamePlayState class
public class GameplayState : GameState
{
public GameplayState(Game game, GameStateManager manager)
: base(game, manager)
{
childGameComponents.Add(new Dirt(game, new Vector2(0, 0)));
}
public override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
base.LoadContent();
}
public override void Update(GameTime gameTime)
{
base.Update(gameTime);
}
public override void Draw(GameTime gameTime)
{
base.Draw(gameTime);
}
}
I have seen your problem. You declare the contentManager variable, but you never assign it until the LoadContent method. If you are loading Dirt before this, you won't have a valid ContentManager variable causing it to fail.
In your constructor of your Salvage class, add the following line:
contentManager = Content;
This should resolve your issue.