public bool CollisionTest(ICollidable other) { if (other != null && IsActive) { return(BoundingRect.Intersects(other.BoundingRect)); } return(false); }
void processCollisions() { for (int i = 0; i < _collisionEntities.Count; i++) { TransformComponent transformCompA = _collisionEntities[i].GetComponent <TransformComponent>(); CollisionComponent collisionCompA = _collisionEntities[i].GetComponent <CollisionComponent>(); BoundingRect locationA = new BoundingRect( transformCompA.Position.X - collisionCompA.BoundingBoxComponent.Width / 2, transformCompA.Position.Y - collisionCompA.BoundingBoxComponent.Height / 2, collisionCompA.BoundingBoxComponent.Width, collisionCompA.BoundingBoxComponent.Height ); for (int j = i + 1; j < _collisionEntities.Count; j++) { TransformComponent transformCompB = _collisionEntities[j].GetComponent <TransformComponent>(); CollisionComponent collisionCompB = _collisionEntities[j].GetComponent <CollisionComponent>(); BoundingRect locationB = new BoundingRect( transformCompB.Position.X - collisionCompB.BoundingBoxComponent.Width / 2, transformCompB.Position.Y - collisionCompB.BoundingBoxComponent.Height / 2, collisionCompB.BoundingBoxComponent.Width, collisionCompB.BoundingBoxComponent.Height ); if (locationA.Intersects(locationB) && !(collisionCompA.collidingWith.Contains(_collisionEntities[j]))) { EventManager.Instance.QueueEvent(new CollisionStartEvent(_collisionEntities[i], _collisionEntities[j])); collisionCompA.collidingWith.Add(_collisionEntities[j]); collisionCompB.collidingWith.Add(_collisionEntities[i]); } else { if (!(locationA.Intersects(locationB)) && collisionCompA.collidingWith.Contains(_collisionEntities[j])) { Console.WriteLine("Normal Collision System"); EventManager.Instance.QueueEvent(new CollisionEndEvent(_collisionEntities[i], _collisionEntities[j])); collisionCompA.collidingWith.Remove(_collisionEntities[j]); collisionCompB.collidingWith.Remove(_collisionEntities[i]); } } } } }
public bool CollisionTest(ICollidable other) { if (other != null) { if (other.ColliderType == ColliderType.hero && Active) { return(BoundingRect.Intersects(other.BoundingRect)); } } return(false); }
private void DrawFieldFontEntities(Camera camera, byte groupMask, float dt, float betweenFrameAlpha, Camera debugCamera) { Matrix transformMatrix = debugCamera == null?camera.GetInterpolatedTransformMatrix(betweenFrameAlpha) : debugCamera.GetInterpolatedTransformMatrix(betweenFrameAlpha); if (_fieldFontEntities.Count > 0) { CheckUpdateProjections(); Matrix wvp = transformMatrix * _fieldFontRendererProjection; FieldFontRenderer.Begin(wvp); foreach (Entity entity in _fieldFontEntities) { FieldFontComponent fieldFontComp = entity.GetComponent <FieldFontComponent>(); if (fieldFontComp.Hidden || (fieldFontComp.RenderGroup & groupMask) == 0) { continue; } TransformComponent transformComp = entity.GetComponent <TransformComponent>(); BoundingRect boundRect = new BoundingRect(transformComp.Position.X - (fieldFontComp.Font.MeasureString(fieldFontComp.Content).X *transformComp.Scale / 2), transformComp.Position.Y - (fieldFontComp.Font.MeasureString(fieldFontComp.Content).Y *transformComp.Scale / 2), fieldFontComp.Font.MeasureString(fieldFontComp.Content).X *transformComp.Scale, fieldFontComp.Font.MeasureString(fieldFontComp.Content).Y *transformComp.Scale); if (!boundRect.Intersects(camera.BoundingRect) && CVars.Get <bool>("debug_show_render_culling")) { continue; } Vector2 position; float rotation; float transformScale; transformComp.Interpolate(betweenFrameAlpha, out position, out rotation, out transformScale); FieldFontRenderer.Draw(fieldFontComp.Font, fieldFontComp.Content, position, rotation, fieldFontComp.Color, transformScale, fieldFontComp.EnableKerning); } FieldFontRenderer.End(); } }
public override void Update(float dt) { foreach (Entity goalEntity in _goalEntities) { TransformComponent goalTransformComp = goalEntity.GetComponent <TransformComponent>(); BoundingRect goalAABB = new BoundingRect(goalTransformComp.Position.X - Constants.Pong.GOAL_WIDTH / 2, goalTransformComp.Position.Y - Constants.Pong.PLAYFIELD_HEIGHT / 2, Constants.Pong.GOAL_WIDTH, Constants.Pong.PLAYFIELD_HEIGHT); foreach (Entity ballEntity in _ballEntities) { TransformComponent ballTransformComp = ballEntity.GetComponent <TransformComponent>(); BallComponent ballComp = ballEntity.GetComponent <BallComponent>(); BoundingRect ballAABB = new BoundingRect(ballTransformComp.Position - ballComp.Bounds / 2, ballTransformComp.Position + ballComp.Bounds / 2); if (ballAABB.Intersects(goalAABB)) { Vector2 goalNormal = goalTransformComp.Position - ballTransformComp.Position; goalNormal.Normalize(); Vector2 ballEdge = ballTransformComp.Position + ballComp.Bounds * -goalNormal; Vector2 goalEdge = goalTransformComp.Position + new Vector2(Constants.Pong.GOAL_WIDTH, Constants.Pong.GOAL_HEIGHT) * goalNormal; Vector2 goalPosition = (ballEdge + goalEdge) / 2; EventManager.Instance.QueueEvent(new GoalEvent(ballEntity, goalEntity, goalPosition)); } } } }
void processCollision(Entity ballEntity) { TransformComponent transformComp = ballEntity.GetComponent <TransformComponent>(); BallComponent ballComp = ballEntity.GetComponent <BallComponent>(); // Wrap ball angle while (ballComp.Direction < 0) { ballComp.Direction += 2 * MathHelper.Pi; } while (ballComp.Direction > 2 * MathHelper.Pi) { ballComp.Direction -= 2 * MathHelper.Pi; } BoundingRect ballAABB = new BoundingRect(transformComp.Position - ballComp.Bounds / 2, transformComp.Position + ballComp.Bounds / 2); // Paddles foreach (Entity paddleEntity in _paddleEntities) { PaddleComponent paddleComp = paddleEntity.GetComponent <PaddleComponent>(); TransformComponent paddleTransformComp = paddleEntity.GetComponent <TransformComponent>(); BoundingRect paddleAABB = new BoundingRect(paddleTransformComp.Position - paddleComp.Bounds / 2, paddleTransformComp.Position + paddleComp.Bounds / 2); if (ballAABB.Intersects(paddleAABB)) { if (!paddleComp.IgnoreCollisions) { { Vector2 ballEdge = transformComp.Position + ballComp.Bounds * -paddleComp.Normal; Vector2 paddleEdge = paddleTransformComp.Position + paddleComp.Bounds * paddleComp.Normal; Vector2 bouncePosition = (ballEdge + paddleEdge) / 2; EventManager.Instance.QueueEvent(new BallBounceEvent(ballEntity, paddleEntity, bouncePosition)); } // Determine alpha of ball relative to the paddle's heigh float relativeY = transformComp.Position.Y - paddleTransformComp.Position.Y; float alpha = (relativeY + (paddleComp.Bounds.Y / 2)) / paddleComp.Bounds.Y; alpha = MathHelper.Clamp(alpha, 0, 1); // Determine new direction float newDir = MathHelper.Lerp(Constants.Pong.PADDLE_BOUNCE_MIN, Constants.Pong.PADDLE_BOUNCE_MAX, alpha); newDir = MathHelper.ToRadians(newDir); // Set ball direction if (paddleComp.Normal.X > 0) { ballComp.Direction = newDir; } else if (paddleComp.Normal.X < 0) { ballComp.Direction = MathHelper.Pi - newDir; } // Make sure ball does not get stuck inside paddle paddleComp.IgnoreCollisions = true; } } else { paddleComp.IgnoreCollisions = false; } } // Edges foreach (Entity edgeEntity in _edgeEntities) { EdgeComponent edgeComp = edgeEntity.GetComponent <EdgeComponent>(); TransformComponent edgeTransformComp = edgeEntity.GetComponent <TransformComponent>(); BoundingRect edgeAABB = new BoundingRect(edgeTransformComp.Position.X - Constants.Pong.PLAYFIELD_WIDTH / 2, edgeTransformComp.Position.Y - Constants.Pong.EDGE_HEIGHT / 2, Constants.Pong.EDGE_WIDTH, Constants.Pong.EDGE_HEIGHT); if (ballAABB.Intersects(edgeAABB)) { { Vector2 ballEdge = transformComp.Position + ballComp.Bounds * -edgeComp.Normal; Vector2 edgeEdge = edgeTransformComp.Position + new Vector2(Constants.Pong.EDGE_WIDTH, Constants.Pong.EDGE_HEIGHT) * edgeComp.Normal; Vector2 bouncePosition = (ballEdge + edgeEdge) / 2; EventManager.Instance.QueueEvent(new BallBounceEvent(ballEntity, edgeEntity, bouncePosition)); } // Determine directional vector of ball Vector2 ballDirection = new Vector2((float)Math.Cos(ballComp.Direction), (float)Math.Sin(ballComp.Direction)); // Determine reflection vector of ball Vector2 ballReflectionDir = getReflectionVector(ballDirection, edgeComp.Normal); // Set angle of new directional vector ballComp.Direction = (float)Math.Atan2(ballReflectionDir.Y, ballReflectionDir.X); } } }
private void RecursiveUpwardTreeCollisionCheck(Entity entityA, TransformComponent transformCompA, CollisionComponent collisionCompA, float cosA, float sinA, Dictionary <Entity, List <Entity> > processedPairs, QuadTreeNode node) { if (node == null) { return; } foreach (Entity entityB in node.leaves) { if (entityA == entityB) { continue; } if (processedPairs[entityA].Contains(entityB)) { continue; } if (!processedPairs.ContainsKey(entityB)) { processedPairs.Add(entityB, new List <Entity>()); } // Add it to entityB's list because A-B won't occur again. // B-A might. processedPairs[entityB].Add(entityA); CollisionComponent collisionCompB = entityB.GetComponent <CollisionComponent>(); if ((collisionCompA.CollisionMask & collisionCompB.CollisionGroup) == 0 && (collisionCompA.CollisionGroup & collisionCompB.CollisionMask) == 0) { continue; } TransformComponent transformCompB = entityB.GetComponent <TransformComponent>(); float cosB = (float)Math.Cos(transformCompB.Rotation), sinB = (float)Math.Sin(transformCompB.Rotation); bool resolved = false; // If true, _any_ of the shapes have intersected bool intersecting = false; foreach (CollisionShape shapeA in collisionCompA.CollisionShapes) { BoundingRect AABB_A = shapeA.GetAABB(cosA, sinA, transformCompA.Scale); AABB_A.Min += transformCompA.Position; AABB_A.Max += transformCompA.Position; foreach (CollisionShape shapeB in collisionCompB.CollisionShapes) { BoundingRect AABB_B = shapeB.GetAABB(cosB, sinB, transformCompB.Scale); AABB_B.Min += transformCompB.Position; AABB_B.Max += transformCompB.Position; if (AABB_B.Intersects(AABB_A)) { // _May_ be intersecting Vector2 pA = transformCompA.Position + new Vector2(shapeA.Offset.X * cosA - shapeA.Offset.Y * sinA, shapeA.Offset.X * sinA + shapeA.Offset.Y * cosA) * transformCompA.Scale; Vector2 pB = transformCompB.Position + new Vector2(shapeB.Offset.X * cosB - shapeB.Offset.Y * sinB, shapeB.Offset.X * sinB + shapeB.Offset.Y * cosB) * transformCompB.Scale; if (CheckShapeIntersection(pA, cosA, sinA, transformCompA.Scale, shapeA, pB, cosB, sinB, transformCompB.Scale, shapeB)) { intersecting = true; resolved = true; break; } } else { // Guarenteed to not be intersecting continue; } } if (resolved) { break; } } bool previouslyIntersecting = collisionCompA.CollidingWith.Contains(entityB) || collisionCompB.CollidingWith.Contains(entityA); if (!previouslyIntersecting && intersecting) { EventManager.Instance.QueueEvent(new CollisionStartEvent(entityA, entityB)); collisionCompA.CollidingWith.Add(entityB); collisionCompB.CollidingWith.Add(entityA); } if (previouslyIntersecting && !intersecting) { EventManager.Instance.QueueEvent(new CollisionEndEvent(entityA, entityB)); collisionCompA.CollidingWith.Remove(entityB); collisionCompB.CollidingWith.Remove(entityA); } } RecursiveUpwardTreeCollisionCheck(entityA, transformCompA, collisionCompA, cosA, sinA, processedPairs, node.parent); }
private void DrawSpriteBatchEntities(Camera camera, byte groupMask, float dt, float betweenFrameAlpha, Camera debugCamera) { Matrix transformMatrix = debugCamera == null?camera.GetInterpolatedTransformMatrix(betweenFrameAlpha) : debugCamera.GetInterpolatedTransformMatrix(betweenFrameAlpha); SpriteBatch.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.AnisotropicClamp, null, null, null, transformMatrix); foreach (Entity entity in _spriteEntities) { SpriteComponent spriteComp = entity.GetComponent <SpriteComponent>(); if (spriteComp.Hidden || (spriteComp.RenderGroup & groupMask) == 0) { continue; } TransformComponent transformComp = entity.GetComponent <TransformComponent>(); BoundingRect boundRect = spriteComp.GetAABB(transformComp.Scale); boundRect.Min += transformComp.Position; boundRect.Max += transformComp.Position; if (!boundRect.Intersects(camera.BoundingRect) && CVars.Get <bool>("debug_show_render_culling")) { continue; } Vector2 position; float rotation; float transformScale; transformComp.Interpolate(betweenFrameAlpha, out position, out rotation, out transformScale); Vector2 scale = new Vector2(spriteComp.Bounds.X / spriteComp.Texture.Width, spriteComp.Bounds.Y / spriteComp.Texture.Height); Vector2 origin = new Vector2(spriteComp.Texture.Bounds.Width, spriteComp.Texture.Bounds.Height) * HalfHalf; AnimationComponent animationComp = entity.GetComponent <AnimationComponent>(); if (animationComp != null && animationComp.ActiveAnimationIndex > -1) { Rectangle sourceRectangle = animationComp.Animations[animationComp.ActiveAnimationIndex].TextureRegion.Bounds; scale = new Vector2(spriteComp.Bounds.X / sourceRectangle.Width, spriteComp.Bounds.Y / sourceRectangle.Height); origin = new Vector2(sourceRectangle.Width, sourceRectangle.Height) * HalfHalf; SpriteBatch.Draw(animationComp.Animations[animationComp.ActiveAnimationIndex].TextureRegion.Texture, position * FlipY, sourceRectangle, spriteComp.Color * spriteComp.Alpha, -rotation, origin, scale * transformScale, SpriteEffects.None, 0); } else { SpriteBatch.Draw(spriteComp.Texture, position * FlipY, spriteComp.Color * spriteComp.Alpha, -rotation, origin, scale * transformScale, SpriteEffects.None, 0); } } foreach (Entity entity in _fontEntities) { BitmapFontComponent fontComp = entity.GetComponent <BitmapFontComponent>(); if (fontComp.Hidden || (fontComp.RenderGroup & groupMask) == 0) { continue; } TransformComponent transformComp = entity.GetComponent <TransformComponent>(); BoundingRect boundRect = new BoundingRect(transformComp.Position.X - (fontComp.Font.MeasureString(fontComp.Content).Width *transformComp.Scale / 2), transformComp.Position.Y - (fontComp.Font.MeasureString(fontComp.Content).Height *transformComp.Scale / 2), fontComp.Font.MeasureString(fontComp.Content).Width *transformComp.Scale, fontComp.Font.MeasureString(fontComp.Content).Height *transformComp.Scale); if (!boundRect.Intersects(camera.BoundingRect) && CVars.Get <bool>("debug_show_render_culling")) { continue; } Vector2 position; float rotation; float transformScale; transformComp.Interpolate(betweenFrameAlpha, out position, out rotation, out transformScale); Vector2 origin = fontComp.Font.MeasureString(fontComp.Content) / 2; SpriteBatch.DrawString(fontComp.Font, fontComp.Content, position * FlipY, fontComp.Color, -rotation, origin, transformScale, SpriteEffects.None, 0); } SpriteBatch.End(); }
private void DrawVectorEntities(Camera camera, byte groupMask, float dt, float betweenFrameAlpha, Camera debugCamera) { Matrix transformMatrix = debugCamera == null?camera.GetInterpolatedTransformMatrix(betweenFrameAlpha) : debugCamera.GetInterpolatedTransformMatrix(betweenFrameAlpha); List <VertexPositionColor> _verts = new List <VertexPositionColor>(); foreach (Entity entity in _vectorSpriteEntities) { VectorSpriteComponent vectorSpriteComp = entity.GetComponent <VectorSpriteComponent>(); if (vectorSpriteComp.Hidden || (vectorSpriteComp.RenderGroup & groupMask) == 0) { continue; } TransformComponent transformComp = entity.GetComponent <TransformComponent>(); BoundingRect boundRect = vectorSpriteComp.GetAABB(transformComp.Scale); boundRect.Min += transformComp.Position; boundRect.Max += transformComp.Position; if (!boundRect.Intersects(camera.BoundingRect) && CVars.Get <bool>("debug_show_render_culling")) { continue; } Vector2 position; float rotation; float transformScale; transformComp.Interpolate(betweenFrameAlpha, out position, out rotation, out transformScale); position *= FlipY; rotation *= -1; int enableFrameSmoothingFlag = CVars.Get <bool>("graphics_frame_smoothing") ? 0 : 1; Vector2 stretch = vectorSpriteComp.Stretch + (vectorSpriteComp.LastStretch - vectorSpriteComp.Stretch) * (1 - betweenFrameAlpha) * enableFrameSmoothingFlag; float cos = (float)Math.Cos(rotation); float sin = (float)Math.Sin(rotation); foreach (RenderShape renderShape in vectorSpriteComp.RenderShapes) { VertexPositionColor[] verts = renderShape.ComputeVertices(); for (int i = verts.Length - 1; i >= 0; i--) { VertexPositionColor vert = verts[i]; _verts.Add(new VertexPositionColor(new Vector3((vert.Position.X * stretch.X * cos + vert.Position.Y * stretch.Y * -1.0f * -sin) * transformScale + position.X, (vert.Position.X * stretch.X * sin + vert.Position.Y * stretch.Y * -1.0f * cos) * transformScale + position.Y, 0), new Color(vert.Color.ToVector4() * renderShape.TintColor.ToVector4() * vectorSpriteComp.Alpha))); } } } if (_verts.Count > 0) { CheckUpdateProjections(); _vectorSpriteEffect.View = transformMatrix; GraphicsDevice.BlendState = BlendState.NonPremultiplied; foreach (EffectPass pass in _vectorSpriteEffect.CurrentTechnique.Passes) { pass.Apply(); GraphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleList, _verts.ToArray(), 0, _verts.Count / 3); } } }