Tiếp tục với phần 1 của sê-ri phát triển trò chơi với pygame, ở phần này, ta sẽ tiến hành mã nhân vật mario
Trước tiên, ta sẽ tiến hành chỉnh sửa lại mã của chương trình lần trước thành lớp MarioGame. bao gồm các chức năng chính
- trong đó. chắc chắn việc tải các sprite và bản đồ
- chạy. vòng lặp chính của trò chơi
- vẽ tranh. chức năng được gọi trong chức năng chạy của trò chơi, đảm nhiệm công việc vẽ lại các nhân vật và bản đồ trong trò chơi
- cập nhật. chức năng được gọi trong chức năng chạy của trò chơi, đảm bảo nhiệm vụ cập nhật trạng thái các nhân vật trong trò chơi qua từng khung hình
- xử lý. chức năng xử lý các sự kiện của trò chơi
import sys
import pygame
import tmx
if not pygame.font: print 'Warning, fonts disabled'
if not pygame.mixer: print 'Warning, sound disabled'
class MarioGame[]:
width = 640
height = 480
def __init__[self]:
self.pygame = pygame
def init[self]:
self.pygame.init[]
self.size = [self.width, self.height]
self.screen = pygame.display.set_mode[self.size]
self.clock = self.pygame.time.Clock[]
self.time_step = 0
# TODO: init sprite, tile,...
self.tilemap = tmx.load["map.tmx", self.screen.get_size[]]
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]
def draw[self, screen]:
screen.fill[[95, 183, 229]] # sky color
if pygame.font:
font = pygame.font.Font[None, 36]
text = font.render["Hello World !", 1, [255, 0, 0]]
textpos = text.get_rect[centerx=self.width/2]
self.screen.blit[text, textpos]
# TODO: sprite tilemap
self.tilemap.set_focus[0, 480]
self.tilemap.draw[screen]
self.pygame.display.flip[]
def update[self, dt]:
#self.mariosprite.update[]
pass
def handle[self, event]:
#self.my_mario.handle[event]
pass
if __name__ == '__main__':
g = MarioGame[]
g.init[]
g.run[]
Time is to the kernel Mario of them ta. Ta use frame of Mario is file small_mario. png dưới đây
Nếu ta đánh số khung từ trái sang phải thì khung 0 ứng với Mario đang đứng, khung 0-1 đang chạy và khung 3 đang nhảy. Ta sẽ thay đổi thuộc tính hình ảnh của Mario tương ứng với từng khung hình và trạng thái. Lớp Mario sẽ được mở rộng từ lớp pygame. ma. Sprite như dưới đây
import os
import math
import pygame
import config
class Mario[pygame.sprite.Sprite]:
FRAME_WIDTH = 20
FRAME_HEIGHT = 19
PADDING = 1
img_file = "small_mario.png"
STAND = 0
RUNNING = [0, 1]
JUMP = 3
index = STAND
loaded_sprites = {}
ANIMATION_INTERVAL = 5
def __init__[self]:
super[Mario, self].__init__[]
img_path = os.path.join[config.image_path, self.img_file]
self.sprite_imgs = pygame.image.load[img_path]
self.image = self.set_sprite[self.index]
self.rect = self.image.get_rect[]
self.pos = self.rect
self.v_state = "resting"
self.h_state = "standing"
self.facing = "right"
def set_position[self, x, y]:
self.rect.x = x
self.rect.y = y
def draw[self, screen]:
screen.blit[self.image, self.pos]
def update[self, dt, game]:
new = self.rect
game.tilemap.set_focus[new.x, new.y]
# change sprite
if game.time_step % self.ANIMATION_INTERVAL == 0:
if self.v_state == "jumping":
self.image = self.set_sprite[self.JUMP]
else:
if self.h_state == "running":
self.index = [self.index + 1] % len[self.RUNNING]
self.image = self.set_sprite[self.index]
elif self.h_state == "standing":
self.image = self.set_sprite[self.STAND]
if self.facing == "left":
self.image = pygame.transform.flip[self.image, True, False]
def set_sprite[self, index]:
if index not in self.loaded_sprites.keys[]:
left = [self.FRAME_WIDTH + self.PADDING] * index
rect = pygame.Rect[left, 0, self.FRAME_WIDTH, self.FRAME_HEIGHT]
_surface = pygame.Surface[[self.FRAME_WIDTH, self.FRAME_HEIGHT], pygame.SRCALPHA]
_surface.blit[self.sprite_imgs, [0, 0], rect]
self.loaded_sprites[index] = _surface
return self.loaded_sprites[index]
Hãy cùng xem qua class Mario. Ta set up a number variable save the information of Mario
- img_file. file ảnh chứa toàn bộ sprite của mario
- Các biến STAND, RUNNING, JUMP là chỉ mục của các khung hình trong tệp ảnh
- ANIMATION_INTERVAL number times update các ảnh [tốc độ chậm] và một số biến trạng thái của mario
Có hai biến quan trọng được khởi tạo trong hàm __init__
- bản thân. hình ảnh. có chứa hình ảnh hiện tại
- bản thân. trực tràng. vị trí và kích thước hiện tại, dựa vào biến này, ta sẽ vẽ lại ảnh của mario ở vị trí mà ta muốn
Chức năng cập nhật sẽ cập nhật ảnh hiện tại của mario tùy chọn vào trạng thái. Hàm draw sẽ vẽ mario tại vị trí ta muốn