配套视频教程
本节最终效果
pygame开发,有一个所谓的最小框架(或称为模板):
main.py
import pygame import time # 游戏中的一些常量定义 SIZE = WIDTH, HEIGHT = 600, 480 FPS = 10 # 颜色常量定义 BLACK = 0, 0, 0 WHITE = 255, 255, 255 # 初始化 pygame.init() pygame.mixer.init() # 窗口、标题等初始化 screen = pygame.display.set_mode(SIZE) pygame.display.set_caption("My Game") clock = pygame.time.Clock() # 循环入口 running = True while running: # 设置帧数 clock.tick(FPS) # 事件处理 for event in pygame.event.get(): # 退出处理 if event.type == pygame.QUIT: running = False # (update) 游戏更新逻辑(比如:改动角色的位置或一些重要变量等,这里仅演示更新当前时间) font = pygame.font.SysFont('Menlo', 48, True) current_time = font.render(time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time())), 1, WHITE) # (draw)渲染屏幕 screen.fill(BLACK) # 先准备一块黑布 screen.blit(current_time, current_time.get_rect(center=(WIDTH / 2, HEIGHT / 2))) # 把时间显示在画布中央 # 屏幕内容刷新 pygame.display.update() # 循环结束后,退出游戏 pygame.quit()
代码头部有很多常量定义,按模块化的思想,可以把这些常量定义单独提取出来,放到一个settings.py文件里,以后修改起来会比较方便。
setting.py
SIZE = WIDTH, HEIGHT = 480, 320 FPS = 30 TITLE = "sprite sample" # define color BLACK = 0, 0, 0 WHITE = 255, 255, 255 RED = 255, 0, 0 GREEN = 0, 255, 0 BLUE = 0, 0, 255 # define player bound PLAYER_TOP_LIMIT = 100 PLAYER_BOTTOM_LIMIT = 250
加入精灵
import pygame from settings import * pygame.init() pygame.mixer.init() screen = pygame.display.set_mode(SIZE) pygame.display.set_caption(TITLE) clock = pygame.time.Clock() # 定义游戏主角类 class Player(pygame.sprite.Sprite): def __init__(self): # 第1行,必须调用Sprite父类的构造函数 pygame.sprite.Sprite.__init__(self) # 注意:sprite必须指定image, rect这二个属性 self.image = pygame.Surface((20, 20)) self.image.fill(GREEN) self.rect = self.image.get_rect() self.rect.center = WIDTH / 2, HEIGHT / 2 # 更新逻辑 def update(self): self.rect.x += 5 if self.rect.left > WIDTH: self.rect.right = 0 # 这里要有一个类似分组(或容器)的东西,存放所有游戏中的sprite实例 all_sprites = pygame.sprite.Group() player = Player() all_sprites.add(player) running = True while running: clock.tick(FPS) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # update all_sprites.update() # draw /render screen.fill(BLACK) all_sprites.draw(screen) # 绘制所有sprite pygame.display.update() pygame.quit()
运行程序,会看到一个绿色的小方块,在窗口中从左向右移动。
引入图像
一个小方块,比较枯燥,可以引入图像。
import pygame from settings import * import os pygame.init() pygame.mixer.init() screen = pygame.display.set_mode(SIZE) pygame.display.set_caption(TITLE) clock = pygame.time.Clock() game_folder = os.path.dirname(__file__) img_folder = os.path.join(game_folder, "./img/") class Player(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(os.path.join(img_folder, "p1_jump.png")) # 如果图片显示时,发现不透明(看具体操作系统),可以加下面这行 self.image.set_colorkey(BLACK) self.rect = self.image.get_rect() self.rect.center = WIDTH / 2, HEIGHT / 2 self.y_speed = 5 def update(self): self.rect.x += 5 self.rect.y += self.y_speed # 边界检测 if self.rect.left > WIDTH: self.rect.right = 0 if self.rect.top < PLAYER_TOP_LIMIT: self.y_speed = -self.y_speed if self.rect.bottom > PLAYER_BOTTOM_LIMIT: self.y_speed = -self.y_speed all_sprites = pygame.sprite.Group() player = Player() all_sprites.add(player) running = True while running: clock.tick(FPS) # process input (events) for event in pygame.event.get(): if event.type == pygame.QUIT: running = False all_sprites.update() # draw /render screen.fill(BLACK) pygame.draw.line(screen, GREEN, (0, PLAYER_TOP_LIMIT), (WIDTH, PLAYER_TOP_LIMIT), 1) pygame.draw.line(screen, GREEN, (0, PLAYER_BOTTOM_LIMIT), (WIDTH, PLAYER_BOTTOM_LIMIT), 1) all_sprites.draw(screen) pygame.display.update() pygame.quit()