我在XNA / Monogame中制作了一个spaceinvaderisch游戏 在遇到这个问题之前,一切都很顺利。 我一直试图修复子弹击打盒几天但没有成功。 我的问题在于,hitbox不会随子弹本身移动。 碰撞检测在Game1类中。 Bullets类中的实际移动和射击的触发器都在Tank类中。 Bullet也继承到Sprite.cs,它给它一个hitbox。
任何人都可以帮助我。我真的只想完成我开始工作之前开始的事情。
帮助得到了极大的赞赏。
Game1.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{
/// <summary>
/// This is the main type for your game.
/// </summary>
public class Game1 : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Tank Tank;
Isis Isis1;
Isis Isis2;
Isis Isis3;
Isis Isis4;
Isis Isis5;
Isis Isis6;
Isis Isis7;
Isis Isis8;
Isis Isis9;
Isis Isis10;
Isis Isis11;
Bullets Bullets;
private Song BgMusic;
int screenWidth;
int screenHeight;
enum GameState
{
MainMenu,
Playing,
}
GameState CurrentGameState = GameState.MainMenu;
Button btnPlay;
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
//Bullet = new Bullets(Tank.position);
Tank = new Tank(new Vector2 (375,425));
Isis1 = new Isis(new Vector2(30, 0));
Isis2 = new Isis(new Vector2(70, 0));
Isis3 = new Isis(new Vector2(110, 0));
Isis4 = new Isis(new Vector2(150, 0));
Isis5 = new Isis(new Vector2(190, 0));
Isis6 = new Isis(new Vector2(230, 0));
Isis7 = new Isis(new Vector2(270, 0));
Isis8 = new Isis(new Vector2(310, 0));
Isis9 = new Isis(new Vector2(350, 0));
Isis10 = new Isis(new Vector2(390, 0));
Isis11 = new Isis(new Vector2(430, 0));
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()
{
graphics.PreferredBackBufferHeight = 800;
graphics.PreferredBackBufferHeight = 600;
graphics.ApplyChanges();
btnPlay = new Button(Content.Load<Texture2D>("Start"), graphics.GraphicsDevice);
IsMouseVisible = true;
spriteBatch = new SpriteBatch(GraphicsDevice);
btnPlay.setPosition(new Vector2(350, 300));
BgMusic = Content.Load<Song>("Music");
Tank.LoadContent(this.Content, "Tank");
Isis1.LoadContent(this.Content, "Isis");
Isis2.LoadContent(this.Content, "Isis");
Isis3.LoadContent(this.Content, "Isis");
Isis4.LoadContent(this.Content, "Isis");
Isis5.LoadContent(this.Content, "Isis");
Isis6.LoadContent(this.Content, "Isis");
Isis7.LoadContent(this.Content, "Isis");
Isis8.LoadContent(this.Content, "Isis");
Isis9.LoadContent(this.Content, "Isis");
Isis10.LoadContent(this.Content, "Isis");
Isis11.LoadContent(this.Content, "Isis");
Sounds.BgMusic(BgMusic);
screenWidth = GraphicsDevice.Viewport.Width;
screenHeight = GraphicsDevice.Viewport.Height;
// TODO: use this.Content to load your game content here
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// game-specific 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)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
// TODO: Add your update logic here
//Bullet.Update(screenWidth, screenHeight, gameTime);
MouseState mouse = Mouse.GetState();
switch (CurrentGameState)
{
case GameState.MainMenu:
if (btnPlay.isClicked == true)
{
CurrentGameState = GameState.Playing;
}
btnPlay.Update(mouse);
break;
case GameState.Playing:
Isis1.Update(screenWidth, screenHeight, gameTime);
Isis2.Update(screenWidth, screenHeight, gameTime);
Isis3.Update(screenWidth, screenHeight, gameTime);
Isis4.Update(screenWidth, screenHeight, gameTime);
Isis5.Update(screenWidth, screenHeight, gameTime);
Isis6.Update(screenWidth, screenHeight, gameTime);
Isis7.Update(screenWidth, screenHeight, gameTime);
Isis8.Update(screenWidth, screenHeight, gameTime);
Isis9.Update(screenWidth, screenHeight, gameTime);
Isis10.Update(screenWidth, screenHeight, gameTime);
Isis11.Update(screenWidth, screenHeight, gameTime);
Tank.Update(screenWidth, screenHeight, gameTime);
break;
}
//Collision
foreach (Bullets item in Tank.bullets)
{
if (item.Bullethitbox.Intersects(Isis1.Box))
{
Isis1.LoadContent(this.Content, "DeadIsis");
}
}
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)
{
GraphicsDevice.Clear(Color.SandyBrown);
spriteBatch.Begin();
switch (CurrentGameState)
{
case GameState.MainMenu:
spriteBatch.Draw(Content.Load<Texture2D>("MainMenu"), new Rectangle(0, 0, 800, 600), Color.White);
btnPlay.Draw(spriteBatch);
break;
case GameState.Playing:
Tank.Draw(spriteBatch);
Isis1.Draw(spriteBatch);
Isis2.Draw(spriteBatch);
Isis3.Draw(spriteBatch);
Isis4.Draw(spriteBatch);
Isis5.Draw(spriteBatch);
Isis6.Draw(spriteBatch);
Isis7.Draw(spriteBatch);
Isis8.Draw(spriteBatch);
Isis9.Draw(spriteBatch);
Isis10.Draw(spriteBatch);
Isis11.Draw(spriteBatch);
break;
}
//Bullet.Draw(spriteBatch);
spriteBatch.End();
// TODO: Add your drawing code here
base.Draw(gameTime);
}
}
}
Bullets.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{
class Bullets : Sprite
{
private Vector2 Position;
public Bullets(Vector2 Position) : base(Position)
{
this.Position = Position;
}
public override void Update(int screenWidth, int Screenheight, GameTime gametime)
{
int Pos = (int)Position.Y;
Pos -= 10;
Position.Y = Pos;
}
public override void LoadContent(ContentManager Contentman, string Spritename)
{
base.LoadContent(Contentman, Spritename);
spritetext = Contentman.Load<Texture2D>("Bullet");
//this.Box = new Rectangle((int)Position.X, (int)Position.Y, spritetext.Width, spritetext.Height);
}
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(spritetext, Position, Color.White);
}
public Texture2D Bulletsprite { get { return this.spritetext; } }
public Vector2 Bulletposition { get { return this.Position; } set { this.Position = value; } }
public Rectangle Bullethitbox { get { return this.Box; } set { this.Box = value; } }
}
}
Tank.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{
class Tank : Sprite
{
private Vector2 P;
private KeyboardState KBS = Keyboard.GetState();
private float bulletspeed = -400f;
public List<Bullets> bullets = new List<Bullets>();
private float reload = 0;
Bullets Bullet;
ContentManager Content;
public Tank(Vector2 Position) : base(Position)
{
}
public override void Update(int screenWidth, int Screenheight, GameTime gametime)
{
KBS = Keyboard.GetState();
P = this.position;
if (KBS.IsKeyDown(Keys.Right))
{
P.X += 8;
this.position = P;
}
if (KBS.IsKeyDown(Keys.Left))
{
P.X -= 8;
this.position = P;
}
reload += (float)gametime.ElapsedGameTime.TotalMilliseconds;
if (reload >= 500 && KBS.IsKeyDown(Keys.Space))
{
Bullets b = new Bullets(position);
b.LoadContent(Content, "Bullet");
bullets.Add(b);
reload = 0;
}
foreach (Bullets item in bullets)
{
//item.Bullethitbox = new Rectangle((int)item.Bulletposition.X, (int)item.Bulletposition.Y, item.Bulletsprite.Width, item.Bulletsprite.Height);
item.Update(screenWidth, Screenheight, gametime);
}
//for (int i = 0; i < bullets.Count; i++)
//{
// float y = bullets[i].position.Y;
// y += bulletspeed * (float)gametime.ElapsedGameTime.TotalSeconds;
// bullets[i] = new Bullets(new Vector2(bullets[i].position.X, y));
//}
}
public override void LoadContent(ContentManager Contentman, string Spritename)
{
base.LoadContent(Contentman, Spritename);
this.Content = Contentman;
}
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(spritetext, position, Color.White);
foreach (Bullets b in bullets)
{
b.Draw(spriteBatch);
}
//for (int i = 0; i < bullets.Count; i++)
//{
// spriteBatch.Draw(Bullet.Bulletsprite, position, Color.White);
//}
}
}
}
Isis.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{
class Isis : Sprite
{
private Vector2 P;
public Isis(Vector2 Position) : base (Position)
{
P = Position;
}
public override void Update(int screenWidth, int screenHeight, GameTime gametime)
{
//P.Y += (float)0.11;
this.position = P;
this.Box = new Rectangle((int)P.X, (int)P.Y, spritetext.Width, spritetext.Height);
}
}
}
Sprite.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace IsisInvaders
{
class Sprite
{
private Texture2D SpriteTexture;
private Rectangle Hitbox;
private Vector2 Position;
public Sprite(Vector2 Position)
{
this.Position = Position;
}
public virtual void Update(int screenWidth, int Screenheight, GameTime gametime)
{
}
public virtual void LoadContent(ContentManager Contentman, string Spritename)
{
SpriteTexture = (Contentman.Load<Texture2D>(Spritename));
}
public virtual void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(SpriteTexture, Position, Color.White);
}
public Texture2D spritetext { get { return this.SpriteTexture; } set { this.SpriteTexture = value; } }
public Vector2 position { get { return this.Position; } set { this.Position = value; } }
public Rectangle Box { get { return new Rectangle((int)Position.X, (int)Position.Y, SpriteTexture.Width, SpriteTexture.Height); } set { this.Hitbox = value; } }
}
}
答案 0 :(得分:0)
在您的Bullets类中,您有一个名为Position的局部变量,它将在Bullets.Update(GameTime)中进行修改,但您的hitbox会引用Sprite类中的Position矢量。希望它有所帮助。