问题描述
所以我一直在做一个类似蚂蚁模拟的项目,我遇到了这个问题并在这里复制了它。本质上,我所做的是使用 pygame.mouse.get_pos() 在光标位置的每个表面更新绘制一个圆圈。
但不知何故,当您将光标从窗口的左上角移开时,我遇到了这个问题,即通过增加间隔来使圆圈的位置远离光标。还有这个图形故障,似乎光标带来了窗口本身的固定表面,其中包含圆后面对象的表面更新以及圆本身在其中移动。正如您从下面的链接中看到的那样,它还挡住了该窗口后面对象的实际表面。
https://i.gyazo.com/c8b268cf072d040bb4000764d4955cd7.mp4
我在网上环顾四周,到目前为止我还没有接近解决这个问题。我不确定这是表面分层问题、我的逻辑问题还是 pygame 内部的故障。无论如何,这里是下面的代码来复制问题。
"""
import sys
from random import randint,uniform
import pygame
from pygame.sprite import Sprite
class MainGame:
"""Main pygame class."""
def __init__(self):
"""Initialize game assets."""
pygame.init()
self.resolution = (1280,720)
self.screen = pygame.display.set_mode(
self.resolution
)
self.screen_rect = self.screen.get_rect()
pygame.display.set_caption('Circle Test')
# Insert game objects below this line.
self.ccirc = CursorCircle(self)
self.sample1 = pygame.sprite.Group()
self.sample2 = pygame.sprite.Group()
for _ in range(10):
self.sample1.add(SampleObject(self))
sample = SampleObject(self)
sample.front = 0
self.sample2.add(sample)
def start(self):
"""Main game loop."""
while True:
self._keyboard_basic()
# Insert object update below this line.
self.ccirc.update()
self._update_screen()
def _update_screen(self):
"""Game screen update."""
self.screen.fill((77,77,77))
# Insert surface update below this line. ###
for i in self.sample2:
i.blitme()
self.ccirc.blitme()
for i in self.sample1:
i.blitme()
pygame.display.flip()
def _keyboard_basic(self):
"""Response to keypress and mouse events"""
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
self._event_keydown(event)
elif event.type == pygame.KEYUP:
self._event_keyup(event)
def _event_keydown(self,event):
"""Keydown events."""
if event.key == pygame.K_UP:
print('pressed ↑')
elif event.key == pygame.K_DOWN:
print('pressed ↓')
elif event.key == pygame.K_LEFT:
print('pressed ←')
elif event.key == pygame.K_RIGHT:
print('pressed →')
elif event.key == pygame.K_q:
sys.exit()
def _event_keyup(self,event):
"""Keyup events."""
pass
class SampleObject(Sprite):
"""Sample object on screen."""
def __init__(self,main_game):
"""Initialize class assets."""
super().__init__()
self.screen = main_game.screen
self.screen_rect = self.screen.get_rect()
self.image = pygame.image.load('pointer.png')
self.image = pygame.transform.rotate(self.image,randint(1,360))
self.image1 = pygame.image.load('pointer-.png')
self.image1 = pygame.transform.rotate(self.image1,360))
self.rect = self.image.get_rect()
self.rect.centerx = randint(1,main_game.resolution[0])
self.rect.centery = randint(1,main_game.resolution[1])
self.front = 1
def blitme(self):
"""Surface update."""
if self.front:
self.screen.blit(self.image,self.rect)
else:
self.screen.blit(self.image1,self.rect)
class CursorCircle(Sprite):
"""Circle that follows the cursor."""
def __init__(self,main_game):
"""Initialize class assets."""
super().__init__()
self.screen = main_game.screen
self.screen_rect = self.screen.get_rect()
self.color = (0,102,204)
# self.center = [self.screen_rect.centerx,self.screen_rect.centery]
# self.center = [0,0]
self.radius = 100
def update(self):
"""Loop update."""
self.center = pygame.mouse.get_pos()
def blitme(self):
"""Surface update."""
self.circle = pygame.draw.circle(self.screen,self.color,self.center,self.radius)
self.screen.blit(self.screen,self.circle)
if __name__ == '__main__':
game = MainGame()
game.start()
"""
版本 *Python 3.9.1 *pygame 2.0.1
解决方法
pygame.draw.circel
在 screen
上画一个圆圈。此函数不会生成类似圆形对象的东西。见how to draw shapes。
然而,self.screen.blit(self.screen,self.circle)
并没有达到您的预期。它将整个屏幕复制到自己的圆形位置。
删除此说明:
class CursorCircle(Sprite):
# [...]
def blitme(self):
"""Surface update."""
pygame.draw.circle(self.screen,self.color,self.center,self.radius)
#self.screen.blit(self.screen,self.circle) <--- DELETE
或者,您可以在具有每像素 Alpha 格式 (pygame.SRCALPHA
) 的 pygame.Surface
对象上绘制圆,并在屏幕上blit
表面:
class CursorCircle(Sprite):
"""Circle that follows the cursor."""
def __init__(self,main_game):
"""Initialize class assets."""
super().__init__()
self.screen = main_game.screen
self.color = (0,102,204)
self.radius = 100
self.circle = pygame.Surface((radius*2,radius*2),pygame.SRCALPHA)
pygame.draw.circle(self.circle,(radius,radius),radius)
self.rect = self.circle.get_rect()
def update(self):
"""Loop update."""
self.rect.center = pygame.mouse.get_pos()
def blitme(self):
"""Surface update."""
self.screen.blit(self.circle,self.rect)