Gameprogrammeren: Enemies in Tick Tick Arjan Egges Paul Bergervoet Wouter van Toll
Overzicht programmaconstructies kun je doen kun je uitrekenen Opdrachten Toekenning Aanroep void-methode return-opdracht while-opdracht for(each)-opdracht { ... }-bundeling if-opdracht switch-opdracht try-catch-opdracht throw-opdracht Expressies Constante Variabele Aanroep methode Expressie met operatoren Expressie met haakjes new-expressie this en base (cast)-conversie met haakjes of as
Wat zit allemaal in een level? Einde van het level Waterdruppels Vijanden Tiles Achtergronden Startpositie van de speler
Rocket Vliegt naar links of naar rechts Verschijnt op een willekeurig moment Uitbreiding van AnimatedGameObject!
Rocket-klasse class Rocket : AnimatedGameObject { protected double spawnTime; protected Vector2 startPosition; public Rocket(bool moveToLeft, Vector2 startPosition) this.LoadAnimation(”spr_rocket@3", "default", true, 0.2f); this.PlayAnimation("default"); this.Mirror = moveToLeft; this.startPosition = startPosition; Reset(); } ...
Rocket-klasse public override void Reset() { this.Visible = false; this.position = startPosition; this.velocity = Vector2.Zero; this.spawnTime = GameEnvironment.Random.NextDouble() * 5; } public void CheckPlayerCollision() Player player = GameWorld.Find("player") as Player; if (this.CollidesWith(player)) player.Die(false);
‘Die’-methode in Player public void Die(bool falling) { if (!isAlive) return; isAlive = false; velocity.X = 0; if (falling) GameEnvironment.AssetManager.PlaySound("snd_player_fall"); else velocity.Y = -900; GameEnvironment.AssetManager.PlaySound("snd_player_die"); } this.PlayAnimation("die");
Rocket-klasse public override void Update(GameTime gameTime) { base.Update(gameTime); if (spawnTime > 0) { spawnTime -= gameTime.ElapsedGameTime.TotalSeconds; return; } this.Visible = true; this.velocity.X = 600; if (Mirror) this.velocity.X *= -1f; CheckPlayerCollision(); Rectangle screenBox = new Rectangle(0, 0, GameEnvironment.Screen.X, GameEnvironment.Screen.Y); if (!screenBox.Intersects(this.BoundingBox)) this.Reset();
Vijanden Lopen heen en weer over de platforms Bij de randen wachten en omdraaien Hier een halve seconde wachten. En hier ook!
PatrollingEnemy-klasse PatrollingEnemy erft van AnimatedGameObject class PatrollingEnemy : AnimatedGameObject { protected float waitTime; public PatrollingEnemy() waitTime = 0.0f; velocity.X = 2.0f; LoadAnimation("Sprites/Flame/spr_flame@9", "default", true); PlayAnimation("default"); } ... Zijn we aan het wachten?
PatrollingEnemy-klasse Twee gevallen waarin de vijand moet stoppen met lopen en omdraaien Vijand kan niet verder vanwege blok tile. Vijand kan niet verder vanwege einde platform/blok. Tile type == Normal Tile type == Background
PatrollingEnemy-klasse public override void Update(GameTime gameTime) { base.Update(gameTime); if (waitTime > 0) waitTime -= (float)gameTime.ElapsedGameTime.TotalSeconds; if (waitTime <= 0.0f) TurnAround(); } else ... this.CheckPlayerCollision(); Wachten aan de randen afhandelen. Pas de wachttijd aan. Vijand moet de andere kant op lopen.
PatrollingEnemy-klasse public void TurnAround() { Mirror = !Mirror; this.velocity.X = 120; if (Mirror) this.velocity.X = -this.velocity.X; } public void CheckPlayerCollision() Player player = GameWorld.Find("player") as Player; if (this.CollidesWith(player)) player.Die(false); Animatie spiegelen en snelheid omdraaien Vijand botst met de speler
TileField tiles = GameWorld.Find("tiles") as TileField; if (waitTime > 0) { ... } else { TileField tiles = GameWorld.Find("tiles") as TileField; float posX = this.BoundingBox.Left; if (!Mirror) posX = this.BoundingBox.Right; int tileX = (int)Math.Floor(posX / tiles.CellWidth); int tileY = (int)(position.Y / tiles.CellHeight); if (tiles.GetTileType(tileX, tileY - 1) == TileType.Normal || tiles.GetTileType(tileX, tileY) == TileType.Background) waitTime = 0.5f; this.velocity.X = 0; } De vijand rent. De vijand loopt naar rechts. We zijn bij de rand aangekomen, dus wachten!
Variaties van PatrollingEnemy Vijand die de speler achtervolgt Vijand die willekeurig van looprichting verandert Gebruik overerving!
PlayerFollowingEnemy Update-methode wordt aangepast class PlayerFollowingEnemy : PatrollingEnemy { public override void Update(GameTime gameTime) Player player = GameWorld.Find("player") as Player; float direction = player.Position.X - position.X; if (Math.Sign(direction) != Math.Sign(velocity.X) && player.Velocity.X != 0.0f) TurnAround(); base.Update(gameTime); } Roep de originele versie aan voor de rest van het gedrag!
versie van de methode aan UnpredictableEnemy Update-methode wordt aangepast class UnpredictableEnemy : PatrollingEnemy { public override void Update(GameTime gameTime) base.Update(gameTime); if (waitTime > 0 || GameEnvironment.Random.NextDouble() > 0.01) return; TurnAround(); velocity.X = Math.Sign(velocity.X) * (float)GameEnvironment.Random.NextDouble() * 5.0f; } Roep weer de originele versie van de methode aan
Turtle Kun je gebruiken om hoger te springen Niest af en toe!
Turtle-klasse class Turtle : AnimatedGameObject { protected float sneezeTime, idleTime; public Turtle() { LoadAnimation("Sprites/Turtle/spr_sneeze@9","sneeze", false); LoadAnimation("Sprites/Turtle/spr_idle", "idle", true); PlayAnimation("idle"); Reset(); } public override void Reset() { sneezeTime = 0.0f; idleTime = 5.0f; ...
public override void Update(GameTime gameTime) { base.Update(gameTime); if (sneezeTime > 0) { this.PlayAnimation("sneeze"); sneezeTime-=(float)gameTime.ElapsedGameTime.TotalSeconds; if (sneezeTime <= 0.0f) { idleTime = 5.0f; sneezeTime = 0.0f; } } else if (idleTime > 0) { this.PlayAnimation("idle"); idleTime -= (float)gameTime.ElapsedGameTime.TotalSeconds; if (idleTime <= 0.0f) { idleTime = 0.0f; sneezeTime = 5.0f; CheckPlayerCollision();
public void CheckPlayerCollision() { Player player = GameWorld.Find("player") as Player; if (!this.CollidesWith(player)) return; if (sneezeTime > 0) player.Die(false); else if (idleTime > 0 && player.Velocity.Y > 0) player.Jump(1500); }
Sparky Valt soms naar beneden en is dan gevaarlijk
Sparky-klasse class Sparky : AnimatedGameObject { protected float idleTime, yoffset, initialY; public Sparky(float initialY) LoadAnimation("spr_electrocute@6x5", "electrocute", false); LoadAnimation("spr_idle", "idle", true); PlayAnimation("idle"); this.initialY = initialY; Reset(); } ...
public override void Update(GameTime gameTime) { base.Update(gameTime); if (idleTime <= 0) { this.PlayAnimation("electrocute"); if (this.velocity.Y != 0) { yoffset -= this.velocity.Y; this.position += this.velocity; if (yoffset <= 0) this.velocity.Y = 0; else if (yoffset >= 120.0f) this.Reset(); } else if (Current.AnimationEnded) this.velocity.Y = -60; } else if (idleTime > 0) { this.PlayAnimation("idle"); idleTime -= (float)gameTime.ElapsedGameTime.TotalSeconds; if (idleTime <= 0.0f) this.velocity.Y = 300; } CheckPlayerCollision();
Sparky klasse public void CheckPlayerCollision() { Player player = GameWorld.Find("player") as Player; if (this.CollidesWith(player) && idleTime <= 0.0f) player.Die(false); }