mirror of
https://github.com/AlexMacocian/MonoGame.Extended.git
synced 2026-07-15 15:09:29 +00:00
attempt to introduce a collision world
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using MonoGame.Extended.Shapes;
|
||||
|
||||
namespace MonoGame.Extended.Collisions
|
||||
{
|
||||
public class CollisionBody : ICollidable
|
||||
{
|
||||
public CollisionBody(ICollidable target)
|
||||
{
|
||||
_target = target;
|
||||
}
|
||||
|
||||
private readonly ICollidable _target;
|
||||
|
||||
public Vector2 Velocity
|
||||
{
|
||||
get { return _target.Velocity; }
|
||||
set { _target.Velocity = value; }
|
||||
}
|
||||
|
||||
public Vector2 Position
|
||||
{
|
||||
get { return _target.Position; }
|
||||
set { _target.Position = value; }
|
||||
}
|
||||
|
||||
public RectangleF GetAxisAlignedBoundingBox()
|
||||
{
|
||||
return _target.GetAxisAlignedBoundingBox();
|
||||
}
|
||||
|
||||
public void OnCollision(CollisionInfo collisionInfo)
|
||||
{
|
||||
_target.OnCollision(collisionInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace MonoGame.Extended.Collisions
|
||||
{
|
||||
public class CollisionWorld : IDisposable, IUpdate
|
||||
{
|
||||
public CollisionWorld(Vector2 gravity)
|
||||
{
|
||||
_gravity = gravity;
|
||||
_bodies = new List<CollisionBody>();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
private readonly Vector2 _gravity;
|
||||
private readonly List<CollisionBody> _bodies;
|
||||
private CollisionGrid _grid;
|
||||
|
||||
public CollisionBody CreateBody(ICollidable collidable)
|
||||
{
|
||||
var body = new CollisionBody(collidable);
|
||||
_bodies.Add(body);
|
||||
return body;
|
||||
}
|
||||
|
||||
public CollisionGrid CreateGrid(byte[] data, int columns, int rows, int cellWidth, int cellHeight)
|
||||
{
|
||||
if (_grid != null)
|
||||
throw new InvalidOperationException("Only one collision grid can be created per world");
|
||||
|
||||
_grid = new CollisionGrid(data, columns, rows, cellWidth, cellHeight);
|
||||
return _grid;
|
||||
}
|
||||
|
||||
public void Update(GameTime gameTime)
|
||||
{
|
||||
var deltaTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
|
||||
foreach (var body in _bodies)
|
||||
{
|
||||
body.Velocity += _gravity * deltaTime;
|
||||
body.Position += body.Velocity * deltaTime;
|
||||
|
||||
if(_grid != null)
|
||||
_grid.CollidesWith(body.GetAxisAlignedBoundingBox(), body.OnCollision);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using MonoGame.Extended.Shapes;
|
||||
|
||||
namespace MonoGame.Extended.Collisions
|
||||
{
|
||||
public interface ICollidable
|
||||
{
|
||||
Vector2 Position { get; set; }
|
||||
Vector2 Velocity { get; set; }
|
||||
RectangleF GetAxisAlignedBoundingBox();
|
||||
void OnCollision(CollisionInfo collisionInfo);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using System.Linq;
|
||||
using MonoGame.Extended.Collisions;
|
||||
|
||||
namespace MonoGame.Extended.Maps.Tiled
|
||||
{
|
||||
public static class CollisionWorldExtensions
|
||||
{
|
||||
public static CollisionGrid CreateGrid(this CollisionWorld world, TiledTileLayer tileLayer)
|
||||
{
|
||||
var data = tileLayer.Tiles
|
||||
.Select(t => (byte)t.Id)
|
||||
.ToArray();
|
||||
|
||||
return world.CreateGrid(data, tileLayer.Width, tileLayer.Height, tileLayer.TileWidth, tileLayer.TileHeight);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,16 @@ namespace MonoGame.Extended.Maps.Tiled
|
||||
get { return _tiles; }
|
||||
}
|
||||
|
||||
public int TileWidth
|
||||
{
|
||||
get { return _map.TileWidth; }
|
||||
}
|
||||
|
||||
public int TileHeight
|
||||
{
|
||||
get { return _map.TileHeight; }
|
||||
}
|
||||
|
||||
private TiledTile[] CreateTiles(int[] data)
|
||||
{
|
||||
var tiles = new TiledTile[data.Length];
|
||||
|
||||
@@ -38,7 +38,10 @@
|
||||
<Compile Include="BitmapFonts\BitmapFontExtensions.cs" />
|
||||
<Compile Include="BitmapFonts\BitmapFontReader.cs" />
|
||||
<Compile Include="BitmapFonts\BitmapFontRegion.cs" />
|
||||
<Compile Include="Collisions\CollisionBody.cs" />
|
||||
<Compile Include="Collisions\CollisionGrid.cs" />
|
||||
<Compile Include="Collisions\CollisionWorld.cs" />
|
||||
<Compile Include="Collisions\ICollidable.cs" />
|
||||
<Compile Include="Content\ContentManagerExtensions.cs" />
|
||||
<Compile Include="Camera2D.cs" />
|
||||
<Compile Include="Content\ContentTypeReaderHelper.cs" />
|
||||
@@ -62,6 +65,7 @@
|
||||
<Compile Include="IRotatable.cs" />
|
||||
<Compile Include="IScalable.cs" />
|
||||
<Compile Include="IUpdate.cs" />
|
||||
<Compile Include="Maps\Tiled\CollisionWorldExtensions.cs" />
|
||||
<Compile Include="Maps\Tiled\TiledMapOrientation.cs" />
|
||||
<Compile Include="Shapes\Circle.cs" />
|
||||
<Compile Include="Shapes\RectangleF.cs" />
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework;
|
||||
using Microsoft.Xna.Framework.Graphics;
|
||||
using Microsoft.Xna.Framework.Input;
|
||||
using MonoGame.Extended;
|
||||
@@ -27,8 +25,9 @@ namespace Sandbox
|
||||
private FramesPerSecondCounter _fpsCounter;
|
||||
private SpriteAnimator _spriteAnimator;
|
||||
private Zombie _zombie;
|
||||
private CollisionGrid _collisionGrid;
|
||||
private Point _mousePoint;
|
||||
//private CollisionGrid _collisionGrid;
|
||||
//private Point _mousePoint;
|
||||
private readonly CollisionWorld _world;
|
||||
|
||||
public SandboxGame()
|
||||
{
|
||||
@@ -37,6 +36,15 @@ namespace Sandbox
|
||||
IsMouseVisible = true;
|
||||
Window.Position = new Point(50, 50);
|
||||
Window.Title = string.Format("MonoGame.Extended - {0}", GetType().Name);
|
||||
|
||||
_world = new CollisionWorld(new Vector2(0, 900));
|
||||
}
|
||||
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
_world.Dispose();
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
protected override void Initialize()
|
||||
@@ -63,12 +71,8 @@ namespace Sandbox
|
||||
_spriteBatch = new SpriteBatch(GraphicsDevice);
|
||||
_bitmapFont = Content.Load<BitmapFont>("Fonts/courier-new-32");
|
||||
_tiledMap = Content.Load<TiledMap>("Tilesets/level01");
|
||||
var collisionData = _tiledMap
|
||||
.GetLayer<TiledTileLayer>("Tile Layer 1")
|
||||
.Tiles
|
||||
.Select(t => (byte) t.Id)
|
||||
.ToArray();
|
||||
_collisionGrid = new CollisionGrid(collisionData, _tiledMap.Width, _tiledMap.Height, _tiledMap.TileWidth, _tiledMap.TileHeight);
|
||||
|
||||
_world.CreateGrid(_tiledMap.GetLayer<TiledTileLayer>("Tile Layer 1"));
|
||||
|
||||
var fireballTexture = Content.Load<Texture2D>("Sprites/fireball");
|
||||
var spriteSheetAtlas = TextureAtlas.Create(fireballTexture, 512, 197);
|
||||
@@ -85,6 +89,8 @@ namespace Sandbox
|
||||
{
|
||||
Position = new Vector2(300, 500)
|
||||
};
|
||||
|
||||
_world.CreateBody(_zombie);
|
||||
}
|
||||
|
||||
protected override void UnloadContent()
|
||||
@@ -97,7 +103,7 @@ namespace Sandbox
|
||||
var keyboardState = Keyboard.GetState();
|
||||
var mouseState = Mouse.GetState();
|
||||
|
||||
_mousePoint = _camera.ScreenToWorld(new Vector2(mouseState.X, mouseState.Y)).ToPoint();
|
||||
//_mousePoint = _camera.ScreenToWorld(new Vector2(mouseState.X, mouseState.Y)).ToPoint();
|
||||
|
||||
// camera
|
||||
if (keyboardState.IsKeyDown(Keys.R))
|
||||
@@ -122,15 +128,14 @@ namespace Sandbox
|
||||
if (keyboardState.IsKeyDown(Keys.Enter))
|
||||
_zombie.Die();
|
||||
|
||||
_zombie.Velocity += new Vector2(0, 900) * deltaSeconds;
|
||||
_zombie.Position += _zombie.Velocity * deltaSeconds;
|
||||
|
||||
// update must be called before collision detection
|
||||
_zombie.Update(gameTime);
|
||||
|
||||
var boundingBox = _zombie.GetAxisAlignedBoundingBox();
|
||||
_collisionGrid.CollidesWith(boundingBox, _zombie.OnCollision);
|
||||
|
||||
_world.Update(gameTime);
|
||||
|
||||
//var boundingBox = _zombie.GetAxisAlignedBoundingBox();
|
||||
//_collisionGrid.CollidesWith(boundingBox, _zombie.OnCollision);
|
||||
|
||||
_camera.LookAt(_zombie.Position);
|
||||
|
||||
// fireball
|
||||
@@ -156,11 +161,11 @@ namespace Sandbox
|
||||
_zombie.Draw(_spriteBatch);
|
||||
_spriteBatch.End();
|
||||
|
||||
var x = _mousePoint.X / _collisionGrid.CellWidth;
|
||||
var y = _mousePoint.Y / _collisionGrid.CellHeight;
|
||||
//var x = _mousePoint.X / _collisionGrid.CellWidth;
|
||||
//var y = _mousePoint.Y / _collisionGrid.CellHeight;
|
||||
|
||||
_spriteBatch.Begin();
|
||||
_spriteBatch.DrawString(_bitmapFont, string.Format("CD: {0}, {1} = {2}", x, y, _collisionGrid.GetDataAt(x, y)), new Vector2(5, 35), new Color(0.5f, 0.5f, 0.5f));
|
||||
//_spriteBatch.DrawString(_bitmapFont, string.Format("CD: {0}, {1} = {2}", x, y, _collisionGrid.GetDataAt(x, y)), new Vector2(5, 35), new Color(0.5f, 0.5f, 0.5f));
|
||||
_spriteBatch.DrawString(_bitmapFont, string.Format("FPS: {0} Zoom: {1}", _fpsCounter.AverageFramesPerSecond, _camera.Zoom), new Vector2(5, 5), new Color(0.5f, 0.5f, 0.5f));
|
||||
_spriteBatch.End();
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace Sandbox
|
||||
Dying
|
||||
}
|
||||
|
||||
public class Zombie : IUpdate
|
||||
public class Zombie : IUpdate, ICollidable
|
||||
{
|
||||
public Zombie(TextureAtlas textureAtlas)
|
||||
{
|
||||
@@ -85,9 +85,7 @@ namespace Sandbox
|
||||
|
||||
public RectangleF GetAxisAlignedBoundingBox()
|
||||
{
|
||||
const float heightOffset = 52;
|
||||
var spriteRectangle = _sprite.GetBoundingRectangle();
|
||||
return new RectangleF(spriteRectangle.X, spriteRectangle.Y + heightOffset, spriteRectangle.Width, spriteRectangle.Height - heightOffset);
|
||||
return _sprite.GetBoundingRectangle();
|
||||
}
|
||||
|
||||
public Vector2 Position
|
||||
@@ -102,8 +100,9 @@ namespace Sandbox
|
||||
|
||||
_animator.Update(gameTime);
|
||||
|
||||
if(State == ZombieState.Walking)
|
||||
Position += new Vector2(200f * _direction, 0) * (float)gameTime.ElapsedGameTime.TotalSeconds;
|
||||
Velocity = State == ZombieState.Walking
|
||||
? new Vector2(200f*_direction, Velocity.Y)
|
||||
: new Vector2(0, Velocity.Y);
|
||||
}
|
||||
|
||||
public void Draw(SpriteBatch spriteBatch)
|
||||
|
||||
Reference in New Issue
Block a user