55 trò chơi trăn nhảy

Ở phần trước ta đã biết cách thay đổi sprite của Mario thông qua các trạng thái.

    def handle[self, event]:
        self.my_mario.handle[event]
        pass
8 is the vertical status. đang nhảy [
    def handle[self, event]:
        self.my_mario.handle[event]
        pass
9] và theo chiều ngang
    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
0. đang đứng yên [
    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
1] hay đang chạy [
    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
2] cùng với đó là các trạng thái đang quay mặt về phía nào [_______23]. left or must. Tuy nhiên, ta không thể tương tác với Mario. Ta sẽ thực hiện công việc tương tác này thông qua các phím di chuyển. up [nhảy lên], left [di chuyển sang trái], must [di chuyển sang phải] Kèm theo là quay mặt nếu cần thiết

Để xử lý các sự kiện phím ấn mà người dùng nhập vào, ta định nghĩa thêm hàm xử lý trong lớp Mario để xử lý các sự kiện. Như ở bài trước, tại hàm

    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
4, vòng lặp chính của trò chơi, sau mỗi lần đánh dấu đồng hồ ta lấy ra các sự kiện diễn ra trong trò chơi và đưa ra từng đối tượng trong trò chơi để xử lý một cách phù hợp

    def run[self]:
        # main game loop
        while True:
            # hold frame rate at 60 fps
            dt = self.clock.tick[60]
            self.time_step += 1
            # enumerate event
            for event in pygame.event.get[]:
                if event.type == pygame.QUIT:
                    sys.exit[0]
                # sprite handle event
                self.handle[event]

            self.update[dt / 1000.]
            # re-draw screen
            self.draw[self.screen]

Tại hàm

    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
5 của vòng lặp của trò chơi, ta tiến hành gọi hàm
    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
5 của mario để xử lý

    def handle[self, event]:
        self.my_mario.handle[event]
        pass

Trong phần này, chúng ta sẽ tiến hành triển khai hàm xử lý cho Mario

    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"

Như trong phần mã ở phía trên, tham số truyền vào là biến

    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
7, từ biến này ta có thể kiểm tra xem sự kiện đó được nhấn 1 phím xuống hay không [
    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
8], tại đây ta sẽ thực hiện các hành động. if nhấn phím sang phải sẽ thực hiện hành động chuyển sang phải. Dưới đây là chi tiết của hàn
    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
9. Đối với hàm
    def handle[self, event]:
        self.my_mario.handle[event]
        pass
50, chúng ta làm hoàn toàn tương tự. Hàm
    def handle[self, event]:
        self.my_mario.handle[event]
        pass
51 chúng ta sẽ nói kỹ hơn khi thực hiện cuộc phỏng vấn nghiêm túc

    def handle[self, event]:
        self.my_mario.handle[event]
        pass
5

Đó là logic khi chúng ta nhấn một phím xuống. Việc cần làm tiếp theo đó là xử lý khi ta giải phóng phím ra, lúc này ta sẽ cập nhật lại các trạng thái của Mario về trạng thái đứng yên như ở đoạn mã phía trên

Lệnh di chuyển sang bên phải, đơn giản là thiết lập vận tốc theo chiều x, thay đổi các trạng thái tương ứng với hướng di chuyển. sau khi thực hiện các bước này, chạy thử ta thấy mario đã di chuyển theo đúng các hướng bên trái mà ta chỉ định

Mô phỏng lực lượng

Chúng ta cũng xem qua một chút logic về phần chuyển động của Mario. Thứ luôn kéo chúng ta về với mặt đất, khiến ta không thể bay lượn như chim mà chính là lực lượng quan trọng. Hãy mô phỏng lượng lớn trong trò chơi như sau. Đầu tiên là định nghĩa một số tham số

    def handle[self, event]:
        self.my_mario.handle[event]
        pass
8
    def handle[self, event]:
        self.my_mario.handle[event]
        pass
9

Ở đây ta cần có chút kiến ​​thức về vật lý. Giả lập quan trọng như sau

  • cứ mỗi bước trò chơi ta tính toán lại vận tốc của Mario, cộng thêm vào vận tốc theo chiều y một lượng là GRAVITY
  • Mức độ mà các vật thể di chuyển được thực hiện sau mỗi bước trò chơi sẽ chính là vận tốc của vật chất theo các chiều x, y
  • Tính toán lại các vận tốc tối đa để tránh việc nhân vật của họ rơi quá nhanh

Khi đó công việc thực hiện nhảy lên chỉ đơn giản là di chuyển với vận tốc âm thanh theo phương y

    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
0

Ta init position of Mario as after at hàm

    def handle[self, event]:
        self.my_mario.handle[event]
        pass
52 của main

    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
2

Như vậy các vật thể sẽ ngày càng chuyển xuống bên dưới và ngày càng nhanh hơn theo đúng mô phỏng trọng lực

Va chạm với mặt đất

Để có thể thực hiện phần va chạm với platformer ta cần chỉnh sửa lại Map trong Tiled một chút. Như nó đã được sơ lược thông qua trong bài đầu tiên của sê-ri. Map được chia thành các lớp layer background, midground layer, foreground layer, các layer này sẽ là phần hiển thị. Nhưng phần sẽ tương tác với các đối tượng của trò chơi sẽ là lớp kích hoạt, phần này chứa các đối tượng nhưng lại không hiển thị, làm cho ta có cảm giác là các đối tượng đang tương tác với lớp gạch

Trong lớp kích hoạt của tệp bản đồ, ta bổ sung các đối tượng hình chữ nhật với các thuộc tính như sau

Ta set value for properties is "tlbr" có nghĩa là chặn theo tất cả các hướng trên [t] trái [l] dưới [b] phải [r] cho

    def handle[self, event]:
        self.my_mario.handle[event]
        pass
53. Và tương tự cho các đối tượng
    def handle[self, event]:
        self.my_mario.handle[event]
        pass
54 được sử dụng để ngăn người chơi rời khỏi màn hình. Tất cả các đối tượng này đều nằm trong lớp kích hoạt của bản đồ

Tiếp theo đó ta cần phải xử lý va chạm giữa người chơi với các đối tượng thuộc loại

    def handle[self, event]:
        self.my_mario.handle[event]
        pass
55 này. Khi đó toàn bộ mã của hàm
    def handle[self, event]:
        self.my_mario.handle[event]
        pass
56 sẽ như sau

    def handle[self, event]:
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_UP:
                if self.v_state == "resting":
                    self.jump[]
            elif event.key == pygame.K_RIGHT:
                self.move_right[]
            elif event.key == pygame.K_LEFT:
                self.move_left[]
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_RIGHT or \
                event.key == pygame.K_LEFT:
                self.vx = 0
                self.h_state = "standing"
7
  • Đầu tiên ta tính toán vị trí của Mario theo tác động của trọng lực
  • Tiếp đến là tính toán va chạm với
        def handle[self, event]:
            self.my_mario.handle[event]
            pass
    
    55. Nguyên lý rất đơn giản. lấy ra các
        def handle[self, event]:
            self.my_mario.handle[event]
            pass
    
    55, kiểm tra xem phần bao bên ngoài của chúng có giao tiếp với phần bao bên ngoài của Mario hay không. Nếu có giao nhau ta sẽ thiết lập lại bao ngoài mới [
        def handle[self, event]:
            self.my_mario.handle[event]
            pass
    
    59] cho Mario để chúng ta không còn giao nhau nữa

Hình demo khi hiển thị lớp

    def handle[self, event]:
        self.my_mario.handle[event]
        pass
80

and when does not display the

    def handle[self, event]:
        self.my_mario.handle[event]
        pass
80 layer

Chấm dứt

Vì vậy ta đã có một nhân vật Mario có thể di chuyển trên một địa hình cơ bản rồi. Phần tiếp theo sẽ là cách sử dụng bản đồ nâng cao tương tự với Tiled

Chủ Đề