12/08/2018, 15:10

Gosu - Thư viện game 2D cho Ruby - Cùng bắt đầu với game đơn giản - Phần 2

Tiếp theo phần 1, ở phần này mình thực hiện tạo những ngôi sao và animation cho chúng. Định nghĩa chiều Z Đầu tiên mình tạo module ZOrder để định nghĩa chiều Z cho đối tượng. Trong game 2D chỉ có 2 chiều X và Y vậy thì chiều Z là cái gì, Z quy định đối tượng nào nằm đè, đối tượng nào bị đè nhé. ...

Tiếp theo phần 1, ở phần này mình thực hiện tạo những ngôi sao và animation cho chúng.

Định nghĩa chiều Z

Đầu tiên mình tạo module ZOrder để định nghĩa chiều Z cho đối tượng. Trong game 2D chỉ có 2 chiều X và Y vậy thì chiều Z là cái gì, Z quy định đối tượng nào nằm đè, đối tượng nào bị đè nhé. Z càng cao thì đối tượng đó sẽ nằm trên cùng. zorder.rb

module ZOrder
  Background, Stars, Player, UI = *0..3
end

Star animation

Mình tạo một class star để định nghĩa animation. star.rb

class Star
  attr_reader :x, :y

  def initialize(animation)
    @animation = animation
    @color = Gosu::Color.new(0xff_000000)
    @color.red = rand(256 - 40) + 40
    @color.green = rand(256 - 40) + 40
    @color.blue = rand(256 - 40) + 40
    @x = rand * 640
    @y = rand * 480
  end

  def draw
    img = @animation[Gosu::milliseconds / 100 % @animation.size];
    img.draw(@x - img.awidth / 2.0, @y - img.height / 2.0,
        ZOrder::Stars, 1, 1, @color, :add)
  end
end

Các bạn down star và để trong /media nhé. @color để random màu cho start, và vị trí cũng được random qua @x, @y. File star gồm 10 sprites (25 x 25) nhỏ, cứ mỗi 0.1s là 1 sprite được gọi bằng phương thức draw img = @animation[Gosu::milliseconds / 100 % @animation.size]; Và ở gosu0.rb mình cắt file star.png thành các sprites kích thước 25x25 bằng @star_anim = Gosu::Image::load_tiles("media/star.png", 25, 25) và đưa vào Array @stars. Ở phương thức Update nếu số stars < 25 và random < 0.04 thì sẽ add thêm 1 star.

if rand(100) < 4 and @stars.size < 25 then
    @stars.push(Star.new(@star_anim))
end

Định nghĩa @font = Gosu::Font.new(20) để hiển thị điểm @font.draw("Score: #{@player.score}", 10, 10, ZOrder::UI, 1.0, 1.0, Gosu::Color::YELLOW)

Code gosu0.rb hoàn chỉnh.

require 'gosu'
require './player'
require './star'
require './zorder'

class GameWindow < Gosu::Window
    def initialize
        super 640,480,false
        self.caption = "Spaceship"
        @background_image = Gosu::Image.new("media/space.png")

        @player = Player.new
        @player.warp(320, 240)

        @star_anim = Gosu::Image::load_tiles("media/star.png", 25, 25)

        @stars = Array.new

        @font = Gosu::Font.new(20)
    end

    def update
        if Gosu::button_down? Gosu::KbLeft or Gosu::button_down? Gosu::GpLeft then @player.turn_left end
        if Gosu::button_down? Gosu::KbRight or Gosu::button_down? Gosu::GpRight then @player.turn_right end
        if Gosu::button_down? Gosu::KbUp or Gosu::button_down? Gosu::GpButton0 then @player.accelerate end
        @player.move
        @player.collect_stars(@stars)

        if rand(100) < 4 and @stars.size < 25 then
            @stars.push(Star.new(@star_anim))
        end
    end

    def draw
        @player.draw
        @background_image.draw(0,0,0)
        @stars.each{ |star| star.draw}
        @font.draw("Score: #{@player.score}", 10, 10, ZOrder::UI, 1.0, 1.0, Gosu::Color::YELLOW)
    end

    def button_down(id)
        close if id == Gosu::KbEscape
    end
end

window = GameWindow.new
window.show

Và bây giờ các bạn chạy game thử xem nhé: $ruby gosu0.rb w_4VuM Chúc các bạn thành công             </div>
            
            <div class=

0