Gosu - Thư viện game 2D cho Ruby - Phần 2
Bài trước mình đã giới thiệu về Gem gosu, tạo cửa sổ game, đưa một đối tượng nhân vật vào cửa sổ game và làm nó chuyển động theo chiều x hoặc y. Nhưng có điều nhân vật "vượt biên" cửa sổ và đi đi đi mãi luôn không quay lại. =)) Vì vậy ở bài này, mình sẽ giới thiệu cách làm cho nhân vật không ...
Bài trước mình đã giới thiệu về Gem gosu, tạo cửa sổ game, đưa một đối tượng nhân vật vào cửa sổ game và làm nó chuyển động theo chiều x hoặc y.
Nhưng có điều nhân vật "vượt biên" cửa sổ và đi đi đi mãi luôn không quay lại. =))
Vì vậy ở bài này, mình sẽ giới thiệu cách làm cho nhân vật không thể "vượt biên".
Mission Start
☆ challenge: Cấm vượt biên
Hay nói cách khác, nếu x = chiều dài, y = chiều cao của cửa sổ thì nhân vật sẽ bật ngược lại.
Code bài 1:
require 'gosu' class GameWindow < Gosu::Window def initialize awidth, height, fullscreen super(awidth, 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
Định nghĩa lại tốc độ di chuyển @speed = 3.
@x += @speed có nghĩa là đối tượng sẽ tiến về bên phải như đã giải thích ở bài trước, và tiếp theo là làm cho nhân vật đập vào cạnh phải bằng cách giới hạn @x như sau.
if x >= 800 @speed *= -1 end
nếu x >= 800 thì @x sẽ giảm dần theo @speed
require 'gosu' class GameWindow < Gosu::Window def initialize awidth, height, fullscreen super(awidth, height, fullscreen) self.caption = "Hello" #set title của game_window @sprite = Gosu::Image.new(self, "Sprite.png", false) @speed = 3 @x = 250 @y = 250 end def update if @x >= 800 @speed *= -1 end @x += @speed end def draw @sprite.draw(@x, @y, 0) end end game_window = GameWindow.new(800, 600, false) game_window.show
OK! Nhân vật đã đập vào cạnh phải sau đó di chuyển dần về bên trái vì @x giảm dần theo @speed. Nhưng lại lần này lại đi xuyên qua cạnh trái. =))
Và cũng tương tự như cạnh phải mình làm như sau:
if x <= 0 @speed *= -1 end
require 'gosu' class GameWindow < Gosu::Window def initialize awidth, height, fullscreen super(awidth, height, fullscreen) self.caption = "Hello" #set title của game_window @sprite = Gosu::Image.new(self, "Sprite.png", false) @speed = 3 @x = 250 @y = 250 end def update if @x >= 800 @speed *= -1 end if @x <= 0 @speed *= -1 end @x += @speed end def draw @sprite.draw(@x, @y, 0) end end game_window = GameWindow.new(800, 600, false) game_window.show
Nhân vật không "vượt biên" và đập vào cạnh phải cạnh trái rồi. Nhìn buồn cười =))
Tương tự với cạnh trên và dưới tức là chiều @y. Nhân vật sẽ bị giới hạn từ 0 ~ 600 px. Các bạn tham khảo code bên dưới.
Mình đặt lại speed tương ướng với 2 chiều x, y là @speedx, @speedy.
require 'gosu' class GameWindow < Gosu::Window def initialize awidth, height, fullscreen super(awidth, height, fullscreen) self.caption = "Hello" #set title của game_window @sprite = Gosu::Image.new(self, "Sprite.png", false) @speedx = 3 @speedy = 5 @x = 250 @y = 250 end def update if @x >= 800 @speedx *= -1 end if @x <= 0 @speedx *= -1 end @x += @speedx if @y >= 600 @speedy *= -1 end if @y <= 0 @speedy *= -1 end @y += @speedy end def draw @sprite.draw(@x, @y, 0) end end game_window = GameWindow.new(800, 600, false) game_window.show
Bạn thử chạy code xem nhân vật chuyển động như nào nhé.
Tiếp theo mình define lại vài method cho dễ đọc.
require 'gosu' class GameWindow < Gosu::Window def initialize awidth, height, fullscreen super(awidth, height, fullscreen) self.caption = "Hello" #set title của game_window @sprite = Gosu::Image.new(self, "Sprite.png", false) @speedx = 3 @speedy = 5 @x = 250 @y = 250 end def update if hit_right_wall @speedx *= -1 end if hit_left_wall @speedx *= -1 end @x += @speedx if hit_bottom_wall @speedy *= -1 end if hit_top_wall @speedy *= -1 end @y += @speedy end def hit_right_wall @x >= 610 end def hit_left_wall @x <= 1 end def hit_bottom_wall @y >= 400 end def hit_top_wall @y <=1 end def draw @sprite.draw(@x, @y, 0) end end game_window = GameWindow.new(800, 600, false) game_window.show
Và kết quả