Game: omgaan met tijd (Jewel-Jam) Arjan Egges Paul Bergervoet Wouter van Toll
Omgaan met tijd Hoe vaak wordt Update/Draw eigenlijk aangeroepen? Twee mogelijkheden: Zo vaak mogelijk Op vaste tijdstippen (bijv. een aantal keer per seconde) fixed time step Standaard wordt de tweede optie gebruikt Update+Draw 60 keer per seconde
Omgaan met tijd Twee soorten tijd in de GameTime klasse: Real time Total real time = echte tijd verstreken sinds de start van het spel Total game time = tijd verstreken afhankelijk van het aantal updates Game tijd vertraagt bij moeilijke berekeningen!
Echte tijd gaat door, game tijd vertraagt! Omgaan met tijd Voorbeeld bij fixed time step = 10ms: TotalGameTime TotalRealTime Update 10ms 10ms Draw 20ms 20ms Update 30ms 30ms Draw 40ms 40ms Update Echte tijd gaat door, game tijd vertraagt! 50ms 70ms Draw 60ms 80ms
De TimeSpan klasse Properties: Methoden: TotalMilliseconds TotalSeconds Milliseconds Seconds Minutes Etc. Methoden: Add, Subtract, en nog een paar
Gebruikmaken van tijd Subklasse van GameObject Zichtbaarheid beheren class VisibilityTimer : GameObject { protected GameObject target; protected float timeleft; protected float totaltime; public VisibilityTimer(GameObject target, int layer=0, string id = "") : base(layer, id) totaltime = 1; timeleft = 0; this.target = target; } ... Subklasse van GameObject Zichtbaarheid beheren van een doelobject 1 seconde laten zien
Gebruikmaken van tijd Overgebleven tijd neemt af public override void Update(GameTime gameTime) { timeleft -= (float)gameTime.ElapsedGameTime.TotalSeconds; if (timeleft <= 0) target.Visible = false; } public override void Reset() { ... } public void StartVisible() timeleft = totaltime; target.Visible = true; Overgebleven tijd neemt af Object zichtbaar maken
Game wereld uitbreiden SpriteGameObject dOvrly = new SpriteGameObject("spr_double", 1); dOvrly.Position = new Vector2(800, 400); VisibilityTimer dTmr = new VisibilityTimer(dOvrly, 0, "doubleTimer"); this.Add(dOvrly); this.Add(dTmr); SpriteGameObject tOvrly = new SpriteGameObject("spr_triple", 1); tOvrly.Position = new Vector2(800, 400); VisibilityTimer tTmr = new VisibilityTimer(tOvrly, 0, "tripleTimer"); this.Add(tOvrly); this.Add(tTmr);
(Drie)dubbele combinaties int nrCombis = 0; if (IsValidCombination((Jewel)grid[middleCol, i], (Jewel)grid[middleCol, i + 1], (Jewel)grid[middleCol, i + 2])) { ... nrCombis++; i = 0; } else i++;
(Drie)dubbele combinaties if (nrCombis == 1) JewelJam.AssetManager.PlaySound("snd_combi"); else if (nrCombis == 2) { score.Score += 50; VisibilityTimer v = GameWorld.Find("doubleTimer") as VisibilityTimer; doubleTimer.StartVisible(); JewelJam.AssetManager.PlaySound("snd_double"); } else if (nrCombis == 3) score.Score += 100; VisibilityTimer v = GameWorld.Find("tripleTimer") as VisibilityTimer; tripleTimer.StartVisible(); JewelJam.AssetManager.PlaySound("snd_triple");
Glitters We definieren een klasse GlitterField Die krijgt een target texture (sprite) Willekeurige glitter sprites afbeelden bovenop de target sprite Maar alleen op plekken waar de sprite niet doorzichtig is!
GlitterField klasse class GlitterField : GameObject { protected List<Vector2> positions; protected List<float> scales; protected int width, height, xoffset; protected Texture2D glitter; protected Texture2D target; … }
Willekeurige positie berekenen public Vector2 CreateRandomPosition() { Vector2 randomPos = Vector2.Zero; while (true) randomPos = new Vector2(JewelJam.Random.Next(width), JewelJam.Random.Next(height)); Rectangle sourceRectangle = new Rectangle((int)randomPos.X + xoffset, (int)randomPos.Y, 1, 1); Color[] retrievedColor = new Color[1]; target.GetData<Color>(0, sourceRectangle, retrievedColor, 0, 1); if (retrievedColor[0].A == 255) break; } return randomPos; Pixeldata opvragen “stop de oneindige while loop”
Update methode public override void Update(GameTime gameTime) { for (int i = 0; i < scales.Count; i++) { if (scales[i] == 0 && JewelJam.Random.NextDouble() < 0.001) scales[i] += 0.05f; else if (scales[i] != 0) if (scales[i] >= 2.0f) scales[i] = 0f; positions[i] = this.CreateRandomPosition(); }
Draw methode public override void Draw(GameTime gameTime, SpriteBatch s) { Vector2 glitterCenter = new Vector2(glitter.Width, glitter.Height) / 2; for (int i = 0; i < scales.Count; i++) float scale = scales[i]; if (scales[i] > 1) scale = 2 - scales[i]; s.Draw(glitter, this.GlobalPosition + positions[i], null, Color.White, 0f, glitterCenter, scale, SpriteEffects.None, 0); }