2011-07-31, 07:29 AM
Okay, I was trying to make my sprite bend down/duck. I got a working but dissatisfactory result; the sprite changes, but rather than crouching, it flies into the air in a crouching motion.
I know why this happens. I placed my ducking sprite in the top right-hand corner of the picture, so when the picture draws, the sprite ends up in the top right-hand corner. Not wanting to adjust it using paint, I tried remedying this by using 'if'. Needless to say it failed miserably. The computer suddenly found problems everywhere, even in code and classes I hadn't touched.
Problem Version of Sprite.cs
The list of errors that suddenly popped up included operator * cannot be applied to opreands of type int and method group and several others. Lots of things also spontaneously failed to exist in the current context, and ;s are suddenly needed when they never were before. If I add the ; as instructed, then the problem remains and extra problems pop up elsewhere.
What I want to know is why the if method doesn't work. Since it doesn't work, what would work?
Original version of sprite.cs
Wizard.cs
Game1.cs
I know why this happens. I placed my ducking sprite in the top right-hand corner of the picture, so when the picture draws, the sprite ends up in the top right-hand corner. Not wanting to adjust it using paint, I tried remedying this by using 'if'. Needless to say it failed miserably. The computer suddenly found problems everywhere, even in code and classes I hadn't touched.
Problem Version of Sprite.cs
Code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//testing crackpot solution
using Microsoft.Xna.Framework.Input;
namespace WindowsGame11
{
class Sprite
{
//The Rectangular area from the original image that
//defines the Sprite.
Rectangle mSource;
public Rectangle Source
{
get
{
return mSource;
}
set
{
mSource = value;
Size = new Rectangle(0, 0, (int)(mSource.Width * Scale), (int)(mSource.Height * Scale));
}
}
//The asset name for the Sprite's Texture
public string AssetName;
//The Size of the Sprite (with scale applied)
public Rectangle Size;
//The amount to increase/decrease the size of the original sprite.
private float mScale = 1.0f;
//The current position of the Sprite
public Vector2 Position = new Vector2(0, 0);
//The texture object used when drawing the sprite
private Texture2D mSpriteTexture;
//crackpot SOLUTION
KeyboardState mPreviousKeyboardState;
//crackpot SOLUTION
public void Update(GameTime theGameTime)
{
KeyboardState aCurrentKeyboardState = Keyboard.GetState();
Scale(aCurrentKeyboardState);
mPreviousKeyboardState = aCurrentKeyboardState;
}
//When the scale is modified through he property, the Size of the
//sprite is recalculated with the new scale applied.
public float Scale(KeyboardState aCurrentKeyboardState)
{
get { return mScale; }
set
{
mScale = value;
if (aCurrentKeyboardState.IsKeyDown(Keys.RightShift) == true)
{
//Recalculate the Size of the Sprite with the new scale
Size = new Rectangle(92, 45, (int)(Source.Width * Scale), (int)(Source.Height * Scale));
}
else
{
//Recalculate the Size of the Sprite with the new scale
Size = new Rectangle(0, 0, (int)(Source.Width * Scale), (int)(Source.Height * Scale));
}
}
}
//Load the texture for the sprite using the Content Pipeline
public void LoadContent(ContentManager theContentManager, string theAssetName, KeyboardState aCurrentKeyboardState)
{
mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName);
AssetName = theAssetName;
Source = new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height);
if (aCurrentKeyboardState.IsKeyDown(Keys.RightShift) == true)
{
Size = new Rectangle(92, 45, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
else
{
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
}
//Update the Sprite and change its position based on the passed in speed, direction and elapsed time.
public void Update(GameTime theGameTime, Vector2 theSpeed, Vector2 theDirection)
{
Position += theDirection * theSpeed * (float)theGameTime.ElapsedGameTime.TotalSeconds;
}
//Draw the sprite to the screen
public void Draw(SpriteBatch theSpriteBatch)
{
theSpriteBatch.Draw(mSpriteTexture, Position, Source,
Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
}
}
}The list of errors that suddenly popped up included operator * cannot be applied to opreands of type int and method group and several others. Lots of things also spontaneously failed to exist in the current context, and ;s are suddenly needed when they never were before. If I add the ; as instructed, then the problem remains and extra problems pop up elsewhere.
What I want to know is why the if method doesn't work. Since it doesn't work, what would work?
Original version of sprite.cs
Code:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace WindowsGame11
{
class Sprite
{
//The Rectangular area from the original image that
//defines the Sprite.
Rectangle mSource;
public Rectangle Source
{
get
{
return mSource;
}
set
{
mSource = value;
Size = new Rectangle(0, 0, (int)(mSource.Width * Scale), (int)(mSource.Height * Scale));
}
}
//The asset name for the Sprite's Texture
public string AssetName;
//The Size of the Sprite (with scale applied)
public Rectangle Size;
//The amount to increase/decrease the size of the original sprite.
private float mScale = 1.0f;
//The current position of the Sprite
public Vector2 Position = new Vector2(0,0);
//The texture object used when drawing the sprite
private Texture2D mSpriteTexture;
//When the scale is modified through he property, the Size of the
//sprite is recalculated with the new scale applied.
public float Scale
{
get { return mScale; }
set
{
mScale = value;
//Recalculate the Size of the Sprite with the new scale
Size = new Rectangle(0, 0, (int)(Source.Width * Scale), (int)(Source.Height * Scale));
}
}
//Load the texture for the sprite using the Content Pipeline
public void LoadContent(ContentManager theContentManager, string theAssetName)
{
mSpriteTexture = theContentManager.Load<Texture2D>(theAssetName);
AssetName = theAssetName;
Source = new Rectangle(0, 0, mSpriteTexture.Width, mSpriteTexture.Height);
Size = new Rectangle(0, 0, (int)(mSpriteTexture.Width * Scale), (int)(mSpriteTexture.Height * Scale));
}
//Update the Sprite and change its position based on the passed in speed, direction and elapsed time.
public void Update(GameTime theGameTime, Vector2 theSpeed, Vector2 theDirection)
{
Position += theDirection * theSpeed * (float)theGameTime.ElapsedGameTime.TotalSeconds;
}
//Draw the sprite to the screen
public void Draw(SpriteBatch theSpriteBatch)
{
theSpriteBatch.Draw(mSpriteTexture, Position, Source,
Color.White, 0.0f, Vector2.Zero, Scale, SpriteEffects.None, 0);
}
}
}Wizard.cs
Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
namespace WindowsGame11
{
class Wizard : Sprite
{
const string WIZARD_ASSETNAME = "stand2_0"; const int START_POSITION_X = 0;
const int START_POSITION_Y = 0;
const int WIZARD_SPEED = 160;
const int MOVE_UP = -1;
const int MOVE_DOWN = 1;
const int MOVE_LEFT = -1;
const int MOVE_RIGHT = 1;
enum State
{
Walking,
Jumping,
Ducking
}
//two instances of the following line will cause an ambiguity error.
State mCurrentState = State.Walking;
Vector2 mStartingPosition = Vector2.Zero;
Vector2 mDirection = Vector2.Zero;
Vector2 mSpeed = Vector2.Zero;
KeyboardState mPreviousKeyboardState;
//You'll notice we set the SourceRectangle after LoadContent in the base sprite class is called.
//We need to do it in that order since the base Sprite class also sets Source and we don't want it to override ours.
public void LoadContent(ContentManager theContentManager)
{
Position = new Vector2(START_POSITION_X, START_POSITION_Y);
base.LoadContent(theContentManager, WIZARD_ASSETNAME);
Source = new Rectangle(0, 0, 106, Source.Height);
}
public void Update(GameTime theGameTime)
{
KeyboardState aCurrentKeyboardState = Keyboard.GetState();
UpdateMovement(aCurrentKeyboardState);
UpdateJump(aCurrentKeyboardState);
UpdateDuck(aCurrentKeyboardState);
mPreviousKeyboardState = aCurrentKeyboardState;
base.Update(theGameTime, mSpeed, mDirection);
}
private void UpdateJump(KeyboardState aCurrentKeyboardState)
{
if (mCurrentState == State.Walking)
{
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{ Jump();
}
}
if (mCurrentState == State.Jumping)
{
if (mStartingPosition.Y - Position.Y > 150)
{
mDirection.Y = MOVE_DOWN;
}
if (Position.Y > mStartingPosition.Y)
{
Position.Y = mStartingPosition.Y;
mCurrentState = State.Walking;
mDirection = Vector2.Zero;
}
}
}
public void UpdateDuck(KeyboardState aCurrentKeyboardState)
{
if (aCurrentKeyboardState.IsKeyDown(Keys.RightShift) == true)
{
Duck();
}
else
{
StopDucking();
}
}
public void Duck()
{
if (mCurrentState == State.Walking)
{
mSpeed = Vector2.Zero;
mDirection = Vector2.Zero;
Source = new Rectangle(106, 0, 149, 61);
mCurrentState = State.Ducking;
}
}
private void StopDucking()
{
if (mCurrentState == State.Ducking)
{
Source = new Rectangle(0, 0, 106, 93);
mCurrentState = State.Walking;
}
}
private void UpdateMovement(KeyboardState aCurrentKeyboardState)
{
if (mCurrentState == State.Walking)
{
mSpeed = Vector2.Zero;
mDirection = Vector2.Zero;
if (aCurrentKeyboardState.IsKeyDown(Keys.Left) == true)
{
mSpeed.X = WIZARD_SPEED;
mDirection.X = MOVE_LEFT;
}
else if (aCurrentKeyboardState.IsKeyDown(Keys.Right) == true)
{
mSpeed.X = WIZARD_SPEED;
mDirection.X = MOVE_RIGHT;
}
if (aCurrentKeyboardState.IsKeyDown(Keys.Up) == true)
{
mSpeed.Y = WIZARD_SPEED;
mDirection.Y = MOVE_UP;
}
else if (aCurrentKeyboardState.IsKeyDown(Keys.Down) == true)
{
mSpeed.Y = WIZARD_SPEED;
mDirection.Y = MOVE_DOWN;
}
}
}
private void Jump()
{
if (mCurrentState != State.Jumping)
{
mCurrentState = State.Jumping;
mStartingPosition = Position;
mDirection.Y = MOVE_UP;
mSpeed = new Vector2(WIZARD_SPEED, WIZARD_SPEED);
}
}
}
}Game1.cs
Code:
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 WindowsGame11
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Wizard Wizard;
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
Wizard = new Wizard();
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
Wizard.LoadContent(this.Content);
}
/// <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)
{
KeyboardState aCurrentKeyboardState = Keyboard.GetState();
// Allows the game to exit
if (aCurrentKeyboardState.IsKeyDown(Keys.X) == true)
this.Exit();
// TODO: Add your update logic here
Wizard.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();
Wizard.Draw(this.spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
}
}
