Game Maker-språk | |
---|---|
Språkklass | objektorienterad , händelseorienterad , skriptad |
Framträdde i | 1999 |
Författare | Marcus Overmars |
Utvecklaren | Overmars, Markus Hendrik |
Filtillägg _ | .gml , .gmk , .gm6 , .gmd , .gm8 , .gm81 |
Blivit påverkad | C++ |
Hemsida | yoyogames.com |
OS | Microsoft Windows |
Game Maker Language (GML) är ett tolkat programmeringsspråk designat för att användas tillsammans med ett datorspelsutvecklingsprogram som heter Game Maker . Språkstöd introducerades ursprungligen i Game Maker av Mark Overmars för att komplettera knapphändelsesystemet, men senare inkluderades alla knapphändelser i GML, vilket gjorde att programmeraren kunde undvika att använda knappfunktioner. GML är mycket starkt relaterat till Game Maker-miljön. Game Maker är designad för att eliminera behovet av manuell programmering av saker som händelsehantering, nivådesign och objektinställning. Det finns en missuppfattning att GML stöder infogning av kodsnuttar på andra språk som Pascal , Assembler eller C++ . Missuppfattningen uppstod på grund av GML-syntaxens partiella likhet med Pascal och C++. (Till exempel kan operatorn "&&" ersättas med "och").
I Game Maker bildar en samling knapphändelser ett bibliotek. I programmets gränssnitt visas bibliotek som bokmärken som innehåller olika händelseikoner. Varje sådan händelse är ett GML- skript eller en funktion som användaren kan använda i spelet. Game Maker kommer med flera standardbibliotek som innehåller de viktigaste händelserna som används i de flesta spel. Det är också möjligt att skapa dina egna bibliotek med hjälp av Library Maker . GMS2 har en inbyggd mekanism för att konvertera knappåtgärder till GML-kod och vice versa, vilket gör att nybörjare snabbt kan byta till GML och förbättrar förståelsen för hur standardåtgärder fungerar.
GML liknar strukturellt ett språk, med kodblock, funktionsanrop, variabeltilldelningar, operatörssyntax och så vidare. GML skiljer på påståenden och uttryck. Till exempel,
g < 1;är inte ett giltigt uttalande och kommer att orsaka ett fel. Variabeltilldelning är också alltid en operator och kan därför inte användas i uttryck. Till exempel skulle följande rad alltid generera ett fel eftersom det skulle utvärdera det kapslade uttrycket till sant eller falskt och sedan jämföra det booleska resultatet med strängen "Ja" (felaktig jämförelse):
if ((answer = get_string("Ja eller Nej?", "")) == "Ja")Det är värt att komma ihåg att likhetstecknet "=" är en tilldelningsoperator och en boolesk jämförelseoperator i uttryck, medan i C ++ skrivs ett dubbeltecken "==" i uttryck. Det dubbla likhetstecknet "==" kommer dock att tolkas korrekt när det används i uttryck. Att använda ett sådant tecken som en tilldelningsoperatör kommer att orsaka ett körtidsfel. GML stöder även inkrementoperatorer :
g++; // både postfix och prefix notation stödsoch
g+= 1;samma som
g = g + 1;Det finns också operatorer: -=, *=, /=, |=, &= och ^=. Från och med GMS2 har stöd för den ternära operatören ?: introducerats . Operatörer i GML kan separeras med semikolon, men detta krävs inte (även om det kan leda till ett fel i vissa specifika fall).
Game Maker innehåller ett omfattande bibliotek med inbyggda funktioner för att tillhandahålla grundläggande funktionalitet. Programmeraren kan skapa sina egna skript som anropas på exakt samma sätt som funktioner. Ritfunktionerna i Game Maker använder Direct3D API . Vid behov låter Game Maker dig också anropa plattformens inbyggda kod genom tillägg (DLL på Windows, Java på Android, JS på HTML5, etc.).
Vanligtvis behöver GML inte fördeklarera en variabel, vilket vissa andra språk gör. En variabel skapas automatiskt, omedelbart efter att den har tilldelats ett värde:
foo="bar";Game Maker har många inbyggda variabler och konstanter . Varje objektinstans innehåller många lokala variabler, som "x" och "y". Det finns också flera inbyggda globala variabler, som "poäng". Dessa variabler existerar oberoende av objektinstanser. Dessa variabler innehåller inte prefixet " global .", till skillnad från de globala variabler som specificeras av programmeraren. Endimensionella och tvådimensionella arrayer stöds också.
GML har funktioner för att skapa och redigera sex typer av datastrukturer : stack , kö , lista , karta (associativ array), prioritetskö och rutnät. Rutnätet, listan och kartan kan också nås via accessorer som tillhandahåller en arrayliknande syntax:
var värde = lista[| 0]; // istället för ds_list_find_value(lista, 0) Karta[? "name"] = "Användarnamn"; // istället för ds_map_add(karta, "namn", "Användarnamn") var värde = karta[? "namn"]; // istället för ds_map_find_value(karta, "namn");GML stöder följande datatyper:
Medan GML kan ses som ett objektorienterat språk, skapar karaktären hos objekt och objektinstanser i Game Maker några viktiga skillnader i hur variabler avgränsas. Det finns två typer av lokalitet: lokalitet i ett objekt och lokalitet i ett skript (eller annan kod som finns i en separat behållare). Det faktum att en variabel är lokal för en instans av ett objekt betyder att variabeln är bunden till en viss instans av objektet och endast kan användas utanför den instansen med prefixet som definierar den instansen; det faktum att en variabel är lokal för ett skript innebär att variabeln bara kan användas i det skriptet (och förstörs när skriptet slutar). Från och med nu kommer termen "lokal" att betyda lokalitet i ett objekt. Som standard är en variabel lokal för objektet, men inte lokal för skriptet där den används. För att göra en variabel tillgänglig för alla objektinstanser kan den definieras via det globala namnområdet :
global .foo = "bar";Det är också möjligt att deklarera globala variabler med nyckelordet globalvar :
globalvar foo, bar;Men denna metod bör undvikas, eftersom den lätt kan leda till svårupptäckta fel på grund av skärningspunkten mellan variabla omfattningar (detsamma rekommenderas av GMS-utvecklarna själva; dessutom är det möjligt att detta nyckelord i framtiden kommer att vara helt borttagen från språket - för tillfället lämnas det enbart på grund av bakåtkompatibilitet). För att göra en variabel lokal till ett skript måste den definieras så här:
var foo, bar;Omfattningen av en lokal variabel är skriptet inom vilket den deklareras. Detta innebär att den fortfarande kommer att vara tillgänglig på en kontextväxel ( med ). Till exempel:
var foo = "bar"; med andra { visa_meddelande(foo); // variabel foo är tillgänglig }Ett objekts lokala variabler kan nås genom att använda objektets instansidentifierare som ett prefix
instans.varnamedet är dock inte möjligt att hämta de lokala variablerna för ett skript från ett annat på detta sätt om de inte skickas som funktionsparametrar. Det aktuella namnområdet för ett objekt kan ändras med konstruktionen " med ". Till exempel kommer följande skript, om det placeras i en kollisionshändelse , att förstöra den andra instansen av objektet som är inblandat i den händelsen (observera att i kollisionshändelsen ställer Game Maker automatiskt variabeln annan till den andra instansen av objektet som var kolliderade):
med andra { instance_destroy(); }GML allokerar automatiskt minne för variabler i farten och använder dynamiska typer , så det är också möjligt att tilldela värden av olika typer till variabler. Till exempel kan du först skapa en heltalsvariabel och sedan ändra den till en sträng:
intNumber = 1; intNumber = "Denna variabel innehåller nu en sträng";Det finns ingen speciell funktionalitet i GML som gör att du kan frigöra minnet som upptas av en variabel, men vid behov kan du tilldela variabeln ett nytt, mindre värde. Om du till exempel har en variabel som lagrar stor text kan det frigöra minne om du ställer in variabeln till en tom sträng. Detsamma gäller för arrayer:
data = [1, 2, 3, 4, 5]; // skapade en array (denna syntax för att skapa arrayer är tillgänglig sedan GMS2) data = 0; // förstörde arrayen (det är bara en variabel nu)När ett objekt förstörs förstörs också alla variabler som är lokala för det, och alla globala variabler existerar oberoende av dem. Därför bör företräde ges åt lokala variabler, och globala variabler bör endast användas om det verkligen är nödvändigt. För att lagra stora mängder information mer effektivt stöder Game Maker flera datastrukturer som stack, kö, lista, karta, prioritetskö och rutnät. Dessa strukturer skapas, modifieras och förstörs genom inbyggda funktioner. Det finns också funktioner i nästan alla strukturer för att sortera data i dem. I vissa fall kommer det att vara bekvämare och mer effektivt att använda buffertar som låter dig lagra godtycklig data och som i själva verket bara tilldelas minnesbitar.
Objekt och resurserGame Makers arbete med resurser bygger på unika identifierare som används för att identifiera en specifik resurs eller objektinstans. Dessa identifierare kan användas av skript eller funktioner för att indikera den nödvändiga resursen. Eftersom att skapa resurser direkt i Game Maker kräver ett namn, fungerar detta namn som en konstant som innehåller resursidentifieraren. ID:t för en viss instans lagras i den lokala variabeln " id ". När du skapar resurser dynamiskt returneras alltid identifieraren för den skapade resursen, som kan användas senare.
Här är ett enkelt manusexempel som skriver ut det legendariska " Hej, värld!" »:
show_message("Hej världen!");Ett annat exempel som visar samma text, men i programfönstret. Observera att Game Maker som standard kontinuerligt ritar om fönstret, så i normalfallet ska denna kod placeras i dragningshändelsen.
draw_text(10, 10, "Hej världen!");Här är ett kodavsnitt från GML-spelet:
// detta är en kommentar /* Så här skrivs kommentarer i C++. */ /* definition av temporära variabler. Dessa variabler kommer att raderas efter slutet av skriptet. Observera att variabler inte kräver någon typdefinition! */ var xx , åå , nn ; // Skick. Det kan förkortas till "om (kan_skjuta)". if ( can_shoot = true ) // "=" och "==" kan användas { // Start av kodblock. Du kan också skriva "börja" som i Pascal. /* Sätt variabeln till false. Detsamma kan skrivas så här: "can_shoot = 0;" Eftersom Game Maker inte skiljer mellan booleska och heltalsvärden. */ can_shoot = false ; /* Här ställer vi in en nolltimer för fem steg. Timervariabeln kommer att gå ner till 0, och när den når den kommer nollräknarehändelsen att anropas. */ larm [ 0 ] = 5 ; /* Här definieras den lokala variabeln xx som ett heltal, OCH funktionen lengthdir_x används. */ xx = x + lengthdir_x ( 14 , riktning ); yy = y + lengthdir_y ( 14 , riktning ); //Denna funktion skapar en instans av obj_bullet och returnerar ID:t för det nya objektet. nn = instans_skapa ( xx , yy , obj_bullet ); /* With-satsen låter dig komma åt objektvariabler direkt */ med ( nn ) { hastighet = obj_tank . hastighet + 3 ; riktning = obj_tank . riktning ; } }Kodstilar kan blandas. Till exempel kan det föregående exemplet skrivas så här:
var xx , åå , nn ; om can_shoot = sant så börja can_shoot := falskt larm [ 0 ] := 5 xx := x + lengthdir_x ( 14 , riktning ) yy := y + lengthdir_y ( 14 , riktning ) nn := instance_create ( xx , yy , obj_bullet ) med nn starthastighet : = obj_tank . hastighet + 3 riktningar := obj_tank . riktning ändände _Här är ett exempel på en normal tangentbordskontroll. Funktionen motion_set tar två parametrar: riktning (i grader) och hastighet (pixlar per steg). Att anropa den här funktionen kommer att ändra de inbyggda lokala variablerna hastighet och riktning som Game Maker använder för att flytta objekt (objekt kan också flyttas direkt med hjälp av de lokala x- och y-variablerna):
if ( keyboard_check ( vk_left )) motion_set ( 180 , 4 ); if ( keyboard_check ( vk_up )) motion_set ( 90 , 4 ); if ( keyboard_check ( vk_right )) motion_set ( 0 , 4 ); if ( keyboard_check ( vk_down )) motion_set ( 270 , 4 ); if ( keyboard_check ( vk_nokey )) motion_set ( 0 , 0 );Och här är ett exempel på ett mer komplext manus för ett plattformsspel. Med den kan spelaren gå på en konvex yta:
om ! plats_fritt ( x -4 , y ) { om plats_fritt ( x -4 , y -4 ) { x -= 4 y- = 4 } annat om plats_fritt ( x -3 , y -5 ) { x -= 3 y -= 5 } annat om plats_fritt ( x -2 , y -6 ) { x -= 2 y- = 6 } } annan x -= 4