0

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 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 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

Đị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 width, height, fullscreen
        super(width, 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 width, height, fullscreen
        super(width, 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 width, height, fullscreen
        super(width, 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 width, height, fullscreen
        super(width, 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ả 😄

gosu_char.gif

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

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí