我正在学习python *\(^o^)/*
我有一个使用Pygame
绘制的简单弹跳框窗口。除了一个小麻烦外,一切似乎都运转正常。它不断口吃!我不知道是什么原因导致口吃。我认为它可能是滞后的,所以我实现了一个固定的时间步骤以允许循环赶上,但这没有任何影响。
#--- initialize pygame window ---#
import pygame
import time
pygame.init()
size = (1200,500)
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
fps = 60
#--- define color palette ---#
black = (0,0,0)
white = (255,255,255)
#--- define the player ---#
class player:
def __init__(self,screen,surface, color):
self.speed = 3
self.direction_x = 1
self.direction_y = 1
self.screen = screen
self.surface = surface
self.rect = self.surface.get_rect()
self.color = color
def set_pos(self, x,y):
self.rect.x = x
self.rect.y = y
def advance_pos(self):
screen_width, screen_height = screen.get_size()
if self.rect.x + self.rect.width > screen_width or player1.rect.x < 0:
player1.direction_x *= -1
player1.speed = 3
elif player1.rect.y + player1.rect.height > screen_height or player1.rect.y < 0:
player1.direction_y *= -1
player1.speed = 3
else:
player1.speed -= 0.001
self.rect.x += self.speed * self.direction_x
self.rect.y += self.speed * self.direction_y
def draw(self):
pygame.draw.rect(self.surface, self.color, [0,0,self.rect.width,self.rect.height])
def blit(self):
screen.blit(self.surface, self.rect)
player1 = player(screen, pygame.Surface((50,50)), white)
player1.set_pos(50,50)
player1.draw()
#--- define game variables ---#
previous = time.time() * 1000
lag = 0.0
background = black
done = False
#--- game ---#
while not done:
#--- update time step ---#
current = time.time() * 1000
elapsed = current - previous
lag += elapsed
previous = current
#--- process events ---#
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
break
if event.type == pygame.VIDEORESIZE:
screen = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)
#--- update logic ---#
while True:
player1.advance_pos()
lag -= fps
if lag <= fps:
break
#--- draw to screen ---#
screen.fill(background)
player1.blit()
pygame.display.update()
pygame.time.Clock().tick(fps)
答案 0 :(得分:1)
这是对代码的重写,它使用opengl代替渲染。主要变化如下:
我修正了计时器的完成方式。我不是手动执行clock.tick(fps),而是手动跟踪对帧执行所有处理所需的时间,并添加适当的毫秒延迟以达到60 fps。您可以在迁移到opengl之前尝试使用现有的pygame代码进行修改,因为这可能足以删除大部分断断续续的内容。
import pygame
import time
from OpenGL.GL import *
class Player:
def __init__(self, screen, width, height, color):
self.x = 0
self.y = 0
self.speed = 3
self.direction_x = 1
self.direction_y = 1
self.screen = screen
self.width = width
self.height = height
self.color = color
def set_pos(self, x, y):
self.x = x
self.y = y
def advance_pos(self):
screen_width, screen_height = screen.get_size()
if self.x + self.width > screen_width or self.x < 0:
self.direction_x *= -1
self.speed = 3
elif self.y + self.height > screen_height or self.y < 0:
self.direction_y *= -1
self.speed = 3
else:
self.speed -= 0.001
self.x += self.speed * self.direction_x
self.y += self.speed * self.direction_y
def draw(self):
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
glTranslate(self.x, self.y, 0)
glBegin(GL_QUADS)
glColor(*self.color)
glVertex(0, 0, 0)
glVertex(self.width, 0, 0)
glVertex(self.width, self.height, 0)
glVertex(0, self.height, 0)
glEnd()
if __name__ == "__main__":
pygame.init()
size = width, height = (550, 400)
screen = pygame.display.set_mode(size, pygame.RESIZABLE | pygame.DOUBLEBUF | pygame.OPENGL)
fps = 60
black = (0,0,0,255)
white = (255,255,255,255)
player1 = Player(screen, 50, 50, white)
player1.set_pos(50,50)
done = False
previous = time.time() * 1000
glClearColor(*black)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, height, 0, -1, 1)
clock = pygame.time.Clock()
while not done:
current = time.time() * 1000
elapsed = current - previous
previous = current
delay = 1000.0/fps - elapsed
delay = max(int(delay), 0)
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
break
if event.type == pygame.VIDEORESIZE:
size = width, height = event.w, event.h
screen = pygame.display.set_mode(size, pygame.RESIZABLE | pygame.DOUBLEBUF | pygame.OPENGL)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
glOrtho(0, width, height, 0, -1, 1)
glViewport(0, 0, width, height)
#reset player movement and position to avoid glitches where player is trapped outside new window borders
player1.set_pos(50, 50)
player1.direction_x = 1
player1.direction_y = 1
player1.advance_pos()
glClear(GL_COLOR_BUFFER_BIT)
glClear(GL_DEPTH_BUFFER_BIT)
player1.draw()
pygame.display.flip()
pygame.time.delay(delay)
答案 1 :(得分:0)
我在进入“未完成”循环之前创建了一个时钟对象,不再有滞后现象
#--- initialize pygame window ---#
import pygame
import time
pygame.init()
size = (1200,500)
screen = pygame.display.set_mode(size, pygame.RESIZABLE)
fps = 60
#--- define color palette ---#
black = (0,0,0)
white = (255,255,255)
#--- define the player ---#
class player:
def __init__(self,screen,surface, color):
self.speed = 3
self.direction_x = 1
self.direction_y = 1
self.screen = screen
self.surface = surface
self.rect = self.surface.get_rect()
self.color = color
def set_pos(self, x,y):
self.rect.x = x
self.rect.y = y
def advance_pos(self):
screen_width, screen_height = screen.get_size()
if self.rect.x + self.rect.width > screen_width or player1.rect.x < 0:
player1.direction_x *= -1
player1.speed = 3
elif player1.rect.y + player1.rect.height > screen_height or player1.rect.y < 0:
player1.direction_y *= -1
player1.speed = 3
else:
player1.speed -= 0.001
self.rect.x += self.speed * self.direction_x
self.rect.y += self.speed * self.direction_y
def draw(self):
pygame.draw.rect(self.surface, self.color, [0,0,self.rect.width,self.rect.height])
def blit(self):
screen.blit(self.surface, self.rect)
player1 = player(screen, pygame.Surface((50,50)), white)
player1.set_pos(50,50)
player1.draw()
#--- define game variables ---#
previous = time.time() * 1000
lag = 0.0
background = black
done = False
clock=pygame.time.Clock()
#--- game ---#
while not done:
#--- update time step ---#
current = time.time() * 1000
elapsed = current - previous
lag += elapsed
previous = current
#--- process events ---#
for event in pygame.event.get():
if event.type == pygame.QUIT:
done = True
break
if event.type == pygame.VIDEORESIZE:
screen = pygame.display.set_mode((event.w, event.h), pygame.RESIZABLE)
#--- update logic ---#
while True:
player1.advance_pos()
lag -= fps
if lag <= fps:
break
#--- draw to screen ---#
screen.fill(background)
player1.blit()
pygame.display.update()
clock.tick(fps)
pygame.quit()