当我点击空格键时,在我的鼠标位置绘制一个圆圈(Pygame)

时间:2013-06-06 17:16:04

标签: python pygame draw

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

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()

3 个答案:

答案 0 :(得分:4)

您需要更改一些内容才能使其正常工作。我在所有这些变化背后都包含了一些冗长的解释,以便您能够理解它们并在游戏的其他部分正确应用它们。如果您不需要额外的解释,可以跳到本答案底部的工作代码。我在任何地方都做了一些改变。

事件处理

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

退出

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没有内置颜色,因此BLUE中的pygame.draw.circle(surface, BLUE, amntTuple, 20, 300)将无效。而是使用RGB颜色模型将BLUE替换为pygame.Color(0,0,255)以自己创建蓝色。

图纸

绘图在Pygame中分两步完成。首先,将对象绘制到虚拟表面,这是无法看到的。然后,当您致电pygame.display.update()时,虚拟表面将被绘制到用户可以看到的屏幕上。这具有技术优势,例如允许计算机平滑地绘制而不会出现屏幕闪烁,但这也意味着只要你不打电话pygame.display.update(),就不会看到任何你画的东西。pygame.display.update(),什么都没有你画的将永远可见。但是,如果你打电话太多次,你的游戏可能会以意想不到的方式闪烁或动作。因此,您通常希望每个游戏循环只调用pygame.display.update()一次(就像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.spaceself.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()

答案 1 :(得分:0)

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

var.Attack

您没有调用attack函数。

将其替换为

var.Attack()

并查看是否有效。

答案 2 :(得分: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()

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