0

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
4

1 回答 1

0

@dodgeCount似乎正在跟踪分数的变量在 class 中Ball,而您正在使用在 classalert中显示另一个(否则未使用的)变量MyGame。当 Ruby 看到一个实例变量名称(以 开头@)时,如果它不存在,它将自动为您创建该实例变量,因此您最终会得到一个nil分数值,然后最终显示为""(because nil.to_s == "")。

还有一个问题是你有三个球,每个球都会单独跟踪得分。

您最好在MyGame要显示它的同一类中跟踪分数。最简单的做法是将一些代码Ball#updateMyGame#update.

您将需要初始化并重新设置分数

@dodgeCount = 0

MyGame#initializeMyGame#restart_game

在您当前所在的位置MyGame#update@balls.each {|ball| ball.update}添加代码以检测闪避,并跟踪分数:

@balls.each do |ball| 
  ball.update
  if ball.y > height
    ball.reset!
    @dodgeCount = @dodgeCount + 1
  end
end

Ball#update简化:

def update
  @y = @y + 10
end

我希望这对你有用,我没有gosu可用于详细检查的副本。

于 2013-08-25T15:34:03.650 回答