1

每当我按下空格键时,我都会尝试在鼠标的位置画圆圈。目标是围绕跟随我的鼠标光标的角色绘制这个圆圈并杀死它接触的其他对象。我在正确的轨道上吗,还有画圈到底是如何工作的

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

pygame.init()
WINDOW_WIDTH = 1000
WINDOW_HEIGHT = 600
surface = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT),0,32)
pygame.display.set_caption('follow mouse')
surface.fill((255,255,255))

class Hero():
    def Attack(self):
        for event in pygame.event.get():
            surface.fill ((255,255,255))
            amntTuple = pygame.mouse.get_pos()
            pygame.draw.circle(surface, BLUE, amntTuple, 20, 300)
            surface.blit (self.space, self.spaceRect)
            pygame.display.update()

var = Hero()
while True:
    for event in pygame.event.get():
            if event.type == KEYDOWN:
                if event.key == K_SPACE:
                    var.Attack()
4

3 回答 3

4

您需要进行一些更改才能使其正常工作。我在所有这些更改背后包含了一个有点冗长的解释,以便您能够理解它们并将它们正确应用到游戏的其他部分。如果您不需要额外的解释,您可以跳到此答案底部的工作代码。我已经在任何我做出改变的地方发表了评论。

事件处理

Pygame 保留了游戏中发生的事件列表,例如按键。当您调用 时,将返回自上次调用以来pygame.event.get()发生的所有事件的列表。这意味着在您的函数中,没有任何代码正在运行,因为它发生在每个事件中,但返回一个空列表,因为您只是在 while 循环中调用了它。一般来说,每个循环只应该调用一次,就像在代码底部一样。您应该删除 for 循环,因为它在那里没有任何用途。Attack()pygame.event.get()pygame.event.get()pygame.event.get()Attack()

退出

pygame 的一个小不便是关闭按钮默认不起作用,这意味着您必须强制关闭游戏。要解决此问题,您应该检查事件循环中的 QUIT 事件,然后关闭游戏。下面是代码如何插入游戏的示例:

while True:
    for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_SPACE:
                    var.Attack()

颜色

遗憾的是,Pygame 没有内置的颜色,所以BLUEinpygame.draw.circle(surface, BLUE, amntTuple, 20, 300)不起作用。相反,使用 RGB 颜色模型替换BLUEpygame.Color(0,0,255)自己创建蓝色。

绘画

在 Pygame 中,绘图分两步完成。首先,物体被绘制到一个看不见的虚拟表面上。然后,当您调用 时pygame.display.update(),虚拟表面被绘制到用户可以看到的屏幕上。这有技术上的优势,比如可以让电脑流畅地绘制,不会出现屏幕闪烁,但也意味着只要你不调用pygame.display.update(),你绘制的任何东西都不会被看到。pygame.display.update(),您绘制的任何内容都将不可见。但是,如果您调用它太多次,您的游戏可能会闪烁或以意想不到的方式运行。因此,您通常希望pygame.display.update()每个游戏循环只调用一次(就像 with 一样pygame.event.get())。通常,pygame.display.update()它可以是您的 while 循环中的最后一行代码,其他所有代码都在它之前。

在 Pygame 中,您可以通过多种方式在屏幕上进行绘制。一种方法是使用内置函数,比如pygame.draw.circle.你在使用它时很接近,但犯了两个错误。首先,正如我之前提到的,BLUE 不存在。其次,width参数是用来画圆的线的宽度,而不是圆本身的宽度。所以你通常希望它是一个小数字。如果将宽度设置为 0,圆形将被填充而不是绘制为轮廓。这是您的 draw.circle 的固定版本:pygame.draw.circle(surface, pygame.Color(0,0,255), amntTuple, 20, 2)

绘制到屏幕的另一种方法是使用 blitting。Pygame 中的所有内容都必须绘制到一个 Surface 上,这就像一个虚拟画布。当您使用 pygame.image.load() 加载图像时,图像将作为 Surface 加载。一旦有了表面,就可以使用 blitting 将其绘制到屏幕上。例如:

man = pygame.image.load("/images/man.png")
surface.blit (man, (0,0))

将用于在像素 0,0 处将一个人的图像绘制到屏幕上。这将在以后的游戏开发过程中很有用。但是,您当前在绘制圆圈后立即拥有的 blit 没有任何作用并导致错误,因为self.space并且self.spaceRect不存在,因此您现在应该将其删除。

工作守则

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

pygame.init()
WINDOW_WIDTH = 1000
WINDOW_HEIGHT = 600
surface = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT),0,32)
pygame.display.set_caption('follow mouse')
surface.fill((255,255,255))

class Hero():
    def Attack(self):
        surface.fill ((255,255,255))
        amntTuple = pygame.mouse.get_pos()
        #Use pygame.Color to make a color.
        #The last parameter is linewidth, and can be set to 0 for filled circles.
        pygame.draw.circle(surface, pygame.Color(0,0,255), amntTuple, 20, 2)
        #The blit was deleted because it did nothing and the broke code.

var = Hero()
while True:
    for event in pygame.event.get():
            #Add a quit event so you can close your game normally.
            if event.type == QUIT:
                pygame.quit()
                sys.exit()
            if event.type == KEYDOWN:
                if event.key == K_SPACE:
                    var.Attack()

    #Update once at the end of each gameloop.
    pygame.display.update()
于 2013-06-06T19:21:59.597 回答
0

使用以下行(程序中的最后一行):

var.Attack

您没有调用该attack函数。

将其替换为

var.Attack()

看看这是否可行。

于 2013-06-06T17:18:11.067 回答
0

该代码在概念上是错误的,您应该只在主循环中处理事件和更新显示:

...
class Hero():
    def __init__(self):
        self.attacks = []

    def attack(self):
        self.attacks.add(pygame.mouse.get_pos())

    def update(self):
        for amntTuple in self.attacks:
            pygame.draw.circle(surface, BLUE, amntTuple, 20, 300)
            surface.blit(self.space, self.spaceRect)

hero = Hero()
while True:
    for event in pygame.event.get():
        if event.type == KEYDOWN:
            if event.key == K_SPACE:
                hero.attack()

    # Clean background
    surface.fill((255,255,255))

    # Update/Draw sprites
    hero.update()

    # Update screen
    pygame.display.update()

在事件期间,您应该只执行游戏逻辑来更新状态,然后根据当前状态绘制屏幕的每一帧。

于 2013-06-06T19:22:11.840 回答