Как исправить несоответствующий тип объекта, возвращаемого в ruby?

#ruby

#ruby

Вопрос:

Я разрабатываю приложение с использованием ruby2d.

У меня есть функция, которая должна возвращать объект, класс которого является «Tile».

Объект, который будет возвращен, — это «tileStone», и пока он находится внутри функции, его класс — «Tile» (я использовал несколько «puts» для печати этой информации). Но, когда он возвращается для функции main, он возвращается как объект «Ruby2D::Window::EventDescriptor». Почему?

  def player1turn(grid)
      tileStone  = stoneChose(1,grid)
      puts tileStone.class #here it prints "Ruby2D::Window::EventDescriptor", which is wrong
  end

  def stoneChose(nplayer,grid)
    Window.on :mouse do |event|
      case event.button
      when :left
        grid.movableStone(grid.getPlayer(nplayer)).each do |tileStone|
          if tileStone.contains? event.x, event.y
            puts tileStone.class #here it prints "Tile"
            tileStone

          end 
        end 
      end
    end 
  end
  

Комментарии:

1. Для меня не ясно, что должно быть возвращено в stoneChose . Это первый найденный tileStone? Если да, то замените tileStone на return tileStone . Я не уверен, но без точного возврата Ruby вернет последний объект, видимый в процедуре

2. Для первого комментария: Да. Он вернет первый найденный tileStone. Я не могу использовать «return tileStone», потому что ruby мне этого не позволяет (там написано, что это неожиданный возврат), поэтому я просто пропустил «return». Во-вторых: почему события будут происходить через долгое время после этого?

Ответ №1:

Я не знаком с ruby2d , но кажется, что Window.on это только помещает прослушиватель / обработчик событий и возвращает EventDescriptor . Далее, при запуске события, будет выполнен код внутри on . Таким образом, ваша функция stoneChose просто устанавливает этот прослушиватель событий и возвращает экземпляр этого класса-дескриптора.

Вы можете проверить общую архитектуру ruby2d проекта в этой игре в понг. Короче говоря:

1) Сначала вы должны настроить все ваши прослушиватели событий

 def setup
    Window.on :mouse do |event|
        case event.button
        when :left
        grid.movableStone(grid.getPlayer(nplayer)).each do |tileStone|
            if tileStone.contains? event.x, event.y
                doSmthWithTileStone(tileStone)
            end
        end
    end
end
  

2) Определите функцию, которая выполняет некоторое действие с вашим найденным объектом при каждом событии

 def doSmthWithTileStone(tileStone)
    puts tileStone
end
  

3) И выполните основной цикл приложения

 def main
    setup

    update do
        ...
    end
end

main