Hoorcollege 5 Herhaling, game object interactie
Ball class class Ball { Texture2D colorRed, colorGreen, colorBlue; Texture2D currentColor; Vector2 position, velocity; Color color; bool shooting; // methoden en properties } De verfbal heeft twee toestanden
Ball invoer afhandelen public void HandleInput(InputHelper inputHelper) { if (inputHelper.MouseLeftButtonPressed() && !shooting) { shooting = true; velocity = (inputHelper.MousePosition - position) / 40; } “Je mag niet schieten tijdens het schieten” Bereken de snelheid aan de hand van de muispositie
Ball update public void Update(GameTime gameTime) { if (shooting) { velocity.X *= 0.99f; velocity.Y += 6f; position += velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; } else { Color = Painter.GameWorld.Cannon.Color; position = Painter.GameWorld.Cannon.BallPosition - Center; } if (Painter.GameWorld.IsOutsideWorld(position)) Reset(); } Luchtweerstand Zwaartekracht Hoe vinden we uit hoe groot de wereld is?
Scherm dimensies (Painter klasse) Bewaren we in een static member variabele: Initialisatie in LoadContent: En een (static) property om erbij te kunnen: static Point screen; screen = new Point(GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height); public static Point Screen { get { return screen; } }
IsOutsideWorld public bool IsOutsideWorld(Vector2 position) { return position.X Painter.Screen.X || position.Y > Painter.Screen.Y; } In de GameWorld klasse:
Klassen met meerdere instanties class PaintCan { … } PaintCan can1, can2, can3; Klassedefinitie: In de GameWorld klasse:
PaintCan Elke verfbus heeft: – Sprites – Positie – Snelheid – Kleur – Doelkleur – Minimumsnelheid class PaintCan { Texture2D colorRed, colorGreen, colorBlue; Texture2D currentColor; Vector2 position, velocity; Color color, targetcolor; float minVelocity; // methoden… } Gebruiken we om willekeurige snelheid te berekenen!
Willekeurigheid Een veelgebruikt concept in spellen – Een stapel kaarten in willekeurige volgorde leggen (ook wel ouderwets “schudden” genoemd) – Een bal een willekeurige richting op laten vliegen – Een vijand op een willekeurige plek in een spel “spawnen” – Levels genereren met een willekeurige structuur
Willekeurigheid Willekeurigheid vergroot het spelplezier – Iedere keer als je speelt, is het weer anders Tot nu toe hadden onze programma’s 100% voorspelbaar gedrag Hoe maken we een programma ‘willekeurig’? – Met behulp van een willekeurige getallengenerator!
Willekeurigheid Twee soorten random generatoren: Fysiek:Computationeel:
Willekeurigheid Bij computationele willekeurigheid gebruiken we vaak een ‘seed’ om aan te geven waar we beginnen in de tabel Voorbeelden van seeds: – Systeemtijd – De R-waarde van pixel (100,100) van het beeld van je webcam – De ID van het huidige proces in Windows
Willekeurigheid In XNA gebruiken we de Random-klasse: Met een maximumwaarde (resultaat < 100): Een double ipv. int (altijd tussen 0.0 en 1.0): Random r = new Random(); Console.WriteLine(r.Next()); Console.WriteLine(r.Next(100)); Console.WriteLine(r.NextDouble());
Willekeurigheid Het kiezen van een willekeurige snelheid voor een game object: Of kiezen welke speler begint: Random r = new Random(); Vector2 balSnelheid = new Vector2(r.Next(100), r.Next(100)); if (r.Next(2) == 0) this.beginnendeSpeler = “rood”; else this.beginnendeSpeler = “blauw”;
Painter klasse uitbreiden static Random member variabele: Met een (static) property om erbij te kunnen: static Random random; public static Random Random { get { return random; } }
Willekeurige snelheid in de PaintCan klasse Het bepalen van een willekeurige kleur: return new Vector2(0.0f, (float)Painter.Random.NextDouble() / 2 + minVelocity); public Color CalculateRandomColor() { int randomval = random.Next(3); if (randomval == 0) return Color.Red; else if (randomval == 1) return Color.Green; else return Color.Blue; } Random snelheid en kleur
public PaintCan(ContentManager Content, float positionOffset, Color targetcol) { this.colorRed = Content.Load ("spr_can_red"); this.colorGreen = Content.Load ("spr_can_green"); this.colorBlue = Content.Load ("spr_can_blue"); targetcolor = targetcol; minVelocity = 30; Color = Color.Blue; position = new Vector2(positionOffset, -currentColor.Height); velocity = Vector2.Zero; } PaintCan object maken
class GameWorld { Texture2D background; Ball ball; PaintCan can1, can2, can3; Cannon cannon; public GameWorld(ContentManager Content) { background = Content.Load ("spr_background"); cannon = new Cannon(Content); ball = new Ball(Content); can1 = new PaintCan(Content, 450.0f, Color.Red); can2 = new PaintCan(Content, 575.0f, Color.Green); can3 = new PaintCan(Content, 700.0f, Color.Blue); }...
Game objecten De Update methode: Draw-methode – Zie de voorbeeld code public void Update(GameTime gameTime) { ball.Update(gameTime); can1.Update(gameTime); can2.Update(gameTime); can3.Update(gameTime); }
public Ball Ball { get { return ball; } } public Cannon Cannon { get { return cannon; } } Handige properties
PaintCan object updaten if (velocity.Y == 0.0f && Painter.Random.NextDouble() < 0.01) { velocity = CalculateRandomVelocity(); Color = CalculateRandomColor(); } position += velocity * (float)gameTime.ElapsedGameTime.TotalSeconds;...
PaintCan object updaten (2)... Vector2 distanceVector = (Painter.GameWorld.Ball.Position + Painter.GameWorld.Ball.Center) - (position + Center); if (Math.Abs(distanceVector.X) < Center.X && Math.Abs(distanceVector.Y) < Center.Y) { Color = Painter.GameWorld.Ball.Color; Painter.GameWorld.Ball.Reset(); } if (Painter.GameWorld.IsOutsideWorld(position)) Reset(); minVelocity += 0.001f;
Herhaling Dezelfde code een aantal keer uitvoeren, met soms kleine verschillen. Bijvoorbeeld: – Een aantal keer een ‘leven’ of ‘resource’ sprite tekenen – Een lijst van game objecten langslopen en daar iets mee doen – Een highscore lijst afdrukken –...
while ( x<1000 ) x = 2*x; public override void Draw(GameTime gameTime) { int x; x = 1; spriteBatch.Draw( sprite, new Vector2(x, 10.0f), Color.White); } Opdrachten herhalen body wordt steeds opnieuw uitgevoerd zolang de voorwaarde geldig is X
int x, t; x=1; t=0; while ( x<1000 ) { x = 2*x; t = t+1; } Meer opdrachten herhalen return t; } n private static int Naam ( ) { accolades smeden twee opdrachten tot één body teller telt hoe vaak er wordt verdubbeld (int n)TweeLog
public void tekenLevens () { int t; t=0; while ( t<10 ) { Vector2 pos = new Vector2(t*heart.Width, 50.0f); spriteBatch.Draw(heart, pos, Color.White ); t = t+1; } Herhalen met een teller teller bepaalt het aantal herhalingen en komt goed van pas in de body
Publieksvraag Maak een methode macht met twee parameters – grondtal (reëel getal) – exponent(natuurlijk getal) die de waarde oplevert van grondtal exponent
while ( t<n ) { t = t+1 ; } t = 0; public double macht (double x, int n) { Machtsverhef-methode return result; result = result * x ; result = 1; int t; double result; }
Syntax van while opdracht
Gebruik van bool expressies Als voorwaarde van een while-opdracht Rechts van een toekenningsopdracht Als resultaat van een methode while (x<10)... bool b; b = x<10 ; return x<10 ;
Publieksvraag Schrijf een methode deelbaar, die antwoordt of x deelbaar is door d private static bool deelbaar (int x, int d) { } x%d == 0return ; waarheidswaarde als resultaat
Publieksvraag Schrijf een methode kleinsteDeler, die antwoordt wat de kleinste deler is van x public int kleinsteDeler (int x) { } int d; d = 2; while ( x%d != 0) d = d+1; return d ; probeer ze één voor één
Variabelen aanpassen Afgekorte notaties: x = x * 2 ; oude waarde wordt nieuwe waarde x = x * 2 ; x *= 2 ; x = x + 5 ; x += 5 ; x = x + 1 ; x += 1 ; x ++ ; wordt vermenigvuldigd met wordt vermeerderd met wordt opgehoogd
Herhaling met een teller int t ; t = 0; while ( t<x ) t ++ ; } { // doe iets nuttigs // met t for ( t=0 ; t<x ; t++ ) for t ++ ; t = 0;
for-opdracht eenmalige initialisatie int t ; for ( t=0 ; t<x ; t++ ) voorwaarde om door te gaan stap naar de volgende Console.WriteLine( "Kolom: " + t ); for ( t=1 ; t<=x ; t++ )for ( t=x ; t>=0 ; t -- )for ( t=2 ; !deelbaar(x,t) ; t++ )
Syntax van for opdracht
Herhaalde herhaling Body van een for-opdracht is een opdracht dat kan zelf ook een for-opdracht zijn! int x, y; for (y=0; y<10; y++) for (x=0; x<10; x++) { Vector2 pos = new Vector2( heart.Width*x, heart.Height*y); spriteBatch.Draw(heart, pos, Color.White); } y
Extreme gevallen Nul keer herhalen for (y=0; y<0; y++) spriteBatch.Draw(…); Oneindig vaak herhalen while (true) audio.Play( ); spriteBatch.Draw(…); deze opdracht komt nooit aan de beurt!
Onbedoelde oneindigheid x=1; aantal = 0; while (aantal<10) x = x*2; aantal = aantal+1; {}{} accolades vergeten...
Compiler-meldingen Foutmeldingen – variabele niet gedeclareerd – puntkomma vergeten –... Waarschuwingen – unreachable code – variable is never used – while-statement doesn’t terminate deze waarschuwing is theoretisch onmogelijk!
Het Halting-problem is onoplosbaar bool stopt (string filenaam) {.... } void gemeen (string filenaam) { while ( stopt(filenaam) ) x++; } stopt( "Gemeen.cs" ) wat komt er dan uit: ? Nietes! Deze methode lost het op: Ha! En dit dan?
Het Halting-problem is onoplosbaar Twee mogelijkheden: “Gemeen” stopt wel void gemeen (string filenaam) { while ( stopt(filenaam) ) x++; } stopt( "Gemeen.cs" ) “Gemeen” stopt niet...dus stopt levert true op...dus gemeen blijft hangen!...dus stopt levert false op...dus gemeen stopt direct! dus stopt kan helemaal niet bestaan tegenspraak!
Andere Halting -achtige problemen Wordt een opdracht ooit uitgevoerd? Is een programma een virus? en hoe werkt een virus-checker dan? òf te streng: keurt teveel af òf te coulant: laat sommige door lastig gevaarlijk
Overzicht programma-constructies Opdrachten Toekenning Aanroep void-methode return-opdracht while-opdracht for-opdracht {... } - bundeling if-opdracht Expressies Constante Variabele Aanroep methode Expressie met operatoren Expressie met haakjes new-expressie this (cast)-conversie kun je doenkun je uitrekenen
De volgende keer Afronding Painter Overerving Hoofdstukken 10 & 11 Let’s reorganize these bad boys…