mirror of
https://github.com/AlexMacocian/MonoGame.Extended.git
synced 2026-07-25 08:22:15 +00:00
enemies can kill you
This commit is contained in:
@@ -1,10 +1,33 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using Microsoft.Xna.Framework;
|
||||
using MonoGame.Extended.Entities.Components;
|
||||
|
||||
namespace Demo.Platformer.Entities.Components
|
||||
{
|
||||
public abstract class BasicCollisionHandler : EntityComponent
|
||||
public class BasicCollisionHandler : EntityComponent
|
||||
{
|
||||
public abstract void OnCollision(BasicCollisionBody bodyA, BasicCollisionBody bodyB, Vector2 depth);
|
||||
public virtual void OnCollision(BasicCollisionBody bodyA, BasicCollisionBody bodyB, Vector2 depth)
|
||||
{
|
||||
var characterState = bodyA.Entity.GetComponent<CharacterState>();
|
||||
var absDepthX = Math.Abs(depth.X);
|
||||
var absDepthY = Math.Abs(depth.Y);
|
||||
|
||||
if (absDepthY < absDepthX)
|
||||
{
|
||||
bodyA.Position += new Vector2(0, depth.Y); // move the player out of the ground or roof
|
||||
var isOnGround = bodyA.Velocity.Y > 0;
|
||||
|
||||
if (isOnGround)
|
||||
{
|
||||
bodyA.Velocity = new Vector2(bodyA.Velocity.X, 0); // set y velocity to zero only if this is a ground collision
|
||||
characterState.IsJumping = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bodyA.Position += new Vector2(depth.X, 0); // move the player out of the wall
|
||||
bodyA.Velocity = new Vector2(bodyA.Velocity.X, bodyA.Velocity.Y < 0 ? 0 : bodyA.Velocity.Y); // drop the player down if they hit a wall
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Demo.Platformer.Entities.Components
|
||||
@@ -7,33 +8,15 @@ namespace Demo.Platformer.Entities.Components
|
||||
{
|
||||
public override void OnCollision(BasicCollisionBody bodyA, BasicCollisionBody bodyB, Vector2 depth)
|
||||
{
|
||||
var playerState = bodyA.Entity.GetComponent<CharacterState>();
|
||||
var characterState = bodyA.Entity.GetComponent<CharacterState>();
|
||||
|
||||
if ((string) bodyB.Tag == "Deadly")
|
||||
{
|
||||
playerState.HealthPoints = 0;
|
||||
characterState.HealthPoints = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
var absDepthX = Math.Abs(depth.X);
|
||||
var absDepthY = Math.Abs(depth.Y);
|
||||
|
||||
if (absDepthY < absDepthX)
|
||||
{
|
||||
bodyA.Position += new Vector2(0, depth.Y); // move the player out of the ground or roof
|
||||
var isOnGround = bodyA.Velocity.Y > 0;
|
||||
|
||||
if (isOnGround)
|
||||
{
|
||||
bodyA.Velocity = new Vector2(bodyA.Velocity.X, 0); // set y velocity to zero only if this is a ground collision
|
||||
playerState.IsJumping = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bodyA.Position += new Vector2(depth.X, 0); // move the player out of the wall
|
||||
bodyA.Velocity = new Vector2(bodyA.Velocity.X, bodyA.Velocity.Y < 0 ? 0 : bodyA.Velocity.Y); // drop the player down if they hit a wall
|
||||
}
|
||||
base.OnCollision(bodyA, bodyB, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,8 +110,8 @@ namespace Demo.Platformer.Entities
|
||||
animationFactory.Add("walk", new SpriteSheetAnimationData(new[] { 96, 97, 98, 99 }, isPingPong: true));
|
||||
|
||||
entity.AttachComponent(new AnimatedSprite(animationFactory, "walk"));
|
||||
entity.AttachComponent(new BasicCollisionBody(textureRegion.Size, Vector2.One * 0.5f));
|
||||
entity.AttachComponent(new PlayerCollisionHandler());
|
||||
entity.AttachComponent(new BasicCollisionBody(textureRegion.Size, Vector2.One * 0.5f) {Tag = "Deadly"});
|
||||
entity.AttachComponent(new BasicCollisionHandler());
|
||||
entity.AttachComponent(new CharacterState());
|
||||
entity.AttachComponent(new EnemyAi());
|
||||
|
||||
|
||||
@@ -58,19 +58,24 @@ namespace Demo.Platformer.Entities.Systems
|
||||
bodyA.Velocity += _gravity * deltaTime;
|
||||
bodyA.Position += bodyA.Velocity * deltaTime;
|
||||
|
||||
foreach (var bodyB in _staticBodies)
|
||||
foreach (var bodyB in _staticBodies.Concat(_movingBodies))
|
||||
{
|
||||
var depth = bodyA.BoundingRectangle.IntersectionDepth(bodyB.BoundingRectangle);
|
||||
|
||||
if (depth != Vector2.Zero)
|
||||
if (bodyA != bodyB)
|
||||
{
|
||||
var collisionHandlers = bodyA.Entity.GetComponents<BasicCollisionHandler>();
|
||||
var depth = bodyA.BoundingRectangle.IntersectionDepth(bodyB.BoundingRectangle);
|
||||
|
||||
foreach (var collisionHandler in collisionHandlers)
|
||||
collisionHandler.OnCollision(bodyA, bodyB, depth);
|
||||
if (depth != Vector2.Zero)
|
||||
{
|
||||
var collisionHandlers = bodyA.Entity.GetComponents<BasicCollisionHandler>();
|
||||
|
||||
foreach (var collisionHandler in collisionHandlers)
|
||||
collisionHandler.OnCollision(bodyA, bodyB, depth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -88,10 +88,8 @@ namespace MonoGame.Extended.Entities
|
||||
|
||||
public void DestroyEntity(Entity entity)
|
||||
{
|
||||
foreach (var component in _components.Where(c => c.Entity == entity).OfType<IDisposable>())
|
||||
component.Dispose();
|
||||
|
||||
_components.RemoveAll(c => c.Entity == entity);
|
||||
foreach (var component in _components.Where(c => c.Entity == entity).ToArray())
|
||||
DetachComponent(component);
|
||||
|
||||
if (entity.Name != null)
|
||||
_entitiesByName.Remove(entity.Name);
|
||||
@@ -115,6 +113,7 @@ namespace MonoGame.Extended.Entities
|
||||
internal void DetachComponent(EntityComponent component)
|
||||
{
|
||||
_components.Remove(component);
|
||||
(component as IDisposable)?.Dispose();
|
||||
ComponentDetached?.Invoke(this, component);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user