Download de presentatie
De presentatie wordt gedownload. Even geduld aub
1
Game Object Structuren
Arjan Egges & Paul Bergervoet
2
Arrays in games Grid-gebaseerd speelveld (zoals Tetris)
Lijst van spelers Lijst van inventory items Lijst van alle game objecten die getekend moeten worden Enzovoorts…
3
Programmeerconstructies in games
Klassen Objecten Collections N-dimensionale arrays
4
Programmeerconstructies in games
Klassen Objecten Collections N-dimensionale arrays
5
Jewel Jam
6
Twee-dimensionale array
tabel 5 3 length int [ , ] tabel; 1 2 tabel = new int [5,3]; 3 4 tabel.GetLength(0) tabel.GetLength(1) 1 2
7
2D array voor speelveld Declaratie: In LoadContent:
Grid initialiseren: int[,] grid; jewel1 = Content.Load<Texture2D>(" spr_single_jewel1"); jewel2 = Content.Load<Texture2D>(" spr_single_jewel2"); jewel3 = Content.Load<Texture2D>(" spr_single_jewel3"); grid = new int[5, 10]; for (int x = 0; x < 5; x++) for (int y = 0; y < 10; y++) grid[x, y] = random.Next(3);
8
2D grid tekenen for (int x = 0; x < 5; x++)
for (int y = 0; y < 10; y++) { Vector2 position = new Vector2(85 + x * 85, y * 85); if (grid[x, y] == 0) spriteBatch.Draw(jewel1, position, Color.White); else if (grid[x, y] == 1) spriteBatch.Draw(jewel2, position, Color.White); else spriteBatch.Draw(jewel3, position, Color.White); }
9
Rij naar onder verplaatsen
Let op de volgorde bij kopieren in loops! // verplaats alle rijen eentje naar onderen int x, y; for (y = 8; y >= 0; y--) for (x = 0; x < 5; x++) grid[x, y + 1] = grid[x, y]; // vul de eerste rij met nieuwe willekeurige juwelen grid[x, 0] = random.Next(3);
10
Game objecten in een structuur
Veel games gebruiken game objecten in een boomstructuur Puzzelgames (groeperen van objecten, objecten bestaan uit onderdelen…) 3D games (omgeving is een boomstructuur) Platform games … Zo’n structuur noemen we ook wel een scene graph
11
Scene graphs
12
Game objecten in een scene graph
Een game object kan een parent hebben Een game object kan bestaan uit een lijst van andere game objecten Een game object kan bestaan uit een grid van andere game objecten Game objecten kunnen een positie en snelheid ten opzichte van hun parent objecten hebben
13
Game object graaf Game object (lijst) Game object Game object (grid)
‘root’ game object Game object (lijst) Game object Game object (grid) Game object (lijst) Game object Game object Game object
14
Nieuwe GameObject klasse (zonder sprite!)
class GameObject { protected GameObject parent; protected Vector2 position, velocity; protected int layer; protected bool visible; … } Game objecten hebben een ‘parent’. Testen of game object aan de top van de hierarchie staat: if (parent != null) // we are not at the top of the hierarchy Het ‘root’ game object heeft als parent null.
15
Positionering van objecten
Globale posities Juweelpositie: (85, 150) Speelveldpositie: (85, 150)
16
Positionering van objecten
Lokale posities Juweelpositie: (0, 0) Speelveldpositie: (85, 150)
17
Positionering van objecten
Globale posities: Locatie object altijd bekend Verplaatsen van object hoger in de hierarchie opnieuw alle posities uitrekenen Lokale posities: Objecten worden lokaal in de hierarchie getekend gamewereld onafhankelijk Opvragen van globale positie kost extra rekenkracht
18
Globale positie berekenen
public virtual Vector2 GlobalPosition { get if (parent != null) return parent.GlobalPosition + this.Position; else return this.Position; } Afhankelijk van de globale positie van de parent.
19
Klasse SpriteGameObject
class SpriteGameObject : GameObject { protected Texture2D sprite; public SpriteGameObject(Texture2D spr, int layer = 0) : base(layer) { sprite = spr; } public override void Draw(GameTime t, SpriteBatch spriteBatch) if (visible) spriteBatch.Draw(sprite, this.GlobalPosition, Color.White); Subklasse van GameObject Tekenen op de globale positie
20
Tekenen in lagen
21
Layers class GameObject { protected Vector2 position, velocity;
protected GameObject parent; protected int layer; protected bool visible; … } Kleinere waarde = Eerder tekenen Ieder game object zit in een ‘laag’.
22
Klasse GameObjectList
Subklasse van GameObject class GameObjectList : GameObject { protected List<GameObject> gameObjects; public GameObjectList(int layer = 0) : base(layer) gameObjects = new List<GameObject>(); } …
23
Klasse GameObjectList
public void Add(GameObject obj) { obj.Parent = this; for (int i = 0; i < gameObjects.Count; i++) if (gameObjects[i].Layer > obj.Layer) gameObjects.Insert(i, obj); return; } gameObjects.Add(obj); public void Remove(GameObject obj) gameObjects.Remove(obj); obj.Parent = null;
24
automatisch in de goede
public override void HandleInput(InputHelper inputHelper) { foreach (GameObject obj in gameObjects) obj.HandleInput(inputHelper); } public override void Update(GameTime gameTime) obj.Update(gameTime); public override void Draw(GameTime time, SpriteBatch s) if (!visible) return; for (int i = 0; i < gameObjects.Count; i++) gameObjects[i].Draw(time, s); Game objecten worden automatisch in de goede volgorde getekend!
25
Klasse GameObjectGrid
class GameObjectGrid : GameObject { protected GameObject[,] grid; protected int cellWidth, cellHeight; public GameObjectGrid(int rows, int columns, int layer = 0) : base(layer) grid = new GameObject[columns, rows]; for (int x = 0; x < columns; x++) for (int y = 0; y < rows; y++) grid[x,y] = null; } Subklasse van GameObject
26
Klasse GameObjectGrid
public void Add(GameObject obj) { for (int x = 0; x < Columns; x++) for (int y = 0; y < Rows; y++) if (grid[x,y] == null) grid[x,y] = obj; obj.Parent = this; obj.Position = new Vector2(x * cellWidth, y * cellHeight); return; } Zoek de eerste lege plek! Zet het object op de juiste positie (lokaal!)
27
Gamewereld bouwen gameWorld = new GameObjectList();
Texture2D background = Content.Load<Texture2D>("spr_bkgrnd"); gameWorld.Add(new SpriteGameObject(background)); GameObjectList playingField = new GameObjectList(1); playingField.Position = new Vector2(85, 150); gameWorld.Add(playingField); GameObjectGrid grid = new GameObjectGrid(10, 5, 60); playingField.Add(grid); Texture2D selectorFrame = Content.Load<Texture2D>("spr_sel_fr"); RowSelectGameObject rowSelector = new RowSelectGameObject(grid, selectorFrame, 1); playingField.Add(rowSelector);
28
Klassenhierarchie
29
playingField positie
30
JewelJamGameWorld class JewelJamGameWorld : GameObjectList {
public JewelJamGameWorld() this.Add(new SpriteGameObject("spr_background")); GameObjectList playingField = new GameObjectList(1); playingField.Position = new Vector2(85, 150); this.Add(playingField); JewelGrid grid = new JewelGrid(10, 5, 60, 0); playingField.Add(grid); playingField.Add(new RowSelectGameObject(grid, 1)); } Subklasse van GameObjectList
31
Jewel klasse class Jewel : SpriteGameObject { protected int variation;
public Jewel(int layer = 0) : base("spr_jewels", layer) variation = JewelJam.Random.Next(27); } ...
32
Een deel van de sprite tekenen
public override void Draw(GameTime gameTime, SpriteBatch spriteBatch) { if (!visible) return; Rectangle source = new Rectangle(variation * sprite.Height, 0, sprite.Height, sprite.Height); spriteBatch.Draw(sprite, GlobalPosition, source, Color.White); }
33
Anchor position In de GameObjectGrid klasse:
public Vector2 GetAnchorPosition(GameObject s) { for (int x = 0; x < Columns; x++) for (int y = 0; y < Rows; y++) if (grid[x, y] == s) return new Vector2(x * cellWidth, y * cellHeight); return Vector2.Zero; }
34
Anchor position opvragen
In de Jewel klasse: Maar dat mag niet, want parent heeft als type GameObject en niet GameObjectGrid Dus, casten: Wat gebeurt er als this.Parent niet het type GameObjectGrid heeft? Vector2 anchorPosition = this.Parent.GetAnchorPosition(this); GameObjectGrid parent = (GameObjectGrid)this.Parent; Boem!
35
Anchor position opvragen
Veiliger: gebruik as Daarna kun je controleren of het gelukt is: Gevolg: Programma veel robuuster! GameObjectGrid parentGrid = this.Parent as GameObjectGrid; if (parentGrid != null) // doe iets met parentGrid
36
Motion effecten In de Update methode van Jewel: if (parent != null) {
Vector2 anchorPosition = parent.GetAnchorPosition(this); velocity = (anchorPosition – position) * 8; base.Update(gameTime); }
37
Tetris
38
Langwerpig tetrisblok
class LangwerpigTetrisBlok { Color kleur; Texture2D blokSprite; const int grootte = 4; bool[,] configuratie; … Hierin bewaren we het blok (false = vrij, true = bezet)
39
Langwerpig tetrisblok
public LangwerpigTetrisBlok() { this.kleur = Color.Red; this.configuratie = new bool[grootte, grootte]; for (int i = 0; i < grootte; ++i) for (int j = 0; j < grootte; ++j) this.configuratie[i, j] = false; configuratie[0,1] = true; configuratie[1,1] = true; configuratie[2,1] = true; configuratie[3,1] = true; } Array initialisatie Een langwerpig blok
40
Tetrisblok draaien j= 0 1 2 3 i=0 1 2 3 public void draaiLinksom() {
bool[,] nieuw = new bool[grootte, grootte]; for (int i = 0; i < grootte; ++i) for (int j = 0; j < grootte; ++j) nieuw[grootte - j - 1, i] = configuratie[i, j]; this.configuratie = nieuw; }
Verwante presentaties
© 2024 SlidePlayer.nl Inc.
All rights reserved.