Den här lektionen kommer att handla mycket om pixlar – de där små punkterna som bilden på en datorskärm är uppbyggd av. Vi ska se till så att vårt rymdskepp kan flyga i alla riktningar, men också så att det håller sig i spelfönstret och inte kommer på villovägar.
Först ska vi ta och ändra lite i Hero
-klassens metod move_forward
, den som får rymdskeppet att röra sig framåt. Vi vet att spelfönstret är 640 pixlar brett. Vi vet också att bilden av rymdskeppet är 70 pixlar bred. Eftersom rymdskeppets position mäts i övre vänstra hörnet på bilden, så vill vi att skeppet ska stanna 70 pixlar från högerkanten, det vill säga när värdet på @x
är 570.
Återigen är det här lättare att förstå om man provar. Lägg till följande if-sats i move_forward
-metoden:
def move_forward
@x = @x + 5
if @x > 570
@x = 570
end
end
Spara och provkör. Som du märker kan skeppet inte längre köra ut från fönstret. If-satsen kontrollerar nämligen om värdet på @x
är större än 570, och om så är fallet ändras värdet tillbaka till 570.
Fast tänk om vi får för oss att ändra bredden på spelfönstret? Då kommer ju skeppet att stanna på fel ställe. Därför är det bättre att skriva så här:
def move_forward
@x = @x + 5
if @x > @window.width - @icon.width
@x = @window.width - @icon.width
end
end
Denna kod är lite mer elegant. Den gör så att rymdskeppet alltid stannar precis vid högerkanten på spelfönstret, oavsett hur brett fönstret är. På grund av if-satsen kan @x
aldrig bli större än fönstrets bredd minus bildens bredd ("width" betyder just "bredd").
Men det går fortfarande inte att flyga skeppet i någon annan riktning än framåt. Därför lägger vi först till ytterligare tre if-satser i Window
-klassens update
-metod:
def update
if button_down? Gosu::Button::KbRight
@hero.move_forward
end
if button_down? Gosu::Button::KbLeft
@hero.move_back
end
if button_down? Gosu::Button::KbUp
@hero.move_up
end
if button_down? Gosu::Button::KbDown
@hero.move_down
end
end
Sedan lägger vi till de move
-metoder som saknas i Hero
-klassen, direkt efter move_forward
:
def move_back
@x = @x - 5
if @x < 0
@x = 0
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 - @icon.height
@y = @window.height - @icon.height
end
end
För att få skeppet att flyga framåt såg vi till att värdet på @x
ökade när man tryckte på högerpilen. När det ska flyga bakåt måste vi i stället minska värdet på @x
. Det sker i metoden move_back
. If-satsen i metoden gör så att @x
aldrig kan bli mindre än 0. Därmed kan skeppet inte heller flyga ut från den vänstra kanten på fönstret.
De båda metoderna move_up
och move_down
fungerar på samma sätt. Men här är det y-värdet – skeppets position i höjdled – som ändras. Tack vare if-satserna kan @y
aldrig bli mindre än 0 eller större än fönstrets höjd minus bildens höjd. Skeppet kan inte längre försvinna!
Hela programmet ska nu se ut så här:
require 'gosu'
class Window < Gosu::Window
def initialize
super(640, 480, false)
@hero = Hero.new(self)
end
def update
if button_down? Gosu::Button::KbRight
@hero.move_forward
end
if button_down? Gosu::Button::KbLeft
@hero.move_back
end
if button_down? Gosu::Button::KbUp
@hero.move_up
end
if button_down? Gosu::Button::KbDown
@hero.move_down
end
end
def draw
@hero.draw
end
end
class Hero
def initialize(window)
@window = window
@icon = Gosu::Image.new(@window, "spaceship.png", true)
@x = 100
@y = 215
end
def move_forward
@x = @x + 5
if @x > @window.width - @icon.width
@x = @window.width - @icon.width
end
end
def move_back
@x = @x - 5
if @x < 0
@x = 0
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 - @icon.height
@y = @window.height - @icon.height
end
end
def draw
@icon.draw(@x, @y, 2)
end
end
window = Window.new
window.show
Puh! De två senaste lektionerna har varit ganska mastiga, och om du behöver ta en paus nu så förstår jag dig. När du är redo att fortsätta ska vi ta och lägga till något som vårt rymdskepp ska undvika – en asteroid!