Game Maker-språk

Den aktuella versionen av sidan har ännu inte granskats av erfarna bidragsgivare och kan skilja sig väsentligt från versionen som granskades den 15 juni 2016; kontroller kräver 6 redigeringar .
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").

Bibliotek

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.

Syntax och semantik för GML

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öds

och

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).

Funktioner

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.).

Variabler

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å.

Datastrukturer

GML har funktioner för att skapa och redigera sex typer av datastrukturer : stack , , 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");

Typer

GML stöder följande datatyper:

Variablers omfattning

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.varname

det ä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(); }

Minnestilldelning

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 resurser

Game 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.

Skriptexempel

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 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

Kritik

Den lösa syntaxen i GML gör det lättare att skapa spel till viss del, men kan generera helt oläsbar kod: switch 0 start case 0 : x = 0 break } om a = 0 sedan börja b = 1 } annars om a == 0 { b := 1 end Även om det inte är en del av språket, var en annan vanlig kritik mot äldre versioner av Game Maker processen att skapa EXE-filer, som består av en laddare och GM-filresurser. När man startar ett sådant spel tolkas koden till ett abstrakt syntaxträd (kodtolkning användes), vilket underlättade dekompileringen och avsevärt ökade laddningstiden. Men i mer moderna versioner (GameMaker: Studio) har mekanismerna ändrats, så det är inga problem med vare sig lanseringshastighet eller dekompilering (det finns inga dekompilatorer för GMS).

Litteratur

  • Matthew DeLucas. GameMaker Spelprogrammering med GML. - Packt, 2014. - 350 sid. — ISBN 978-1-78355-944-2 .

Se även

Länkar