【发布时间】:2014-01-27 04:50:51
【问题描述】:
我正在制作角色扮演游戏,并编写了精灵的运动和动画。当我运行项目时,精灵会向下或向右移动。当按下右箭头键时,精灵会向右移动,但不会停止。当按下向下键时,精灵将向下移动,并在释放键时停止。但是,当您按下向下或向右键后按下另一个箭头键时,精灵图像不会改变方向。此外,当按下新的箭头键时,精灵图像不会改变。为什么会这样?任何帮助表示赞赏。
Game.cs
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 RPG
{
/// <summary>
/// Default Project Template
/// </summary>
public class Game1 : Game
{
#region Fields
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Vector2 aPosition = new Vector2(250, 100);
MageChar mageSprite;
#endregion
#region Initialization
public Game1 ()
{
graphics = new GraphicsDeviceManager (this);
Content.RootDirectory = "Content";
graphics.IsFullScreen = false;
}
/// <summary>
/// Overridden from the base Game.Initialize. Once the GraphicsDevice is setup,
/// we'll use the viewport to initialize some values.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
mageSprite = new MageChar();
base.Initialize();
}
/// <summary>
/// Load your graphics 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
mageSprite.LoadContent(this.Content);
}
#endregion
#region Update and Draw
/// <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)
{
// game exits id back button is pressed
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
//calls update method of MageChar class
mageSprite.Update(gameTime);
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)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin();
//calls draw method of MageChar class
mageSprite.Draw(this.spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
#endregion
}
}
CharMovement.cs
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 RPG
{
public class CharMovement
{
//The asset name for the Sprite's Texture
public string charSprite;
//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 charTexture;
//Load the texture for the sprite using the Content Pipeline
public void LoadContent(ContentManager theContentManager, string theCharSprite)
{
//loads the image of the sprite
charTexture = theContentManager.Load<Texture2D>(theCharSprite);
theCharSprite = charSprite;
//creates a new rectangle the size of the sprite
Size = new Rectangle(0, 0, (int)(charTexture.Width * mScale), (int)(charTexture.Height * mScale));
}
//Update the Sprite and change it's position based on the set speed, direction and elapsed time.
public void Update(GameTime theGameTime, Vector2 theSpeed, Vector2 theDirection)
{
//calculates the position of the sprite using the speed and direction from the MageChar class
Position += theDirection * theSpeed * (float)theGameTime.ElapsedGameTime.TotalSeconds;
if (Position.X < 0)
{
Position.X = 0;
}
if (Position.Y < 0)
{
Position.Y = 0;
}
}
//Draw the sprite to the screen
public void Draw(SpriteBatch theSpriteBatch)
{
//draw the sprite to the screen inside a rectangle
theSpriteBatch.Draw(charTexture, Position,
new Rectangle(0, 0, charTexture.Width, charTexture.Height),
Color.White, 0.0f, Vector2.Zero, mScale, SpriteEffects.None, 0);
}
}
}
MageChar.cs
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 RPG
{
public class MageChar : CharMovement
{
//variable where sprite file name is stored
string MageAssetName = "WalkingFront";
//starting x position
const int StartPositionX = 0;
//starting y position
const int StartPositionY = 0;
//speed that the sprite will move on screen
const int MageSpeed = 160;
//move sprite 1 up/down when the arrow key is pressed
const int MoveUp = 1;
const int MoveDown = 1;
const int MoveLeft = 1;
const int MoveRight = 1;
//used to store the current state of the sprite
enum State
{
WalkingLeft,
WalkingRight,
WalkingFront,
WalkingBack
}
//set to current state of the sprite. initally set to walking
State CurrentState = State.WalkingFront;
//stores direction of sprite
Vector2 Direction = Vector2.Zero;
//stores speed of sprite
Vector2 Speed = Vector2.Zero;
//stores previous state of keyboard
KeyboardState PreviousKeyboardState;
public void LoadContent(ContentManager theContentManager)
{
//sets position to the top left corner of the screen
Position = new Vector2(StartPositionX, StartPositionY);
//calls the load content method of the CharMovement class, passing in the content manager, and the name of the sprite image
base.LoadContent(theContentManager, MageAssetName);
}
//checks state of the keyboard
private void Update(KeyboardState aCurrentKeyboardState)
{
//run if the sprite is walking
if (CurrentState == State.WalkingFront)
{
//sets direction and speed to zero
Speed = Vector2.Zero;
Direction = Vector2.Zero;
//if left key is pressed, move left
if (aCurrentKeyboardState.IsKeyDown(Keys.Left) == true)
{
CurrentState = State.WalkingLeft;
MageAssetName = "WalkingLeft";
//speed of sprite movement
Speed.X -= MageSpeed;
//moves the sprite left
Direction.X -= MoveLeft;
}
//if right key is pressed, move right
else if (aCurrentKeyboardState.IsKeyDown(Keys.Right) == true)
{
CurrentState = State.WalkingRight;
MageAssetName = "WalkingRight";
//speed of sprite movement
Speed.X += MageSpeed;
//moves the sprite right
Direction.X += MoveRight;
}
//if up key is pressed, move up
if (aCurrentKeyboardState.IsKeyDown(Keys.Up) == true)
{
CurrentState = State.WalkingBack;
MageAssetName = "WalkingBack";
//speed of sprite movement
Speed.Y += MageSpeed;
//moves sprite up
Direction.Y += MoveUp;
}
//if down key is pressed, move down
else if (aCurrentKeyboardState.IsKeyDown(Keys.Down) == true)
{
CurrentState = State.WalkingFront;
MageAssetName = "WalkingFront";
//speed of sprite movement
Speed.Y -= MageSpeed;
//moves sprite down
Direction.Y -= MoveDown;
}
}
}
public void Update(GameTime theGameTime)
{
//obtains current state of the keyboard
KeyboardState aCurrentKeyboardState = Keyboard.GetState();
//calls in UpdateMovement and passes in current keyboard state
Update(aCurrentKeyboardState);
//set previous state to current state
PreviousKeyboardState = aCurrentKeyboardState;
//call update method of the charMovement class, passing in the gametime, speed and direction of the sprite
base.Update(theGameTime, Speed, Direction);
}
}
}
【问题讨论】:
-
我有点害怕 MageChar 是一个动作而不是一个动作变量……不过你一定是在学习。