目前正试图在我使用XNA 4.0在C#中制作的游戏中为一系列敌人精灵制作动画
使用此动画代码
namespace Rotationgame
{
class Animation
{
Texture2D texture;
Rectangle rectangle;
Vector2 position;
Vector2 origin;
Vector2 velocity;
int currentFrame;
int frameHeight;
int frameWidth;
float timer;
float interval = 150;
public Animation(Texture2D newTexture, Vector2 newPosition, int newFrameHeight, int newFrameWidth)
{
texture = newTexture;
position = newPosition;
frameHeight = newFrameHeight;
frameWidth = newFrameWidth;
}
public void Update(GameTime gameTime)
{
rectangle = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);
origin = new Vector2(rectangle.Width / 2, rectangle.Height / 2);
position = position + velocity;
if (Keyboard.GetState().IsKeyUp(Keys.F1))
{
AnimateRight(gameTime);
velocity.X = 0;
}
else if (Keyboard.GetState().IsKeyUp(Keys.F2))
{
AnimateLeft(gameTime);
velocity.X = -0;
}
else velocity = Vector2.Zero;
}
public void AnimateRight(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
if (timer > interval)
{
currentFrame++;
timer = 0;
if (currentFrame > 1)
currentFrame = 0;
}
}
public void AnimateLeft(GameTime gameTime)
{
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds / 2;
if (timer > interval)
{
currentFrame++;
timer = 0;
if (currentFrame > 1)
currentFrame = 0;
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, rectangle, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0);
}
}
}
这个数组的代码
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Animation[] invaders;
protected override void Initialize()
{
invaders = new Animation[13];
// TODO: Add your initialization logic here
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// Array of Space Invaders
invaders[0] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(400, 400), 115, 96);
invaders[1] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 310), 115, 96);
invaders[2] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 490), 115, 96);
invaders[3] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 250), 115, 96);
invaders[4] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 550), 115, 96);
invaders[5] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 240), 115, 96);
invaders[7] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 560), 115, 96);
invaders[8] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 550), 115, 96);
invaders[9] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 250), 115, 96);
invaders[10] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 490), 115, 96);
invaders[11] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 310), 115, 96);
invaders[12] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(757, 400), 115, 96);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
// Drawing Invaders
foreach (Animation invader in invaders)
invaders.Draw(spriteBatch);
}
spriteBatch.End();
一切都在Visual Studio的代码中工作但是我在Draw方法上得到一个错误:“错误1'System.Array'不包含'Draw'的定义,也没有扩展方法'Draw'接受第一个参数可以找到'System.Array'类型(您是否缺少using指令或程序集引用?)“
任何想法出了什么问题?
编辑:这是game1文件的完整代码
namespace Rotationgame
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Animation[] invaders;
// Different Windows
enum GameState
{
MainMenu,
Playing,
}
GameState CurrentGameState = GameState.MainMenu;
// Screeb Adjustments
int screenWidth = 1250, screenHeight = 930;
// Main Menu Buttons
button btnPlay;
button btnQuit;
// Pause Menu & buttons
bool paused = false;
button btnResume;
button btnMainMenu;
// Player's Movement
Vector2 spriteVelocity;
const float tangentialVelocity = 0f;
float friction = 1f;
Texture2D spriteTexture;
Rectangle spriteRectangle;
Vector2 spritePosition;
float rotation;
// The centre of the image
Vector2 spriteOrigin;
// Background
Texture2D backgroundTexture;
Rectangle backgroundRectangle;
// Shield
Texture2D shieldTexture;
Rectangle shieldRectangle;
// Bullets
List<Bullets> bullets = new List<Bullets>();
KeyboardState pastKey;
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()
{
invaders = new Animation[12];
// 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);
// Load Player's Shield (Cosmetic at moment as not set up fully
shieldTexture = Content.Load<Texture2D>("Shield");
shieldRectangle = new Rectangle(517, 345, 250, 220);
// Load Player's Ship
spriteTexture = Content.Load<Texture2D>("PlayerShipright");
spritePosition = new Vector2(640, 450);
// Load Game background
backgroundTexture = Content.Load<Texture2D>("Background");
backgroundRectangle = new Rectangle(0, 0, 1250, 930);
// Screen Adjustments
graphics.PreferredBackBufferWidth = screenWidth;
graphics.PreferredBackBufferHeight = screenHeight;
graphics.ApplyChanges();
IsMouseVisible = true;
// Main menu Buttons & locations
btnPlay = new button(Content.Load<Texture2D>("Playbutton"), graphics.GraphicsDevice);
btnPlay.setPosition(new Vector2(550, 310));
btnQuit = new button(Content.Load<Texture2D>("Quitbutton"), graphics.GraphicsDevice);
btnQuit.setPosition(new Vector2(550, 580));
// Array of Space Invaders
invaders[0] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(400, 400), 115, 96);
invaders[1] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 310), 115, 96);
invaders[2] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(427, 490), 115, 96);
invaders[3] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 250), 115, 96);
invaders[4] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(490, 550), 115, 96);
invaders[5] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 240), 115, 96);
invaders[6] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(580, 560), 115, 96);
invaders[7] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 550), 115, 96);
invaders[8] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(670, 250), 115, 96);
invaders[9] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 490), 115, 96);
invaders[10] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(730, 310), 115, 96);
invaders[11] = new Animation(Content.Load<Texture2D>("SpaceInvaderbefore"), new Vector2(757, 400), 115, 96);
// Pause menu buttons & locations
btnResume = new button(Content.Load<Texture2D>("Playbutton"), graphics.GraphicsDevice);
btnResume.setPosition(new Vector2(550, 310));
btnMainMenu = new button(Content.Load<Texture2D>("Quitbutton"), graphics.GraphicsDevice);
btnMainMenu.setPosition(new Vector2(550, 580));
// 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)
{
MouseState mouse = Mouse.GetState();
// Allows the game to exit
if (Keyboard.GetState().IsKeyDown(Keys.Escape))
this.Exit();
switch (CurrentGameState)
{
case GameState.MainMenu:
if(btnPlay.isClicked == true) CurrentGameState = GameState.Playing;
btnPlay.Update(mouse);
if (btnQuit.isClicked == true)
this.Exit();
btnQuit.Update(mouse);
break;
case GameState.Playing:
if (!paused)
{
if (Keyboard.GetState().IsKeyDown(Keys.Enter))
{
paused = true;
btnResume.isClicked = false;
}
}
else if (paused)
{
if (Keyboard.GetState().IsKeyDown(Keys.Enter))
if (btnResume.isClicked)
paused = false;
if (btnMainMenu.isClicked) CurrentGameState = GameState.MainMenu;
}
break;
}
// TODO: Add your update logic here
if (Keyboard.GetState().IsKeyDown(Keys.Space) && pastKey.IsKeyUp(Keys.Space))
Shoot();
pastKey = Keyboard.GetState();
spritePosition = spriteVelocity + spritePosition;
spriteRectangle = new Rectangle((int)spritePosition.X, (int)spritePosition.Y,
spriteTexture.Width, spriteTexture.Height);
spriteOrigin = new Vector2(spriteRectangle.Width / 2, spriteRectangle.Height / 2);
if (Keyboard.GetState().IsKeyDown(Keys.Right)) rotation += 0.025f;
if (Keyboard.GetState().IsKeyDown(Keys.Left)) rotation -= 0.025f;
if (Keyboard.GetState().IsKeyDown(Keys.Up))
{
spriteVelocity.X = (float)Math.Cos(rotation) * tangentialVelocity;
spriteVelocity.Y = (float)Math.Sin(rotation) * tangentialVelocity;
}
else if (Vector2.Zero != spriteVelocity)
{
float i = spriteVelocity.X;
float j = spriteVelocity.Y;
spriteVelocity.X = i -= friction * i;
spriteVelocity.Y = j -= friction * j;
base.Update(gameTime);
}
UpdateBullets();
}
public void UpdateBullets()
{
foreach (Bullets bullet in bullets)
{
bullet.position += bullet.velocity;
if (Vector2.Distance(bullet.position, spritePosition) > 760)
bullet.isVisible = false;
}
for (int i = 0; i < bullets.Count; i++)
{
if(!bullets[i].isVisible)
{
bullets.RemoveAt(i);
i--;
}
}
}
public void Shoot()
{
Bullets newBullet = new Bullets(Content.Load<Texture2D>("bullet"));
newBullet.velocity = new Vector2((float)Math.Cos(rotation),(float)Math.Sin(rotation)) * 3f + spriteVelocity;
newBullet.position = spritePosition + newBullet.velocity * 5;
newBullet.isVisible = true;
if(bullets.Count() < 25)
bullets.Add(newBullet);
}
/// <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();
switch (CurrentGameState)
{
case GameState.MainMenu:
spriteBatch.Draw(Content.Load<Texture2D>("MainMenu"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
btnPlay.Draw(spriteBatch);
btnQuit.Draw(spriteBatch);
break;
case GameState.Playing:
// Drawing Background
spriteBatch.Draw(backgroundTexture, backgroundRectangle, Color.White);
// Drawing Shield
spriteBatch.Draw(shieldTexture, shieldRectangle, Color.White);
// Drawing Invaders
foreach (Animation invader in invaders)
invader.Draw(spriteBatch);
// Drawing Bullets
foreach (Bullets bullet in bullets)
bullet.Draw(spriteBatch);
// Drawing Player's Character
spriteBatch.Draw(spriteTexture, spritePosition, null, Color.White, rotation, spriteOrigin, 1f, SpriteEffects.None, 0);
if (paused)
{
spriteBatch.Draw(Content.Load<Texture2D>("PauseMenu"), new Rectangle(0, 0, screenWidth, screenHeight), Color.White);
btnResume.Draw(spriteBatch);
btnMainMenu.Draw(spriteBatch);
}
break;
}
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
第二次编辑:按钮类
namespace Rotationgame
{
class button
{
Texture2D texture;
Vector2 position;
Rectangle rectangle;
Color colour = new Color(255, 255, 255, 255);
public Vector2 size;
public button(Texture2D newTexture, GraphicsDevice graphics)
{
texture = newTexture;
// ScreenW = 1250 (currently atm 800), ScreenH = 930 (currently atm 600)
//ImgW = 100 , ImgH = 20
size = new Vector2(graphics.Viewport.Width / 8, graphics.Viewport.Height / 30);
}
bool down;
public bool isClicked;
public void Update(MouseState mouse)
{
rectangle = new Rectangle((int)position.X,(int)position.Y,
(int)size.X, (int)size.Y);
Rectangle mouseRectangle = new Rectangle(mouse.X, mouse.Y, 1, 1);
if (mouseRectangle.Intersects(rectangle))
{
if (colour.A == 255) down = false;
if (colour.A == 0) down = true;
if (down) colour.A += 3; else colour.A -= 3;
if (mouse.LeftButton == ButtonState.Pressed) isClicked = true;
}
else if (colour.A < 255)
{
colour.A += 3;
isClicked = false;
}
}
public void setPosition(Vector2 newPosition)
{
position = newPosition;
}
public void Draw(SpriteBatch spritebatch)
{
spritebatch.Draw(texture, rectangle, colour);
}
}
}
答案 0 :(得分:0)
C#有很棒的集合类库来替换列表。我非常不鼓励使用Array,因为它不够灵活。如果您正在编写专门用于低端硬件的代码,并且知道代码的内外部分并管理它的每一部分,那么只需要使用数组。
但我喜欢你组织课程的方式。非常好。现在,如果你有列表,那么你可以随时添加任意数量的课程。你不必决定如何做到这一点。
现在,该类有一个Rectangles集合,它在sprite集合中给出了sprite的位置,然后你只需要在你的动画逻辑中使用in draw方法。你已经拥有的。
还有一件事,没有必要添加
Content.Load<Texture2D>("SpaceInvaderbefore")
多次。而是将其存储到变量并使用它。
这里有两条精彩的文章。 1和2。其中提供了有关如何使用XNA进行动画的详细信息。 游戏开发必须有Plural Sight的过程。你也可以试试。
我希望我的回答可以帮到你。如果需要进一步的详细信息,请告诉我。