/// <summary> /// Initializes a new instance of the <see cref="Rabbit" /> class. /// </summary> /// <param name="position">The position.</param> /// <param name="drawOrder">The draw order.</param> public Rabbit(Vector2 position, float drawOrder) { this.entity = new Entity() .AddComponent(new Transform2D() { Origin = Vector2.One / 2, X = position.X, Y = position.Y, DrawOrder = drawOrder, XScale=0.8f, YScale = 0.8f, }) .AddComponent(new RectangleCollider()) .AddComponent(new RabbitBehavior()) .AddComponent(new SpriteAtlas(Directories.TexturePath + "game.wpk", "rabbit")) .AddComponent(new SpriteAtlasRenderer(DefaultLayers.GUI)); // Cached this.rabbitBehavior = this.entity.FindComponent<RabbitBehavior>(); this.collider = this.entity.FindComponent<RectangleCollider>(); // Particles this.entity.AddChild(new Entity("rabbitParticles") .AddComponent(new Transform2D()) .AddComponent(ParticleFactory.CreateStarsParticle()) .AddComponent(new Material2D(new BasicMaterial2D(Directories.TexturePath + "starParticle.wpk"))) .AddComponent(new ParticleSystemRenderer2D("rabbitParticles", DefaultLayers.Additive))); }
public BallBehavior(Entity player, Entity barBot, Entity barTop, Entity playerIA) : base("BallBehavior") { this.trans2D = null; this.player = player; this.rectPlayer = player.FindComponent<RectangleCollider>(); this.player2 = playerIA; this.rectPlayer2 = playerIA.FindComponent<RectangleCollider>(); this.barBot = barBot; this.rectBarBot = barBot.FindComponent<RectangleCollider>(); this.barTop = barTop; this.rectBarTop = barTop.FindComponent<RectangleCollider>(); }
/// <summary> /// Gets whether or not the rectangle colliders intersect. This is based off multiple /// Separated Axis Theorm tutorials online, but optimized/coded for rectangles. /// </summary> /// <param name="rectCollider">The given collider</param> /// <param name="otherCollider">The other collider</param> /// <param name="mtv"> /// The minimum translation vector, the smallest vector that can move <paramref name="rectCollider"/> out of /// <paramref name "otherCollider"/>. /// </param> /// <returns>true if there's an intersection, otherwise false</returns> public static bool Intersects(this RectangleCollider rectCollider, RectangleCollider otherCollider, out Vector2? mtv) { Requires.NotNull(rectCollider, nameof(rectCollider)); Requires.NotNull(otherCollider, nameof(otherCollider)); List<Vector2> testingAxes = new List<Vector2>(); testingAxes.AddRange(GetTestingAxes(rectCollider)); testingAxes.AddRange(GetTestingAxes(otherCollider)); mtv = null; float smallestOverlap = float.MaxValue; Vector2 smallestOverlapAxis = Vector2.Zero; foreach (Vector2 axis in testingAxes) { Projection rectProjection = rectCollider.ProjectOn(axis); Projection otherProjection = otherCollider.ProjectOn(axis); float overlap; if (!rectProjection.GetOverlap(otherProjection, out overlap)) { return false; } else { if (overlap < smallestOverlap) { smallestOverlap = overlap; smallestOverlapAxis = axis; } } } // A little bit of a hacky way of making sure I'm always pushing in the right direction... if (Vector2.Dot(rectCollider.Transform2D.Position - otherCollider.Transform2D.Position, smallestOverlapAxis) < 0) { smallestOverlapAxis = -smallestOverlapAxis; } mtv = smallestOverlap * smallestOverlapAxis; return true; }
public Switchblock(Vector2 position, bool active, bool switchOnce, Layer layer) : base(layer) { Active = active; _switchOnce = switchOnce; AddComponent(new PositionComponent(position)); var solid = new SolidComponent(); var collider = new RectangleCollider(); collider.Size = Vector2.One * Size; collider.Position = position + Vector2.One * Size / 2; solid.Collider = collider; solid.Collider.Enabled = active; AddComponent(solid); }
public void TestRectangleColliderRectangleIntersection() { GameObject gameObject = new GameObject(new Vector2(100, 100), ""); gameObject.Size = new Vector2(50, 50); RectangleCollider collider = new RectangleCollider(gameObject); Rectangle intersectionRectangle = new Rectangle(0, 0, 100, 100); Assert.IsTrue(collider.CheckIntersects(intersectionRectangle)); intersectionRectangle = new Rectangle(50, 50, 50, 50); Assert.IsTrue(collider.CheckIntersects(intersectionRectangle)); intersectionRectangle = new Rectangle(0, 0, 10, 10); Assert.IsFalse(collider.CheckIntersects(intersectionRectangle)); intersectionRectangle = new Rectangle(175, 100, 50, 50); Assert.IsFalse(collider.CheckIntersects(intersectionRectangle)); }
public BallBehavior(Entity player, Entity barBot, Entity barTop, Entity barLeft, Entity barRight, Entity brick) : base("BallBehavior") { this.trans2D = null; // this.player = player; // this.rectPlayer = player.FindComponent<RectangleCollider>(); this.barBot = barBot; this.rectBarBot = barBot.FindComponent<RectangleCollider>(); playerTrans = barBot.FindComponent<Transform2D>(); this.barTop = barTop; this.rectBarTop = barTop.FindComponent<RectangleCollider>(); this.barLeft = barLeft; this.rectBarLeft = barLeft.FindComponent<RectangleCollider>(); this.barRight = barRight; this.rectBarRight = barRight.FindComponent<RectangleCollider>(); this.brick = brick; this.rectBrick = brick.FindComponent<RectangleCollider>(); //this.circleBall = this.Owner.FindComponent<CircleCollider>(); }
public void TestRectangleColliderOnRectangleColliderCollision() { GameObject gameObject = new GameObject(new Vector2(100, 100), ""); gameObject.Size = new Vector2(50, 50); RectangleCollider collider = new RectangleCollider(gameObject); GameObject gameObject2 = new GameObject(new Vector2(150, 100), ""); gameObject2.Size = new Vector2(60, 60); RectangleCollider collider2 = new RectangleCollider(gameObject2); GameObject gameObject3 = new GameObject(new Vector2(200, 100), ""); gameObject3.Size = new Vector2(60, 60); RectangleCollider collider3 = new RectangleCollider(gameObject3); Assert.IsTrue(collider.CheckCollisionWith(collider2)); Assert.IsFalse(collider.CheckCollisionWith(collider3)); Assert.IsTrue(collider2.CheckCollisionWith(collider3)); }
internal override void OnTriggerEnter(RectangleCollider collider, Actor other, RectangleCollider otherCollider) { base.OnTriggerEnter(collider, other, otherCollider); if (other is Player p) { if (direction == Direction.Top || direction == Direction.Bottom) { other.Position = new Vector2(other.Position.X, direction == Direction.Top ? collider.Bottom - (otherCollider.HalfHeight + 2) : collider.Top + (otherCollider.HalfHeight + 2)); p.Rigidbody.Velocity = new Vector2(p.Rigidbody.Velocity.X, 0); } else { other.Position = new Vector2( direction == Direction.Right ? collider.Left - (otherCollider.HalfWidth + 2) : collider.Right + (otherCollider.HalfWidth + 2), other.Position.Y); p.Rigidbody.Velocity = new Vector2(0, p.Rigidbody.Velocity.Y); } } else if (other is Boomerang b) { if (direction == Direction.Top || direction == Direction.Bottom) { other.Position = new Vector2(other.Position.X, direction == Direction.Top ? collider.Bottom - (otherCollider.HalfHeight + 2) : collider.Top + (otherCollider.HalfHeight + 2)); b.Rigidbody.Velocity = new Vector2(b.Rigidbody.Velocity.X, -b.Rigidbody.Velocity.Y) * 0.5f; b.Rigidbody.Acceleration = new Vector2(b.Rigidbody.Acceleration.X, -b.Rigidbody.Acceleration.Y); } else { other.Position = new Vector2( direction == Direction.Right ? collider.Left - (otherCollider.HalfWidth + 2) : collider.Right + (otherCollider.HalfWidth + 2), other.Position.Y); b.Rigidbody.Velocity = new Vector2(-b.Rigidbody.Velocity.X, b.Rigidbody.Velocity.Y) * 0.5f; b.Rigidbody.Acceleration = new Vector2(-b.Rigidbody.Acceleration.X, b.Rigidbody.Acceleration.Y); } } }
public override void FixedUpdate() { var physics = GetComponent <CPhysics>(); if (Input.CheckButtonPress(Buttons.MouseLeft)) { var position = GetComponent <CPosition>(); var dir = new Angle(position.Position, Input.MousePosition); physics.Speed = _speed * dir.ToVector2(); } var ddir = Angle.Down; var collider = new RectangleCollider( physics.Collider.Position + Vector2.UnitY * (physics.Collider.HalfSize.Y + 1), new Vector2(physics.Collider.HalfSize.X * 2 - 2, 1) ); //if (SPhysics.GetCollision(collider, physics) == null) { physics.Speed += 10 * ddir.ToVector2() * Vector2.UnitY; } if (physics.Speed.Y > _maxFallSpeed) { physics.Speed.Y = _maxFallSpeed; } if (physics.PositionComponent.Position.Y > 1000) { DestroyEntity(); } }
/// <summary> /// Returns collider for a given tile and sets an offset. /// </summary> ICollider GetCollider(TiledMapTilesetTile tiledTile, Tileset tileset, ref Vector2 colliderOffset) { ICollider collider = null; if (tiledTile.Objects.Length > 0 && tiledTile.Objects[0] is TiledRectangleObject) { var obj = tiledTile.Objects[0]; if (obj.Type.ToLower() == _rectangleName) { collider = new RectangleCollider(); collider.Size = obj.Size; } if (obj.Type.ToLower() == _platformName) { collider = new PlatformCollider(); collider.Size = obj.Size; } // Here we need to flip y in the offset, because tiles are draw with origin in bottom left corner, // but colliders take origin as top left corner. Why? Ask Tiled dev. colliderOffset = obj.Position + tileset.Offset * new Vector2(1, -1) + obj.Size / 2; } return(collider); }
private static void Main() { var game = new Lib.GameMAQ(Color.Aqua); var obj = new GameObject(); obj.Game = game; var vec = new Vector2(100, 100); obj.Components.Add(new RectangleSprite(vec, Color.Black, Color.Transparent, 0, 5)); obj.Components.Add(new FollowMouse(-vec / 2)); game.Scene.Components.Add(new RectangleSprite(vec, Color.Purple, Color.Transparent, 0, 25)); game.Scene.Children.Add(obj); obj.Transform.RelativePosition = new Vector2(100, 100); game.Scene.Transform.RelativePosition = new Vector2(100, 100); RectangleCollider col1 = new RectangleCollider(new Vector2(50, 50), true); RectangleCollider col2 = new RectangleCollider(new Vector2(50, 50), true); obj.Components.Add(col1); game.Scene.Components.Add(col2); game.Run(); }
// Rectangle & Rectangle private bool CalculateCollisionData(RectangleCollider a, RectangleCollider b) { Vector2[] verticesA = new Vector2[4]; Vector2[] verticesB = new Vector2[4]; a.GetWorldSpaceVertices(ref verticesA); b.GetWorldSpaceVertices(ref verticesB); List <CollisionData> collisionDataA = new List <CollisionData> { new CollisionData(verticesA[0]), new CollisionData(verticesA[1]), new CollisionData(verticesA[2]), new CollisionData(verticesA[3]) }; List <CollisionData> collisionDataB = new List <CollisionData> { new CollisionData(verticesB[0]), new CollisionData(verticesB[1]), new CollisionData(verticesB[2]), new CollisionData(verticesB[3]) }; //Vertices from B in A { int p0Index = 3; for (int i = 0; i < 4; i++) { Vector2 axis = (verticesA[i] - verticesA[p0Index]).normalized; Vector2 norm = new Vector2(axis.y, -axis.x); for (int ii = 0; ii < collisionDataB.Count; ii++) { float depth = -Vector2.Dot(norm, collisionDataB[ii].vertexPosition - verticesA[p0Index]); //Discard point if it is outside if (depth <= 0) { collisionDataB.RemoveAt(ii); ii--; } else { //Get smallest penetration depth if (depth < collisionDataB[ii].penetrationDepth) { CollisionData collisionData = collisionDataB[ii]; collisionData.penetrationDepth = depth; collisionData.penetrationNormal = norm; collisionDataB[ii] = collisionData; } } } p0Index = i; } } //Vertices from A in B { int p0Index = 3; for (int i = 0; i < 4; i++) { Vector2 axis = (verticesB[i] - verticesB[p0Index]).normalized; Vector2 norm = new Vector2(axis.y, -axis.x); for (int ii = 0; ii < collisionDataA.Count; ii++) { float depth = -Vector2.Dot(norm, collisionDataA[ii].vertexPosition - verticesB[p0Index]); //Discard point if it is outside if (depth <= 0) { collisionDataA.RemoveAt(ii); ii--; } else { //Get smallest penetration depth if (depth < collisionDataA[ii].penetrationDepth) { CollisionData collisionData = collisionDataA[ii]; collisionData.penetrationDepth = depth; collisionData.penetrationNormal = norm; collisionDataA[ii] = collisionData; } } } p0Index = i; } } //Get biggest penetration depth penetrationDepth = Mathf.NegativeInfinity; foreach (CollisionData collisionData in collisionDataB) { if (collisionData.penetrationDepth > penetrationDepth) { penetrationDepth = collisionData.penetrationDepth; contactPoint = collisionData.vertexPosition; contactNormal = collisionData.penetrationNormal; } } foreach (CollisionData collisionData in collisionDataA) { if (collisionData.penetrationDepth > penetrationDepth) { penetrationDepth = collisionData.penetrationDepth; contactPoint = collisionData.vertexPosition; contactNormal = -collisionData.penetrationNormal; } } return(penetrationDepth != Mathf.NegativeInfinity); }
// Circle & Rectangle private bool CalculateCollisionData(CircleCollider a, RectangleCollider b) { Vector2 centerA = Util.RotateVector2(a.GetCenter() - b.GetCenter(), -b.attachedPhysicsBody.rotation); Vector2 inflatedExtents = b.extent + Vector2.one * a.radius; if (centerA.x <= inflatedExtents.x && centerA.x >= -inflatedExtents.x && centerA.y <= inflatedExtents.y && centerA.y >= -inflatedExtents.y) { Vector2 absCenterA = new Vector2(Mathf.Abs(centerA.x), Mathf.Abs(centerA.y)); //In Corner if (absCenterA.x >= b.extent.x && absCenterA.y >= b.extent.y) { if ((absCenterA - b.extent).sqrMagnitude <= a.radius * a.radius) { Vector2 mirrorDir = new Vector2(Mathf.Sign(centerA.x), Mathf.Sign(centerA.y)); contactPoint = b.extent; contactNormal = (contactPoint - absCenterA).normalized * mirrorDir; contactPoint *= mirrorDir; penetrationDepth = a.radius - (absCenterA - b.extent).magnitude; } else { return(false); } } //Right else if (centerA.x > b.extent.x) { contactPoint = new Vector2((b.extent.x + centerA.x - a.radius) * 0.5f, centerA.y); contactNormal = Vector2.left; penetrationDepth = Mathf.Abs(b.extent.x - (centerA.x - a.radius)); } //Left else if (centerA.x < -b.extent.x) { contactPoint = new Vector2((-b.extent.x + centerA.x + a.radius) * 0.5f, centerA.y); contactNormal = Vector2.right; penetrationDepth = Mathf.Abs(-b.extent.x - (centerA.x + a.radius)); } //Up else if (centerA.y > b.extent.y) { contactPoint = new Vector2(centerA.x, (b.extent.y + centerA.y - a.radius) * 0.5f); contactNormal = Vector2.down; penetrationDepth = Mathf.Abs(b.extent.y - (centerA.y - a.radius)); } //Down else if (centerA.y < -b.extent.y) { contactPoint = new Vector2(centerA.x, (-b.extent.y + centerA.y + a.radius) * 0.5f); contactNormal = Vector2.up; penetrationDepth = Mathf.Abs(-b.extent.y - (centerA.y + a.radius)); } else { return(false); } contactPoint = b.GetCenter() + Util.RotateVector2(contactPoint, b.attachedPhysicsBody.rotation); contactNormal = Util.RotateVector2(contactNormal, b.attachedPhysicsBody.rotation); return(true); } return(false); }
private void PushMemberOutOfWall(Entity memberEntity, RectangleCollider memberCollider, RectangleCollider wallCollider) { Requires.NotNull(memberEntity, nameof(memberEntity)); Requires.NotNull(memberCollider, nameof(memberCollider)); Requires.NotNull(wallCollider, nameof(wallCollider)); Vector2?pushOut; if (memberCollider.Intersects(wallCollider, out pushOut)) { memberCollider.Transform2D.Position += (Vector2)pushOut; } }
/// <summary> /// Since a rectangle is a type of parallelogram, I only need to get two axes - two adjacent ones. In the /// more general case, I would get the normals of all the edges in the convex polygon. /// This function assumes the "GetPoints2D()" method is ordered (first and second points are an edge, /// second and third are an edge, etc) /// </summary> /// <param name="rectCollider">The <see cref="RectangleCollider"/> to get all testing axes</param> /// <returns>An <see cref="IEnumerable{T}"/> that needs to be tested.</returns> private static IEnumerable<Vector2> GetTestingAxes(RectangleCollider rectCollider) { Requires.NotNull(rectCollider, nameof(rectCollider)); Vector2 edge1 = rectCollider.GetPoints2D()[1] - rectCollider.GetPoints2D()[0]; Vector2 axis1 = edge1.Normal(); axis1.Normalize(); yield return axis1; Vector2 edge2 = rectCollider.GetPoints2D()[0] - rectCollider.GetPoints2D()[3]; Vector2 axis2 = edge2.Normal(); axis2.Normalize(); yield return axis2; }
internal override void OnTriggerEnter(RectangleCollider collider, Actor other, RectangleCollider otherCollider) { base.OnTriggerEnter(collider, other, otherCollider); if (returning && other == user) { Destroy(); catchSound.Play(); } else if (other is Enemy) { other.Destroy(); Game.Instance.SpawnEnemy(); enemyDeathSound.Play(); enemiesKilled++; if (enemiesKilled % 2 == 0) { Game.Instance.SpawnBomb(); } Scoreboard s = Game.Instance.GetActor <Scoreboard>(); if (s != null) { s.Score += enemiesKilled; if (enemiesKilled > s.EnemiesKilledStreak) { s.EnemiesKilledStreak = enemiesKilled; } } } }
protected override bool IsColliding(RectangleCollider collider, out Collision collision) { return(CollisionUtils.IsColliding <Circle, TopLeftRectangle>(IntersectionUtils.Collides, this, collider, out collision)); }
internal virtual void OnTriggerEnter(RectangleCollider collider, Actor other, RectangleCollider otherCollider) { }
public abstract bool CheckCollisionWith(RectangleCollider rectangle);
// Default collider is a rectangular one public virtual void AddCollider() { Collider = new RectangleCollider(this, Size); }
public override void FinalDestroy() { base.FinalDestroy(); collider = null; }
internal override void OnTriggerEnter(RectangleCollider collider, Actor other, RectangleCollider otherCollider) { base.OnTriggerEnter(collider, other, otherCollider); if (other is Boomerang) { other.Destroy(); Destroy(); explosion.Play(); Instantiate(new ExplosionEffect(Position)); } }
protected abstract bool IsColliding(RectangleCollider collider, out Collision collision);
public void SetRectangleCollider() { collider = new RectangleCollider(scale.x, scale.y); }
public static bool Collides(RectangleCollider a, RectangleCollider b) { return(!(a.Right < b.Left || a.Left > b.Right || a.Top < b.Bottom || a.Bottom > b.Top)); }
internal override void Start() { base.Start(); collider = AddComponent(new RectangleCollider(this, Position, 64, 64)); }
public void AddCollider(RectangleCollider collider) { colliders.Add(collider); }
protected override bool IsColliding(RectangleCollider collider, out Collision collision) => throw new NotImplementedException();
public override void AddCollider() { Collider = new RectangleCollider(this, HardPointDimension, HardPointDimension); }
public override void Hit(RectangleCollider rectangleCollider) { }
public override void Update(List <Component> components) { foreach (CatEnemyComponent gato in components) { var physics = gato.Owner.GetComponent <PhysicsComponent>(); var actor = gato.Owner.GetComponent <StackableActorComponent>(); actor.LeftAction = (gato.Direction == -1); actor.RightAction = (gato.Direction == 1); if (actor.LogicStateMachine.CurrentState == ActorStates.OnGround) { var position = gato.Owner.GetComponent <PositionComponent>(); // Checking if there is a wall next to us. physics.Collider.Position = position.Position + Vector2.UnitX * gato.Direction * (physics.Collider.Size.X / 2 + 1); if (physics.CollisionH == gato.Direction) { gato.Direction *= -1; actor.Orientation = gato.Direction; } // Checking if there is a wall next to us. else { // Checking if there is a pit below us. var collider = new RectangleCollider(); collider.Size = Vector2.One; collider.Position = position.Position + (physics.Collider.Size / 2 + Vector2.One) * new Vector2(gato.Direction, 1); if (PhysicsSystem.CheckCollision(gato.Owner, collider) == null) { gato.Direction *= -1; actor.Orientation = gato.Direction; } // Checking if there is a pit below us. } } // Damaging the player. if ( ( actor.StackOwner == null || ( actor.StackOwner != null && !actor.StackOwner.HasComponent <PlayerComponent>() ) ) && actor.LogicStateMachine.CurrentState != ActorStates.Dead ) { var players = SceneMgr.CurrentScene.GetEntityListByComponent <PlayerComponent>(); foreach (var playerEntity in players) { var player = playerEntity.GetComponent <PlayerComponent>(); var playerActor = playerEntity.GetComponent <StackableActorComponent>(); if (playerActor.Crouching && actor.LogicStateMachine.CurrentState != ActorStates.Stacked) { continue; } var position = gato.Owner.GetComponent <PositionComponent>(); var playerPosition = playerEntity.GetComponent <PositionComponent>(); var playerPhysics = playerEntity.GetComponent <PhysicsComponent>(); // Setting up colliders. physics.Collider.Position = position.Position; physics.Collider.PreviousPosition = position.PreviousPosition; playerPhysics.Collider.Position = playerPosition.Position; playerPhysics.Collider.PreviousPosition = playerPosition.PreviousPosition; // Seting up colliders. if (CollisionDetector.CheckCollision(physics.Collider, playerPhysics.Collider)) { StackableActorSystem.Damage(playerEntity.GetComponent <StackableActorComponent>()); } } } // Damaging the player. } }
public override void Hit(RectangleCollider rectangleCollider) { throw new NotImplementedException(); }
private void PushMemberOutOfWall(Entity memberEntity, RectangleCollider memberCollider, RectangleCollider wallCollider) { Requires.NotNull(memberEntity, nameof(memberEntity)); Requires.NotNull(memberCollider, nameof(memberCollider)); Requires.NotNull(wallCollider, nameof(wallCollider)); Vector2? pushOut; if (memberCollider.Intersects(wallCollider, out pushOut)) { memberCollider.Transform2D.Position += (Vector2)pushOut; } }