private bool QueryCallback(int proxyId) { var actor = (Actor)_tree.GetUserData(proxyId); actor.Overlap = CollisionUtils.TestOverlap(_queryAABB, actor.AABB); return(true); }
// ---------------------------------------------------------------------------------------------------- #endregion #region Initialization // ---------------------------------------------------------------------------------------------------- /// <summary> /// Called upon awaking this behavior. /// </summary> private void Awake() { this.triggerEventGroup = new TriggerEventGroup(triggerEvents); this.interactionTarget = this.GetComponent <InteractionTarget>(); this.cameraShakeEffect = this.GetComponent <CameraShakeEffect>(); this.highlightMaterial = this.GetComponent <HighlightMaterialController>(); this.collisionGravity = this.GetComponent <CollisionGravity>(); this.interactionTarget.OnInteraction += (playerController) => { var playerStateController = playerController.StateController; if (CollisionUtils.IsObjectInsideTile(transform.position, playerStateController.transform.position)) { this.Toggle(); } }; this.OnStatusChanged += (toggleSwitch) => { if (toggleSwitch.isActivated) { this.triggerEventGroup.Invoke(); } else { this.triggerEventGroup.Reset(); } }; this.SetActive(this.activatedByDefault, true); }
void FixedUpdate() { numberOfCollisions = collisions.Count; Vector3 impulseSum = Vector3.zero; float impulseMagnitudeSum = 0f; for (int i = 0; i < collisions.Count; i++) { Vector3 normal = CollisionUtils.GetAverageNormal(collisions[i]); float impulseStrength = collisions[i].impulse.magnitude; Vector3 impulseDir = collisions[i].impulse.normalized; Vector3 impulse = normal * impulseStrength * Mathf.Abs(Vector3.Dot(impulseDir, normal)); //HACK super hacky, are there times when this could go horribly wrong? // Vector3 impulse = collisions[i].impulse; //TODO test on moving ground or with the other collider moving past etc... //maybe multiply it with abs(dot(normal, impulse)) just to be sure. normalized impulse of course... //maybe the impulse could point away if the other object is lighter? i dont know. it doesnt make any sense //OR ... IDEA... TEST IF ANY FORCE IS POINTING INTO ANYTHING. AND IF HOW BIG THAT FORCE IS //so get the forces, dot product that shit with other contacts' normals and see what's left? maybe even calculate how much resistance that other thing would put up? impulseSum += impulse; impulseMagnitudeSum += impulse.magnitude; // Debug.DrawRay(transform.position, impulse.normalized * 0.3f, Color.magenta, Time.fixedDeltaTime, false); // Debug.DrawRay(GetAveragePoint(collisions[i]), impulse.normalized * 0.3f, rayColor, Time.fixedDeltaTime, false); currentForce = CalculateForce(collisions[i]); if (currentForce > peakForceInKG) { peakForceInKG = currentForce; } // DrawCollisionContacts(collisions[i]); } // Debug.DrawRay(transform.position, impulseSum * impulseScale, Color.yellow, Time.fixedDeltaTime, false); float deltaMag = impulseMagnitudeSum - impulseSum.magnitude; //this is the crushing "force"... //it scales linearly with mass of THIS rigidbody (or the other one) // Debug.Log("CRUSHING WITH " + deltaMag); // if(deltaMag > peakCrushValue) peakCrushValue = deltaMag; currentCrushValue = deltaMag / (Time.fixedDeltaTime * rb.mass); //this is a pretty good approximation. DebugDrawHelper.DrawSphere(transform.position, currentCrushValue * crushScale, Color.yellow, Time.fixedDeltaTime, false); // Debug.Log("CRUSHING WITH " + crushForce + " | " + deltaMag); if (currentCrushValue > peakCrushValue) { peakCrushValue = currentCrushValue; } collisions.Clear(); if (jumpInput) { rb.velocity += Vector3.up * 10f; } if (gravity) { rb.velocity += Physics.gravity * Time.fixedDeltaTime; } // if(Input.GetKey(KeyCode.R)) rb.velocity = Vector3.zero; // if(Input.GetKey(KeyCode.T)) rb.velocity = Vector3.down; jumpInput = false; }
public Slash(MovingEntity origin, Vector2 target, float damage, bool flipped, Vector2?relativeOriginPosition = null) : base(origin.Position, origin) { Vector2 _relativeOriginPosition = relativeOriginPosition ?? Vector2.Zero; Vector2 newPosition = Vector2.Add(origin.Position.ToVector(), _relativeOriginPosition); Vector2 direction = new Vector2(target.X - newPosition.X, target.Y - newPosition.Y); direction.Normalize(); // Get Hitted Targets hitboxCircle = new Circle((int)(newPosition.X + direction.X * 40), (int)(newPosition.Y + direction.Y * 40), 16); newPosition.X += (direction.X * WorldGrid.BlockSize.X * 1.5f); newPosition.Y += (direction.Y * WorldGrid.BlockSize.Y * 1.5f); Angle = GeometryUtils.GetAngleFromDirection(direction) + (float)Math.PI * 0.5f; Flipped = flipped; origin.CanWalk = false; updatePosition(new WorldPosition(newPosition, origin.InteriorID)); List <LivingEntity> hittedObjects = CollisionUtils.GetLivingHittedObjects(hitboxCircle, origin.InteriorID, origin); foreach (var hittedObject in hittedObjects) { if (hittedObject is LivingEntity) { ((LivingEntity)hittedObject).ModifyHealth((int)-damage, Origin); } } }
private ClosestSeeable canCharacterSeeCharacter(Character source, Character target) { ClosestSeeable candidate = null; if (target.isVisible()) { Vector2 direction = Vector2.Subtract(target.Position, source.Position); Nullable <float> distanceToTarget = CollisionUtils.castRay(target.BBox, source.Position, direction); bool canSee = true; if (distanceToTarget != null) { foreach (Wall wall in map.Walls) { Nullable <float> distance = CollisionUtils.castRay(wall.BBox, source.Position, direction); // as soon as we cannot see the target, stop looking if (distance != null && distance < distanceToTarget) { canSee = false; break; } } if (canSee) { candidate = new ClosestSeeable() { Target = target, Distance = (float)distanceToTarget, Source = source }; } } } return(candidate); }
public override void OnRender() { var manifold = new Manifold(); CollisionUtils.CollidePolygons(ref manifold, _polygonA, _transformA, _polygonB, _transformB); var worldManifold = new WorldManifold(); worldManifold.Initialize(manifold, _transformA, _polygonA.Radius, _transformB, _polygonB.Radius); DrawString($"point count = {manifold.PointCount}"); { var color = Color.FromArgb(230, 230, 230); var v = new Vector2[Settings.MaxPolygonVertices]; for (var i = 0; i < _polygonA.Count; ++i) { v[i] = MathUtils.Mul(_transformA, _polygonA.Vertices[i]); } Drawer.DrawPolygon(v, _polygonA.Count, color); for (var i = 0; i < _polygonB.Count; ++i) { v[i] = MathUtils.Mul(_transformB, _polygonB.Vertices[i]); } Drawer.DrawPolygon(v, _polygonB.Count, color); } for (var i = 0; i < manifold.PointCount; ++i) { Drawer.DrawPoint(worldManifold.Points[i], 4.0f, Color.FromArgb(230, 77, 77)); } }
private void MoveNode(int index) { var node = pathingScript.PathingNodes[index]; EditorGUI.BeginChangeCheck(); Vector3 newTargetPosition; if (node.IsEnabled == true) { Handles.color = Color.white; newTargetPosition = Handles.FreeMoveHandle(node.Position, Quaternion.identity, 0.5f, Vector3.zero, Handles.SphereHandleCap); } else { Handles.color = Color.gray; newTargetPosition = Handles.FreeMoveHandle(node.Position, Quaternion.identity, 0.5f, Vector3.zero, Handles.SphereHandleCap); } if (EditorGUI.EndChangeCheck()) { Undo.RecordObject(pathingScript, "Change Look At Target Position"); node.Position = CollisionUtils.SnapToTile(newTargetPosition); if (index == 0) { pathingScript.transform.position = node.Position; } } }
bool CheckCapsuleAtPos(Vector3 pos, Color debugColor, Vector3 fromPos) { Vector3 spawnPosReal = CollisionUtils.GetGroundedPos(pos); Vector3 A = spawnPosReal + Vector3.up * (m_Radius + 0.05f); // take it little bit over the ground Vector3 B = spawnPosReal + Vector3.up * (m_Height - m_Radius); int Default = 1 << LayerMask.NameToLayer("Default"); int PhysicsMetal = 1 << LayerMask.NameToLayer("PhysicsMetal"); if (Physics.CheckCapsule(A, B, m_Radius, Default | PhysicsMetal)) { DebugDraw.DisplayTime = 1; //DebugDraw.Diamond( debugColor, 0.03f, A ); //DebugDraw.LineOriented( debugColor, A, B, 0.05f ); DebugDraw.Capsule(debugColor, m_Radius, A, B); //if( fromPos != null ) { DebugDraw.LineOriented(Color.magenta, fromPos, A); DebugDraw.LineOriented(Color.magenta, fromPos, B); DebugDraw.LineOriented(Color.magenta, fromPos, 0.5f * (A + B)); } return(false); } return(true); }
/// Called for each fixture found in the query AABB. /// @return false to terminate the query. public bool QueryCallback(Fixture fixture) { if (Count == MaxCount) { return(false); } var body = fixture.Body; var shape = fixture.Shape; var overlap = CollisionUtils.TestOverlap( shape, 0, Circle, 0, body.GetTransform(), Transform, fixture.Body.World.GJkProfile); if (overlap) { var color = Box2DSharp.Common.Color.FromArgb(0.95f, 0.95f, 0.6f); var center = body.GetWorldCenter(); _drawer.DrawPoint(center, 5.0f, color); ++Count; } return(true); }
/** * Resolves a collision with the given solid collider. * * In hindsight, it may have been easier to look for collisions BEFORE * attempting the movement, but I am too far down the rabbit hole to change it * now. * * That approach would allow us to consider all collisions ahead of time and * then decide how to resolve them, whereas this approach means that we have * to resolve collisions as they occur, without knowing what other collisions * may have occurred simultaneously. */ private void CollideWithSolid(Collider2D other) { float distanceTravelled = (rigidbody.position - prevPosition).magnitude; // We know that a collision has occurred but we don't know where exactly. // To find the position of the collision, we re-enact the movement that's // just occurred using raycasts from each of our collision nodes. foreach (Vector2 node in collisionNodes) { Vector2 prev = prevPosition + node; Vector2 current = rigidbody.position + node; RaycastHit2D hit = Physics2D.Raycast( prev, current - prev, distanceTravelled, LayerMask.GetMask("Level")); // We only care about collisions with the collider that caused this // callback; other colliders can take care of their own collisions. if (hit.collider == other && CollisionUtils.IsCollisionValid(hit) && CollisionUtils.CanNodeCollide( node, hit, spriteRenderer.bounds.extents, SlopeTolerance)) { ProcessCollision(hit); return; } } }
public bool IsBlockWalkable(int blockX, int blockY) { ThreadingUtils.assertChildThread(); if (CollisionUtils.IsBlockBlocking(GetBlockType(blockX, blockY))) { return(false); } Rect blockBounds = new Rect(blockX * WorldGrid.BlockSize.X, blockY * WorldGrid.BlockSize.Y, WorldGrid.BlockSize.X, WorldGrid.BlockSize.Y); if (ContainedObjects != null) { lock (ContainedObjects) { foreach (var containedObject in ContainedObjects) { lock (containedObject) { if (containedObject.IsBlocking() && containedObject.BlockingBounds.Intersects(blockBounds)) { return(false); } } } } } return(true); }
void ManageCrushDamage(List <Collision> collisions) { if (collisions.Count > 1) //TODO just running into a corner (backing out and running back in) can do 40 damage... { float impulseMagnitudeSum = 0f; Vector3 impulseSum = Vector3.zero; for (int i = 0; i < collisions.Count; i++) { Vector3 normal = CollisionUtils.GetAverageNormal(collisions[i]); Vector3 impulse = normal * collisions[i].impulse.magnitude * Mathf.Abs(Vector3.Dot(normal, collisions[i].impulse.normalized)); impulseMagnitudeSum += impulse.magnitude; impulseSum += impulse; } float deltaMag = impulseMagnitudeSum - impulseSum.magnitude; float crushForce = deltaMag / (Time.fixedDeltaTime * rb.mass); float lerpFactor = (crushForce - crushForceMin) / (crushForceMax - crushForceMin); if (lerpFactor > 0f) { // float crushDamage = lerpFactor * 100f; // Debug.LogWarning(crushDamage + " damage from crushing"); // DamageDirect(crushDamage); Debug.LogWarning("Crushing damage commented out"); } } }
public void AssignTargets(List <Transform> targets) { targetPosition = targets[0].position; if (!followingTarget) { followingTarget = true; if (usePathing) { var transformPosition = (Vector2)transform.position; // If in same block as target, move to target if ((CollisionUtils.SnapToTile(transformPosition) - CollisionUtils.SnapToTile(targetPosition)).sqrMagnitude <= 0.01f) { previousPoint = currentPoint; currentPoint = targetPosition; } else // Move to next tile { previousPoint = currentPoint; currentPoint = GetPointToTarget(targetPosition); } } } }
/// Called for each fixture found in the query AABB. /// @return false to terminate the query. public bool QueryCallback(Fixture fixture) { if (Count == MaxCount) { return(false); } var body = fixture.Body; var shape = fixture.Shape; var overlap = CollisionUtils.TestOverlap( shape, 0, Circle, 0, body.GetTransform(), Transform, fixture.Body.World.GJkProfile); if (overlap) { DrawFixture(fixture); ++Count; } return(true); }
public void UnblockRect(Rect blockingBounds) { Point blockTopLeft = GeometryUtils.GetChunkPosition(blockingBounds.Left, blockingBounds.Top, WorldGrid.BlockSize.X, WorldGrid.BlockSize.Y); Point blockBottomRight = GeometryUtils.GetChunkPosition(blockingBounds.Right, blockingBounds.Bottom, WorldGrid.BlockSize.X, WorldGrid.BlockSize.Y); for (int blockX = blockTopLeft.X; blockX <= blockBottomRight.X; blockX++) { for (int blockY = blockTopLeft.Y; blockY <= blockBottomRight.Y; blockY++) { Point walkableGridChunkPos = GeometryUtils.GetChunkPosition(blockX, blockY, WalkableGridBlockChunkSize.X, WalkableGridBlockChunkSize.Y); if (IsLoaded(GeometryUtils.ConvertPointToLong(walkableGridChunkPos.X, walkableGridChunkPos.Y))) { Point worldGridChunkPos = GeometryUtils.GetChunkPosition(blockX, blockY, WorldGrid.WorldChunkBlockSize.X, WorldGrid.WorldChunkBlockSize.Y); WorldGridChunk worldGridChunk = SimulationGame.World.GetFromChunkPoint(worldGridChunkPos.X, worldGridChunkPos.Y); int blockType = worldGridChunk.GetBlockType(blockX, blockY); if (CollisionUtils.IsBlockBlocking(blockType)) { continue; } var found = false; if (worldGridChunk.ContainedObjects != null) { foreach (HitableObject interactiveObject in worldGridChunk.ContainedObjects) { if (interactiveObject.IsBlocking() && interactiveObject.BlockingBounds.Intersects(new Rect(blockX * WorldGrid.BlockSize.X, blockY * WorldGrid.BlockSize.Y, WorldGrid.BlockSize.X, WorldGrid.BlockSize.Y))) { found = true; break; } } } if (worldGridChunk.OverlappingObjects != null) { foreach (HitableObject interactiveObject in worldGridChunk.OverlappingObjects) { if (interactiveObject.IsBlocking() && interactiveObject.BlockingBounds.Intersects(new Rect(blockX * WorldGrid.BlockSize.X, blockY * WorldGrid.BlockSize.Y, WorldGrid.BlockSize.X, WorldGrid.BlockSize.Y))) { found = true; break; } } } if (!found) { SetBlockNotWalkable(blockX, blockY, false); } } } } }
public static bool collision(Nuke nuke, Terrain terrain, out Vector2 collisionPoint) { bool collision = false; if (CollisionUtils.doPixelsIntersect(nuke.TextureColourData, nuke.Matrix, terrain.TextureColourData, terrain.Matrix, out collisionPoint)) { collision = true; } return(collision); }
public static bool collision(Launcher launcher, Terrain terrain, out Vector2 collisionPoint) { bool collision = false; if (CollisionUtils.doPixelsIntersect(launcher.TextureColourData, launcher.Matrix, terrain.TextureColourData, terrain.Matrix, out collisionPoint)) { collision = true; } return(collision); }
void BroadPhase(float Delta) { PossibleContacts.Clear(); ActualContacts.Clear(); for (int i = 0; i < PhysicsRectangles.Count; i++) { PhysicsRectangle a = PhysicsRectangles[i]; for (int j = 0; j < 4; j++) { a.Hit[j] = null; } PhysicsRectangles[i] = a; } for (int i = 0; i < PhysicsRectangles.Count; i++) { for (int j = 0; j < PhysicsRectangles.Count; j++) { if (i != j) { PhysicsRectangle a = PhysicsRectangles[i].Clone(); PhysicsRectangle b = PhysicsRectangles[j].Clone(); float AMinX = Math.Min(a.X, a.X + (a.VelX * Delta)); float AMinY = Math.Min(a.Y, a.Y + (a.VelY * Delta)); float AMaxX = Math.Max(a.X + a.SizeX, a.X + a.SizeX + (a.VelX * Delta)); float AMaxY = Math.Max(a.Y + a.SizeY, a.Y + a.SizeY + (a.VelY * Delta)); float BMinX = Math.Min(b.X, b.X + (b.VelX * Delta)); float BMinY = Math.Min(b.Y, b.Y + (b.VelY * Delta)); float BMaxX = Math.Max(b.X + b.SizeX, b.X + b.SizeX + (b.VelX * Delta)); float BMaxY = Math.Max(b.Y + b.SizeY, b.Y + b.SizeY + (b.VelY * Delta)); a.SizeX = Math.Abs(AMaxX - AMinX); a.SizeY = Math.Abs(AMaxY - AMinY); a.X = AMinX; a.Y = AMinY; b.SizeX = Math.Abs(BMaxX - BMinX); b.SizeY = Math.Abs(BMaxY - BMinY); b.X = BMinX; b.Y = BMinY; if (CollisionUtils.RectangleIntersect(a, b)) { PossibleContacts.Add(new Tuple <int, int>(i, j)); } } } } }
public static bool collision(Nuke nuke, Launcher launcher, out Vector2 collisionPoint) { bool collision = false; collisionPoint = new Vector2(-1f); if (CollisionUtils.doPixelsIntersect(nuke.TextureColourData, nuke.Matrix, launcher.TextureColourData, launcher.Matrix, out collisionPoint)) { collision = true; } return(collision); }
// ---------------------------------------------------------------------------------------------------- #endregion #region Initialization // ---------------------------------------------------------------------------------------------------- /// <summary> /// Called upon awaking this behavior. /// </summary> private void Awake() { this.interactionTarget = this.GetComponent <InteractionTarget>(); this.interactionTarget.OnInteraction += (playerController) => { var playerStateController = playerController.StateController; if (CollisionUtils.IsObjectInsideTile(transform.position, playerStateController.transform.position)) { StartCoroutine(playerStateController.TeleportTo(targetTeleporter.transform)); this.OnTeleport?.Invoke(this); } }; }
protected override BehaviourTreeStatus internalUpdate(GameTime gameTime) { var movingEntity = (MovingEntity)subject; if (GeometryUtils.VectorsWithinDistance(movingEntity.Position, from.Position, maxDistance) == false) { movingEntity.StopWalking(); return(BehaviourTreeStatus.Success); } else { var neighbors = new SortedList <float, Point>(); var originalDistanceToTarget = GeometryUtils.GetDiagonalDistance(movingEntity.BlockPosition.X, movingEntity.BlockPosition.Y, from.BlockPosition.X, from.BlockPosition.Y); // Find blockPosition to walk to for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { if (i == 0 && j == 0) { continue; } var neighborBlockPosition = new Point(i + movingEntity.BlockPosition.X, j + movingEntity.BlockPosition.Y); var distanceToTarget = GeometryUtils.GetDiagonalDistance(neighborBlockPosition.X, neighborBlockPosition.Y, from.BlockPosition.X, from.BlockPosition.Y); if (distanceToTarget > originalDistanceToTarget && CollisionUtils.IsBlockPositionWalkable(neighborBlockPosition.X, neighborBlockPosition.Y, movingEntity.InteriorID)) { if (neighbors.ContainsKey(distanceToTarget) == false) { neighbors.Add(distanceToTarget, neighborBlockPosition); } } } } if (neighbors.Count > 0) { Point pointToWalkTo = neighbors.Values[neighbors.Count - 1]; movingEntity.WalkToPosition(new WorldPosition(pointToWalkTo.X * WorldGrid.BlockSize.X + 15, pointToWalkTo.Y * WorldGrid.BlockSize.Y + 15, movingEntity.InteriorID)); return(BehaviourTreeStatus.Running); } return(BehaviourTreeStatus.Failure); } }
// Create WorldGridChunks public void Build() { //ElevationGenerator.PrintHeightMap(this); for (int i = 0; i < WorldSegmentChunkSize.X; i++) { for (int j = 0; j < WorldSegmentChunkSize.Y; j++) { var worldGridChunkExists = WorldLoader.DoesWorldGridChunkExist(startChunkPosition.X + i, startChunkPosition.Y + j); if (worldGridChunkExists == true) { continue; } if (Blocks[i * WorldGrid.WorldChunkBlockSize.X, j *WorldGrid.WorldChunkBlockSize.Y].BlockId == BlockType.Invalid) { continue; } var chunkBlockPosition = new Point(startBlockPosition.X + i * WorldGrid.WorldChunkBlockSize.X, startBlockPosition.Y + j * WorldGrid.WorldChunkBlockSize.Y); WorldGridChunk worldGridChunk = new WorldGridChunk(WorldGrid.BlockSize.X * chunkBlockPosition.X, WorldGrid.BlockSize.Y * chunkBlockPosition.Y); WalkableGridChunk walkableGridChunk = WalkableGridChunk.CreateEmpty(startChunkPosition.X + i, startChunkPosition.Y + j); worldGridChunk.SetBiomeType(Biome); for (int x = 0; x < WorldGrid.WorldChunkBlockSize.X; x++) { for (int y = 0; y < WorldGrid.WorldChunkBlockSize.Y; y++) { var blockPosition = new Point(chunkBlockPosition.X + x, chunkBlockPosition.Y + y); var worldSegmentPosition = new Point(i * WorldGrid.WorldChunkBlockSize.X + x, j * WorldGrid.WorldChunkBlockSize.Y + y); worldGridChunk.SetBlockType(blockPosition.X, blockPosition.Y, Blocks[worldSegmentPosition.X, worldSegmentPosition.Y].BlockId); if (CollisionUtils.IsBlockBlocking(Blocks[worldSegmentPosition.X, worldSegmentPosition.Y].BlockId)) { walkableGridChunk.SetWalkable(blockPosition.X, blockPosition.Y, false); } } } WorldLoader.SaveWorldGridChunk(startChunkPosition.X + i, startChunkPosition.Y + j, worldGridChunk); WorldLoader.SaveWalkableGridChunk(startChunkPosition.X + i, startChunkPosition.Y + j, walkableGridChunk); } } }
protected void ApplyGravity() { Rectangle futurePosition = new Rectangle(CollisionBox.X, CollisionBox.Y - VelocityY, CollisionBox.Width, CollisionBox.Height); Collision.LineSegment intersectedPlatform = CollisionUtils.IntersectsWithSlopedPlatforms(futurePosition) ?? CollisionUtils.IntersectsWithAxisAlignedPlatforms(futurePosition); if (intersectedPlatform == null) { SetCollisionBoxY(CollisionBox.Y - VelocityY); IsGrounded = false; IsFalling = true; } else { if (intersectedPlatform.IsSloped) { do { // Set the incline angle if ((intersectedPlatform.IsAscending && CollisionBox.Y + CollisionBox.Height < intersectedPlatform.PointB.Y) || (!intersectedPlatform.IsAscending && CollisionBox.Y + CollisionBox.Height < intersectedPlatform.PointA.Y)) { // Don't apply incline angle if we are completely above the platform InclineAngle = 0; } else { InclineAngle = intersectedPlatform.IsAscending ? Maths.DegreesToRadians(360) - intersectedPlatform.InclineAngleWithX : intersectedPlatform.InclineAngleWithX; } // Check for collision a little higher futurePosition.Y -= Math.Abs(StartingVelocityY * 0.1f); intersectedPlatform = CollisionUtils.IntersectsWithSlopedPlatforms(futurePosition); }while (intersectedPlatform != null); SetCollisionBoxY(futurePosition.Y); } else { InclineAngle = 0; float distanceToPlatform = intersectedPlatform.PointA.Y - (CollisionBox.Y + CollisionBox.Height) - 1; SetCollisionBoxY(CollisionBox.Y + distanceToPlatform); } IsGrounded = true; IsFalling = false; } }
private void Query() { _tree.Query(QueryCallback, _queryAABB); for (var i = 0; i < ActorCount; ++i) { if (_actors[i].ProxyId == BroadPhase.NullProxy) { continue; } var overlap = CollisionUtils.TestOverlap(_queryAABB, _actors[i].AABB); Debug.Assert(overlap == _actors[i].Overlap); } }
private CollisionInfo FindEarliestLineCollision() { var myGame = (MyGame)game; var collisionInfo = new CollisionInfo(Vec2.Zero, null, Mathf.Infinity); foreach (var line in myGame.Lines) { var currentCollisionInfo = CollisionUtils.CircleLineCollision(Position, OldPosition, Velocity * Time.deltaTime, Radius, line); if (currentCollisionInfo != null && currentCollisionInfo.TimeOfImpact < collisionInfo.TimeOfImpact) { collisionInfo = new CollisionInfo(currentCollisionInfo.Normal, null, currentCollisionInfo.TimeOfImpact); } } return(float.IsPositiveInfinity(collisionInfo.TimeOfImpact) ? null : collisionInfo); }
public override void Update(GameTime gameTime) { if (!HasHitTarget) { updatePosition(new WorldPosition(Position.X + (direction.X * velocity * (int)gameTime.ElapsedGameTime.TotalMilliseconds), Position.Y + (direction.Y * velocity * gameTime.ElapsedGameTime.Milliseconds), Position.InteriorID)); if (GeometryUtils.VectorsWithinDistance(Position.X, Position.Y, startPosition.X, startPosition.Y, MaxDistance)) { var rotateVector = new Vector2(Position.X, Position.Y + 7.5f); var rotatedPoint = GeometryUtils.Rotate(Angle, Position.ToVector(), ref rotateVector); var collisionRect = new Rect((int)(rotatedPoint.X - 7.5f), (int)(rotatedPoint.Y - 7.5f), 15, 15); var hittedObjects = CollisionUtils.GetHittedObjects(collisionRect, Position.InteriorID, Origin); if (hittedObjects.Count == 0) { if (CollisionUtils.IsHitableBlockHitted(collisionRect, InteriorID)) { HasHitTarget = true; } } else { HasHitTarget = true; foreach (var hittedObject in hittedObjects) { if (hittedObject is LivingEntity) { ((LivingEntity)hittedObject).ModifyHealth((int)-damage, Origin); } } } } else { IsFinished = true; } } else { if (InteriorID != SimulationGame.Player.InteriorID || effectRendererInformation == null || effectRendererInformation.IsFinished) { IsFinished = true; } } }
public void RefreshBlock(int blockX, int blockY) { Point walkableGridChunkPos = GeometryUtils.GetChunkPosition(blockX, blockY, WalkableGridBlockChunkSize.X, WalkableGridBlockChunkSize.Y); if (IsLoaded(GeometryUtils.ConvertPointToLong(walkableGridChunkPos.X, walkableGridChunkPos.Y))) { Point worldGridChunkPos = GeometryUtils.GetChunkPosition(blockX, blockY, WorldGrid.WorldChunkBlockSize.X, WorldGrid.WorldChunkBlockSize.Y); WorldGridChunk worldGridChunk = SimulationGame.World.GetFromChunkPoint(worldGridChunkPos.X, worldGridChunkPos.Y); int blockType = worldGridChunk.GetBlockType(blockX, blockY); if (CollisionUtils.IsBlockBlocking(blockType)) { SetBlockNotWalkable(blockX, blockY, true); return; } var found = false; if (worldGridChunk.ContainedObjects != null) { foreach (HitableObject interactiveObject in worldGridChunk.ContainedObjects) { if (interactiveObject.IsBlocking() && interactiveObject.BlockingBounds.Intersects(new Rect(blockX * WorldGrid.BlockSize.X, blockY * WorldGrid.BlockSize.Y, WorldGrid.BlockSize.X, WorldGrid.BlockSize.Y))) { found = true; break; } } } if (worldGridChunk.OverlappingObjects != null) { foreach (HitableObject interactiveObject in worldGridChunk.OverlappingObjects) { if (interactiveObject.IsBlocking() && interactiveObject.BlockingBounds.Intersects(new Rect(blockX * WorldGrid.BlockSize.X, blockY * WorldGrid.BlockSize.Y, WorldGrid.BlockSize.X, WorldGrid.BlockSize.Y))) { found = true; break; } } } SetBlockNotWalkable(blockX, blockY, found); } }
public static WorldPosition GetWalkablePositionCloseTo(WorldPosition realOrigin, WorldPosition realTarget, int realDistanceFromTarget) { Debug.Assert(realOrigin.InteriorID == realTarget.InteriorID, "Problem origin != target interior"); var direction = new Vector2(realTarget.X - realOrigin.X, realTarget.Y - realOrigin.Y); direction.Normalize(); var realPosition = new WorldPosition(realTarget.X - realDistanceFromTarget * direction.X, realTarget.Y - realDistanceFromTarget * direction.Y, realOrigin.InteriorID); var isBlockWalkable = CollisionUtils.IsRealPositionWalkable(realPosition); var worldLink = SimulationGame.World.GetWorldLinkFromRealPosition(realPosition); if (isBlockWalkable && worldLink == null) { return(realPosition); } return(null); }
/// Called for each fixture found in the query AABB. /// @return false to terminate the query. private bool ReportFixture(Fixture fixture) { if (Count == MaxCount) { return(false); } var body = fixture.Body; var shape = fixture.Shape; var overlap = CollisionUtils.TestOverlap(shape, 0, Circle, 0, body.GetTransform(), Transform); if (overlap) { DrawFixture(fixture); ++Count; } return(true); }
public override bool IntersectWith(Shapes other) { if (other is Circle circle2) { var dx = this.x - circle2.x; var dy = this.y - circle2.y; var distance = Math.Sqrt(dx * dx + dy * dy); if (distance < this.radius + circle2.radius) { return true; } } if (other is Rectangle rectangle) { return CollisionUtils.IntersectRectangleCircle(this, rectangle); } return false; }