桌面精灵(二)

import pygame, sys
from pygame.locals import *
from functools import wraps
from collections import defaultdict
import win32gui, win32api
from win32.lib import win32con
from itertools import repeat, cycle

# Constants
SCREEN_WIDTH, SCREEN_HEIGHT = 400, 300
DEFAULT_SPEED = (1, 1)
KEY_DIRECTIONS = {
    K_LEFT: ("左", (-3, 0)),
    K_RIGHT: ("右", (3, 0)),
    K_UP: ("上", (0, -3)),
    K_DOWN: ("下", (0, 3))
}

def make_window_transparent(hwnd):
    win32gui.SetWindowLong(hwnd, win32con.GWL_EXSTYLE, win32gui.GetWindowLong(hwnd, win32con.GWL_EXSTYLE) | win32con.WS_EX_LAYERED)
    win32gui.SetLayeredWindowAttributes(hwnd, win32api.RGB(0, 0, 0), 0, win32con.LWA_COLORKEY)

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 Game:
    def __init__(self):
        pygame.init()
        self.route = Route()
        self.screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT), pygame.NOFRAME)
        self.rect = self.screen.get_rect()
        self._make_window_transparent()
        self.clock = pygame.time.Clock()
        self.heros = pygame.sprite.Group()

    def _make_window_transparent(self):
        hwnd = pygame.display.get_wm_info()["window"]
        make_window_transparent(hwnd)

    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.heros.update()
            self.heros.draw(self.screen)
            pygame.display.flip()
            self.clock.tick(60)

game = Game()

class Hero(pygame.sprite.Sprite):
    def __init__(self, image_path, position=(100, 100), speed=DEFAULT_SPEED, image_direction="下左右上", image_scale=1):
        super().__init__()
        self.image_ = pygame.image.load(image_path)
        self.image_ = pygame.transform.scale(self.image_, (self.image_.get_width() * image_scale, self.image_.get_height() * image_scale))
        self.state = "下"
        self.speed = speed
        self.width, self.height = self.image_.get_size()
        self.tile_width = self.width // 4
        self.tile_height = self.height // 4
        self.image_dict = self._create_animation_frames(image_direction)
        self.rect = self.image_dict[self.state][0].get_rect()
        self.image_dict = {key: cycle(value) for key, value in self.image_dict.items()}
        self.rect.center = position
        game.heros.add(self)

    def _create_animation_frames(self, image_direction):
        image_dict = {direct: [] for direct in image_direction}
        for row, key in enumerate(image_dict.keys()):
            for col in range(4):
                x = col * self.tile_width
                y = row * self.tile_height
                tile = self.image_.subsurface((x, y, self.tile_width, self.tile_height))
                image_dict[key].extend([tile] * 10)
        return image_dict

    @property
    def image(self):
        return self.image_dict[self.state].__next__()

    def update(self):
        self.rect.move_ip(self.speed)
        if self.rect.top < 0:
            self.speed = (self.speed[0], -self.speed[1])
            self.state = "下"
        elif self.rect.bottom > game.rect.height:
            self.speed = (self.speed[0], -self.speed[1])
            self.state = "上"
        if self.rect.left < 0:
            self.speed = (-self.speed[0], self.speed[1])
            self.state = "右"
        elif self.rect.right > game.rect.width:
            self.speed = (-self.speed[0], self.speed[1])
            self.state = "左"

shero = Hero("girl.png", (100, 100), DEFAULT_SPEED, "下左右上", image_scale=1.5)
hero = Hero("man.png", (200, 200), DEFAULT_SPEED, "下左上右", image_scale=2)

@game.route(KEYDOWN)
def keydown(e):
    if e.key == K_ESCAPE:
        pygame.quit()
        sys.exit()
    elif e.key in KEY_DIRECTIONS:
        state, speed = KEY_DIRECTIONS[e.key]
        for character in [hero, shero]:
            character.state, character.speed = state, speed

@game.route(MOUSEMOTION)
def mousemotion(e):
    pass

@game.route(MOUSEBUTTONDOWN)
def mousebuttondown(e):
    pass

game.run()

精灵图:


girl.png
man.png

运行后:


桌面精灵
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容