12/08/2018, 14:26

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ả             </div>
            
            <div class=

0