我的碰撞检测不起作用。我有一个我的弹丸列表和另一个我的块。我尝试使用循环来检测碰撞检测,如我的代码所示,但它不起作用。我的碰撞检测代码是:
public void Collision_Detection()
{
for (int p = 0; p < projectile.Count; p++)
{
for (int i = 0; i < level_1.Count; i++)
{
if (projectile_obj[p].logRect.Intersects(level_1_blocks[i].rectangle))
{
//Subprogram here
}
}
}
}
我的射弹类是:
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 DestroytheFort
{
class Projectile
{
public static Texture2D log;
public static Vector2 logPos;
public Rectangle logRect;
public Projectile(Texture2D newLog, Vector2 newLogPos, Rectangle newLogRect)
{
log = newLog;
logPos = newLogPos;
logRect = newLogRect;
}
public void Initialize()
{
}
static double g = 520;
public static int keyState = 0;
static double v, vx, vy, alpha, t2 = 0;
public static void Update(GameTime gameTime)
{
// TODO: Add your update code here
if ((ISU.mouse.LeftButton == ButtonState.Pressed) && ISU.isInLevel == true)
{
keyState = 1;
v = -820;
alpha = MathHelper.ToRadians(33f);
vx = v * Math.Cos(alpha);
vy = v * Math.Sin(alpha);
}
if (keyState == 1)
{
logPos.Y = (float)(vy * t2 + g * t2 * t2 / 2) + 540 - log.Height;
logPos.X = (float)((vx * -1) * t2) + 60;
t2 = t2 + gameTime.ElapsedGameTime.TotalSeconds;
}
if (logPos.Y > ISU.graphics.GraphicsDevice.Viewport.Height - log.Height)
{
logPos.Y = ISU.graphics.GraphicsDevice.Viewport.Height - log.Height;
keyState = 0;
t2 = 0;
}
if (logPos.X > ISU.graphics.GraphicsDevice.Viewport.Width - log.Width)
{
logPos.X = ISU.graphics.GraphicsDevice.Viewport.Width - log.Width;
keyState = 0;
t2 = 0;
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(log, logPos, logRect, Color.White);
}
}
我的level_1课程:
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 DestroytheFort
{
class Wood_Level_1
{
public Texture2D texture;
public Rectangle rectangle;
public Wood_Level_1(Texture2D newTexture, Rectangle newRect)
{
texture = newTexture;
rectangle = newRect;
}
/// <summary>
/// Allows the game component to perform any initialization it needs to before starting
/// to run. This is where it can query for any required services and load content.
/// </summary>
public void Initialize()
{
// TODO: Add your initialization code here
}
/// <summary>
/// Allows the game component to update itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
public void Update(GameTime gameTime)
{
// TODO: Add your update code here
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, rectangle, Color.White);
}
}
}
level_1是我的1级课程列表的名称。我在我的主类中调用Update()中的碰撞检测方法。任何帮助将不胜感激。
答案 0 :(得分:1)
问题是你要比较纹理子图,而不是对象的边界。 Projectile.logRect
和Wood_Level_1.rectangle
是纹理子图,用于碰撞检测和绘图。您需要存储和更新每个对象的当前位置,以便检查它们在世界上的界限。
class Projectile
{
// Removed 'static' and renamed from 'log' and 'logRect', as static limits
// instancing and a class called "Projectile" shouldn't be limited to logs.
public Texture2D texture;
public Rectangle srcRect;
public Vector2 position;
// I suggest moving this to your input system. It's out of place here.
public static int keyState; // = 0 is the default.
public Projectile(Texture2D texture, Rectangle srcRect, Vector2 position)
{
this.texture = texture;
this.srcRect = srcRect;
this.position = position;
}
public void Update(GameTime gameTime)
{
// You use static variables where locals will suffice.
double v = 0;
double vx = 0, vy = 0;
double alpha = 0;
double t2 = 0;
// I haven't thoroughly analyzed your math, but assuming it's correct, bounds should be computed correctly.
if ((ISU.mouse.LeftButton == ButtonState.Pressed) && ISU.isInLevel == true)
{
keyState = 1;
v = -820;
alpha = MathHelper.ToRadians(33f);
vx = v * Math.Cos(alpha);
vy = v * Math.Sin(alpha);
}
if (keyState == 1)
{
position.Y = (float)(vy * t2 + g * t2 * t2 / 2) + 540 - srcRect.Height;
position.X = (float)((vx * -1) * t2) + 60;
t2 = t2 + gameTime.ElapsedGameTime.TotalSeconds;
}
// Clamp to the left of the viewport.
if (position.X < 0)
{
position.X = 0;
keyState = 0;
}
// Clamp to the right of the viewport.
var right = ISU.graphics.GraphicsDevice.Viewport.Width - srcRect.Width;
if (position.X > right)
{
position.X = right;
keyState = 0;
}
// Clamp to the top of the viewport.
if (position.Y < 0)
{
position.Y = 0;
keyState = 0;
}
// Clamp to the bottom of the viewport.
var bottom = ISU.graphics.GraphicsDevice.Viewport.Height - srcRect.Height;
if (position.Y > bottom)
{
position.Y = bottom;
keyState = 0;
}
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(texture, position, srcRect, Color.White);
}
}
最后,在Collision_Detection
的最里面的循环中:
var proj = projectile_obj[p];
var projBounds = new Rectangle(
proj.position.X, proj.position.Y,
proj.srcRect.Width, proj.srcRect.Height);
if (projBounds.Intersects(level_1_blocks[i].rectangle))
{
//Subprogram here
}
我建议将Wood_Level_1
重命名为Level
,因此它似乎不限于您的第一级。如果您不打算这样做,至少将其重命名为WoodLevel1
以符合.NET约定。