2015-08-07 2 views
0

Я новичок в pygame и у меня возникли проблемы со спринтером, который мерцает/перетаскивает его изображение, когда он перемещается по экрану. Я читал другие ответы здесь о получении определенных пикс/с, где вам нужно изменить частоту кадров и более низкий pix/frame, но это решение не помогло, поэтому мне было интересно, не правильно ли я его правильно реализую, и это только решение или если я что-то упускаю. Ниже приведен код для игры, которая работает с постоянной частотой кадров. Спасибо!Pygame Sprite мерцает при перемещении

pygame.init() 
display=pygame.display.set_mode((screen_width,screen_height), pygame.RESIZABLE) 
background=pygame.Surface((screen_width, screen_height)) 
background.fill(background_color) 

class Ship(pygame.sprite.Sprite): 
    def __init__(self, image_file): 
     pygame.sprite.Sprite.__init__(self) 
     self.original_image_unscaled=pygame.image.load(image_file) 
     self.original_image=pygame.transform.smoothscale(self.original_image_unscaled, (56,70)) 
     self.image=self.original_image 
     self.rect=self.image.get_rect() 
     self.xpos=0 
     self.ypos=0 
     self.rect.centerx=self.xpos 
     self.rect.centery=self.ypos 
     self.vel=0 
     self.acc=.05 
     self.brake=.2 
     self.turn_brake=1.5 
     self.angle=0 
     self.max_speed=5 

    def getShipPos(self): 
     return (self.xpos, self.ypos) 

    def getShipVel(self): 
     return self.vel 

    def getShipAcc(self): 
     return self.acc 

    def getShipRect(self): 
     return self.rect 

    def update(self): 
     self.rect.centerx=self.xpos 
     self.rect.centery=self.ypos 

    def rotateShip(self, angle): 
     #this rotates the ship by a specified angle 
     self.image, self.rect = pygameRotateImage2(self.original_image, self.rect, angle-self.angle) 
     self.angle+=angle 

    def simpleMove(self, x_final, y_final): 
     self.xpos=x_final 
     self.ypos=y_final 

    def moveShip(self): 
     keys=pygame.key.get_pressed() 
     xpos_i=self.xpos 
     ypos_i=self.ypos 
     if keys[K_w]: 
      if self.vel>self.max_speed: 
       self.vel=self.max_speed 
      else: 
       self.vel+=self.acc   
     elif keys[K_s]: 
      self.vel-=self.brake 
      if self.vel<0: 
       self.vel=0   

     if keys[K_a]: 
      self.rotateShip(-self.turn_brake) 
     elif keys[K_d]: 
      self.rotateShip(self.turn_brake) 

     self.xpos+=self.vel*math.sin(math.radians(self.angle)) 
     self.ypos+= -self.vel*math.cos(math.radians(self.angle)) 

display.blit(background, (0,0)) 
pygame.display.update() 

player_ship=Ship('image.png') 
player_ship.simpleMove(screen_width/2, screen_height/2) 

movement_group=pygame.sprite.Group() 
movement_group.add(player_ship) 

clock=pygame.time.Clock() 
while True: 
    clock.tick(60) 
    (mousex,mousey)=pygame.mouse.get_pos() 
    for event in pygame.event.get(): 
     if event.type==QUIT: 
      pygame.quit() 
      sys.exit() 
    player_ship.moveShip() 

    movement_group.update() 
    display.blit(background, (0,0)) 
    movement_group.draw(display) 
    pygame.display.update() 
+0

На первый взгляд, с ним ничего не получается. Я попытался запустить ваш код, но получил много ошибок. Это ваш полный код? – DJMcMayhem

+0

Нет, это не так, я вынул импортный pygame, математическую линию и функцию вращения, которая является просто общей, которую я взял с сайта pygame. Также необходимо реализовать ширину экрана, высоту и цвет фона, я оставил эти переменные, чтобы люди могли выбирать то, что они хотели на своем экране. – TTrickle

ответ

0

Двойная буферизация, вероятно, поможет хотя бы некоторым. Это технология, используемая в компьютерной графике, чтобы уменьшить количество изменений в пикселях. Он может быть реализован в виде:

pygame.display.set_mode(dimensions, pygame.RESIZEABLE|pygame.DOUBLEBUF) 

Другой вариант заключается в перемещении clock.tick от начала цикла к концу цикла. Именно там я обычно вижу это, и это может изменить исход графики.

+0

Это, похоже, не очень к сожалению. Может быть, pygame - это не то, что я должен использовать? Я считаю, что трудно поверить, хотя, поскольку это похоже на такую ​​простую вещь, это просто перемещение объекта на экране. Даже когда я вынимаю часть вращения, я все еще не получаю приятное изображение, движущееся по экрану. Может, я слишком много прошу? – TTrickle

+0

@TTrickle только что обновил мой ответ с другой идеей – bcdan

+0

Эй, спасибо за быстрые ответы! К сожалению, я тоже это пробовал. Я также попробовал: имея два оператора clock.tick(), увеличивая FPS на оператора clock.tick(), меняя pygame.display.update() на pygame.display.flip(), не используя спрайты вообще и просто blitting изображение в прямоугольник каждый раз, – TTrickle

0

Попробуйте изменить линию pygame.display.update() на номер pygame.display.flip().

0

У меня была такая же проблема в прошлом. Теперь я обычно создаю метод в классах, которые нужно отображать на экране, которые накладывают изображение (самого класса) на экран. Я не называю этот метод перед обновлением экрана.

Например, это метод класса «танк», который на самом деле построить резервуар, используемый игроком:

def master_player(self): #calculate and draw the player sprite 
    self.posix() # call of a method which calculate the position 
    self.image_tank.set_colorkey(PURPLE) 
    screen.blit(player.image_tank, player.position_tuple) 

Как я уже говорил, я называю этот метод в конце игры цикл и до обновления экрана.

0

Попробуйте переместить player_ship.moveShip() прямо под pygame.display.update()

Как это: player_ship.moveShip()

movement_group.update() 
display.blit(background, (0,0)) 
movement_group.draw(display) 
pygame.display.update()