Python 简单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
导入时间
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()
    皮格姆