Willekeurigheid en Herhaling Arjan Egges & Paul Bergervoet
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 “Je mag niet schieten tijdens het schieten” public void HandleInput(InputHelper inputHelper) { if (inputHelper.MouseLeftButtonPressed() && !shooting) shooting = true; velocity = (inputHelper.MousePosition - position) / 40; } 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 In de GameWorld klasse: public bool IsOutsideWorld(Vector2 position) { return position.X < 0 || position.X > Painter.Screen.X || position.Y > Painter.Screen.Y; }
Klassen met meerdere instanties Klassedefinitie: In de GameWorld klasse: class PaintCan { … } PaintCan can1, can2, can3;
willekeurige snelheid 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; } }
Random snelheid en kleur 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; }
PaintCan object maken public PaintCan(ContentManager Content, float positionOffset, Color targetcol) { this.colorRed = Content.Load<Texture2D>("spr_can_red"); this.colorGreen = Content.Load<Texture2D>("spr_can_green"); this.colorBlue = Content.Load<Texture2D>("spr_can_blue"); targetcolor = targetcol; minVelocity = 30; Color = Color.Blue; position = new Vector2(positionOffset, -currentColor.Height); velocity = Vector2.Zero; }
class GameWorld { Texture2D background; Ball ball; PaintCan can1, can2, can3; Cannon cannon; public GameWorld(ContentManager Content) background = Content.Load<Texture2D>("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); }
Handige properties public Ball Ball { get { return ball; } } public Cannon Cannon get { return cannon; }
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 ...
Opdrachten herhalen zolang de voorwaarde geldig is public override void Draw(GameTime gameTime) { int x; x = 1; spriteBatch.Draw( sprite, new Vector2(x, 10.0f) , Color.White); } body wordt steeds opnieuw uitgevoerd while ( x<1000 ) x = 2*x; X 1024 512 256 128 64 16 32 4 1 2 8
Meer opdrachten herhalen private static int Naam ( ) { TweeLog (int n) int x, t; x=1; t=0; while ( x<1000 ) { x = 2*x; t = t+1; } teller telt hoe vaak er wordt verdubbeld n accolades smeden twee opdrachten tot één body return t; }
Herhalen met een teller 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; } 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 grondtalexponent
Machtsverhef-methode public double macht (double x, int n) { double result; int t; t = 0; result = 1; while ( t<n ) { t = t+1 ; } result = result * x ; return result; }
Syntax van while opdracht
Gebruik van bool expressies Als voorwaarde van een while-opdracht while (x<10) ... Rechts van een toekenningsopdracht bool b; b = x<10 ; Als resultaat van een methode return x<10 ;
waarheidswaarde als resultaat Publieksvraag Schrijf een methode deelbaar , die antwoordt of x deelbaar is door d waarheidswaarde als resultaat private static bool deelbaar (int x, int d) { } return ; x%d == 0
Publieksvraag Schrijf een methode kleinsteDeler , die antwoordt wat de kleinste deler is van x probeer ze één voor één public int kleinsteDeler (int x) { } int d; d = 2; while ( x%d != 0) d = d+1; return d ;
wordt vermenigvuldigd met Variabelen aanpassen x = x * 2 ; nieuwe waarde wordt oude waarde Afgekorte notaties: wordt vermenigvuldigd met x = x * 2 ; x *= 2 ; wordt vermeerderd met x = x + 5 ; x += 5 ; wordt opgehoogd x = x + 1 ; x += 1 ; x ++ ;
Herhaling met een teller int t ; t = 0; t = 0; for while ( t<x ) for ( t=0 ; t<x ; t++ ) { // doe iets nuttigs // met t t ++ ; t ++ ; }
for-opdracht int t ; for ( t=0 ; t<x ; t++ ) eenmalige initialisatie voorwaarde om door te gaan stap naar de volgende int t ; for ( t=0 ; t<x ; t++ ) 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
deze opdracht komt nooit aan de beurt! 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... { }
deze waarschuwing is theoretisch onmogelijk! 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 Nietes! Deze methode lost het op: bool stopt (string filenaam) { .... } void gemeen (string filenaam) { while ( stopt(filenaam) ) x++; } Ha! En dit dan? stopt( "Gemeen.cs" ) wat komt er dan uit: ?
Het Halting-problem is onoplosbaar stopt( "Gemeen.cs" ) void gemeen (string filenaam) { while ( stopt(filenaam) ) x++; } Twee mogelijkheden: “Gemeen” stopt wel ...dus stopt levert true op ...dus gemeen blijft hangen! “Gemeen” stopt niet tegenspraak! ...dus stopt levert false op ...dus gemeen stopt direct! dus stopt kan helemaal niet bestaan
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 kun je doen kun je uitrekenen 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