我正在使用MonoGame框架制作一款平台游戏。游戏有一些基本的机制,例如:重力和碰撞检测,它只适用于列表中的最后一个对象。
以下是游戏游戏区域的代码(主要脚本): `
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Survive.Engine;
using System.Collections.Generic;
namespace Game
{
public class MainGame : Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Player player = new Player();
List<Box> boxes = new List<Box>();
public MainGame()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
protected override void Initialize()
{
Box box = new Box();
box.Init(new Vector2(100, 400), Content.Load<Texture2D>("Player"));
Box box2 = new Box();
box2.Init(new Vector2(132, 400), Content.Load<Texture2D>("Player"));
player.Init(new Vector2(100, 100), Content.Load<Texture2D>("Player"));
boxes.Add(box);
boxes.Add(box2);
base.Initialize();
}
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
}
protected override void UnloadContent()
{
}
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
for (int i = 0; i < boxes.Count; i++)
{
if (player.Colliding(boxes[i]))
{
player.falling = false;
}
if (!player.Colliding(boxes[i]))
{
player.falling = true;
}
}
player.Update();
boxes.ForEach(k => k.Update());
base.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
player.Draw(spriteBatch);
for (int i = 0; i < boxes.Count; i++)
{
boxes[i].Draw(spriteBatch);
}
spriteBatch.End();
base.Draw(gameTime);
}
}
}`
这是对象类(构建的是什么播放器和框):
`
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Game.Engine
{
public class Object2D
{
public int Health = 100;
public Vector2 Position;
public Texture2D Texture;
public Rectangle BoundingBox;
public bool Colliding(Object2D obj)
{
bool col = false;
if (BoundingBox.Intersects(obj.BoundingBox))
{
col = true;
}
return col;
}
public virtual void Init(Vector2 pos, Texture2D text)
{
Position = pos;
Texture = text;
}
public virtual void Update()
{
BoundingBox = new Rectangle((int)Position.X, (int)Position.Y, Texture.Width, Texture.Height);
}
public virtual void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(Texture, Position, Color.White);
}
}
}
`
玩家脚本:
`
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Survive.Engine;
using Microsoft.Xna.Framework.Input;
namespace Survive
{
public class Player : Object2D
{
public float vsp = 0;
public float grav = 0.1f;
public bool falling = true;
public bool jmping = false;
public override void Init(Vector2 pos, Texture2D text)
{
base.Init(pos, text);
}
public override void Update()
{
if (Keyboard.GetState().IsKeyDown(Keys.A))
{
Position.X -= 2;
}
if (Keyboard.GetState().IsKeyDown(Keys.D))
{
Position.X += 2;
}
if (falling)
{
vsp += grav;
Position.Y += vsp;
}
base.Update();
}
public override void Draw(SpriteBatch spriteBatch)
{
base.Draw(spriteBatch);
}
}
}`
该框仅继承自Object2D.cs
,未更改任何代码。
但是在MainGame.cs
的更新中,我们正在检查碰撞:
`
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
Exit();
for (int i = 0; i < boxes.Count; i++)
{
if (player.Colliding(boxes[i]))
{
player.falling = false;
}
if (!player.Colliding(boxes[i]))
{
player.falling = true;
}
}
player.Update();
boxes.ForEach(k => k.Update());`
代码有效,但仅适用于我们列表中的第二个对象,当我移动添加的第一个框时,我只是在应用重力时摔倒。
我不确定为什么它只检查列表框中的最后一个框。
答案 0 :(得分:2)
一旦发现碰撞,您就不会停止搜索。更改此代码:
for (int i = 0; i < boxes.Count; i++)
{
if (player.Colliding(boxes[i]))
{
player.falling = false;
}
if (!player.Colliding(boxes[i]))
{
player.falling = true;
}
}
...类似于:
var isFalling=true; // assume the worst
for (int i = 0; i < boxes.Count; i++)
{
if (player.Colliding(boxes[i]))
{
isFalling = false;
break;
}
}
player.falling = isFalling;