490 likes | 610 Views
Hoorcollege 4. Objecten en methoden. Eigen methode toevoegen. class Painter : Game { public void HandleInput () { … } protected override void Update( GameTime gameTime ) { HandleInput (); … } }. Eigen bedachte methode !. De ‘HandleInput’ methode.
E N D
Hoorcollege 4 Objecten en methoden
Eigen methode toevoegen class Painter : Game { public voidHandleInput() { … } protectedoverridevoidUpdate(GameTimegameTime) { HandleInput(); … } } Eigen bedachtemethode!
De ‘HandleInput’ methode public voidHandleInput() { prevMS = currMS; prevKS = currKS; currMS = Mouse.GetState(); currKS = Keyboard.GetState(); if (currKS.IsKeyDown(Keys.R) && prevKS.IsKeyUp(Keys.R)) cannonColor = Color.Red; else if (currKS.IsKeyDown(Keys.G) && prevKS.IsKeyUp(Keys.G)) cannonColor = Color.Green; else if (currKS.IsKeyDown(Keys.B) && prevKS.IsKeyUp(Keys.B)) cannonColor = Color.Blue; }
Verschillende soorten methoden • Methoden met een resultaat object: • Methoden zonder een resultaat object: • Methoden met parameters: • Methoden zonder parameters: currMS = Mouse.GetState(); GraphicsDevice.Clear(Color.Olive); currKS.IsKeyDown(Keys.G) spriteBatch.Begin()
Verschillende soorten methoden • Sommige methoden bewerken objecten • Sommige methoden bewerken geen objecten (maar horen wel bij een klasse) • Deze methoden noemen we static • In de methode header kun je zien wat voor soort methode het is! spriteBatch.Begin() Console.WriteLine("Hallo");
Methode headers public static voidMain() { … } public voidHandleInput() { … } protectedoverridevoidUpdate(GameTimegameTime) { … } methode zonder parameters methode zonder resultaatobject static methode (bewerktgeen object) methode met 1 parameter
Methoden met resultaat We stoppen er een float in... • Vergelijkbaar met wiskundige functie • f(x) = x2; • In het gebruik: ...en we levereneen float op. public floatCalculateSquare(float x) { return x*x; } Met returngeven we aan watopgeleverdwordt. float f = CalculateSquare(10.0f);
Methoden met resultaat public int SomeMethod() { return 12; inttmp = 45; } • Na eenreturnstopt de methode • Daarkunnen we gebruik van maken! Wordt nooit uitgevoerd! public floatSquareRoot(float f) { if (f < 0.0f) return 0.0f; // Hier weten we nu zeker dat altijd geldt dat f >= 0 }
Methoden met resultaat • Return waarde kunnen we in een variabele bewaren: • Maar dat hoeft niet! float f = CalculateSquare(10.0f); if (CalculateSquare(10.0f) != 100.0f) Console.WriteLine("Your processor is broken");
Tekenen of opleveren? • Console.Writeline (x, ...) • spriteBatch.Draw(cannon, Vector2.Zero,...) • return x; resultaatkomtmeteen op het scherm resultaatwordtteruggegevenaan deaanroeper, die zelfkanbeslissenwathijermeedoet
Declaraties vs. parameters • Lijken erg op elkaar public floatSquareRoot(floatf) { if (f < 0.0f) return 0.0f; … } Gebruiken we als locale variabele Locale variabele protectedoverridevoidUpdate(GameTimegameTime) { int red; red = gameTime.TotalGameTime.Milliseconds; … }
Methoden • Hoe meer parameters, des te flexibeler de methode public void Draw(Texture2D sprite, Vector2 position, Color col, float rotation, float scale, boolmirror, float transparency, Rectangle part, Vector2 origin, Rectangle destination, …) { … en des telastigeraanteroepen...
Veel parameters: Nu lastig om te programmeren In de toekomstmisschien gemakkelijkuit te breiden Weinig parameters: Nu gemakkelijk om te programmeren In de toekomstmisschien lastigte onderhouden Flexibiliteit
Programma en geheugen opdrachten variabelen veranderen zijn gegroepeerd in zijngegroepeerd in methoden objecten bewerken zijngegroepeerd in hebbenals type klasse klasse klasse
Objecten en geheugen • Built-in types in het geheugen - Numerieke typen (int, double, ...) - Tekst (strings) - Waarheidswaarden inti = 12; double pi = 3.14; i 12 pi 3.14 string s = "hallo, "; s += "Arjan"; s "hallo, " b "hallo, Arjan" true bool b = true; b = !b; false
Objecten en geheugen • Gevolg: public void keerTwee(inti) { i *= 2; } public void keerTwee(intgetal) { getal *= 2; } inti = 3; keerTwee(i); // wat is nu de waarde van i? Nog steeds 3, want de waardewordtgekopieerd bij het doorgevenaan de keerTweemethode!
Objecten en geheugen cannonBarrel • Typen die gebaseerd zijn op een klasse werken anders Texture2D verwijzing! width … height … data … …
Waarom verwijzingen? • Bij een aanroep van een methode wordt niet het hele geheugen gekopieerd, alleen de verwijzing • Objecten kunnen worden doorgegeven tussen methoden
Verwijzingen • Built-in types (int, double, float) • Values • Speciaalgeval: string “non-mutable” • Object-typengedefinieerd door klassen • References (verwijzingen) • Object-typengedefinieerd door structs • Values (!) • Wordtgebruiktvoorsimpeledatastructuren • Voorbeelden: Vector2, Point, Color…
Creatie van objecten • Opbouw van objectis gespecificeerd in de klasse class Painter { : Game GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Texture2D background, cannonBarrel; Vector2 barrelPosition, barrelOrigin; float angle; // methoden... Overgeërfduit de Game-klasse Painter game GraphicsDevice IsMouseVisible Content barrelPosition angle barrelOrigin graphics } spriteBatch background cannonBarrel
Painter geërfd van Game zelf gedeclareerd game
SpriteBatch GraphicsDeviceManager Painter game graphics barrelPosition barrelOrigin spriteBatch 72 34 Texture2D Texture2D background 405 34 angle cannonBarrel 0
De Cannon klasse • Groepeer alle member variabelen die bij het kannon horen in een klasse Cannon classCannon { Texture2D cannonBarrel; Texture2D colorRed, colorGreen, colorBlue; Texture2D currentColor; Vector2 position; Vector2 barrelOrigin, colorOrigin; Color color; float angle; // methoden worden nog toegevoegd. }
Declaratie Declaratie reserveert geheugenruimte • Vooreenprimitievewaarde zoals be- schreven in struct Vector2 int x; 5 x x = 5; zoals be- schreven in klasse SpriteBatch • Vooreen object-waarde p Vector2 p; X 0 10 p = new Vector2(10,20); Y 0 20 • Vooreen object-verwijzing SpriteBatch s; s s = new SpriteBatch(…);
Constructie van nieuw object • Geheugenruimteklaarzetten new-expressie doet twee dingen: cannon cannon = new Cannon (…) ; position color 72 405 0 Texture2D 0 cannonBarrel 255 • Constructormethodeaanroepen … Cannon waarde is pijl naar het nieuwe object die je kunt opslaan
public Cannon(ContentManager Content) { this.cannonBarrel = Content.Load<Texture2D>("spr_cannon_barrel"); this.colorRed = Content.Load<Texture2D>("spr_cannon_red"); this.colorGreen = Content.Load<Texture2D>("spr_cannon_green"); this.colorBlue = Content.Load<Texture2D>("spr_cannon_blue"); this.currentColor = colorBlue; color = Color.Blue; barrelOrigin = new Vector2(cannonBarrel.Height, cannonBarrel.Height) / 2; colorOrigin = new Vector2(currentColor.Width, currentColor.Height) / 2; position = new Vector2(72, 405); } Geen return type! Parameter(s) van de constructormethode Member- variabelen krijgeneen waarde.
Constructie van een nieuw object classPainter : Game { ... Cannoncannon; ... protected override LoadContent() { spriteBatch = new SpriteBatch(GraphicsDevice); background = Content.Load<Texture2D>("spr_background"); } ... } Membervariabele Informatiedoorgeven via parameters! cannon = new Cannon(Content);
null • Als een variabele nog nergens naar wijst, dan zeggen we dat de variabele null is: • Dit kunnen we zelfs in condities gebruiken: • Of korter: Cannon cannon; if (cannon == null) cannon = new Cannon(Content); nullmaptnaar de booleanwaardefalse if (!cannon) cannon = new Cannon(Content);
r 255 g 255 b 0 w 100 h a l l o ! h 20 aantal 3 prijs 199.95 Objecten • Object: groepje variabelendat bij elkaar hoort
Objecten "vraag niet hoe het kan... " • Om een object tegebruiken,hoef je niettewetenuitwelkevariabelen het object bestaat "maar profiteer ervan! " • Je hoeftalleenteweten • - welkemethodenerzijn • - welkepropertieserzijn
Game objecten ontwerpen • Watdoeteen game object? • Invoer van de spelerafhandelen • Zichzelfbijwerken (update) • Zichzelftekenen (draw) • Bijbehorendemethoden: • HandleInput • Update • Draw • Daarnaast: • Reset
Methoden in Cannon public void Draw(GameTimegameTime, SpriteBatchspriteBatch) { spriteBatch.Draw(cannonBarrel, position, null, Color.White, angle, barrelOrigin, 1f, SpriteEffects.None, 0); spriteBatch.Draw(currentColor, position, null, Color.White, 0f, colorOrigin, 1f, SpriteEffects.None, 0); } public void Reset() { currentColor = colorBlue; color = Color.Blue; angle = 0.0f; }
Property voor lezen positie public Vector2 Position { get { return position; } } Naam van de property Type van de property • Zogebruiken we de property: Property lezen Vector2 cannonPos = cannon.Position;
public Color Color { get { return color; } set { if (value != Color.Red && value != Color.Green && value != Color.Blue) return; color = value; if (color == Color.Red) currentColor = colorRed; else if (color == Color.Green) currentColor = colorGreen; else if (color == Color.Blue) currentColor = colorBlue; } } Controleren of het wel mag. value bevat de rechterkant van de toekenning Property lezen Property schrijven
Properties • Sommige properties mag je alleen lezen • String.Length • Viewport.Width • Sommige properties mag je ook schrijven • Vector2.X • Content.RootDirectory • Cannon.Color
Properties • Properties hoeven niet altijd direct met een waarde van een membervariabele te corresponderen, bijv.: public Vector2 Center { get { return new Vector2(sprite.Width, sprite.Height) / 2; } }
Spelerinvoer afhandelen • Spelerinvoer afhandelen is nogal omslachtig momenteel: previousMS = currentMS; previousKS = currentKS; currentMS = Mouse.GetState(); currentKS = Keyboard.GetState(); if (currentKS.IsKeyDown(Keys.R) && previousKS.IsKeyUp(Keys.R)) cannon.Color = Color.Red; else if (currentKS.IsKeyDown(Keys.G) && previousKS.IsKeyUp(Keys.G)) cannon.Color = Color.Green; else if (currentKS.IsKeyDown(Keys.B) && previousKS.IsKeyUp(Keys.B)) cannon.Color = Color.Blue; ... Veeldubbele code, dus je maaktsnelfouten!
De InputHelper klasse classInputHelper { MouseStatecurrMS, prevMS; KeyboardStatecurrKS, prevKS; // methoden en properties } Dezeinformatiewordtbewaard in eenInputHelper object De klasseInputHelperbeschrijft hoe een object van het type InputHelpereruitziet!
class Painter : Game { GraphicsDeviceManager graphics; SpriteBatchspriteBatch; InputHelperinputHelper; … static void Main() { Painter game = new Painter(); game.Run(); } public Painter() { Content.RootDirectory = "Content"; graphics = newGraphicsDeviceManager(this); inputHelper = newInputHelper(); } … Declaratie Toekenning en maken van eeninstantie
Handige methoden classInputHelper { MouseStatecurrMS, prevMS; KeyboardStatecurrKS, prevKS; public void Update() { prevMS = currMS; prevKS = currKS; currMS = Mouse.GetState(); currKS = Keyboard.GetState(); } … InputHelper object bijwerken in zijn eigen Update methode
= dezemethode mag in eenandereklasse aangeroepenworden. Handige methoden public boolMouseLeftButtonPressed() { returncurrMS.LeftButton == ButtonState.Pressed && prevMS.LeftButton == ButtonState.Released; } public boolKeyPressed(Keys k) { returncurrKS.IsKeyDown(k) && prevKS.IsKeyUp(k); }
InputHelper gebruiken protected override void Update(GameTimegameTime) { inputHelper.Update(); HandleInput(inputHelper); // hiernog de game wereldbijwerken }
Cannon krijgtzijneigenHandleInput public void HandleInput(InputHelper inputHelper) { if (inputHelper.KeyPressed(Keys.R)) Color = Color.Red; else if (inputHelper.KeyPressed(Keys.G)) Color = Color.Green; else if (inputHelper.KeyPressed(Keys.B)) Color = Color.Blue; double opposite = inputHelper.MousePosition.Y - position.Y; double adjacent = inputHelper.MousePosition.X - position.X; angle = (float)Math.Atan2(opposite, adjacent); } Veelkorter en veel overzichtelijker!
GameWorld klasse class GameWorld { Texture2D background; Cannon cannon; public GameWorld(ContentManager Content) { background = Content.Load<Texture2D>("spr_background"); cannon = new Cannon(Content); } public void HandleInput(InputHelper inputHelper) { cannon.HandleInput(inputHelper); } ... Game wereldbestaat uitalle game objecten
... public void Update(GameTime gameTime) { } public void Draw(GameTimegameTime, SpriteBatchspriteBatch) { spriteBatch.Begin(); spriteBatch.Draw(background, Vector2.Zero, Color.White); cannon.Draw(gameTime, spriteBatch); spriteBatch.End(); } public Cannon Cannon { get { return cannon; } } }
classPainter : Game { GraphicsDeviceManagergraphics; SpriteBatchspriteBatch; InputHelperinputHelper; staticGameWorldgameWorld; … protectedoverridevoidLoadContent() { spriteBatch = newSpriteBatch(GraphicsDevice); gameWorld = newGameWorld(Content); } … public staticGameWorldGameWorld { get { returngameWorld; } } } Static member variabele Constructie van de game wereld Static property om erbijtekunnen
protected override void Update(GameTimegameTime) { inputHelper.Update(); gameWorld.HandleInput(inputHelper); gameWorld.Update(gameTime); } protected override void Draw(GameTimegameTime) { GraphicsDevice.Clear(Color.White); gameWorld.Draw(gameTime, spriteBatch); }
Overzicht programma-constructies waarde-verzamelingvan een expressie geeft het typevan variabelen Declaratie • Lokale variabelevoor tijdelijk gebruik • Membervariabelepermanent deel vanhet object • Parameterom waarden doorte spelen aan methoden Type • Primitief type • int • double • bool, enz. • Object-type • Color, Vector2 enz. • Game, SpriteBatch, enz.
De volgende keer… Let’s add these bad boys… • Hoofdstukken 8 & 9 uit het boek • Willekeurigheid in games • Game object interactie • …meer game objecten!