这个计划是关于快速驾驶和避开障碍。我按照了几个教程并设法创建了一个爆炸类。每当碰撞发生时,爆炸就会出现,但它并不存在。
没有错误,但我认为问题出在Game1.cs中。我在Game1.cs中创建了以下函数:
//list
List <Explosion> explosionList = new List<Explosion>();
//This is in the update method
foreach (Explosion ex in explosionList)
{
ex.Update(gameTime);
}
//This is a method called manage explosions
public void ManageExplosions()
{
for (int i = 0; i < explosionList.Count; i++)
{
if (explosionList[i].isVisible)
{
explosionList.RemoveAt(i);
i--;
}
}
}
//This is placed in the CheckCollision method
explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(theHazard.Position.X, theHazard.Position.Y)));
Game1.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 DriveFast
{
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
private Texture2D mCar;
private Texture2D mBackground;
private Texture2D mRoad;
private Texture2D mHazard;
private Texture2D hazardCrash;
private KeyboardState mPreviousKeyboardState;
private Vector2 mCarPosition = new Vector2(280, 440);
private int mMoveCarX = 160;
private int mVelocityY;
private double mNextHazardAppearsIn;
private int mCarsRemaining;
private int mHazardsPassed;
private int mIncreaseVelocity;
private double mExitCountDown = 10;
private int[] mRoadY = new int[2];
private List<Hazard> mHazards = new List<Hazard>();
private Random mRandom = new Random();
private SpriteFont mFont;
//video
List <Explosion> explosionList = new List<Explosion>();
private enum State
{
TitleScreen,
Running,
Crash,
GameOver,
Success
}
private State mCurrentState = State.TitleScreen;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
graphics.PreferredBackBufferHeight = 600;
graphics.PreferredBackBufferWidth = 800;
}
protected override void Initialize()
{
base.Initialize();
}
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
mCar = Content.Load<Texture2D>("Images/Car");
mBackground = Content.Load<Texture2D>("Images/Background");
mRoad = Content.Load<Texture2D>("Images/Road");
mHazard = Content.Load<Texture2D>("Images/Hazard");
hazardCrash = Content.Load<Texture2D>("Images/hazardCrash");
mFont = Content.Load<SpriteFont>("MyFont");
}
protected override void UnloadContent()
{
}
protected void StartGame()
{
mRoadY[0] = 0;
mRoadY[1] = -1 * mRoad.Height;
mHazardsPassed = 0;
mCarsRemaining = 3;
mVelocityY = 3;
mNextHazardAppearsIn = 1.5;
mIncreaseVelocity = 5;
mHazards.Clear();
mCurrentState = State.Running;
}
protected override void Update(GameTime gameTime)
{
KeyboardState aCurrentKeyboardState = Keyboard.GetState();
//Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
aCurrentKeyboardState.IsKeyDown(Keys.Escape) == true)
{
this.Exit();
}
switch (mCurrentState)
{
case State.TitleScreen:
case State.Success:
case State.GameOver:
{
ExitCountdown(gameTime);
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{
StartGame();
}
break;
}
case State.Running:
{
//If the user has pressed the Spacebar, then make the car switch lanes
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{
mCarPosition.X += mMoveCarX;
mMoveCarX *= -1;
}
ScrollRoad();
foreach (Hazard aHazard in mHazards)
{
if (CheckCollision(aHazard) == true)
{
//video
explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(aHazard.Position.X, aHazard.Position.Y)));
break;
}
MoveHazard(aHazard);
}
UpdateHazards(gameTime);
break;
}
case State.Crash:
{
//If the user has pressed the Space key, then resume driving
if (aCurrentKeyboardState.IsKeyDown(Keys.Space) == true && mPreviousKeyboardState.IsKeyDown(Keys.Space) == false)
{
mHazards.Clear();
mCurrentState = State.Running;
}
break;
}
}
mPreviousKeyboardState = aCurrentKeyboardState;
//video
ManageExplosions();
//
base.Update(gameTime);
//video
foreach (Explosion ex in explosionList)
{
ex.Update(gameTime);
}
}
private void ScrollRoad()
{
//Move the scrolling Road
for (int aIndex = 0; aIndex < mRoadY.Length; aIndex++)
{
if (mRoadY[aIndex] >= this.window.ClientBounds.Height)
{
int aLastRoadIndex = aIndex;
for (int aCounter = 0; aCounter < mRoadY.Length; aCounter++)
{
if (mRoadY[aCounter] < mRoadY[aLastRoadIndex])
{
aLastRoadIndex = aCounter;
}
}
mRoadY[aIndex] = mRoadY[aLastRoadIndex] - mRoad.Height;
}
}
for (int aIndex = 0; aIndex < mRoadY.Length; aIndex++)
{
mRoadY[aIndex] += mVelocityY;
}
}
private void MoveHazard(Hazard theHazard)
{
theHazard.Position.Y += mVelocityY;
if (theHazard.Position.Y > graphics.GraphicsDevice.Viewport.Height && theHazard.Visible == true)
{
theHazard.Visible = false;
mHazardsPassed += 1;
if (mHazardsPassed >= 100)
{
mCurrentState = State.Success;
mExitCountDown = 10;
}
mIncreaseVelocity -= 1;
if (mIncreaseVelocity < 0)
{
mIncreaseVelocity = 5;
mVelocityY += 1;
}
}
}
private void UpdateHazards(GameTime theGameTime)
{
mNextHazardAppearsIn -= theGameTime.ElapsedGameTime.TotalSeconds;
if (mNextHazardAppearsIn < 0)
{
int aLowerBound = 24 - (mVelocityY * 2);
int aUpperBound = 30 - (mVelocityY * 2);
if (mVelocityY > 10)
{
aLowerBound = 6;
aUpperBound = 8;
}
mNextHazardAppearsIn = (double)mRandom.Next(aLowerBound, aUpperBound) / 10;
AddHazard();
}
}
private void AddHazard()
{
int aRoadPosition = mRandom.Next(1, 3);
int aPosition = 275;
if (aRoadPosition == 2)
{
aPosition = 440;
}
bool aAddNewHazard = true;
foreach (Hazard aHazard in mHazards)
{
if (aHazard.Visible == false)
{
aAddNewHazard = false;
aHazard.Visible = true;
aHazard.Position = new Vector2(aPosition, -mHazard.Height);
break;
}
}
if (aAddNewHazard == true)
{
//Add a hazard to the left side of the Road
Hazard aHazard = new Hazard();
aHazard.Position = new Vector2(aPosition, -mHazard.Height);
mHazards.Add(aHazard);
}
}
private bool CheckCollision(Hazard theHazard)
{
BoundingBox aHazardBox = new BoundingBox(new Vector3(theHazard.Position.X, theHazard.Position.Y, 0), new Vector3(theHazard.Position.X + (mHazard.Width * .4f), theHazard.Position.Y + ((mHazard.Height - 50) * .4f), 0));
BoundingBox aCarBox = new BoundingBox(new Vector3(mCarPosition.X, mCarPosition.Y, 0), new Vector3(mCarPosition.X + (mCar.Width * .2f), mCarPosition.Y + (mCar.Height * .2f), 0));
if (aHazardBox.Intersects(aCarBox) == true)
{
//video
explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(theHazard.Position.X, theHazard.Position.Y)));
mCurrentState = State.Crash;
mCarsRemaining -= 1;
if (mCarsRemaining < 0)
{
mCurrentState = State.GameOver;
mExitCountDown = 10;
}
return true;
}
return false;
}
private void ExitCountdown(GameTime theGameTime)
{
mExitCountDown -= theGameTime.ElapsedGameTime.TotalSeconds;
if (mExitCountDown < 0)
{
this.Exit();
}
}
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(mBackground, new Rectangle(graphics.GraphicsDevice.Viewport.X, graphics.GraphicsDevice.Viewport.Y, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height), Color.White);
foreach (Explosion ex in explosionList)
{
ex.Draw(spriteBatch);
}
switch (mCurrentState)
{
case State.TitleScreen:
{
//Draw the display text for the Title screen
DrawTextCentered("Drive and avoid the hazards!", 200);
DrawTextCentered("Press 'Space' to start", 260);
DrawTextCentered("Exit in " + ((int)mExitCountDown).ToString(), 475);
break;
}
default:
{
DrawRoad();
DrawHazards();
spriteBatch.Draw(mCar, mCarPosition, new Rectangle(0, 0, mCar.Width, mCar.Height), Color.White, 0, new Vector2(0, 0), 0.2f, SpriteEffects.None, 0);
spriteBatch.DrawString(mFont, "Cars:", new Vector2(28, 520), Color.Brown, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
for (int aCounter = 0; aCounter < mCarsRemaining; aCounter++)
{
spriteBatch.Draw(mCar, new Vector2(25 + (30 * aCounter), 550), new Rectangle(0, 0, mCar.Width, mCar.Height), Color.White, 0, new Vector2(0, 0), 0.05f, SpriteEffects.None, 0);
}
spriteBatch.DrawString(mFont, "Hazards: " + mHazardsPassed.ToString(), new Vector2(5, 25), Color.Brown, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
if (mCurrentState == State.Crash)
{
DrawTextDisplayArea();
DrawTextCentered("Crash!", 200);
DrawTextCentered("Press 'Space' to continue driving.", 260);
}
else if (mCurrentState == State.GameOver)
{
DrawTextDisplayArea();
DrawTextCentered("Game Over.", 200);
DrawTextCentered("Press 'Space' to re-try.", 260);
DrawTextCentered("Exit in " + ((int)mExitCountDown).ToString(), 400);
}
else if (mCurrentState == State.Success)
{
DrawTextDisplayArea();
DrawTextCentered("Well Done!", 200);
DrawTextCentered("Press 'Space' to play again.", 260);
DrawTextCentered("Exit in " + ((int)mExitCountDown).ToString(), 400);
}
break;
}
}
spriteBatch.End();
base.Draw(gameTime);
}
private void DrawRoad()
{
for (int aIndex = 0; aIndex < mRoadY.Length; aIndex++)
{
if (mRoadY[aIndex] > mRoad.Height * -1 && mRoadY[aIndex] <= this.window.ClientBounds.Height)
{
spriteBatch.Draw(mRoad, new Rectangle((int)((this.window.ClientBounds.Width - mRoad.Width) / 2 - 18), mRoadY[aIndex], mRoad.Width, mRoad.Height + 5), Color.White);
}
}
}
private void DrawHazards()
{
foreach (Hazard aHazard in mHazards)
{
if (aHazard.Visible == true)
{
spriteBatch.Draw(mHazard, aHazard.Position, new Rectangle(0, 0, mHazard.Width, mHazard.Height), Color.White, 0, new Vector2(0, 0), 0.4f, SpriteEffects.None, 0);
}
}
}
private void DrawTextDisplayArea()
{
int aPositionX = (int)((graphics.GraphicsDevice.Viewport.Width / 2) - (450 / 2));
spriteBatch.Draw(mBackground, new Rectangle(aPositionX, 75, 450, 400), Color.White);
}
private void DrawTextCentered(string theDisplayText, int thePositionY)
{
Vector2 aSize = mFont.MeasureString(theDisplayText);
int aPositionX = (int)((graphics.GraphicsDevice.Viewport.Width / 2) - (aSize.X / 2));
spriteBatch.DrawString(mFont, theDisplayText, new Vector2(aPositionX, thePositionY), Color.Beige, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
spriteBatch.DrawString(mFont, theDisplayText, new Vector2(aPositionX + 1, thePositionY + 1), Color.Brown, 0, new Vector2(0, 0), 1.0f, SpriteEffects.None, 0);
}
//video
//manage explosions
public void ManageExplosions()
{
for (int i = 0; i < explosionList.Count; i++)
{
if (explosionList[i].isVisible)
{
explosionList.RemoveAt(i);
i--;
}
}
}
}
}
Explosion.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 DriveFast
{
public class Explosion
{
public Texture2D texture;
public Vector2 position;
public float timer;
public float interval;
public Vector2 origin;
public int currentFrame, spriteWidth, spriteHeight;
public Rectangle sourceRect;
public bool isVisible;
//Constructor
public Explosion(Texture2D newTexture, Vector2 newPosition)
{
position = newPosition;
texture = newTexture;
timer = 0;
interval = 20f;
currentFrame = 1;
spriteWidth = 128;
spriteHeight = 128;
isVisible = true;
}
//load content
public void LoadContent(ContentManager Content)
{
}
//update
public void Update(GameTime gameTime)
{
//increase
timer += (float)gameTime.ElapsedGameTime.TotalMilliseconds;
if (timer > interval)
{
currentFrame++;
timer = 0f;
}
if (currentFrame == 17)
{
isVisible = false;
currentFrame = 0;
}
sourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);
origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
}
//draw
public void Draw(SpriteBatch spriteBatch)
{
if (isVisible == true)
{
spriteBatch.Draw(texture, position, sourceRect, Color.White, 0f, origin, 1.0f, SpriteEffects.None, 0);
}
}
}
}
Hazard.cs
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace DriveFast
{
class Hazard
{
public Vector2 Position;
public bool Visible = true;
public Hazard()
{
}
}
}
答案 0 :(得分:1)
首先,您需要在道路,汽车,危险等之后绘制爆炸。替换下面的代码,如下所示:
DrawRoad();
DrawHazards();
spriteBatch.Draw(mCar, mCarPosition, new Rectangle(0, 0, mCar.Width, mCar.Height), Color.White, 0, new Vector2(0, 0), 0.2f, SpriteEffects.None, 0);
// place code here
foreach (Explosion ex in explosionList)
{
ex.Draw(spriteBatch);
}
//
进入管理爆炸方法make!isVisible而不是isVisible:
public void ManageExplosions()
{
for (int i = 0; i < explosionList.Count; i++)
{
if (!explosionList[i].isVisible)
{
explosionList.RemoveAt(i);
i--;
}
}
}
删除行:
foreach (Hazard aHazard in mHazards)
{
if (CheckCollision(aHazard) == true)
{
//remove next line because it is duplicate of adding Explosion which is already added inside CheckCollision(Hazard) method
//explosionList.Add(new Explosion(Content.Load<Texture2D>("Images/explosion3"), new Vector2(aHazard.Position.X, aHazard.Position.Y)));
break;
}
MoveHazard(aHazard);
}
更改下一个变量:
spriteWidth = 71;//128;
spriteHeight = 100;//128;
sourceRect = new Rectangle(currentFrame * spriteWidth, 0, spriteWidth, spriteHeight);
//origin = new Vector2(sourceRect.Width / 2, sourceRect.Height / 2);
origin = new Vector2(-(sourceRect.Width / 4), 0);
评论下一个测试代码:
if (mCurrentState == State.Crash)
{
//DrawTextDisplayArea();
//DrawTextCentered("Crash!", 200);
//DrawTextCentered("Press 'Space' to continue driving.", 260);
}