Informatica GameMaker lesnr. 3 INLEIDING Deze laatste les bestuderen we de opbouw van een complete maze-game. We maken gebruik van het lesmateriaal van professor Mark Overmars (de bedenker van GameMaker). Op de site is nog veel meer lesmateriaal aanwezig, samen met links naar vele andere GameMaker-sites en forums. In 7 stappen (van maze game 1 tot maze game final) wordt een compleet spel gebouwd, met diamonts, monsters, puzzles en allerlei handige tools. In deze les wordt bij iedere stap in het kort uitgelegd, wat er allemaal nieuw is. MAZE GAME 1 In de eerste stap is er maar weinig nieuws te zien. Drie objecten, waarvan we de werking al kennen. Alle objecten zijn zichtbaar gemaakt m.b.v. een sprite van 32 bij 32 pixels. MAZE GAME 2 Het object door moet doorlopend in de gaten houden, of alle diamonds al vernietigd zijn. De step-event wordt iedere stap in het spel uitgevoerd. Zeer geschikt voor eventhandlers, die doorlopend moeten worden uitgevoerd. Is het aantal diamanten gelijk aan 0? - 1 -
Het object person moet tijdens het indrukken van de pijltjestoetsen netjes uitgelijnd blijven op het aangebrachte grid van 32 bij 32 pixels. Alleen wanneer het object uitgelijnd is op het grid, mag het bewegen. MAZE GAME 3 De eerste stappen worden gezet, om het spel een beetje professioneler te maken: Er worden onzichtbare controller-objecten gebruikt, die het begin en einde van het spel en het verloop van de score gaan regelen. Er vallen punten te verdienen, 5 per diamand en 40 per level. Er worden backgrounds gebruikt om de achtergrond wat leuker te maken. Er is een room_start en een room_end, waarin het begin en het einde van het spel wordt geregeld. Het begrip parent wordt geïntroduceerd. Een object erft automatisch alle eigenschappen van zijn parent. De controllerobjecten Het object wall_corner is de parent van de objecten wall_horizontal, wall_vertical en door. - 2 -
Het start_controller object Het onzichtbare object start_controller bevindt zich in de room_start, en regelt de aanvang van het spel. Bij het maken van een start_controller wordt er een wekker aangezet, die na 150 steps (+/- 5 sec.) een alarm doet afgaan. Dit alarm start het volgende level. Ook zet de start_controller de score op 0. Een alarm-event is een soort stopwatch, die terugtelt naar 0, en dan actief wordt. Wanneer je op een willekeurige toets drukt, dan ga je naar het volgende level. Bij het verschijnen van het openingsscherm zijn er dus 2 mogelijkheden: Het spel begint automatisch na +/- 5 sec. Het spel begint direct, zodra de speler op een toets drukt. - 3 -
Het controller object Het onzichtbare object controller bevindt zich in room1 en room2. Het toont de score van het spel aan de onderkant van het speelveld. Keuze van het lettertype Op het speelveld verschijnt de tekst: Score: Op de puntjes verschijnt de daadwerkelijke score, als string. In de Game Options is het vinkje voor Show the score weggehaald. - 4 -
Het end_controller object Het onzichtbare object end_controller bevindt zich in de room_end, en regelt de beëindiging van het spel. Bij het maken van een end_controller wordt er een wekker aangezet, die na 1 step (= vrijwel direct) een alarm doet afgaan. Dit alarm toont een boodschap, laat de highscore-table zien, en start het spel opnieuw. Het door object De event-handler van het object door is een beetje uitgebreid. Zelf bekijken! Het diamond object Wanneer het object door in contact komt met het object person, dan wordt de score met 5 punten opgehoogd: Wanneer een object vernietigd wordt, dan kun je de event-handler onderbrengen bij de event Destroy. - 5 -
Het person object Maze3 heeft 4 verschillende objecten, die de functie van een solid wall hebben: wall_corner, wall_horizontal, wall_vertical en door. Omdat wall_corner de parent is van de andere drie objecten, hoef je bij het object person alleen maar een event-handler te maken voor een botsing met wall_corner. Deze event-handler is tevens geldig voor de andere drie objecten (die we ook wel childs noemen). Alleen een event-handler maken voor de parent. De background De background van de verschillende levels ontstaat, door allemaal plaatjes background_main.gif naast elkaar en onder elkaar te leggen. (= Tile Hor. En Tile Vert.) De background van het eerste level is apart gemaakt. Mark Overmars heeft daar een hele grote bitmap voor gebruikt, en daarom is dit spel zo groot geworden. Het is slimmer om voor de achtergrond gebruik te maken van plaatjes met extensie gif. Kleine plaatjes aan elkaar plakken levert een grote achtergrond. - 6 -
MAZE GAME 4 Het spel wordt verder uitgebreid: Er worden monsters toegevoegd. Er worden levens toegevoegd. Er worden extra geluidjes toegevoegd. Door op de letters p en n te drukken kun je de verschillende levels doorlopen. (Dat is erg handig tijdens het ontwerpen van het spel. Bij de definitieve versie zou ik die optie zelf verwijderen.) De start_controller stelt het aantal levens op 3, en de controller toont het aantal levens m.b.v. plaatjes. De controller objecten Het object start_controller stelt het aantal levens op 3. Het object controller laat zowel de score (in punten) als het aantal levens (m.b.v. plaatjes) zien. Het aantal levens staat links, de score staat rechts. Positie van de score: breedte van de room 150 pixels - 7 -
Een stukje code om de beertjes te tekenen De positie van de tekst Lives: GameMaker beschikt ook over een programmeertaal (GML). Een beschrijving van deze programmeertaal (die erg veel lijkt op DELPHI) kun je vinden in de HELP. GameMaker accepteert zelfs stukjes code, die volledig identiek zijn aan de code, die wij tijdens de vorige cursus geleerd hebben bij DELPHI. { } Herhalingslus for (i = 0; i < lives; i += 1) draw_sprite_scaled(sprite_person, 0, x+64+20*i, y+8, 0.5); Teken een sprite met aangepaste schaal Naam van de sprite Horizontale positie van de sprite Verticale positie van de sprite Schaal factor - 8 -
Natuurlijk moet de controller ook in de gaten houden of het aantal levens op is, en het spel beëindigd moet worden. Zijn de levens op? Highscore tonen en opnieuw beginnen. Tenslotte zorgt de controller er nog voor, dat je met P naar de vorige room, en met N naar de volgende room kunt. De monster objecten Er zijn 3 verschillende monster objecten: Monster_lr kan alleen bewegen van links naar rechts. Monster_ud kan alleen bewegen van boven naar beneden. Monster_all kan zowel horizontaal als vertikaal bewegen. De objecten monster_lr en monster_ud worden op dezelfde manier gemaakt: - 9 -
Zodra een instantie van het object gemaakt is, begint het te bewegen. De snelheid is aangepast aan de grootte van de sprites (32 pixels). Het object monster_all kan zowel horizontaal als verticaal bewegen. Wanneer dit monster tegen een solid object aanbotst, dan: Kijkt het eerst of het 90 naar links kan draaien. Als dat niet lukt, omdat er een solid object staat, dan Kijkt het vervolgens of het 90 naar rechts kan draaien. Als dat niet lukt, omdat er een solid object staat, dan Draait het object 180 en gaat weer terug in de richting, waar het vandaan kwam. Zodra een instantie van het object gemaakt is, begint het met aangepaste snelheid te bewegen. - 10 -
Wanneer het object naar rechts beweegt, dan is de hspeed gelijk aan 32/6, en wordt gecontroleerd, of deze positie vrij is. Wanneer het object omlaag beweegt, dan is de vspeed gelijk aan 32/6, en wordt gecontroleerd of deze positie vrij is. Enz. Wanneer je goed kijkt, dan zie je, dat de monsters onder de diamantjes door bewegen. Wanneer 2 objecten zich op dezelfde positie bevinden, dan kun je met Depth regelen, welke sprite er zichtbaar is. Regels: Het object met de grootste Depth wordt als eerste getekend, en ligt dus onderop. Wanneer 2 objecten dezelfde Depth hebben, dan worden ze getekend in de volgorde, waarin ze zijn gemaakt. Omdat de sprites van sommige monsters niet een volledig vakje van 32 32 pixels vullen wordt het vakje Precise collision checking uitgezet. Bij een botsing wordt dan niet meer exact gecontroleerd of de sprite geraakt is. Er wordt alleen gekeken of het vakje van 32 32 pixels is geraakt. - 11 -
MAZE GAME 5 Het spel wordt verder uitgebreid: Het object controller wordt voorzien van de mogelijkheid om op de letter R te drukken. Ten koste van 1 leven kan de speler het level dan opnieuw spelen, wanneer hij vast zit. Er worden gaten (holes) geïntroduceerd, waar het object person niet overheen kan. Door een rotsblok (rock) in zo n gat te duwen, wordt het wel toegankelijk. Er worden bommen (bombs) geïntroduceerd, die m.b.v. een ontsteekmechanisme (trigger) tot ontploffing (explosion) kunnen worden gebracht. Het controller object Door op de R te drukken start het level opnieuw, en wordt het aantal levens met 1 verminderd. R indrukken vermindert het aantal levens met 1 Het rock object en het hole object Het object hole is een eenvoudig object. Het is solid, en heeft als parent het object wall_corner. Het gedraagt zich dus net als een muur, zowel monster objecten als het object person botsen tegen een hole object aan, en kunnen dan niet verder. Wanneer een rock object tegen een hole object botst, dan worden beiden verniertigd. - 12 -
Het object rock is iets gecompliceerder. Het is solid, en heeft als parent het object wall_corner Het gedraagt zich dus net als een muur, zowel monster objecten als het object person botsen tegen het hole object aan, en kunnen dan niet verder. Het kan verschoven worden door het object person. (Wanneer er ruimte is!) Het object person beweegt zowel horizontaal als verticaal met snelheid 4. 8 * 4 = 32 en dat is precies de afmeting van het eerstvolgende vakje. Het object rock moet dus kijken naar de richting en de snelheid van het andere object person. Vandaar: 8 * other.hspeed En wanneer die ruimte aanwezig is, dan springt het object rock precies 1 vakje in dezelfde richting, waarin het andere object person zich bewoog. - 13 -
Wanneer er een object hole op de nieuwe positie staat, dan moet het object rock toch 32 pixels verspringen! Tenslotte moeten we nog aan het object person vertellen, dat het niets moet doen, wanneer het tegen het object rock aanbotst. Het trigger object, het bomb object en het explosion object Deze 3 objecten horen bij elkaar. In de room staat zowel een trigger object als een bomb object opgesteld. (Niet te dicht bij elkaar!) Wanneer het object person in contact komt met het object trigger, dan: Wordt het object trigger vernietigd. Wordt het object bomb, dat gekoppeld is aan een sprite van 32 32 pixels, vervangen door het object explosion, dat gekoppeld is aan een sprite van 96 96 pixels. Wordt het object explosion samen met alle andere objecten in het betreffende gebied van 96 96 pixels vernietigd. N.b. de sprite explosion.gif is een Animated GIF. - 14 -
Het object trigger komt in contact met het object person. Vervolgens wordt het object bomb veranderd in het object explosion. Zodra het object explosion is gemaakt, wordt er een stukje code uitgevoerd, dat alle aangrenzende objecten vernietigd. Wanneer je de exacte betekenis van dit stukje code wilt doorgronden, dan zul je je een beetje moeten verdiepen in de taal GML. (Maar dat valt buiten het bestek van dit project!) Deze code heb je ook niet nodig om exact hetzelfde effect te kunnen bereiken. Je kunt e.e.a. ook realiseren door bij de creatie van het object explosion alle vakjes te noemen, waar een aanwezige instantie van een ander object moet worden vernietigd. - 15 -
Bij het maken van het object explosion worden eerst alle andere objecten op de posities (-32,-32), (0,-32), (32,-32), (32,0), (32,32), (0,32), (-32,32) en (-32,0) vernietigd. Als laatste wordt het object zelf op positie (0,0) vernietigd. MAZE GAME 6 Het spel is bijna af, we voegen nog een paar elementen toe: We vervangen de sprites van het object person en de monster objecten door Animated GIF s. We voegen bonusobjecten toe, waarvoor je extra punten (bonus) of extra levens (heart) krijgt. We voegen éénrichtingsverkeer objecten toe (move_up, move_down, move_left en move_right), die het object person een bepaalde kant opsturen. - 16 -
Voor de sprites sprite_person, sprite_monster1, sprite_monster2 en sprite_monster3 zijn Animated GIF s gebruikt, die steeds bestaan uit 4 plaatjes. Dit soort Animated GIF s kun je van het Internet plukken of zelf maken met bijv. het programma Animagic GIF. Ook GameMaker zelf heeft mogelijkheden om een sprite te animeren. De eigenschappen van sprite_monster3 samen met de Sprite Editor Vervolgens moet iedere stap van het spel even gekeken worden, in welke richting het object beweegt. Afhankelijk van de richting wordt dan een ander plaatje getoond. Bij iedere stap van het object monster_all wordt er een stukje code uitgevoerd. Als hspeed < 0, dan beweegt het object naar links, en moet dus plaatje 3 worden getoond. Als vspeed > 0, dan beweegt het object naar beneden, en moet dus plaatje 0 worden getoond. Enz. - 17 -
Het bonus object en het heart object Dit zijn hele simpele objecten. Wanneer het object person ermee in contact komt, dan: wordt er een geluidje afgespeeld, wordt er een aantal extra punten of een extra leven toegekend, wordt het object zelf vernietigd. Object heart in contact met object person? Aantal levens wordt opgehoogd met de waarde De objecten move_up, move_down, move_left en move_right Dit zijn hele simpele objecten, die zelf helemaal niets doen. De code zit bij het object person. Iedere stap houdt het object person in de gaten, of er misschien contact is met een van de objecten move_up, enz. Wanneer dat contact er is, dan worden richting (en snelheid) van het object person aangepast. Bij iedere stap van het object person wordt er gecontroleerd of er sprake is van éénrichtingsverkeer. - 18 -
Wanneer het object person in contact komt met het object move_up, dan wordt de bewegingsrichting gewijzigd in omhoog, en de snelheid gewijzigd in 8. MAZE GAME FINAL Alle objecten zijn af. Er kunnen nu verschillende levels gemaakt worden. (Met steeds oplopende moeilijkheidsgraad, en zo af en toe de introductie van een nieuw object.) OPDRACHTEN Opdracht 1 Kopieer het bestand maze.zip naar de harde schijf, en pak het uit. Je hebt nu de beschikking over de behandelde 7 stappen, samen met een korte handleiding en de verzameling gebruikte sprites. Bestudeer het ontwerp van de verschillende stappen. Na deze les moet je in staat zijn om zelf een eenvoudige maze game te ontwerpen. - 19 -