用pygame画完整的圆弧

问题描述 投票:0回答:1

我目前正在使用 Pygame 编写吃豆人代码,但我被精灵挡住了。我想制作一个带有黑色(或背面颜色)弧线的黄色圆圈,就像没有一块蛋糕的馅饼一样。我阅读了有关它的文档,但我发现的所有内容都不符合我的水平(我在高中)。 感谢您阅读并回复我, 问候。

(抱歉,因为我是法国人,所以这是法语和英语的混合体。我尽力使用 PEP8 和翻译做到最好:))

import pygame
from pygame.locals import *
from board import *
from math import *
import time
import sys

screen_width, screen_height = 660, 700
case_h = (screen_height-50)//32
case_w = screen_width//30

def create_window(longueur, largeur, titre, back_color):
    """
        Création de la fenêtre principale
        :param screen_width : la longueur de l'écran (en pixels)
        :type screen_width : int
        :param screen_height : la largeur de l'écran (en pixels)
        :type screen_height : int
        :param titre : nom donné à la fenêtre
        :type titre : str
    """
    # Création de la fenêtre
    windows = pygame.display.set_mode((longueur, largeur))
    windows.fill(back_color)
    # Nommage de la fenêtre
    pygame.display.set_caption('Pac-Man')
    return windows

def key_pressed():
    """
        Lecture du clavier du joueur
    """
    global run, direction
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_ESCAPE:
                run = False
            if event.key == pygame.K_LEFT:
                direction = 'gauche'
            if event.key == pygame.K_RIGHT:
                direction = 'droite'
            if event.key == pygame.K_UP:
                direction = 'haut'
            if event.key == pygame.K_DOWN:
                direction = 'bas'

def draw_board(boards):
    """
        Affichage du plateau
        :param boards : matrice contenant les cases à afficher
        :type boards : list
    """
    for i in range(len(boards)):
        for j in range(len(boards[i])):
            if boards[i][j] == 1:
                pygame.draw.circle(windows, (255, 255, 0), (case_w*(j+0.5),
                                                    case_h*(i+0.5)), 4)
            if boards[i][j] == 2:
                pygame.draw.circle(windows, (255, 255, 0), (case_w*(j+0.5),
                                                    case_h*(i+0.5)), 6)
            if boards[i][j] == 3:
                pygame.draw.line(windows, (0, 0, 255), (case_w*(j+0.5), case_h*i),
                                (case_w*(j+0.5), case_h*(i+1)))
            if boards[i][j] == 4:
                pygame.draw.line(windows, (0, 0, 255), (case_w*j, case_h*(i+0.5)),
                                (case_w*(j+1), case_h*(i+0.5)))
            if boards[i][j] == 5:
                pygame.draw.arc(windows, (0, 0, 255), [case_w*(j-0.5), case_h*(i+0.5)
                                        , case_w, case_h], 0, pi/2, 1)
            if boards[i][j] == 6:
                pygame.draw.arc(windows, (0, 0, 255), [case_w*(j+0.5), case_h*(i+0.5)
                                        , case_w, case_h], pi/2, pi, 1)
            if boards[i][j] == 7:
                pygame.draw.arc(windows, (0, 0, 255), [case_w*(j+0.5), case_h*(i-0.5)
                                        , case_w, case_h], pi, (3*pi)/2, 1)
            if boards[i][j] ==8:
                pygame.draw.arc(windows, (0, 0, 255), [case_w*(j-0.5), case_h*(i-0.5)
                                        , case_w, case_h], (3*pi)/2, 2*pi, 1)
            if boards[i][j] == 9:
                pygame.draw.line(windows, (255, 255, 255), (case_w*j, case_h*(i+0.5)),
                                        (case_w*(j+1), case_h*(i+0.5)))

def pac_man_move(direction):
    """
        Création et affichage du Pac-man
        :param direction : direction du Pac-man
        :param direction : str
    """
    global posx, posy
    pygame.draw.rect(windows, (255, 255, 0), (case_w*posx, case_h*posy, case_w, case_h))
    if direction == 'gauche':
        posx -= 0.1
    elif direction == 'droite':
        posx += 0.1
    elif direction == 'haut':
        posy -= 0.1
    elif direction == 'bas':
        posy += 0.1

def draw_test():
    global posx, posy
    pygame.draw.arc(windows, (255, 255, 0), (case_w*posx, case_h*posy, case_w*(posx+1), case_h*(posy+1)), (11*pi)/6, pi/6, width=1)

run = True
posx = 15
posy = 24
direction = 'droite'
while run:
    pygame.init()
    windows = create_window(screen_width, screen_height, 'Pac-Man', (0, 0, 0))
    pygame.draw.arc(windows, (255, 255, 255), [300, 350, 100, 100], (11*pi)/6, pi/6, width=1)
    pygame.draw.line(windows, (255, 255, 255), (300, 400), (300+100*cos(pi/6), 400-100*sin(pi/6)))
    pygame.display.update()
    key_pressed()

我尝试用 pygame.draw.arc(...) 和 width=0 制作一个圆弧,就像当你绘制一个矩形时,如果 width=0,它会填充矩形,但不会用圆弧填充。

python pygame
1个回答
0
投票

恭喜该项目!

问题是 Pygame 的绘图 API 并不像其他绘图 API 那样完整,并且根本缺乏绘制精灵等“饼图”的选项。

此时有一些选择:(1)使用另一个绘图API作为库,例如Cairo、pyglet、matplotlib或PIL(不确定最新的是否也有“饼图”的东西) - 并复制生成的像素到 pygame 兼容对象; (2) 在成像程序中预先绘制图像,并在运行时从“.png”文件加载这些图像用于 pygame 项目(可能是更简单的路径); (3) 它可以让您更多地了解“事物是如何工作的”:使用基本原语仅用数学函数绘制吃豆人形状 - 这可以让您更好地控制,您可以添加渐变和其他颜色- 也会改变填充区域的效果。

上面的第三种方法将需要一些三角思维,以及光栅化形状的相同基本规则,这些学习将为您提供一些关于事物如何工作的基础: 基本思想是只有两个嵌套的 for 循环,它们将生成您正在绘制 pacman 的感兴趣区域 (ROI) 的所有 (x, y) 值 - 对于每个坐标,您然后测试是否应该填充(当做更奇特的事情时,也许可以计算自定义颜色)。对于吃豆人形状,(x,y) 应该位于半径为“r”的圆内,在指定的角度范围之外,您必须使用

math.asin
math.acos

来找出
def pacman(surf,  total_r, min_ang):
    width, height = sc.get_size()
    cx, cy = width // 2, height // 2
    for y in range(height):
        for x in range(width):
            nx, ny = (x - cx) / cx, (y - cy) / cy
            r = (nx ** 2 + ny ** 2 ) ** 0.5
            alpha = math.degrees(math.asin(ny / r if r else 0.00001))
            if r < total_r and (abs(alpha) > min_ang or nx < 0) :
                color = (255, 255, 0)
            else:
                color = (0, 0, 0)
            surf.set_at((x,y), color)
    # pygame.display.flip()

通过一个表面(如 64x64 像素,或任何你想要的),或者直接通过你的屏幕来测试它 - 它将绘制一个类似吃豆人的形状,以角度“0”镜像(从左到右的水平线)

然后,当然,渲染这样的图像太慢了,无法完成每一帧:在游戏设置阶段绘制各种吃豆人精灵,然后将其保留在不同的 pygame

Surface
对象中,您可以在以下位置使用
.blit
进行标记游戏时间。

© www.soinside.com 2019 - 2024. All rights reserved.