Python 简单Pygame动画口吃
我有一个简单的弹跳框窗口,它是用“Pygame”绘制的。除了一点烦恼外,一切似乎都正常工作。它经常口吃!我不知道是什么导致口吃。我认为这可能是一个延迟,所以我实现了一个固定的时间步长,以允许循环赶上,但这没有效果Python 简单Pygame动画口吃,python,pygame,Python,Pygame,我有一个简单的弹跳框窗口,它是用“Pygame”绘制的。除了一点烦恼外,一切似乎都正常工作。它经常口吃!我不知道是什么导致口吃。我认为这可能是一个延迟,所以我实现了一个固定的时间步长,以允许循环赶上,但这没有效果 #---初始化pygame窗口---# 导入pygame 导入时间 pygame.init() 尺寸=(1200500) screen=pygame.display.set_模式(大小,pygame.resizeable) fps=60 #---定义调色板---# 黑色=(0,0,0)
#---初始化pygame窗口---#
导入pygame
导入时间
pygame.init()
尺寸=(1200500)
screen=pygame.display.set_模式(大小,pygame.resizeable)
fps=60
#---定义调色板---#
黑色=(0,0,0)
白色=(255255)
#---定义玩家---#
职业球员:
定义初始(自身、屏幕、表面、颜色):
自身速度=3
自身方向_x=1
自身方向_y=1
self.screen=屏幕
self.surface=曲面
self.rect=self.surface.get_rect()
self.color=颜色
def设置位置(自身、x、y):
self.rect.x=x
自校正y=y
def前进位置(自身):
屏幕宽度,屏幕高度=屏幕。获取屏幕大小()
如果self.rect.x+self.rect.width>screen\u width或player1.rect.x<0:
player1.direction_x*=-1
player1.speed=3
elif player1.rect.y+player1.rect.height>屏幕高度或player1.rect.y<0:
player1.direction_y*=-1
player1.speed=3
其他:
player1.speed-=0.001
self.rect.x+=self.speed*self.direction\ux
self.rect.y+=self.speed*self.direction\u y
def牵引(自):
pygame.draw.rect(self.surface,self.color,[0,0,self.rect.width,self.rect.height])
def blit(自身):
screen.blit(self.surface、self.rect)
player1=玩家(屏幕,pygame.Surface((50,50)),白色)
播放器1.设置位置(50,50)
player1.draw()
#---定义游戏变量---#
previous=时间。时间()*1000
滞后=0.0
背景=黑色
完成=错误
#---游戏---#
虽然没有这样做:
#---更新时间步长---#
当前=时间。时间()*1000
已用=当前-上一个
滞后时间+=经过的时间
先前=当前
#---处理事件---#
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
完成=正确
打破
如果event.type==pygame.VIDEORESIZE:
screen=pygame.display.set_模式((event.w,event.h),pygame.resizeable)
#---更新逻辑---#
尽管如此:
播放机1.前进位置()
滞后时间-=fps
如果lag,这是对代码的重写,使用opengl代替渲染。主要变化如下:
我使用的是opengl即时模式,它已经过时了,不推荐使用,但一开始要容易理解得多。大多数gl调用要么在player.draw()方法中,要么在主循环中
我修正了计时器的工作方式。我不只是做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)
导入pygame
导入时间
从OpenGL.GL导入*
职业球员:
定义初始(自身、屏幕、宽度、高度、颜色):
self.x=0
self.y=0
自身速度=3
自身方向_x=1
自身方向_y=1
self.screen=屏幕
self.width=宽度
自我高度=高度
self.color=颜色
def设置位置(自身、x、y):
self.x=x
self.y=y
def前进位置(自身):
屏幕宽度,屏幕高度=屏幕。获取屏幕大小()
如果self.x+self.width>屏幕宽度或self.x<0:
自身方向_x*=-1
自身速度=3
elif self.y+self.height>屏幕高度或self.y<0:
自我方向_y*=-1
自身速度=3
其他:
自身速度-=0.001
self.x+=self.speed*self.direction\u x
self.y+=self.speed*self.direction\u y
def牵引(自):
glMatrixMode(GLU模型视图)
glLoadIdentity()
glTranslate(self.x,self.y,0)
glBegin(GLU四边形)
glColor(*self.color)
glVertex(0,0,0)
glVertex(self.width,0,0)
glVertex(self.width、self.height、0)
glVertex(0,self.height,0)
格伦德()
如果名称=“\uuuuu main\uuuuuuuu”:
pygame.init()
尺寸=宽度,高度=(550400)
screen=pygame.display.set_模式(大小,pygame.resizeable | pygame.DOUBLEBUF | pygame.OPENGL)
fps=60
黑色=(0,0,0255)
白色=(255255)
player1=播放器(屏幕,50,50,白色)
播放器1.设置位置(50,50)
完成=错误
previous=时间。时间()*1000
glClearColor(*黑色)
glMatrixMode(GL_投影)
glLoadIdentity()
格洛托(0,宽度,高度,0,-1,1)
clock=pygame.time.clock()
虽然没有这样做:
当前=时间。时间()*1000
已用=当前-上一个
先前=当前
延迟=1000.0/fps-已过
延迟=最大值(整数(延迟),0)
对于pygame.event.get()中的事件:
如果event.type==pygame.QUIT:
完成=正确
打破
如果event.type==pygame.VIDEORESIZE:
尺寸=宽度,高度=事件.w,事件.h
screen=pygame.display.set_模式(大小,pygame.resizeable | pygame.DOUBLEBUF | pygame.OPENGL)
glMatrixMode(GL_投影)
glLoadIdentity()
格洛托(0,宽度,高度,0,-1,1)
glViewport(0,0,宽度,高度)
#重置玩家移动和位置,以避免玩家被困在新窗口边界之外时出现故障
播放者1.设置位置(50,50)
播放器1.方向_x=1
player1.方向_y=1
播放机1.前进位置()
glClear(GLU颜色缓冲位)
glClear(GLU深度缓冲位)
player1.draw()
皮格姆