python - Pygame 在鼠标位置绘制的圆圈有位置不匹配和奇怪的显示故障
问题描述
所以我一直在做一个类似蚂蚁模拟的项目,我遇到了这个问题并在这里复制了它。本质上,我所做的是使用 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, randint(1, 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
。此函数不会生成类似于圆形对象的东西。了解如何绘制形状。
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
pygame.Surface
或者,您可以在具有每像素 alpha 格式 ( pygame.SRCALPHA
)的对象上绘制圆,并blit
在屏幕上绘制Surface :
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, self.color, (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)
推荐阅读
- postgresql - Cloud SQL(postgres)外部数据包装器连接超时到副本实例
- c - 为什么这段代码在 C 中没有返回任何内容
- reactjs - React 模态提交表单
- reactjs - React 中的可重用文本字段
- c++ - 如何使用 C++ 正则表达式在方括号之间查找字符
- python - 我在定义变量时收到变量未定义错误
- ubuntu-18.04 - com.sun.jersey.server.impl.application.WebApplicationImpl._initiate 启动 Jersey 应用程序,版本 'Jersey: 1.9 09/02/2011 11:17 AM'
- windows - 如何在 Windows 10 中重新启动网络堆栈
- javascript - Ember:将模型数据设置为组件值?
- windows - 如何在 Windows git-bash 控制台下运行批处理文件?