Векторные «Игроки», а не изображения с использованием Chingu и Gosu - PullRequest
3 голосов
/ 09 июля 2010

Пример Chingu выглядит примерно так:

require 'rubygems'
require 'chingu'

class Game < Chingu::Window
  def initialize
    super
    @player = Player.new
  end
end

class Player < Chingu::GameObject
  def initialize(options = {})
    super(options.merge(:image => Gosu::Image["player.png"])
  end
end

Game.new.show

Если я хочу, чтобы объект Player рисовался линиями, а не изображениями, как бы я это сделал?

Следующий код кажется интуитивно понятным, но я не могу заставить его работать!

class Player < Chingu::BasicGameObject
  def initialize(options = {})
    super
    @radius = options[:radius]
    @c = Gosu::Color.new(0xffff0000)
  end

  def draw
    $window.draw_rect([@x-1,@y+1,@x+1,@y+1,@x+1,@y-1,@x+1,@y+1],@c,1)
  end
end

Я что-то не так делаю?

1 Ответ

5 голосов
/ 29 июля 2010

Давайте разберемся.

Я предполагаю, что это неполные фрагменты вашего реального кода, так как код, как показано, вызывает draw_rect с @x и @y, установленными в ноль, бросая «неопределенный метод» - для исключения nil: nilClass, потому что Вы ничего не можете вычесть из нуля.)

Я подозреваю, что вы видите пустое окно, в котором ничего не нарисовано, потому что, как написано, ваш Player.draw никогда не будет вызван.

Почему? Потому что Chingu обеспечивает автоматическое рисование и обновление для всех его GameObjects, но только если вы используете GameObject.create вместо GameObject.new.

(http://rdoc.info/projects/ippa/chingu)

Chingu :: GameObject

Используйте это для всех ваших в игре объекты. Игрок, враги, пули, бонусы, бабло лежать вокруг Это очень многоразово и не содержит игровой логики (это до вас!). Только вещи, чтобы положить это на экране определенным образом. Если вы делаете GameObject.create () вместо new () Чингу продолжит сохранять объект в список «game_object» для автоматического Обновления / розыгрыши.

Chingu :: BasicGameObject

Новый () против создания () поведение GameObject поставляется с BasicGameObject.

Так что нам нужно это исправить. Однако ...

Теперь, когда Player.draw правильно вызывается каждый кадр Чингу, мы нашли новую проблему: вызов draw_rect не работает! Вот что говорит мне Руби:

in draw_rect': undefined method x 'для [99, 101, 101, 101, 101, 99, 101, 101]: Array (NoMethodError)

Хммм ... я вижу, что передается в метод draw_rect, Интересно, что он ожидает получить? Давайте посмотрим на код.

(http://github.com/ippa/chingu/blob/master/lib/chingu/helpers/gfx.rb)

  # Draws an unfilled rect in given color
  #
  def draw_rect(rect, color, zorder)
    $window.draw_line(rect.x, rect.y, color, rect.right, rect.y, color, zorder)
    $window.draw_line(rect.right, rect.y, color, rect.right, rect.bottom, color, zorder)
    $window.draw_line(rect.right, rect.bottom, color, rect.x, rect.bottom, color, zorder)
    $window.draw_line(rect.x, rect.bottom, color, rect.x, rect.y, color, zorder)
  end

Ах, теперь это имеет смысл. draw_rect ожидает передачи объекта Rectangle, а не куча координат. Вот оно:

(http://rdoc.info/projects/ippa/chingu)

     Chingu::Rect

     Constructor Details

- (Rect) initialize(*argv)

Create a new Rect, attempting to extract its own information from the 
given arguments.

The arguments must fall into one of these cases:

- 4 integers +(x, y, w, h)+.
- 1 Rect or Array containing 4 integers +([x, y, w, h])+.
- 2 Arrays containing 2 integers each +([x,y], [w,h])+.
- 1 object with a +rect+ attribute which is a valid Rect object.

All rect core attributes (x,y,w,h) must be integers.

Так что нам просто нужно сначала создать объект Rect, а затем вызвать draw_rect с этим Rect в качестве первого параметра.

Хорошо, давайте сделаем это. Вот рабочий код -

require 'rubygems'
require 'chingu'

class Game < Chingu::Window
  def initialize
    super
    puts "initializing player..."
    @player = Player.create
  end

end

class Player < Chingu::BasicGameObject
  def initialize(options = {})
    super
    @x = 100
    @y = 100
    @rect = Chingu::Rect.new(@x, @y, 10, 10)
    @c = Gosu::Color.new(0xffff0000)
  end

  def draw
    puts "inside draw"
    puts @x, @y
    $window.draw_rect(@rect, @c, 1)
  end
end

Game.new.show

При запуске теперь отображается маленький красный прямоугольник на 100 100.

Надеюсь, это поможет.

* * С тысячей сорок-девять ~
...