Partial Classes, Enemies, Exceptions

Slides:



Advertisements
Verwante presentaties
Hoofdstuk 6: Controle structuren
Advertisements

Inleiding Informatica Prof. Dr. O. De Troyer Hoofdstuk 10: Omgaan met problemen.
Hoofdstuk 2 Hallo, C# !.
Hoorcollege 14 Vijanden, excepties. Wat zit allemaal in een level? Startpositie van de speler Waterdruppels Tiles Vijanden Einde van het level Achtergronden.
Laatste toets Vrijdag 8 november van 8.30 – uur Locatie: EDUC-BETA Stof: Alles! Slides Boek Werkcollegeopgaven Practicumopgaven.
1 Datastructuren Introductie tot de programmeeropgaven in C++ Jan van Rijn
Opgave 2a nMet een InputStream lees je bytes uit een binare file nMet een Reader lees je characters uit een tekstfile.
Hoorcollege 14 Vijanden, excepties. Overzicht programmaconstructies Opdrachten Toekenning Aanroep void-methode return-opdracht while-opdracht for(each)-opdracht.
Hoorcollege 4 Objecten en methoden. Eigen methode toevoegen class Painter : Game { public void HandleInput() { … } protected override void Update(GameTime.
tircms02-p les 1 Operating Systems practicum
Tircms03-p les 4 Klassen. Abstracte datatypes in C struct stack { char info[100]; int top; }; void reset(stack *s) { s->top = -1; } void push(stack *s,
Java Objectgeoriënteerd Programmeren in Java met BlueJ
Java Objectgeoriënteerd Programmeren in Java met BlueJ Hoofdstuk 7 Polymorfie en overerving © 2014, Gertjan Laan, versie 2.
Soorten programma’s nConsole- applicatie. Soorten programma’s nConsole- applicatie nWindows- applicatie.
Aangepaste timing nTheorie (16 colleges + 2 deeltentamens) nPraktijk (16 keer, 3 inleveropdrachten) college Tent. 1 Tent. 3 college prakt. 1 prakt. 3 prakt.
Java voor beginners Doel: Een spel maken in LWJGL Door: Jim van Leeuwen.
Informatie beoordelen If else Switch En Wiskunde.
Animatie & Game Physics
Game Object Structuren
Objectgeoriënteerd Programmeren (2)
Aanroep van een methode voert opdrachten uit in de body daarvan
ISensorEventListener
Gameprogrammeren: Objecten en geheugen
Gameprogrammeren: Game Assets
Gameprogrammeren: Lists en interfaces
Gameprogrammeren: Keuzeopdrachten
Gameprogrammeren: Introductie
Gameprogrammeren: Overerving
Hoofdstuk 9.2 Strings.
Gameprogrammeren: Char en String
Arjan Egges & Paul Bergervoet
Gameprogrammeren: Expressies
Gameprogrammeren: Animatie
Gameprogrammeren: Methoden
Arjan Egges & Paul Bergervoet
vandaag èn vrijdag deadline maandag 12 dec.
Gameprogrammeren: Overerving in Painter
Gameprogrammeren: Player input in Painter
Tinpro015b-les 1 C++ voor C-kenners Voor Technische Informatica.
Basis Gameprogrammeren
Gameprogrammeren: Tiles in Tick Tick
Gameprogrammeren: Afsluiting
Gameprogrammeren: Willekeurigheid (Randomness)
Gameprogrammeren: Herhalingen
Gameprogrammeren: Platform-games
Gameprogrammeren: Properties
Arjan Egges & Paul Bergervoet
Gameprogrammeren: Game Basics
Game Assets, Invoer Verwerken
Arjan Egges & Paul Bergervoet
Voorbeeld: Simulatie van bewegende deeltjes
Voortborduren op eerder gedaan werk
Libraries, Platform Games
Gameprogrammeren: Recursie
Gameprogrammeren: Exceptions
Gameprogrammeren: Abstracte klassen
Willekeurigheid en Herhaling
Gameprogrammeren: Interfaces
Arjan Egges Paul Bergervoet Wouter van Toll
Gameprogrammeren: Tiles en File I/O in Tick Tick
Game: omgaan met tijd (Jewel-Jam)
Gameprogrammeren: Klassen en objecten
Arjan Egges & Paul Bergervoet
Implementatie Zoekboom
Object Communication (Jewel Jam)
Eerste deeltentamen Nagekeken werk ligt voor in de zaal
Gameprogrammeren: Enemies in Tick Tick
Gameprogrammeren: Sprite sheets
Software Development fundamentals
Gameprogrammeren: Arrays
Transcript van de presentatie:

Partial Classes, Enemies, Exceptions Arjan Egges & Paul Bergervoet

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 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

Omgaan met grote klassen Level is een vrij grote klasse Laden van een level De game loop Veel verschillende methoden Maar ook lastig/onhandig om in verschillende klassen op te delen Hoe kunnen we dit overzichtelijk houden? Gebruik partial classes

Partial classes Spreidt de klassedefinitie over meerdere files A_deel1.cs A.cs partial class A { // hier een deel van de // members, properties en // methoden van A. } class A { // heeeeeeel veel code . } A_deel2.cs partial class A { // hier de rest van de // members, properties en // methoden van A. }

Level en Player zijn partial classes Level.cs Membervariabelen Handige properties en methoden LevelLoading.cs Alle methoden om tiles mee te laden LevelGameLoop.cs Player.cs PlayerPhysics.cs

Rocket Vliegt naar links of naar rechts Verschijnt op een willekeurig moment Uitbreiding van AnimatedGameObject!

Rocket 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 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 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();

Turtle klasse 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); }

Level finished Overlay

‘Edit states’ Een edit state is een game state die gebruikt maakt van andere game states Voorbeelden: Game over state Level finished state …

Plaats de overlay in het midden LevelFinishedState class LevelFinishedState : GameObjectList { protected IGameLoopObject playingState; public LevelFinishedState() GameStateManager gm = GameEnvironment.GameStateManager; playingState = gm.GetGameState("playingState"); SpriteGameObject o = new SpriteGameObject(“spr_welldone"); o.Position = new Vector2(GameEnvironment.Screen.X, GameEnvironment.Screen.Y) / 2 - o.Center; this.Add(o); } … Plaats de overlay in het midden van het scherm.

LevelFinishedState public override void HandleInput(InputHelper inputHelper) { if (!inputHelper.KeyPressed(Keys.Space)) return; GameEnvironment.GameStateManager.SwitchTo("playingState"); (playingState as PlayingState).NextLevel(); } public override void Update(GameTime gameTime) { playingState.Update(gameTime); public override void Draw(GameTime gameTime, SpriteBatch s) { playingState.Draw(gameTime, s); base.Draw(gameTime, s);

Level afgemaakt? public bool Completed { get SpriteGameObject exitObj = this.Find("exit") as SpriteGameObject; Player player = this.Find("player") as Player; GameObjectList w = this.Find("waterdrops") as GameObjectList; if (!exitObj.CollidesWith(player)) return false; foreach (GameObject d in w.Objects) if (d.Visible) return true; } Speler heeft de uitgang nog niet bereikt Alle waterdruppels zijn nog niet verzameld

Update-actie van Level public override void Update(GameTime gameTime) { TimerGameObject timer = Find("timer") as TimerGameObject; Player player = Find("player") as Player; // check if we died … // check if we ran out of time // check if we won base.Update(gameTime); }

Update-actie van Level // check if we died if (!player.IsAlive) timer.Running = false; // check if we ran out of time if (timer.GameOver) player.Explode(); // check if we won if (this.Completed && timer.Running) { player.LevelFinished(); }

public void Explode() { if (!isAlive || finished) return; isAlive = false; exploded = true; velocity = Vector2.Zero; position.Y += 15; this.PlayAnimation("explode"); } public void LevelFinished() { finished = true; velocity.X = 0.0f; this.PlayAnimation("celebrate"); GameEnvironment.AssetManager.playSound("snd_player_won");

Game development Van prototype naar commercieel product Robuustheid Meer levels, uitgebreider game ontwerp Professioneel ontworpen assets Goed opgezette programmacode Hoge mate van robuustheid Robuustheid Zoveel mogelijk bugs verwijderen Zoveel mogelijk gevallen/problemen ondervangen Testen, testen, testen!

Robuustheid Goed ontwerp van je code is cruciaal Duidelijke afspraken voor gedrag van methoden/klassen Zoveel mogelijk bugs verwijderen Zoveel mogelijk verschillende gevallen/problemen ondervangen Testen, testen, testen!

Software testen Verschillende soorten tests: Handmatig Automatisch (unit tests) Verschillende niveau’s van testen: Alpha test Intern Meestal alleen developers Beta test Extern Grotere groep spelers

Excepties Voorbeeld: StreamReader r = new StreamReader("test.txt"); string t = r.ReadToEnd(); // oops… the file test.txt doesn’t exist… Wat nu?

Excepties Zijn een manier om robuustheid van games te vergroten Excepties gebruik je om externe problemen op te lossen: Er mist een bestand De internetverbinding wordt verbroken Een andere speler gaat plotseling off-line …

Excepties Dit soort gevallen kun je afhandelen met excepties try { StreamReader r = new StreamReader("test.txt"); string t = r.ReadToEnd(); } catch (FileNotFoundException e) Console.WriteLine(“The file was not found”);

Excepties Meerdere catch-gedeelten voor verschillende soorten excepties try { StreamReader r = new StreamReader("test.txt"); string t = r.ReadToEnd(); } catch (FileNotFoundException e) Console.WriteLine("The file was not found"); catch (IOException e) Console.WriteLine("IOException during file read");

Excepties Exceptie klassen zijn georganiseerd in een hierarchie Bovenaan die hierarchie: de Exception klasse Dus de volgende catch handelt alle mogelijke excepties af: catch (Exception e) { Console.WriteLine("Unknown exception occurred"); }

Excepties Je kunt zelf ook een exceptie “werpen”: private Tile LoadTile(char tileType, int x, int y) { switch (tileType) case '.': return new Tile(); … default: throw new IOException("Unknown tile type"); }

Vertaalt exceptie naar string Excepties En die kun je ergens anders weer afhandelen try { char c = textlines[i][j]; tiles[i,j] = LoadTile(c, i, j); } catch (IOException e) Console.WriteLine("Exception: " + e.ToString()); Vertaalt exceptie naar string

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

Laatste toets Vrijdag 11 november van 11.00 – 13.00 uur Locatie: EDUC-GAMMA Stof: Alles! Slides Boek Werkcollegeopgaven Practicumopgaven

Een paar tips Wees kort en bondig Wees precies (termen zoals klasse, object, subklasse, variabele, declaratie, opdracht, toekenning niet door elkaar halen) Als je voor een methode meer dan het antwoordvak nodig hebt, dan doe je iets verkeerd Als je bepaalde stukken code vijf keer moet overschrijven, probeer eens een loop

Voorbereiding Programmeren leer je door te doen Doe de opgaven uit het boek Doe de toetsen van vorige jaren Probeer de problemen uit de practicumopgave nog eens zelf op te lossen (zonder partner!) Lees het boek goed door, en zorg dat je alle termen en verbanden snapt Rust goed uit

Wat hebben we zoal gedaan? De belangrijkste programmeerprincipes behandeld: Keuze, iteratie, loops Object-georienteerd-programmeren Arrays, strings, files Games programmeren: De game loop, botsingen afhandelen, game states, game objecten, … En natuurlijk zelf games maken!

Wat komt er nog? In de bachelor: Gameproject Toepassen van opgedane kennis Samenwerken in teamverband Vakken over databases, graphics, gameontwerp, en nog veel meer En dan zijn er ook nog masterprogramma’s: GMT, AI, COSC, …

Cursusevaluatie Wat vonden jullie ervan? Klopt het vak met jullie verwachtingen? Wat misten jullie? Wat moet vooral zo blijven? Vul het online evaluatieformulier in! https://caracal.science.uu.nl