260 likes | 373 Views
Introductie GameEngine. Inhoud. De Game Package Speelveld aanmaken GameObjecten met plaatjes neerzetten De Game-loop Besturing door de speler Een timer gebruiken Events in het spel, waaronder collisions. Structuur van een spel.
E N D
Inhoud • De Game Package • Speelveld aanmaken • GameObjecten met plaatjes neerzetten • De Game-loop • Besturing door de speler • Een timer gebruiken • Events in het spel, waaronder collisions
Structuur van een spel Een spel bestaat in het algemeen uit een aantal 'onderdelen': • Een 'wereld' (rooms, levels) met achtergrond waarin het spel zich afspeelt. • GameObject dat door de speler bestuurd wordt. • Andere GameObjecten die met elkaar interacteren. • Geluid, Menu, Formulier, Scorebord... • Spel 'loopt'.....!
De Game Package De game-package bevat allerlei zaken, die je helpen een spel te bouwen: • 'Tile environment', wereldgrenzen, image... • GameObject: statisch object in het spel. • MovableGameObject: bewegend object in het spel (de gameplayer is ook van dit type) • Timer, Geluid, Formulier, Dashboard... • Besturing (Touch screen, Motion Sensor..) • GameEngine: laat het spel lopen, beheert lijst van GameObjects, MovableGameObjects, achtergrond, etc.
De Game Loop (eerste keer) De GameEngine start het spel en komtdan in een loop: maakspeelveld met achtergrond plaatsinitiëleGameItems en GamePlayer Initialiseervariabelen (punten, etc) while ( gameRunning ) { doe spelacties...... tekenspelopnieuw }
Het speelveld (1) Het speelveld kan zo groot zijn als je scherm en stil staan (bijv pacman). Het speelveld kan ook groter dan je scherm zijn. Er is dan een viewport, een venster waardoor je een deel van het speelveld ziet. speelveld viewport speler
Het speelveld (2) In platform games en shooters zorgt de game-package ervoor dat viewport met de speler mee beweegt. Je kunt dan de positie van de speler in de viewport instellen. In dit voorbeeld: horizontaal: midden. verticaal: beneden speelveld viewport speler
Het speelveld (3) Achtergrond kan leeg zijn, maar je kunt deze ook vullen met plaatjes: tiles int[][] map ={ { -1, -1, 0, 2, -1, -1, -1, -1, -1, -1, -1, -1 }, { -1, 0, 3, 3, 2, -1, -1, -1, -1, 0, 1, 1 }, { 0, 3, 3, 3, 3, 2, -1, -1, 0, 3, 3, 3 }, { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 } }; 0 1 2 3 4
Game Objects (1) GameObjectenkunnenstatisch of bewegendzijn. Voorbeidebevat de game-package standaardklassen, die je uitbreidt met je eigenfunctionaliteit. class Flesje extends GameObject { // eigenplaatje, gedrag... // bijv: puntenalsspeler het pakt } class Kogel extends MoveableGameObject { // eigenplaatje, gedrag... // bijv: snelheidgeven, botsen met vijand }
Game Objects (2) • Statischeobjecten: • maak je (constructor) • geef je eenpositie • laat je door de GameEngine op het speelveldzetten • hebben 1 of meerplaatjes (sprite) • kunnenzichtbaar/onzichtbaarzijn • hebben een methode update() die elke gameloop wordt aangeroepen • Plus het gedragdat je erbijmaakt!
Game Objects (3) Plaatjes zijn ingedeeld in frames. Die frames zitten in één image-bestand. Je geeft het aantal frames op, en de game-engine knipt dat plaatje op in frames. Animatie kan, zelf frame kiezen ook.
Game Objects (4) • Bewegende objecten: hebben alles wat statische objecten ook hebben, plus: • snelheid • botsingen • wrijving
Game Objects (5) GameObjectenhebbeneenmethodeupdate() die elke gameloop wordt aangeroepen. De standaardinvulling van deze methode zorgt voor essentiële basisacties als rendering, verplaatsen van bewegende objecten e.d. Door deze methode te overriden voeg je gedrag toe, bijvoorbeeld het afhandelen van botsingen, verwerken van input. Begin deze override altijd met super.update(), anders gebeuren de basisacties niet meer!
De speler Er is geen speciaal object voor de speler. Dit is soms een gewoon GameObject, soms geen enkel. Je kunt wel een GameObject in de rol van speler aan de game toevoegen. De viewport volgt dan dit GameObject. NB. Tetris is eenvoorbeeld van een spel zonder zichtbare speler.
De Game Loop (tweede keer) De GameEngineverplaatst de bewegendeobjecten: .... while ( gameRunning ) { update() van alleGameObjects (standaard: sprite-animatie, verplaatsen van Moveables...) (niet-standaard in eigen override van update()) .... pas zonodig viewport aan (bijbewegendespeler) teken viewport opnieuw }
Collision (1) • De GameEnginekent twee manieren van collision detection: • MoveableGameObjects met andere GameObjects • MoveableGameObjects met tiles • De afhandeling van deze botsingen gaat op zeer verschillende wijze • (vanwege de performance van de GameEngine)
Collision (2) In de methode update() van een MoveableGameObject kun je opvragen met welke andere objecten je gebotst bent. Je krijgt een ArrayList van objecten terug: ArrayList<GameObject> gebotst = getCollidedObjects(); Je kunt deze lijst nu aflopen en actie ondernemen. Zie bijvoorbeeld de klasse Vis. NB: Alleenbewegendeobjecten (onderling + met stilstaande)!
Collision (3) Wanneer je in de achtergrond'tiles'hebt, detecteert de GameEngineookbotsingen met die tiles. Dit is automatischvoor de MoveableGameObjects die de interface ICollisionimplementeren. Bij botsingen met tiles wordt dan aangeroepen collisionOccurred(List<TileCollision> collidedTiles) In de parameter krijg je een lijst van speciale objecten mee: TileCollision
Collision (4) • EenTileCollision is eensimpel object met twee variabelen: • De Tile waartegen je botste • een getal (0,1,2,3) dat aangeeft tegen welke kant je botste. • Deze informatie kun je doorgeven aan methoden die het object laten ‘bouncen’ of stilzetten: • bounce(TileCollisiontc) • MoveUpToTileSide(TileCollisiontc)
De Game Loop (derdekeer) De GameEnginedetecteertbotsingen : .... while ( gameRunning ) { update() van alleGameObjects (standaard: sprite-animatie, verplaatsen van Moveables, detecteer tile-collisions voorICollision-objecten...) (niet-standaard in eigen override van update() met: vraag object-collisions op) .... pas zonodig viewport aan (bijbewegendespeler) teken viewport opnieuw }
Aansturing op tijd (1) Somswil je dingen met eenvertraginglatengebeuren. Je kuntdanbij de GameEngineeenwekker (alarm) zetten, met het verzoekomeenseintjetekrijgennaeenbepaaldetijd (eenaantalstappen in de game-loop. Bijv 1: Spelerschiet en kan pas opnieuwschietennaverloop van eenkortetijd. Bijv 2: Na eentijdjeverschijntereennieuwhapje of power-up Objecten die Alarms willen gebruiken, moeten de interface IAlarm gebruiken om wake-upcalls te ontvangen. Alarms kun je hergebruiken door ze te ‘restarten’. Voorbeeld: StrawberryControler.
Timers Werking timer: new Alarm(tijd, id-nummer, this) startAlarm() GameEngine Object implements IAlarm (na <tijd> stappen van de game-loop:) triggerAlarm(id-nummer)
De Game Loop (vierdekeer) De GameEnginelaat alarms afgaan: .... while ( gameRunning ) { update() van alleGameObjects (standaard: sprite-animatie, verplaatsen van Moveables, detecteer tile-collisions voorICollision-objecten...) (niet-standaard in eigen override van update() met: vraag object-collisions op) update Alarms en laatzezonodigaflopen .... pas zonodig viewport aan (bijbewegendespeler) teken viewport opnieuw }
De Game Loop (vierdekeer) De GameEnginedetecteertbotsingen: while ( gameRunning ) { verplaatsbewegendeobjecten detecteer tile-collisions voorICollision-objecten pas zonodig viewport aan (bijbewegendespeler) roepmethode update() van GameObjectsaan (in update: vraag object-collisions op) laat Alarms tikkenen zonodigaflopen .... teken viewport opnieuw }
En nu aan de slag! • Geen game-idee? Pak je favoriete Nintendo-spelletje, of kijk eens rond naar Flash-spelletjes op internet • Maandag nog geen idee? Paul komt paar spel-ideeën laten zien.
Samenstelling groepje • Naar eigen inzicht duo’s kiezen, maar… • Docent kan veto uitspreken • Samenstelling uiterlijk maandag om 10.00 uur doorgeven per mail: ralphniels+oopd@gmail.com.