private void Update(AbstractHumanoid sprite, SpritePool spritePool, AbstractHumanoid currentPlayer, AbstractMap map, double timeDelta, out bool isNeedRefreshHud) { isNeedRefreshHud = false; sprite.ReceivedAttackCycle.Update(timeDelta); //We manage received attack if (sprite.ReceivedAttackCycle.GetCycleState() > 0) { Physics.TryMakeWalk(sprite, sprite.ReceivedAttackAngleRadian - sprite.AngleRadian, spritePool, map, 1); sprite.IsNeedToJumpAgain = false; Physics.MakeJump(sprite, timeDelta); sprite.Health -= sprite.LatestAttackerDamage; if (!sprite.IsAlive) { isNeedRefreshHud = true; sprite.LatestAttacker.FragCount++; currentPlayer.RefreshRanking(spritePool); } if (sprite == currentPlayer) { isNeedRefreshHud = true; } } else { sprite.ReceivedAttackCycle.UnFire(); } }
public void Update(AbstractHumanoid currentPlayer, RayTracer rayTracer, AbstractMap map, Surface surface) { int columnXLeftMargin = 0; for (int columnId = 0; columnId < columnCount; columnId++) { double straightDistance = Optics.GetStraightDistance(currentPlayer, rayTracer[columnId]); double columnHeight = Optics.GetColumnHeight(straightDistance, screenHeight, heightDistanceRatio); double topMargin = Optics.GetColumnTopMargin(screenHeight, columnHeight, currentPlayer.PositionZ, currentPlayer.IsCrouch, currentPlayer.MouseLook); Rectangle rectangle = rectangleCache[columnId]; rectangle.X = columnXLeftMargin; rectangle.Y = (int)topMargin; rectangle.Height = (int)columnHeight; columnXLeftMargin += columnWidthPixel; double brightness = Optics.GetBrightness(Math.Min(screenHeight, columnHeight), screenHeight); double red, green, blue; map.GetColors(rayTracer[columnId].X, rayTracer[columnId].Y, brightness, out red, out green, out blue); if (echolocationCycle.IsHighlightedColumn(columnId)) { red = Math.Max(0, Math.Min(255, 256 - red)); green = Math.Max(0, Math.Min(255, 256 - green)); blue = Math.Max(0, Math.Min(255, 256 - blue)); this.echolocationBeeper.Beep(straightDistance, columnId, columnCount); } surface.Fill(rectangle, Color.FromArgb(255, (byte)(red), (byte)(green), (byte)(blue))); } }
private void DrawSpriteAngle(AbstractHumanoid sprite, Surface surface) { int pixelLocationX = (int)(sprite.PositionX / precision); int pixelLocationY = (int)(sprite.PositionY / precision); double realEndingLocationX = sprite.PositionX + Math.Cos(sprite.AngleRadian) * sprite.Diameter; double realEndingLocationY = sprite.PositionY + Math.Sin(sprite.AngleRadian) * sprite.Diameter; short pixelEndingLocationX = (short)(realEndingLocationX / precision); short pixelEndingLocationY = (short)(realEndingLocationY / precision); IPrimitive primitive; Line angleLine; if (angleLineCache.TryGetValue(sprite, out primitive)) { angleLine = (Line)primitive; } else { angleLine = new Line(); } angleLine.XPosition1 = (short)pixelLocationX; angleLine.YPosition1 = (short)pixelLocationY; angleLine.XPosition2 = pixelEndingLocationX; angleLine.YPosition2 = pixelEndingLocationY; surface.Draw(angleLine, Color.White); }
private AbstractHumanoid TryChoosePrey(AbstractHumanoid predator, SpritePool spritePool, SharedConsciousness sharedConsciousness, AbstractMap map, int fov, AbstractHumanoid currentPlayer) { AbstractHumanoid closestPrey = null; double closestDistance = -1; foreach (AbstractHumanoid prey in spritePool) { if (prey == predator) { continue; } //if (!Physics.IsWithinAttackRange(predator, prey) && !sharedConsciousness.IsSpriteViewable(predator, prey, map, fov)) // continue; if (sharedConsciousness.IsSpriteViewable(predator, prey, map, fov) || (sharedConsciousness.IsSpriteViewable(prey, predator, map, fov) && predator.LatestAttacker == prey)) { double currentDistance = Physics.GetSpriteDistance(predator, prey); if (closestPrey == null || currentDistance < closestDistance) { closestPrey = prey; closestDistance = currentDistance; } } } return(closestPrey); }
/// <summary> /// Whether predator can attack prey /// </summary> /// <param name="predator">predator</param> /// <param name="prey">prey</param> /// <returns>whether predator can attack prey</returns> public static bool IsInAttackHeight(AbstractHumanoid predator, AbstractHumanoid prey) { if (predator.IsCrouch) { if (prey.IsCrouch) { return(true); } else if (prey.PositionZ <= predator.Height / 2) { return(true); } } else { if (!prey.IsCrouch) { return(true); } else if (predator.PositionZ > 0 && predator.PositionZ < prey.Height / 2) { return(true); } } return(false); }
private void DrawSpriteBounds(AbstractHumanoid sprite, bool isViewable, Surface surface) { int pixelLocationX = (int)(sprite.PositionX / precision); int pixelLocationY = (int)(sprite.PositionY / precision); int radius = (int)(sprite.Radius / precision); IPrimitive primitive; Circle circle; if (circleCache.TryGetValue(sprite, out primitive)) { circle = (Circle)primitive; } else { circle = new Circle((short)pixelLocationX, (short)pixelLocationY, (short)radius); circleCache.Add(sprite, circle); } circle.PositionX = (short)pixelLocationX; circle.PositionY = (short)pixelLocationY; if (sprite is Player) { surface.Draw(circle, Color.MediumBlue); } else if (isViewable) { surface.Draw(circle, Color.Magenta); } else { surface.Draw(circle, Color.Orange); } }
public void Update(SpritePool spritePool, AbstractHumanoid currentPlayer, AbstractMap map, double timeDelta) { foreach (AbstractHumanoid sprite in spritePool) { bool currentSpriteNeedRefreshHud; Update(sprite, spritePool, currentPlayer, map, timeDelta, out currentSpriteNeedRefreshHud); } }
/// <summary> /// Make walk sprite /// </summary> /// <param name="sprite">sprite</param> /// <param name="angleOffsetRadian">angle offset (default 0) (in radian)</param> /// <param name="spritePool">other sprites</param> /// <param name="map">map</param> /// <param name="timeDelta">time delta</param> public static bool TryMakeWalk(AbstractSprite sprite, double angleOffsetRadian, SpritePool spritePool, AbstractMap map, double timeDelta) { double xMove = Math.Cos(sprite.AngleRadian + angleOffsetRadian) * sprite.DefaultWalkingDistance * timeDelta; double yMove = Math.Sin(sprite.AngleRadian + angleOffsetRadian) * sprite.DefaultWalkingDistance * timeDelta; if (sprite is AbstractHumanoid) { AbstractHumanoid humanoid = (AbstractHumanoid)sprite; humanoid.WalkCycle.UnFire(); humanoid.WalkCycle.Fire(); humanoid.WalkCycle.Update(1); if (humanoid.IsCrouch) { xMove *= humanoid.CrouchSpeedMultiplier; yMove *= humanoid.CrouchSpeedMultiplier; } //If is attacking and not jumping if (humanoid.StrongAttackCycle.IsFired && humanoid.PositionZ <= 0) { xMove *= humanoid.AttackWalkSpeedMultiplier; yMove *= humanoid.AttackWalkSpeedMultiplier; } } //If is jump if (sprite.PositionZ > 0) { xMove *= sprite.JumpSpeedMultiplier; yMove *= sprite.JumpSpeedMultiplier; } sprite.PositionX += xMove; bool isDetectCollisionX = IsDetectCollision(sprite, spritePool, map); if (isDetectCollisionX) { sprite.PositionX -= xMove; } sprite.PositionY += yMove; bool isDetectCollisionY = IsDetectCollision(sprite, spritePool, map); if (isDetectCollisionY) { sprite.PositionY -= yMove; } return(!(isDetectCollisionX || isDetectCollisionY)); }
/// <summary> /// Distance for which predator sprite can attack prey /// </summary> /// <param name="predator">predator</param> /// <param name="prey">prey</param> /// <returns>Distance for which predator sprite can attack prey</returns> private static double GetAttackRange(AbstractHumanoid predator, AbstractSprite prey) { double predatorAttackRange = predator.AttackRange; if (predator.PositionZ > 0) { predatorAttackRange *= predator.AttackRangeJumpMultiplier; } else if (predator.IsCrouch) { predatorAttackRange *= predator.AttackRangeCrouchMultiplier; } return(predatorAttackRange); }
public void Trace(AbstractHumanoid viewerSprite, double angleDegree, double rayDistanceResolution, AbstractMap map) { double xMove = Math.Cos(angleDegree / 180 * Math.PI) * rayDistanceResolution; double yMove = Math.Sin(angleDegree / 180 * Math.PI) * rayDistanceResolution; x = viewerSprite.PositionX; y = viewerSprite.PositionY; while (true) { x += xMove; y += yMove; xMove *= 1.01; yMove *= 1.01; if (x < 0 || y < 0 || x > map.Width || y > map.Height) { break; } if (map.GetMatterTypeAt(x, y) != null) { break; } } if (x < 0) { x = 0; } else if (x > map.Width) { x = map.Width - xMove; } if (y < 0) { y = 0; } else if (y > map.Height) { y = map.Height - yMove; } }
public bool IsSpriteViewable(AbstractHumanoid viewerSprite, AbstractHumanoid viewedSprite, AbstractMap map, int fov) { Dictionary <AbstractHumanoid, bool> viewedList; if (!internalList.TryGetValue(viewerSprite, out viewedList)) { viewedList = new Dictionary <AbstractHumanoid, bool>(); internalList.Add(viewerSprite, viewedList); } bool isViewed; if (!viewedList.TryGetValue(viewedSprite, out isViewed)) { isViewed = Optics.IsSpriteViewable(viewerSprite, viewedSprite, map, fov); viewedList.Add(viewedSprite, isViewed); } return(isViewed); }
private void Respawn(AbstractHumanoid fighter, AbstractMap map, SpritePool spritePool) { if (this.map != map) { this.map = map; emptyMapLocationCache = new EmptyMapLocationCache(this.map); } Point point; do { point = emptyMapLocationCache.GetRandomAvailableLocation(map, spritePool, random); fighter.PositionX = (double)point.X + 0.5; fighter.PositionY = (double)point.Y + 0.5; } while (Physics.IsDetectCollision(fighter, spritePool, map)); fighter.Health = fighter.DefaultHealth; fighter.AngleDegree = random.Next(360); fighter.ReceivedAttackCycle.Reset(); }
/// <summary> /// Whether sprite 1 can attack or block sprite 2 because angle allows it /// </summary> /// <param name="sprite1">sprite 1</param> /// <param name="sprite2">sprite 2</param> /// <returns>Whether sprite 1 can attack or block sprite 2 because angle allows it</returns> public static bool IsInAttackOrBlockAngle(AbstractHumanoid sprite1, AbstractHumanoid sprite2) { double angleToSprite = Optics.GetSpriteAngleToSpriteRadian(sprite1, sprite2); double attackAngleRange = sprite1.AttackAngleRange; if (Math.Abs(angleToSprite - sprite1.AngleRadian) < attackAngleRange) { return(true); } else if (Math.Abs(angleToSprite - sprite1.AngleRadian + Math.PI * 2.0) < attackAngleRange) { return(true); } else if (Math.Abs(angleToSprite - sprite1.AngleRadian + Math.PI * 2.0) < attackAngleRange) { return(true); } return(false); }
public List <RayTracerPoint> Trace(AbstractHumanoid viewerSprite, AbstractMap map) { double startAngle = viewerSprite.AngleDegree - fov / 2; double endAngle = viewerSprite.AngleDegree + fov / 2; double angleResolution = (double)fov / (double)columnCount; startAngle = Optics.FixAngleDegree(startAngle); endAngle = Optics.FixAngleDegree(endAngle); int pointCounter = 0; for (double angle = startAngle; pointCounter < columnCount; angle += angleResolution) { angle = Optics.FixAngleDegree(angle); pointList[pointCounter].Trace(viewerSprite, angle, rayDistanceResolution, map); pointCounter++; } return(pointList); }
/// <summary> /// Whether sprite 1 has a valid height to block sprite2's attack /// </summary> /// <param name="sprite1">sprite 1</param> /// <param name="sprite2">sprite 2</param> /// <returns>whether sprite 1 has a valid height to block sprite2's attack</returns> public static bool IsInBlockingHeight(AbstractHumanoid sprite1, AbstractHumanoid sprite2) { if (!sprite1.IsCrouch && !sprite2.IsCrouch && sprite1.PositionZ <= 0 && sprite2.PositionZ <= 0) { return(true); } if (sprite1.PositionZ > sprite2.Height / 4) { return(false); } if (sprite1.IsCrouch && sprite2.PositionZ > 0) { return(false); } if (!sprite1.IsCrouch && sprite2.IsCrouch) { return(false); } return(true); }
/// <summary> /// Whether prey is withing predator's attack range /// </summary> /// <param name="predator">predator sprite</param> /// <param name="prey">prey sprite</param> /// <returns>Whether prey is withing predator's attack range</returns> public static bool IsWithinAttackRange(AbstractHumanoid predator, AbstractHumanoid prey, double multiplicator) { return(Physics.GetSpriteDistance(predator, prey) <= GetAttackRange(predator, prey) * multiplicator);// predatorAttackRange + prey.Radius; }
public bool TryGetValue(AbstractHumanoid sprite, out IPrimitive circle) { return(internalCache.TryGetValue(sprite, out circle)); }
private bool IsReadyToSpin(AbstractHumanoid predator) { return(predator.SpinChargeAttackCycle.IsAtParoxism && !predator.SpinAttackCycle.IsFired); }
/// <summary> /// Create sprite pool /// </summary> /// <param name="spriteToAdd">sprite to add</param> public SpritePool(AbstractHumanoid spriteToAdd) { Add(spriteToAdd); }
private void DrawSprite(AbstractHumanoid sprite, bool isViewable, Surface surface) { DrawSpriteBounds(sprite, isViewable, surface); DrawSpriteAngle(sprite, surface); }
public void Animate(AbstractHumanoid predator, AbstractMap map, SpritePool spritePool, SharedConsciousness sharedConsciousness, double timeDelta, int fov, Random random, AbstractHumanoid currentPlayer) { AbstractHumanoid prey; if (random.Next(howManyFrameBeforeChoosingPreyAgain) == 0) { prey = TryChoosePrey(predator, spritePool, sharedConsciousness, map, fov, currentPlayer); predator.LatestSelectedPrey = prey; } else { prey = predator.LatestSelectedPrey; } predator.IsNeedToJumpAgain = false; predator.IsBlock = false; byte currentStateJumpCrouch = predator.StateJumpCrouch.GetCurrentState(); //We manage jumping state if (currentStateJumpCrouch == SpriteStates.Jump) { predator.IsCrouch = false; Physics.MakeJump(predator, timeDelta); } //We manage crouch state if (currentStateJumpCrouch == SpriteStates.Crouch) { predator.IsCrouch = true; } //We manage standing state if (currentStateJumpCrouch == SpriteStates.Stand) { predator.IsCrouch = false; predator.IsNeedToJumpAgain = false; } //We manage walking if (prey != null) { if (random.Next(5) == 0 && !predator.SpinAttackCycle.IsFired) { predator.AngleRadian = Optics.GetSpriteAngleToSpriteRadian(predator, prey); } byte currentAttackBlockState = predator.StateAttackBlock.GetCurrentState(); byte currentAttackTypeState = predator.StateAttackType.GetCurrentState(); byte currentMovementState = predator.StateMovement.GetCurrentState(); if (currentAttackBlockState == SpriteStates.SpinCharge) { predator.StateAttackType.Reset(); } if (predator.SpinChargeAttackCycle.IsFired) { currentAttackBlockState = SpriteStates.SpinCharge; } if (currentMovementState == SpriteStates.Offensive) { Physics.TryMakeWalk(predator, spritePool, map, timeDelta); } else if (currentMovementState == SpriteStates.Defensive) { Physics.TryMakeWalk(predator, Math.PI, spritePool, map, timeDelta); } else if (currentMovementState == SpriteStates.FurtiveLeft) { Physics.TryMakeWalk(predator, Math.PI * 1.5, spritePool, map, timeDelta); } else if (currentMovementState == SpriteStates.FurtiveRight) { Physics.TryMakeWalk(predator, Math.PI * 0.5, spritePool, map, timeDelta); } //We manage attacking, and blocking bool isWithinAttackRange = BattlePhysics.IsWithinAttackRange(predator, prey); bool isWithinAttackOrBlockAngle = BattlePhysics.IsInAttackOrBlockAngle(predator, prey); if (currentAttackBlockState == SpriteStates.Block && predator.PositionZ > 0) { currentAttackBlockState = SpriteStates.Attack; } if (isWithinAttackRange || isWithinAttackOrBlockAngle) { if (predator.ReceivedAttackCycle.IsAtBegining) { if (currentAttackBlockState == SpriteStates.Attack) { if (currentAttackTypeState == SpriteStates.FastAttack) { if (random.Next(2) == 1) { if (BattlePhysics.IsWithinAttackRange(predator, prey, 1.5) && isWithinAttackOrBlockAngle) { predator.FastAttackCycle.UnFire(); predator.FastAttackCycle.Fire(); } } } else if (currentAttackTypeState == SpriteStates.StrongAttack) { if (random.Next(2) == 1) { if (BattlePhysics.IsWithinAttackRange(predator, prey, 1.5) && isWithinAttackOrBlockAngle) { predator.StrongAttackCycle.UnFire(); predator.StrongAttackCycle.Fire(); } } } predator.SpinChargeAttackCycle.Reset(); } else if (currentAttackBlockState == SpriteStates.SpinCharge) { if (IsReadyToSpin(predator) && BattlePhysics.IsWithinAttackRange(predator, prey, 1.5)) { if (random.Next(3) == 1) { predator.SpinAttackCycle.Reset(); predator.SpinAttackCycle.Fire(); predator.SpinChargeAttackCycle.Reset(); predator.StateAttackBlock.Reset(); } } else if (!predator.SpinAttackCycle.IsFired) { if (predator.SpinChargeAttackCycle.IsFired) { predator.SpinChargeAttackCycle.Update(timeDelta); } else { predator.SpinChargeAttackCycle.Fire(); } } } else if (currentAttackBlockState == SpriteStates.Block && !predator.SpinAttackCycle.IsFired) { predator.StrongAttackCycle.UnFire(); predator.SpinAttackCycle.UnFire(); predator.SpinChargeAttackCycle.Reset(); predator.FastAttackCycle.UnFire(); predator.IsBlock = true; } else { predator.SpinChargeAttackCycle.Reset(); } } } predator.StateAttackBlock.Update(timeDelta, random); predator.StateAttackType.Update(timeDelta, random); predator.StateMovement.Update(timeDelta, random); } else { if (!predator.SpinAttackCycle.IsFired && !Physics.TryMakeWalk(predator, spritePool, map, timeDelta)) { predator.AngleDegree = (double)random.Next(360); } } predator.StateJumpCrouch.Update(timeDelta, random); }
private void Update(AbstractHumanoid attacker, SpritePool spritePool, SharedConsciousness sharedConsciousness, AbstractHumanoid currentPlayer) { bool IsAttackerAttackAtParoxism; double damage; bool isFastAttack = false; if (attacker.StrongAttackCycle.IsAtParoxism) { damage = attacker.AttackPowerStrong; IsAttackerAttackAtParoxism = true; } else if (attacker.FastAttackCycle.IsAtParoxism) { damage = attacker.AttackPowerFast; IsAttackerAttackAtParoxism = true; isFastAttack = true; } else if (attacker.SpinAttackCycle.IsFired) { damage = attacker.AttackPowerStrong; IsAttackerAttackAtParoxism = true; } else { return; } if (IsAttackerAttackAtParoxism && attacker.ReceivedAttackCycle.GetCycleState() <= 0) { foreach (AbstractHumanoid attacked in spritePool) { if (attacked == attacker) { continue; } if (BattlePhysics.IsWithinAttackRange(attacker, attacked)) { if (BattlePhysics.IsInAttackOrBlockAngle(attacker, attacked)) { if (BattlePhysics.IsInAttackHeight(attacker, attacked)) { if (!attacked.IsBlock || !BattlePhysics.IsInAttackOrBlockAngle(attacked, attacker) || !BattlePhysics.IsInBlockingHeight(attacked, attacker)) { //We abort attacked's attack attacked.FastAttackCycle.Reset(); attacked.StrongAttackCycle.Reset(); attacked.BlockSuccessCycle.Reset(); attacked.SpinChargeAttackCycle.Reset(); attacked.SpinAttackCycle.Reset(); attacked.FastAttackCycle.IsNeedToClickAgain = true; attacked.StrongAttackCycle.IsNeedToClickAgain = true; attacked.ReceivedAttackAngleRadian = attacker.AngleRadian; attacked.ReceivedAttackCycle.Fire(); if (isFastAttack) { attacked.ReceivedAttackCycle.PercentComplete = 0.25; attacked.ReceivedAttackCycle.IsForward = false; attacked.IsJustReceivedFastAttack = true; } else { if (attacker.IsCrouch || attacker.PositionZ >= 0) { attacked.IsJustReceivedStrongKick = true; } else { attacked.IsJustReceivedStrongPunch = true; } } attacked.LatestAttacker = attacker; attacked.LatestAttackerDamage = damage; if (!(attacked is Player)) { attacked.StateJumpCrouch.Reset(); attacked.StateMovement.Reset(); attacked.StateAttackBlock.Reset(); if (attacked.StateAttackBlock.GetCurrentState() == SpriteStates.SpinCharge) { attacked.StateAttackBlock.Reset(); } } if (!(attacker is Player)) { attacker.StateJumpCrouch.Renew(); attacker.StateMovement.Renew(); attacker.StateAttackBlock.Renew(); } } else if (attacked.IsBlock) { attacked.BlockSuccessCycle.Reset(); attacked.BlockSuccessCycle.Fire(); } } } } } } }
public void Update(SpritePool spritePool, SharedConsciousness sharedConsciousness, AbstractHumanoid currentPlayer) { foreach (AbstractHumanoid sprite in spritePool) { Update(sprite, spritePool, sharedConsciousness, currentPlayer); } }
public void Add(AbstractHumanoid sprite, IPrimitive circle) { internalCache.Add(sprite, circle); }