Att kunna skapa sina egna datorspel – det är vad många, i synnerhet kanske barn, ser som själva poängen med att lära sig programmering. När mina egna ungar gör spel så använder de än så länge Scratch, ett lättanvänt och roligt verktyg som jag har skrivit om tidigare. Men även med Ruby är det relativt enkelt att skapa ett spel. Tricket är att använda sig av något som heter Gosu, och som jag strax ska berätta mer om.

Först några rader om vad som väntar. Det här långa inlägget handlar om hur man kan göra ett enkelt rymdspel, eller i alla fall början på ett, med Rubykod. För att du ska kunna hänga med på ”lektionen” krävs att du har installerat Ruby på din dator, och att du vet hur man skriver program i en texteditor och kör dem via kommandoprompten. Det vill säga precis vad bloggposten Kom igång med Ruby handlade om. Har du dessutom ett hum om vad begrepp som objekt, klasser, metoder och variabler betyder i det här sammanhanget så underlättas förståelsen, men det är inte nödvändigt.

Så där. Åter till Gosu, som rent konkret är ett bibliotek med programsnuttar. I de här snuttarna definieras klasser och metoder som används vid spelprogrammering, för att exempelvis skapa grafikfönster, spela upp ljud och musik och känna av när spelaren rör på musen eller trycker på tangentbordet. Grovjobbet är, med andra ord, redan gjort. Men för att kunna använda Gosu måste du först installera det. Starta Rubys kommandoprompt och skriv gem install gosu följt av return. Klart!

Nu är det dags att börja på själva programmet. Öppna ett nytt dokument i din texteditor. Allra överst ska det stå:

require 'gosu'

Denna rad ger oss tillgång till Gosu-biblioteket. Sedan är det dags att skriva den första så kallade klassdefinitionen, som ska se ut så här (du kan, om du vill, bortse från att vissa rader är indragna men var noga med små/stora bokstäver):

class Window < Gosu::Window
  def initialize
    super(300, 400, false)
  end

  def update
  end

  def draw
  end
end

window = Window.new
window.show

Här definieras klassen Window, som vi först låter ärva egenskaper från Gosu-klassen med samma namn. Sedan definieras tre metoder: initialize, update och draw. I initialize-metoden talar vi om att grafikfönstret ska vara 300 pixlar brett och 400 pixlar högt, samt att det inte ska fylla upp hela skärmen (annars hade vi skrivit ”true” i stället för ”false”). De två sista raderna i programmet skapar ett nytt objekt av klassen Window, innan själva grafikfönstret framkallas med metoden ”show”. Om du tycker att det här låter krångligt är det helt i sin ordning – det hade jag också tyckt för bara några veckor sedan.

När det här programmet körs visas alltså ett grafikfönster. Dessutom startas en loop som hela tiden anropar metoderna update och draw som, än så länge, inte utför något alls. Nu vill vi ha någonting som symboliserar spelaren: en bild av ett rymdskepp. Här tar jag en genväg och använder en bildfil som följer med Rubyinstallationen och som heter ”Starfighter.bmp” (sök på filnamnet och du lär hitta den i din dator). Om du vill rita ett rymdskepp själv i ett ritprogram kan du förstås göra det – se bara till att bilden är 50 gånger 50 pixlar stor. Annars: kopiera ”Starfighter.bmp” och lägg bilden i samma mapp som ditt program.

Nu är det dags att definiera ytterligare en klass, som får namnet Player:

class Player
  def initialize(window)
    @window = window
    @icon = Gosu::Image.new(@window, "Starfighter.bmp", true)
    @x = 125
    @y = 175
  end

  def draw
    @icon.draw(@x, @y, 1)
  end
end

Här berättar vi för datorn vilken bild som ska användas samt, med variablerna @x och @y, vilket utgångsläge den ska ha i grafikfönstret. Vi måste också göra några ändringar i klassen Window. I metoden initialize lägger vi, på en egen rad, till @player1 = Player.new(self) som skapar ett nytt objekt av klassen Player när spelet startas. I metoden draw låter vi rymdskeppet framträda på skärmen med raden @player1.draw, som helt enkelt anropar motsvarande metod i Player-objektet.

Om vi nu sparar programmet, förslagsvis som ”spel.rb”, och provkör det genom att skriva ruby spel.rb vid kommandprompten öppnas ett fönster som ser ut så här:

spel

Vackert så. Men vi vill ju kunna styra vårt rymdskepp också. Vi tar återigen hjälp av Gosu, som innehåller metoder som känner av om olika tangenter är nedtryckta. I Window-klassens metod update lägger vi till följande så kallade villkorssatser:

if button_down? Gosu::Button::KbLeft
  @player1.move_left
end

if button_down? Gosu::Button::KbRight
  @player1.move_right
end

if button_down? Gosu::Button::KbUp
  @player1.move_up
end

if button_down? Gosu::Button::KbDown
  @player1.move_down
end

Och så måste vi, i klassen Player, lägga till de metoder som anropas ovan och som, beroende på vilken piltangent som är nedtryckt, ska ändra värdena på variablerna @x och @y:

def move_left
  @x = @x - 5
  if @x < 0
    @x = 0
  end
end

def move_right
  @x = @x + 5
  if @x  > @window.width - 50
    @x = @window.width - 50
  end
end

def move_up
  @y = @y - 5
  if @y < 0
    @y = 0
  end
end

def move_down
  @y = @y + 5
  if @y  > @window.height - 50
    @y = @window.height - 50
  end
end

Om du nu kör programmet igen ska du kunna styra rymdskeppet över hela grafikfönstret. Går det för snabbt eller för långsamt? Ändra då move-metoderna ovan och låt @x och @y minska/öka med mer/mindre än 5 (t ex @x = @x - 10). Funkar det inte alls? Allra sist i inlägget länkar jag till en textfil som innehåller programmet i sin helhet. Jämför med din egen kod. Kanske har du stavat fel någonstans, eller missat något tecken?

Vi har nu kommit en bra bit på väg. Men det är fortfarande mycket som saknas: någon form av motståndare eller hinder, poängräkning, en bakgrundsbild osv. Fast vet du vad? Hädanefter får du klara dig på egen hand!

Lugn, bara lugn. På nätet finns flera bra tutorials, kurser, om hur man använder Gosu, och som jag själv lärt mig mycket av och lånat friskt ifrån när jag skrev det här inlägget. Till exempel tar tredje lektionen i den här kursen vid där jag slutade. Det finns också en bra kurs inbyggd i verkyget Kids Ruby, som kan laddas ner här.

Lycka till! Och berätta gärna hur det gick, eller lämna synpunkter, i kommentarsfältet nedan.

/Mats

Programmet i sin helhet hittar du här.

Annonser