Gosu - Thư viện game 2D cho Ruby - Phần 3
Bài đăng này đã không được cập nhật trong 7 năm
Trong bài viết này mình sẽ giới thiệu về chức năng di chuyển nhân vật bằng phím Mình thử 1 ví dụ di chuyển nhân vật bằng 4 phím điều hướng và thoát bằng phím Esc.
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.gif", false)
@x = 20
@y = 30
end
def update
@x -= 1 if button_down?(Gosu::KbLeft)
@x += 1 if button_down?(Gosu::KbRight)
@y -= 1 if button_down?(Gosu::KbUp)
@y += 1 if button_down?(Gosu::KbDown)
end
def button_down(id)
close if id == Gosu::KbEscape
end
def draw
@sprite.draw(@x, @y, 0)
end
end
game_window = GameWindow.new(800, 600, false)
game_window.show
Trong đoạn code dưới, khi ấn 4 phím điều hướng sẽ tương đương với sự thay đổi toạ độ @x, @y.
def update
@x -= 1 if button_down?(Gosu::KbLeft)
@x += 1 if button_down?(Gosu::KbRight)
@y -= 1 if button_down?(Gosu::KbUp)
@y += 1 if button_down?(Gosu::KbDown)
end
Và cửa sổ sẽ được tắt nếu ấn phím Escape.
def button_down(id)
close if id == Gosu::KbEscape
end
Nhưng về cơ bản các bạn xem hình bên dưới để hiểu rõ hơn về vòng lặp nhé.
Nhưng các bạn chú ý function draw, nó được tạo liên tục kể cả bạn không thực hiện thao tác gì cả, vì vậy nó sẽ làm hệ thống chậm đi khá nhiều với game nặng. Để ngăn chặn việc này, Gosu cung cấp hàm needs_redraw? Và bây giờ các bạn thử thêm một đoạn code như dưới để hiểu thêm về draw nhé.
- Trường hợp không sử dụng needs_draw?
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.gif", false)
@x = 20
@y = 30
@draws = 0
end
def update
@x -= 1 if button_down?(Gosu::KbLeft)
@x += 1 if button_down?(Gosu::KbRight)
@y -= 1 if button_down?(Gosu::KbUp)
@y += 1 if button_down?(Gosu::KbDown)
end
def button_down(id)
close if id == Gosu::KbEscape
end
def draw
@draws += 1
@sprite.draw(@x, @y, 0)
@message = Gosu::Image.from_text(self,@draws, Gosu.default_font_name, 30)
@message.draw(@x, @y, 1)
end
end
game_window = GameWindow.new(800, 600, false)
game_window.show
Trong đoạn code trên có thêm 1 biến @draws = 0 được tạo. Đưa biến này vào phương thức draw để xem sự thay đổi. Vì gosu chỉ cho hiển thị ảnh nên mình phải chuyển @draws bằng function Image trong gosu như sau.
@message = Gosu::Image.from_text(self,@draws, Gosu.default_font_name, 30)
Chạy đoạn code ví dụ trên bạn sẽ thấy biến @draws không ngừng tăng bên cạnh nhân vật như hình dưới.
Để ngăn việc draw liên tục như vậy thì mình sử dụng needs_draw? như sau.
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.gif", false)
@x = 20
@y = 30
@draws = 0
@buttons_down = 0
end
def update
@x -= 1 if button_down?(Gosu::KbLeft)
@x += 1 if button_down?(Gosu::KbRight)
@y -= 1 if button_down?(Gosu::KbUp)
@y += 1 if button_down?(Gosu::KbDown)
end
def button_down(id)
close if id == Gosu::KbEscape
@buttons_down += 1
end
def button_up(id)
@buttons_down -= 1
end
def needs_redraw?
@draws == 0 || @buttons_down > 0
end
def draw
@draws += 1
@sprite.draw(@x, @y, 0)
@message = Gosu::Image.from_text(self, @draws, Gosu.default_font_name, 30)
@message.draw(@x, @y, 1)
end
end
game_window = GameWindow.new(800, 600, false)
game_window.show
Phương thức needs_redraw? được gọi ra khi @draws==0 hoặc khi có 1 button được ấn (@buttons_down >0) Phải tạo phương thức button_up để gosu hiểu được bạn không giữ 1 nút liên tục.
Các bạn thử làm xem kết quả thế nào nhé. Chúc các bạn vui vẻ
All rights reserved