I wrote a fairly simple game in ruby, where you are a space shuttle and you have to dodge a few meteorites. I decided to put in a dodge counter, but the alert message isn't showing the actual score. Here's the code:
@dodgeCount = 0
require 'gosu'
class MyGame < Gosu::Window
def initialize
super(600, 400, false)
@player1 = Player.new(self)
@balls = 3.times.map {Ball.new(self)}
@running = true
end
def update
if @running
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
@balls.each {|ball| ball.update}
if @player1.hit_by? @balls
stop_game!
alert "Your score is " + @dodgeCount.to_s
end
else
#the game is now stopped
if button_down? Gosu::Button::KbEscape
restart_game
end
end
end
def draw
@player1.draw
@balls.each {|ball| ball.draw}
end
def stop_game!
@running = false
end
def restart_game
@running = true
@balls.each {|ball| ball.reset!}
end
end
class Player
def initialize(game_window)
@game_window = game_window
@icon = Gosu::Image.new(@game_window, "gosu/player1.png", true)
@x = 50
@y = 330
end
def draw
@icon.draw(@x, @y, 1)
end
def move_left
if @x < 0
@x = 0
else
@x = @x - 10
end
end
def move_right
if @x > (@game_window.width - 75)
@x = @game_window.width - 75
else
@x = @x + 10
end
end
def move_up
if @y < 0
@y = 0
else
@y = @y - 10
end
end
def move_down
if @y > (@game_window.height - 75)
@y = @game_window.height - 75
else
@y = @y + 10
end
end
def hit_by? (balls)
balls.any? {|ball| Gosu::distance(@x, @y, ball.x, ball.y) < 50}
end
end
class Ball
def initialize(game_window)
@game_window = game_window
@icon = Gosu::Image.new(@game_window, "gosu/asteroid.png", true)
reset!
end
def update
if @y > @game_window.height
reset!
@dodgeCount = @dodgeCount + 1
else
@y = @y + 10
end
end
def draw
@icon.draw(@x, @y, 2)
end
def x
@x
end
def y
@y
end
def reset!
@y = 0
@x = rand(@game_window.width)
end
end
window = MyGame.new
window.show
The
@dodgeCount
variable that appears to be tracking the score is in classBall
, whilst you are usingalert
to display another (otherwise unused) variable in classMyGame
. When Ruby sees an instance variable name (beginning with@
), it will create that instance variable for you automatically if it doesn't already exist, so you end up with anil
value for the score, which then ends up displaying as""
(becausenil.to_s == ""
).There is also the problem that you have three balls, and each one will track the score separately.
You will be better off tracking the score in the same
MyGame
class where you want to display it. The easiest thing to do is move some of the code fromBall#update
toMyGame#update
.You will need to initialise and re-set the score with
In
MyGame#initialize
andMyGame#restart_game
Where you currently have in
MyGame#update
,@balls.each {|ball| ball.update}
add code to detect dodges, and track the score:And
Ball#update
is simplified:I hope this works for you, I don't have a copy of
gosu
available to check in detail.