简体   繁体   English

pygame精灵在移动时会闪烁-如何解决?

[英]pygame sprite flickers when moving - how to fix?

I'm writing a top-down type game and I can't seem to fix the flicker of my world entities when they are drawn to screen... I was wondering if someone can review this code and help me find the solution. 我正在写一个自上而下的游戏,当我的世界实体被吸引到屏幕上时,我似乎无法解决它们的闪烁问题。我想知道是否有人可以查看此代码并帮助我找到解决方案。 Thanks. 谢谢。

#!/usr/bin/env python

#Unnamed Game

import pygame,sys,spriteUtil,random 
from pygame.locals import *
from threading import Thread

class Game():
  def __init__(self):
    pygame.init()
    pygame.key.set_repeat(1,100)
    self.size = (512, 512)
    self.screen = pygame.display.set_mode(self.size)
    self.clock = pygame.time.Clock()

    self.titleScreen = pygame.image.load("unnamed.png")
    self.titleScreenRect = self.titleScreen.get_rect()

    self.screen.blit(self.titleScreen, self.titleScreenRect)
    pygame.display.flip()

class Hero(pygame.sprite.Sprite):
  def __init__(self, screen, background):
    pygame.sprite.Sprite.__init__(self)
    self.size = (30,30)
    self.northWalk = 'link.png'
    self.screen = screen
    self.background = background
    self.s = spriteUtil.SpriteUtility()  #this just takes a sprite sheet and returns a list of sprite images  
    self.northSprites = self.s.getSprites(self.size, self.northWalk) #as above

    self.x_coord = 0
    self.y_coord = 0

  def walkNorthAnimation(self):
    for sprite in self.northSprites:
      self.screen.blit(self.background,(0,0))
      self.screen.blit(sprite, (256-20,256-30))
      pygame.display.update()

class WorldEntity(pygame.sprite.Sprite):
  def __init__(self, screen, ent_img, size=(60,90)):
    pygame.sprite.Sprite.__init__(self)
    self.screen = screen
    self.size = size
    self.ent = pygame.image.load(ent_img)
    self.layer = -100

    self.width, self.height = size
    self.x_coord = random.randint(0,513)
    self.y_coord = random.randint(0,513)


  def drawEnt(self):  
    self.screen.blit(self.ent,(self.x_coord, self.y_coord))

class World():
  def __init__(self, screen):
    self.screen = screen
    self.background = pygame.image.load('grass.png')
    self.backgroundRect = self.background.get_rect()
    self.entityList = []

  def loadWorld(self):
    self.screen.blit(self.background, self.backgroundRect)
    pygame.display.update()

  def populateEntities(self):
    for tree in range(1):
      tree = WorldEntity(self.screen,'tree.png')
      self.entityList.append(tree)

  def drawWorld(self):
    for ent in self.entityList:    
      ent.drawEnt()
    pygame.display.update()

def main():
  g = Game()
  world = World(g.screen)
  world.populateEntities()
  player = Hero(g.screen, world.background)
  player.walkNorthAnimation()
  world.drawWorld()
  while 1: 
    for event in pygame.event.get():
      if event.type == pygame.QUIT: 
        sys.exit()
      elif event.type == KEYDOWN:
        if event.key == pygame.K_w:
          steps = 6
          for step in range(steps): 
            for ent in world.entityList:
              ent.y_coord += 5        
            player.walkNorthAnimation()
            world.drawWorld()

if __name__ == '__main__':
  main()

I have tried just blitting the sprites in the northWalk animation method rather than updating display there and it results in successfully removing the flicker, but then the sprite doesn't animate/"walk".... grateful for advice on how to fix this. 我试过只是在northWalk动画方法中略过精灵,而不是在那里更新显示,这会成功消除闪烁,但是之后精灵无法动画/“行走”。...感谢您提供有关如何解决此问题的建议。

if you need sprites animated all time you will have to move blit outside for event loop. 如果您需要一直保持动画的精灵,则必须将blit移到外面for event循环。

you example 你的例子

# --- events ---

for event in pygame.event.get():
    if event.key == pygame.K_w:
         move_y = 1
    if event.key == pygame.K_s:
         move_y = -1
    if event.key == pygame.K_a:
         move_x = -1
    if event.key == pygame.K_d:
         move_x = 1

# --- updates in every loop (without drawing) ---

for sprite in player.northSprites:
    for ent in world.entityList:
        ent.x_coord += move_x
        ent.y_coord += move_y

# --- draws in every loop (without updates) ---

g.screen.blit(world.background, (0,0))

g.screen.blit(sprite, (256-20,256-30))
world.drawWorld() 

pygame.display.update()

# --- 25 FPS ---

clock.tick(25)

-- -

Pygame is not ideal - probably it has problem with VSYNC ( vertical synchronization ) so it has problem with screen tearing . Pygame并不理想-可能是VSYNC( 垂直同步 )有问题,所以屏幕破裂有问题。

thanks for the tips guys - I worked it out! 谢谢大家的提示-我解决了!

if event.key == pygame.K_w:
  for sprite in player.northSprites:
    for ent in world.entityList:
      ent.y_coord +=1            
    g.screen.blit(world.background, (0,0))
    g.screen.blit(sprite, (256-20,256-30))
    world.drawWorld() 

And removed the updating from within classes. 并从类内删除了更新。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM