Gosu - Thư viện game 2D cho Ruby

Stage 1: Make something moves

Mở đầu

Khi nhắc đến lập trình game thì hầu hết mọi người đều bảo rằng bạn nên học C++ hoặc một nền tảng khá phổ biến là Unity, còn Ruby thì có vẻ như lại là sự lựa chọn cuối cùng mà bất kỳ nhà phát triển game nào cũng sẽ trả lời như vậy.

Chính xác, cho đến nay thì cũng có rất ít tài liệu hướng dấn phát triển game bằng Ruby, nhưng không hẳn game phải là một 3D MMORPG khủng, một thế giới rộng lớn và phong phú như GTA, cứ để việc đó cho Ubisoft, Rockstar hay Bethesda...thể loại game mình muốn đề cập đến đó là một cái gì đó bé hạt tiêu kiểu từ thời Super Nintendo 😄

Chuẩn bị và cài đặt

Trong bài này mình sử dụng OSX (Những hệ điều hành khác cũng OK).

Với OSX thì cần có Xcode. được cài đặt với câu lệnh:

xcode-select --install

Tiếp theo là gem Gosu:

gem install gosu

Để test Gosu được cài đặt chưa thì kiểm tra qua irb.

$ irb

irb(main):001:0> require 'gosu' => true

Ngoài ra nếu bạn muốn tự design môi trường hoặc nhân vật theo phong cách pixel thì có thể sử dụng photoshop hoặc Pixen...

Mission Start

☆ challenge 1: make game screen

Ví dụ mình đặt tên file là main.rb

Đầu tiên, "yêu cầu" Gosu.

   require 'gosu'

Tiếp theo tạo mới một game window với các đối số tương ứng là: width, heigh, fullscreen (kiểu boolean, mình để là false).

game_window = Gosu::Window.new(800, 600, false)
#game window 800px - 600px không fullscreen

Sau đó bạn thử chạy màn hình vừa tạo xem thế nào nhé.

$ ruby main.rb

Nhưng rất tiếc chả có gì hiện ra đâu vì game_window vừa tạo cần phải có phương thức show để hiện ra cơ >:)

require 'gosu'
game_window = Gosu::Window.new(800, 600, false)
#game window 800px - 600px không fullscreen
game_window.show

OK, bây giờ một cửa sổ đen ngòm 800x600 hiện ra rồi 😄

Bây giờ bỏ mọi thứ vào một class cho gọn.

require 'gosu'

class GameWindow < Gosu::Window

    def initialize width, height, fullscreen
        super(width, height, fullscreen)
        self.caption = "Hello" #set title của game_window

    end

    def update
    end

    def draw
    end
end

game_window = GameWindow.new(800, 600, false)
#game window 800px - 600px không fullscreen
game_window.show

Có 3 phương thức chính là initialize, draw và update. Để hiểu rõ hơn thì mình sẽ tiếp tục với ví dụ chèn thêm hình ảnh và tạo vật thể chuyển động trong game_window.

Chèn hình ảnh: sử dụng phương thức Image trong Gosu. Ví dụ tên biến là sprite ~:>

@sprite = Gosu::Image.new(self, "Pokechar.png", false)

require 'gosu'

class GameWindow < Gosu::Window

    def initialize width, height, fullscreen
        super(width, height, fullscreen)
        self.caption = "Hello" #set title của game_window
        @sprite = Gosu::Image.new(self, "Pokechar.png", false)

    end

    def update
    end

    def draw
    end
end

game_window = GameWindow.new(800, 600, false)
#game window 800px - 600px không fullscreen
game_window.show

Cụ thể đối số của Gosu::Image là:

self: hiển thị ảnh trong game_window

"Pokechar.png": browse đến file ảnh. Trường hợp này file ảnh cùng chỗ với file main.rb

true hoặc false: đây là title set của image. false nghĩa là ảnh sẽ được làm mềm viền nếu kích cỡ cho vào game_window nhỏ hơn so với thực tế.

OK khai báo xong. Bây giờ đưa nó vào màn game_window bằng phương thức draw.

@sprite.draw(250, 250, 0)

require 'gosu'

class GameWindow < Gosu::Window

    def initialize width, height, fullscreen
        super(width, height, fullscreen)
        self.caption = "Hello" #set title của game_window
        @sprite = Gosu::Image.new(self, "Pokechar.png", false)

    end

    def update
    end

    def draw
        @sprite.draw(250, 250, 0)
    end
end

game_window = GameWindow.new(800, 600, false)
#game window 800px - 600px không fullscreen
game_window.show

Phương thức draw có 3 đối số là chiều ngang x = 250px, chiều dọc y = 250px và một "chiều" nữa là z = 0. Rõ là game 2D mà lại có 3 chiều =.=, thực ra đây là độ ưu tiên của vật thể khi đưa vào màn game_window. Vật thể nào có giá trị z cao hơn sẽ đè lên vật thể có giá trị z nhỏ hơn.

Và sau khi chạy main.rb thì kết quả sẽ là:

Sprite.png

Và tiếp theo là làm nhân vật di chuyển bằng cách làm đối số x thay đổi 😃)

Vì ảnh đang được cố định là 250, 250 như trên nên mình sẽ khai báo thêm @x và @y để có thể thay đổi được nó trong phương thức update. @sprite.draw(250, 250, 0)

require 'gosu'

class GameWindow < Gosu::Window

    def initialize width, height, fullscreen
        super(width, height, fullscreen)
        self.caption = "Hello" #set title của game_window
        @sprite = Gosu::Image.new(self, "Sprite.png", false)

        @x = 250
        @y = 250
    end

    def update
        @x += 3
    end

    def draw
        @sprite.draw(@x, @y, 0)
    end
end

game_window = GameWindow.new(800, 600, false)
game_window.show

Vây là nhân vật di chuyển được rồi 😄 Trong phương thức update sẽ được gọi 60 lần 1 giây, đồng nghĩa với việc mỗi lần gọi thì @x sẽ tăng lên 3px, từ đó nhân vật sẽ "di chuyển" theo chiều x. Nếu thay đổi @y thì nhân vật sẽ di chuyển theo chiều y. Còn nếu thay đổi cả @x và @y thì... Các bạn làm thử xem nhé 😄

Trong các bài viết tới sẽ còn nhiều điều thú vị nữa nhé 😄

Cảm ơn các bạn đã theo dõi \m/

Tài liệu tham khảo:

https://leanpub.com/developing-games-with-ruby/read

https://www.youtube.com/watch?v=L4RWsE8z-is&t=712s

All Rights Reserved