12/08/2018, 13:06

Ruby game with gosu (part 1)

1 Gosu là gì? Gosu là 1 thư viện game 2D dành cho Ruby và C++. Bạn có thể cài đặt Gosu trên các hệ điều hành sau Mac OS X, Windows và Linux. Gosu cung cấp một số phương tiện cơ bản để tạo một ứng dụng game: Cửa sổ game với các vòng lặp Các hình ảnh 2D và chữ (2D graphics and text) ...

maxresdefault.jpg

1 Gosu là gì?

Gosu là 1 thư viện game 2D dành cho Ruby và C++. Bạn có thể cài đặt Gosu trên các hệ điều hành sau Mac OS X, Windows và Linux.

Gosu cung cấp một số phương tiện cơ bản để tạo một ứng dụng game:

  • Cửa sổ game với các vòng lặp
  • Các hình ảnh 2D và chữ (2D graphics and text)
  • Các âm thanh trong game với nhiều định dạng khác nhau
  • Các sự kiện input cho game như chuột, bàn phím

2 Cài đặt gosu

Trước tiên bạn cần cài đặt ruby, version khuyến khích cài đặt hiện tại là 2.2.

Tiếp theo bạn sử dụng lệnh

gem install gosu

Tuy nhiên đối với với các hệ điều hành khác nhau thì cần cài đặt thêm một số thư viện khác trước khi cài đặt gosu. Bạn có thể tham khảo chi tiết tại

gosu on Windows

gosu on Linux

gosu on OS X

3 Một số ứng dụng đơn giản với Gosu

3.1 Hello world

Đối với một lập trình viên chắc đã quá quen thuộc với hello world. Đây là một ví dụ đơn giản nhất để làm quen với một ngôn ngữ hay một công nghệ gì đó mới mẻ. Dưới đây là một ví dụ rất đơn giản tạo ra một cửa sổ với kích thước 640, 480 với title là Hello World

require 'gosu'

class MyWindow < Gosu::Window
  def initialize
   super(640, 480, false)
   self.caption = 'Hello World!'
  end
end

window = MyWindow.new
window.show

3.2 Gosu Window

Tất cả ứng dụng viết bằng gosu thì đều bắt đầu từ Gosu::Window. Dưới đây là một ví dụ đơn giản cho gosu window

require 'gosu'

class GameWindow < Gosu::Window
  def initialize
    super 640, 480
    self.caption = "Gosu Tutorial Game"
  end

  def update
  end

  def draw
  end
end

window = GameWindow.new
window.show

Trong ví dụ trên lớp con GameWindow sử dụng hàm tạo initialize ở lớp cha Gosu::Window với 2 parameter là 640, 480 sẽ tạo ra một của sổ với độ rộng 640px và cao 480px.

Method update và draw là 2 method quan trọng trong class Gosu::Window để mô phỏng game. Theo mặc định thì 2 method này được gọi 60 lần trong 1 giây để mô phỏng chuyển động của các đối tượng trong game. Theo thứ tự method update được gọi trước để cập nhật giá trị cho các đối tượng sau đó method draw được gọi để vẽ lại các đối tượng trên màn hình.

Ở dòng cuối trong ví dụ trên ta sử dụng method show. Method này sẽ tạo một window và kết thúc khi method close được gọi. Hoạt động của game window được mô tả chi tiết tại Window-Main-Loop

3.3 Using Images (Gosu::Image)

require 'gosu'

class GameWindow < Gosu::Window
  def initialize
    super 640, 480
    self.caption = "Gosu Tutorial Game"

    @background_image = Gosu::Image.new "media/space.png", tileable: true
  end

  def update
  end

  def draw
    @background_image.draw(0, 0, 0)
  end
end

window = GameWindow.new
window.show

(Bạn cần download ảnh space.png và lưu vào thư mục media)

Gosu::Image#initialize với 2 parameters là filename và options.

Gosu::Image#draw để vẽ ra ảnh với các parameters theo thứ tự X coordinate, Y coordinate, Z-order, scale_x, scale_y, color, mode (:default, :additive)

Tương tự với Gosu::Image#draw Gosu::Image cung cấp một method là Gosu::Image:draw_rot dùng để vẽ ảnh khi xoay ở các góc khác nhau.

3.4 Gosu simple animations

Đầu tiên ta tạo module ZOrder dùng để lưu trữ thứ tự hiển thị ưu tiên khi hiển thị các đối tượng trên window. Đối tượng có độ ưu tiên cao (giá trị lớn) sẽ hiển thị đè lên trên đối tượng có giá trị nhỏ hơn nếu chúng bị trùng nhau.

# lib/z_order.rb
module ZOrder
  BACKGROUND = 0
  PLAYER = 1
end

Ta tạo một class class PlayerShip mô tả con tàu mà người chơi điều khiển như sau:

# lib/player_ship.rb

require "./lib/z_order"

class PlayerShip
  def initialize window
    @image = Gosu::Image.new("media/starfighter.bmp")
    @x = @y = @speed_x = @speed_y = @angle = 0.0
    @window = window
  end

  def warp(x, y)
    @x, @y = x, y
  end

  def turn_left
    @angle = -90
  end

  def turn_right
    @angle = 90
  end

  def turn_up
    @angle = 0
  end

  def turn_down
    @angle = 180
  end

  def accelerate
    @speed_x += Gosu::offset_x(@angle, 0.4)
    @speed_y += Gosu::offset_y(@angle, 0.4)
  end

  def move
    @x += @speed_x
    @y += @speed_y
    padding = 16
    @x = [@window.awidth - padding, @x].min
    @y = [@window.height - padding, @y].min
    @x = [padding, @x].max
    @y = [padding, @y].max

    @speed_x *= 0.96
    @speed_y *= 0.96
  end

  def draw
    @image.draw_rot(@x, @y, ZOrder::PLAYER, @angle, 0.5, 0.5, 0.7, 0.7)
  end
end

(Bạn cần download ảnh starfighter.bmp và lưu vào thư mục media)

Trong class này có các thuộc tính như

  • x, y lưu giá trị tọa độ của đối tượng
  • speed_x và speed_y lưu giái trị vận tốc theo trục x và trục y
  • image lưu hình ảnh của đối tượng Các methods
  • turn_left, turn_right, turn_up, turn_down thay đổi hướng di chuyển của đối tượng sang trái, phải, trên, dưới.
  • accelerate tăng tốc cho đối tượng khi người dùng bấm các phím di chuyển đối tượng.
  • move di chuyển đối tượng theo vận tốc của nó và kiểm tra giá trị của nó có vượt ra ngoài độ rộng của window không.
  • draw vẽ lại đối tượng

Thêm đối tượng của PlayerShip vào trong cửa sổ window

Giờ đã sẵn sàng để thêm đối tượng của PlayerShip vào trong cửa sổ window

# game_window.rb
require 'gosu'
require './lib/player_ship'
require './lib/z_order'

class GameWindow < Gosu::Window
  def initialize
    super 640, 480
    self.caption = "Gosu Tutorial Game"

    @background_image = Gosu::Image.new "media/space.png", tileable: true

    @player_ship = PlayerShip.new self
    @player_ship.warp(320, 240)
  end

  def update
    if Gosu::button_down? Gosu::KbLeft
      @player_ship.turn_left
      @player_ship.accelerate
    end
    if Gosu::button_down? Gosu::KbRight
      @player_ship.turn_right
      @player_ship.accelerate
    end
    if Gosu::button_down? Gosu::KbUp
      @player_ship.turn_up
      @player_ship.accelerate
    end

    if Gosu::button_down? Gosu::KbDown
      @player_ship.turn_down
      @player_ship.accelerate
    end
    @player_ship.move
  end

  def draw
    @background_image.draw 0, 0, ZOrder::BACKGROUND
    @player_ship.draw
  end

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

window = GameWindow.new
window.show

Như vậy chúng ta đã thêm được đối tượng PlayerShip vào trong window và sử dụng được các phím mũi tên để điều khiển hướng chuyển động cho đối tượng này.

Screenshot from 2015-12-28 09:16:10.png

Trong phần này chúng ta đã có thể dùng gosuđể tạo ra một ứng dụng game đơn giản với việc hiển thị đối tượng dưới dạng ảnh và điểu khiển được đối tượng này. Trong phần tiếp theo chúng ta sẽ tìm hiểu sâu hơn về gosu và tạo ra những hiệu ứng khó hơn với gosu.

Cảm ơn bạn đã theo dõi bài viết !

Demo github

0