重拾三年前的微型pygame框架,加入小型物理引擎:
# 框架文件 game.py
import pygame, sys
import pymunk.pygame_util
from functools import wraps
from pygame.locals import *
from collections import defaultdict
class Route:
def __init__(self):
self.lib = defaultdict(lambda : lambda e: ...)
def __call__(self, routepath):
def warpper(func):
self.lib[routepath] = func
@wraps(func)
def inner_wrapped(*args):
return func(*args)
return inner_wrapped
return warpper
class MySprite(pygame.sprite.Sprite):
def __init__(self, image_path, position,space):
super().__init__()
self.image = pygame.image.load(image_path).convert_alpha()
self.image = pygame.transform.scale(self.image, (self.image.get_width() // 5, self.image.get_height() // 5))
self.image.set_colorkey((255, 255, 255)) # 设置白色为透明色
self.rect = self.image.get_rect(center=position)
# 创建 pymunk 刚体和形状
mass = 1
moment = pymunk.moment_for_circle(mass, 0, self.rect.width / 2)
self.body = pymunk.Body(mass, moment)
self.body.position = position
self.shape = pymunk.Circle(self.body, self.rect.width / 2)
self.shape.elasticity = 0.85 # 设置弹性
space.add(self.body, self.shape)
def update(self):
self.rect.center = self.body.position
class Game:
def __init__(self):
pygame.init()
self.route = Route()
self.clock = pygame.time.Clock()
self.screen = pygame.display.set_mode((400, 300), pygame.NOFRAME | pygame.SRCALPHA) # 确保支持透明度
self.space = pymunk.Space()
self.space.debug_draw(pymunk.pygame_util.DrawOptions(self.screen))
self.space.gravity = (0, 900)
self.group = pygame.sprite.Group()
self.create_ground()
def create_ground(self):
# 创建静态刚体
ground_body = pymunk.Body(body_type=pymunk.Body.STATIC)
# 创建地面形状(矩形)
ground_shape = pymunk.Segment(ground_body, (0, 290), (400, 290), 5) # (x1, y1), (x2, y2), thickness
ground_shape.elasticity = 0.25 # 设置弹性
ground_shape.friction = 0.3 # 设置摩擦力
self.space.add(ground_body, ground_shape)
def run(self):
while True:
for event in pygame.event.get():self.route.lib[event.type](event)
self.screen.fill((0, 0, 0, 0))
self.space.step(1/60.0)
self.group.update()
self.group.draw(self.screen)
pygame.display.flip()
self.clock.tick(60)
# 应用文件 app.py
from game import Game,MySprite
import numpy as np
game = Game()
@game.route(KEYDOWN)
def keydown(e):
if e.key == K_ESCAPE:
pygame.quit()
sys.exit()
@game.route(MOUSEMOTION)
def mousemotion(e):
...
@game.route(MOUSEBUTTONDOWN)
def mousebuttondown(e):
sprite.body.apply_impulse_at_local_point((0, -500), (0, 0))
# 创建精灵组
sprite = MySprite("IMG_1153.JPG", tuple(np.random.randint(100, 120, size=2)),game.space)
game.group.add(sprite)
game.run()
按ESC键可退出游戏