public new static void LoadSharedAssetsOnce() { #if __IOS__ var whiteColor = UIColor.White; #else NSColor whiteColor = null; new NSObject().InvokeOnMainThread(() => { whiteColor = NSColor.White; }); #endif SKTextureAtlas atlas = SKTextureAtlas.FromName("Environment"); sharedProjectile = SKSpriteNode.FromTexture(atlas.TextureNamed("warrior_throw_hammer.png")); sharedProjectile.PhysicsBody = SKPhysicsBody.CreateCircularBody(ProjectileCollisionRadius); sharedProjectile.Name = "Projectile"; sharedProjectile.PhysicsBody.CategoryBitMask = (uint)ColliderType.Projectile; sharedProjectile.PhysicsBody.CollisionBitMask = (uint)ColliderType.Wall; sharedProjectile.PhysicsBody.ContactTestBitMask = sharedProjectile.PhysicsBody.CollisionBitMask; sharedProjectileEmitter = GraphicsUtilities.EmitterNodeWithEmitterNamed("WarriorProjectile"); sharedIdleAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Warrior_Idle", "warrior_idle_", WarriorIdleFrames); sharedWalkAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Warrior_Walk", "warrior_walk_", DefaultNumberOfWalkFrames); sharedAttackAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Warrior_Attack", "warrior_attack_", WarriorThrowFrames); sharedGetHitAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Warrior_GetHit", "warrior_getHit_", WarriorGetHitFrames); sharedDeathAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Warrior_Death", "warrior_death_", WarriorDeathFrames); sharedDamageAction = SKAction.Sequence(new [] { SKAction.ColorizeWithColor(whiteColor, 10, 0), SKAction.WaitForDuration(0.5), SKAction.ColorizeWithColorBlendFactor(0, 0.25) }); }
public override nfloat DistanceToWall(CGPoint pos0, CGPoint pos1) { var a = ConvertWorldPointToLevelMapPoint(pos0); var b = ConvertWorldPointToLevelMapPoint(pos1); var deltaX = b.X - a.X; var deltaY = b.Y - a.Y; var dist = GraphicsUtilities.DistanceBetweenCGPoints(a, b); var inc = 1f / dist; var p = CGPoint.Empty; for (nfloat i = 0; i <= 1; i += inc) { p.X = a.X + i * deltaX; p.Y = a.Y + i * deltaY; DataMap point = levelMap.QueryLevelMap(p); if (point.Wall > 200) { CGPoint wpos2 = ConvertLevelMapPointToWorldPoint(p); return(GraphicsUtilities.DistanceBetweenCGPoints(pos0, wpos2)); } } return(nfloat.MaxValue); }
public void Generate() { if (GoblinCap <= 0 || sGlobalAllocation >= GoblinCap) { return; } Goblin character = inactiveGoblins [inactiveGoblins.Count - 1]; if (character == null) { return; } var offset = CollisionRadius * 0.75f; var rot = GraphicsUtilities.PalarAdjust(VirtualZRotation); var pos = new CGPoint((float)Math.Cos(rot) * offset, (float)Math.Sin(rot) * offset); character.Position = new CGPoint(pos.X + Position.X, pos.Y + Position.Y); MultiplayerLayeredCharacterScene scene = CharacterScene; character.AddToScene(CharacterScene); character.ZPosition = -1f; character.FadeIn(0.5f); inactiveGoblins.Remove(character); ActiveGoblins.Add(character); sGlobalAllocation++; }
public void MoveTowards(CGPoint position, double timeInterval) { CGPoint curPosition = Position; var dx = position.X - curPosition.X; var dy = position.Y - curPosition.Y; var ds = MovementSpeed * (float)timeInterval; var angle = GraphicsUtilities.RadiansBetweenCGPoints(position, curPosition); angle = GraphicsUtilities.PalarAdjust(angle); ZRotation = angle; var distRemaining = GraphicsUtilities.Hypotenuse(dx, dy); if (distRemaining < ds) { Position = position; } else { var x = (float)(curPosition.X - Math.Sin(angle) * ds); var y = (float)(curPosition.Y + Math.Cos(angle) * ds); Position = new CGPoint(x, y); } RequestedAnimation = AnimationState.Walk; }
protected HeroCharacter AddHeroFor(Player player) { if (player == null) { throw new ArgumentNullException("player", "Player should not be null"); } if (player.Hero != null && !player.Hero.Dying) { player.Hero.RemoveFromParent(); } CGPoint spawnPos = DefaultSpawnCGPoint; HeroCharacter hero = CreateHeroBy(player.HeroType, spawnPos, player); if (hero != null) { var emitter = (SKEmitterNode)SharedSpawnEmitter.Copy(); emitter.Position = spawnPos; AddNode(emitter, WorldLayer.AboveCharacter); GraphicsUtilities.RunOneShotEmitter(emitter, 0.15f); hero.FadeIn(2f); hero.AddToScene(this); Heroes.Add(hero); } player.Hero = hero; return(hero); }
void OnDidBeginContact(object sender, EventArgs e) { var contact = (SKPhysicsContact)sender; // Either bodyA or bodyB in the collision could be a character. var node = contact.BodyA.Node as Character; if (node != null) { node.CollidedWith(contact.BodyB); } // Check bodyB too. node = contact.BodyB.Node as Character; if (node != null) { node.CollidedWith(contact.BodyA); } // Handle collisions with projectiles. var isBodyA = (contact.BodyA.CategoryBitMask & (uint)ColliderType.Projectile) != 0; var isBodyB = (contact.BodyB.CategoryBitMask & (uint)ColliderType.Projectile) != 0; if (isBodyA || isBodyB) { SKNode projectile = isBodyA ? contact.BodyA.Node : contact.BodyB.Node; projectile.RunAction(SKAction.RemoveFromParent()); // Build up a "one shot" particle to indicate where the projectile hit. var emitter = (SKEmitterNode)SharedProjectileSparkEmitter.Copy(); AddNode(emitter, WorldLayer.AboveCharacter); emitter.Position = projectile.Position; GraphicsUtilities.RunOneShotEmitter(emitter, 0.15f); } }
public static void LoadSharedAssetsOnce() { #if __IOS__ var whiteColor = UIColor.White; #else NSColor whiteColor = null; new NSObject().InvokeOnMainThread(() => { whiteColor = NSColor.White; }); #endif SKTextureAtlas atlas = SKTextureAtlas.FromName("Environment"); sharedIdleAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Goblin_Idle", "goblin_idle_", DefaultNumberOfIdleFrames); sharedWalkAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Goblin_Walk", "goblin_walk_", DefaultNumberOfWalkFrames); sharedAttackAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Goblin_Attack", "goblin_attack_", GoblinAttackFrames); sharedGetHitAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Goblin_GetHit", "goblin_getHit_", GoblinGetHitFrames); sharedDeathAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Goblin_Death", "goblin_death_", GoblinDeathFrames); sharedDamageEmitter = GraphicsUtilities.EmitterNodeWithEmitterNamed("Damage"); sharedDeathSplort = SKSpriteNode.FromTexture(atlas.TextureNamed("minionSplort.png")); sharedDamageAction = SKAction.Sequence(new [] { SKAction.ColorizeWithColor(whiteColor, 1, 0), SKAction.WaitForDuration(0.75f), SKAction.ColorizeWithColorBlendFactor(0, 0.1) }); }
public void MoveInDirection(CGPoint direction, double timeInterval) { var curPosition = Position; var dx = MovementSpeed * direction.X; var dy = MovementSpeed * direction.Y; var ds = MovementSpeed * (float)timeInterval; var targetPosition = new CGPoint(curPosition.X + dx, curPosition.Y + dy); var angle = GraphicsUtilities.RadiansBetweenCGPoints(targetPosition, curPosition); var ang = GraphicsUtilities.PalarAdjust(angle); ZRotation = ang; var distRemaining = GraphicsUtilities.Hypotenuse(dx, dy); if (distRemaining < ds) { Position = targetPosition; } else { float x = (float)(curPosition.X - Math.Sin(ang) * ds); float y = (float)(curPosition.Y + Math.Cos(ang) * ds); Position = new CGPoint(x, y); } // Don't change to a walk animation if we planning an attack. if (!Attacking) { RequestedAnimation = AnimationState.Walk; } }
protected override void LoadSceneAssets() { SKTextureAtlas atlas = SKTextureAtlas.FromName("Environment"); // Load archived emitters and create copyable sprites. sharedProjectileSparkEmitter = GraphicsUtilities.EmitterNodeWithEmitterNamed("ProjectileSplat"); sharedSpawnEmitter = GraphicsUtilities.EmitterNodeWithEmitterNamed("Spawn"); sharedSmallTree = new Tree(new SKNode[] { SKSpriteNode.FromTexture(atlas.TextureNamed("small_tree_base.png")), SKSpriteNode.FromTexture(atlas.TextureNamed("small_tree_middle.png")), SKSpriteNode.FromTexture(atlas.TextureNamed("small_tree_top.png")) }, 25); sharedBigTree = new Tree(new SKNode[] { SKSpriteNode.FromTexture(atlas.TextureNamed("big_tree_base.png")), SKSpriteNode.FromTexture(atlas.TextureNamed("big_tree_middle.png")), SKSpriteNode.FromTexture(atlas.TextureNamed("big_tree_top.png")) }, 150); sharedBigTree.FadeAlpha = true; sharedLeafEmitterA = GraphicsUtilities.EmitterNodeWithEmitterNamed("Leaves_01"); sharedLeafEmitterB = GraphicsUtilities.EmitterNodeWithEmitterNamed("Leaves_02"); // Load the tiles that make up the ground layer. LoadWorldTiles(); // Load assets for all the sprites within this scene. Cave.LoadSharedAssetsOnce(); HeroCharacter.LoadSharedAssetsOnce(); Archer.LoadSharedAssetsOnce(); Warrior.LoadSharedAssetsOnce(); Goblin.LoadSharedAssetsOnce(); Boss.LoadSharedAssetsOnce(); }
public void FaceTo(CGPoint position) { var angle = GraphicsUtilities.RadiansBetweenCGPoints(position, Position); var ang = GraphicsUtilities.PalarAdjust(angle); SKAction action = SKAction.RotateToAngle(ang, 0); RunAction(action); }
public override void DidSimulatePhysics() { base.DidSimulatePhysics(); // Get the position either of the default hero or the hero spawn point. HeroCharacter defaultHero = DefaultPlayer.Hero; CGPoint position; if (defaultHero != null && Heroes.Contains(defaultHero)) { position = defaultHero.Position; } else { position = DefaultSpawnCGPoint; } // Update the alphas of any trees that are near the hero (center of the camera) and therefore visible or soon to be visible. foreach (Tree tree in trees) { if (GraphicsUtilities.DistanceBetweenCGPoints(tree.Position, position) < 1024) { tree.UpdateAlphaWithScene(this); } } if (!WorldMovedForUpdate) { return; } // Show any nearby hidden particle systems and hide those that are too far away to be seen. foreach (SKEmitterNode particles in particleSystems) { bool particlesAreVisible = GraphicsUtilities.DistanceBetweenCGPoints(particles.Position, position) < 1024; if (!particlesAreVisible && !particles.Paused) { particles.Paused = true; } else if (particlesAreVisible && particles.Paused) { particles.Paused = false; } } // Update nearby parallax sprites. foreach (ParallaxSprite sprite in parallaxSprites) { if (GraphicsUtilities.DistanceBetweenCGPoints(sprite.Position, position) >= 1024) { continue; } sprite.UpdateOffset(); } }
public override void UpdateWithTimeSinceLastUpdate(double interval) { if (Character.Dying) { Target = null; return; } var position = Character.Position; MultiplayerLayeredCharacterScene scene = Character.CharacterScene; nfloat closestHeroDistance = float.MaxValue; // Find the closest living hero, if any, within our alert distance. foreach (HeroCharacter hero in scene.Heroes) { var heroPosition = hero.Position; var distance = GraphicsUtilities.DistanceBetweenCGPoints(position, heroPosition); if (distance < EnemyAlertRadius && distance < closestHeroDistance && !hero.Dying) { closestHeroDistance = distance; Target = hero; } } // If there's no target, don't do anything. if (Target == null) { return; } // Otherwise chase or attack the target, if it's near enough. var heroPos = Target.Position; float chaseRadius = ChaseRadius; if (closestHeroDistance > MaxAlertRadius) { Target = null; } else if (closestHeroDistance > ChaseRadius) { Character.MoveTowards(heroPos, interval); } else if (closestHeroDistance < ChaseRadius) { Character.FaceTo(heroPos); Character.PerformAttackAction(); } }
public override void UpdateWithTimeSinceLastUpdate(double interval) { Cave cave = (Cave)Character; if (cave.Health <= 0) { return; } MultiplayerLayeredCharacterScene scene = cave.CharacterScene; nfloat closestHeroDistance = MinimumHeroDistance; var closestHeroPosition = CGPoint.Empty; var cavePosition = cave.Position; foreach (SKNode hero in scene.Heroes) { var heroPosition = hero.Position; var distance = GraphicsUtilities.DistanceBetweenCGPoints(cavePosition, heroPosition); if (distance < closestHeroDistance) { closestHeroDistance = distance; closestHeroPosition = heroPosition; } } var distScale = closestHeroDistance / MinimumHeroDistance; // Generate goblins more quickly if the closest hero is getting closer. cave.TimeUntilNextGenerate -= (float)interval; // Either time to generate or the hero is so close we need to respond ASAP! int goblinCount = cave.ActiveGoblins.Count; if (goblinCount < 1 || cave.TimeUntilNextGenerate <= 0 || (distScale < 0.35f && cave.TimeUntilNextGenerate > 5)) { if (goblinCount < 1 || (goblinCount < 4 && closestHeroPosition != CGPoint.Empty) && scene.CanSee(closestHeroPosition, cave.Position)) { cave.Generate(); } cave.TimeUntilNextGenerate = 4 * distScale; } }
public override void Initialize() { base.Initialize(); // Build level and tree maps from map_collision.png and map_foliage.png respectively. levelMap = GraphicsUtilities.CreateMapScaner("map_level.png"); treeMap = GraphicsUtilities.CreateMapScaner("map_trees.png"); Cave.GoblinCap = 32; BuildWorld(); // Center the camera on the hero spawn point. var startPosition = DefaultSpawnCGPoint; CenterWorld(startPosition); }
public static void LoadSharedAssetsOnce() { #if __IOS__ var whiteColor = UIColor.White; #else NSColor whiteColor = null; new NSObject().InvokeOnMainThread(() => { whiteColor = NSColor.White; }); #endif SKTextureAtlas atlas = SKTextureAtlas.FromName("Environment"); SKEmitterNode fire = GraphicsUtilities.EmitterNodeWithEmitterNamed("CaveFire"); fire.ZPosition = 1; SKEmitterNode smoke = GraphicsUtilities.EmitterNodeWithEmitterNamed("CaveFireSmoke"); var sKNode = new SKNode(); sKNode.Add(fire); sKNode.Add(smoke); SKNode torch = sKNode; sharedCaveBase = SKSpriteNode.FromTexture(atlas.TextureNamed("cave_base.png")); // Add two torches either side of the entrance. torch.Position = new CGPoint(83, 83); sharedCaveBase.AddChild(torch); var torchB = (SKNode)torch.Copy(); torchB.Position = new CGPoint(-83, 83); sharedCaveBase.AddChild(torchB); sharedCaveTop = SKSpriteNode.FromTexture(atlas.TextureNamed("cave_top.png")); sharedDeathSplort = SKSpriteNode.FromTexture(atlas.TextureNamed("cave_destroyed.png")); sharedDamageEmitter = GraphicsUtilities.EmitterNodeWithEmitterNamed("CaveDamage"); sharedDeathEmitter = GraphicsUtilities.EmitterNodeWithEmitterNamed("CaveDeathSmoke"); sharedDamageAction = SKAction.Sequence(new [] { SKAction.ColorizeWithColor(whiteColor, 1, 0), SKAction.WaitForDuration(0.25), SKAction.ColorizeWithColorBlendFactor(0, 0.1), }); }
// Apply damage and return true if death. public virtual bool ApplyDamage(nfloat damage) { Health -= damage; if (Health <= 0) { PerformDeath(); return(true); } var emitter = (SKEmitterNode)DamageEmitter.Copy(); CharacterScene.AddNode(emitter, WorldLayer.AboveCharacter); emitter.Position = Position; GraphicsUtilities.RunOneShotEmitter(emitter, 0.15f); // Show the damage. RunAction(DamageAction); return(false); }
public static void LoadSharedAssetsOnce() { #if __IOS__ var whiteColor = UIColor.White; #else NSColor whiteColor = null; new NSObject().InvokeOnMainThread(() => { whiteColor = NSColor.White; }); #endif sharedIdleAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Boss_Idle", "boss_idle_", BossIdleFrames); sharedWalkAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Boss_Walk", "boss_walk_", BossWalkFrames); sharedAttackAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Boss_Attack", "boss_attack_", BossAttackFrames); sharedGetHitAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Boss_GetHit", "boss_getHit_", BossGetHitFrames); sharedDeathAnimationFrames = GraphicsUtilities.LoadFramesFromAtlas("Boss_Death", "boss_death_", BossDeathFrames); sharedDamageEmitter = GraphicsUtilities.EmitterNodeWithEmitterNamed("BossDamage"); sharedDamageAction = SKAction.Sequence(new [] { SKAction.ColorizeWithColor(whiteColor, 1, 0), SKAction.WaitForDuration(0.5), SKAction.ColorizeWithColorBlendFactor(0, 0.1) }); }
public override void AnimationDidComplete(AnimationState animation) { switch (animation) { case AnimationState.Death: var emitter = (SKEmitterNode)DeathEmitter.Copy(); emitter.ZPosition = -0.8f; AddChild(emitter); GraphicsUtilities.RunOneShotEmitter(emitter, 4.5f); RunAction(SKAction.Sequence(new [] { SKAction.WaitForDuration(4), SKAction.Run(() => CharacterScene.HeroWasKilled(this)), SKAction.RemoveFromParent() })); break; case AnimationState.Attack: FireProjectile(); break; } }
public void UpdateAlphaWithScene(MultiplayerLayeredCharacterScene scene) { if (scene == null) { throw new ArgumentNullException("scene"); } if (!FadeAlpha) { return; } nfloat closestHeroDistance = nfloat.MaxValue; // See if there are any heroes nearby. var ourPosition = Position; foreach (SKNode hero in scene.Heroes) { var theirPos = hero.Position; var distance = GraphicsUtilities.DistanceBetweenCGPoints(ourPosition, theirPos); closestHeroDistance = (nfloat)Math.Min(distance, closestHeroDistance); } if (closestHeroDistance > OpaqueDistance) { // No heroes nearby. Alpha = 1; } else { // Adjust the alpha based on how close the hero is. var ratio = closestHeroDistance / OpaqueDistance; Alpha = 0.1f + ratio * ratio * 0.9f; } }
void ConfigureController(GCController controller, Player player) { Console.WriteLine("Assigning {0} to player {1} [{2}]", controller.VendorName, player, players.IndexOf(player)); // Assign the controller to the player. player.Controller = controller; GCControllerDirectionPadValueChangedHandler dpadMoveHandler = (dpad, xValue, yValue) => { var length = GraphicsUtilities.Hypotenuse(xValue, yValue); if (length > 0f) { var invLength = 1 / length; player.HeroMoveDirection = new CGPoint(xValue * invLength, yValue * invLength); } else { player.HeroMoveDirection = CGPoint.Empty; } }; // Use either the dpad or the left thumbstick to move the character. controller.ExtendedGamepad.LeftThumbstick.ValueChangedHandler = dpadMoveHandler; controller.Gamepad.DPad.ValueChangedHandler = dpadMoveHandler; GCControllerButtonValueChanged fireButtonHandler = (button, value, pressed) => { player.FireAction = pressed; }; controller.Gamepad.ButtonA.SetValueChangedHandler(fireButtonHandler); controller.Gamepad.ButtonB.SetValueChangedHandler(fireButtonHandler); if (player != DefaultPlayer && player.Hero == null) { AddHeroFor(player); } }
public override bool CanSee(CGPoint pos0, CGPoint pos1) { var a = ConvertWorldPointToLevelMapPoint(pos0); var b = ConvertWorldPointToLevelMapPoint(pos1); var deltaX = b.X - a.Y; var deltaY = b.Y - a.Y; var dist = GraphicsUtilities.DistanceBetweenCGPoints(a, b); var inc = 1 / dist; var p = CGPoint.Empty; for (nfloat i = 0; i <= 1; i += inc) { p.X = a.X + i * deltaX; p.Y = a.Y + i * deltaY; DataMap point = levelMap.QueryLevelMap(p); if (point.Wall > 200) { return(false); } } return(true); }
public override void Update(double currentTime) { // Handle time delta. // If we drop below 60fps, we still want everything to move the same distance. double timeSinceLast = currentTime - lastUpdateTimeInterval; lastUpdateTimeInterval = currentTime; // more than a second since last update if (timeSinceLast > 1) { timeSinceLast = MIN_TIME_INTERVAL; WorldMovedForUpdate = true; } UpdateWithTimeSinceLastUpdate(timeSinceLast); var defaultPlayer = DefaultPlayer; HeroCharacter hero = Heroes.Count > 0 ? defaultPlayer.Hero : null; #if __IOS__ if (hero != null && !hero.Dying && defaultPlayer.TargetLocation != CGPoint.Empty) { if (defaultPlayer.FireAction) { hero.FaceTo(defaultPlayer.TargetLocation); } if (defaultPlayer.MoveRequested) { if (defaultPlayer.TargetLocation != hero.Position) { hero.MoveTowards(defaultPlayer.TargetLocation, timeSinceLast); } else { defaultPlayer.MoveRequested = false; } } } #endif foreach (var player in players) { if (player == null) { continue; } hero = player.Hero; if (hero == null || hero.Dying) { continue; } // heroMoveDirection is used by game controllers. CGPoint heroMoveDirection = player.HeroMoveDirection; if (GraphicsUtilities.Hypotenuse(heroMoveDirection.X, heroMoveDirection.Y) > 0f) { hero.MoveInDirection(heroMoveDirection, timeSinceLast); } else { if (player.MoveForward) { hero.Move(MoveDirection.Forward, timeSinceLast); } else if (player.MoveBack) { hero.Move(MoveDirection.Back, timeSinceLast); } if (player.MoveLeft) { hero.Move(MoveDirection.Left, timeSinceLast); } else if (player.MoveRight) { hero.Move(MoveDirection.Right, timeSinceLast); } } if (player.FireAction) { hero.PerformAttackAction(); } } }
public static void LoadSharedAssetsOnce() { sharedProjectileSoundAction = SKAction.PlaySoundFileNamed("magicmissile.caf", false); sharedDeathEmitter = GraphicsUtilities.EmitterNodeWithEmitterNamed("Death"); sharedDamageEmitter = GraphicsUtilities.EmitterNodeWithEmitterNamed("Damage"); }