Python MacBook Pro上的Pygame laggy

Python MacBook Pro上的Pygame laggy,python,macos,python-3.x,pygame,Python,Macos,Python 3.x,Pygame,我正试图在我的MBP 2013(i5,4go内存,intel iris 1536mo)上用Pygame制作一个视频游戏,我在网上找到的任何样本都是非常滞后的。 然而,如果我使用旧版mac(2011)启动这些游戏,但使用专用图形卡(??),我可以玩没有FPS问题的游戏 这是一个样本(来自) 我尝试使用pygame.display.update()更改pygame.display.flip()但未成功,使用pygame.timer.wait()更改了pygame.display.flip(),但随机

我正试图在我的MBP 2013(i5,4go内存,intel iris 1536mo)上用Pygame制作一个视频游戏,我在网上找到的任何样本都是非常滞后的。 然而,如果我使用旧版mac(2011)启动这些游戏,但使用专用图形卡(??),我可以玩没有FPS问题的游戏

这是一个样本(来自)

我尝试使用
pygame.display.update()
更改pygame.display.flip()但未成功,使用
pygame.timer.wait()
更改了
pygame.display.flip()
,但随机结果

有什么办法可以解决我的问题吗

"""
Sample Python/Pygame Programs
Simpson College Computer Science
http://programarcadegames.com/
http://simpson.edu/computer-science/

From:
http://programarcadegames.com/python_examples/f.php?file=platform_scroller.py

Explanation video: http://youtu.be/QplXBw_NK5Y

Part of a series:
http://programarcadegames.com/python_examples/f.php?file=move_with_walls_example.py
http://programarcadegames.com/python_examples/f.php?file=maze_runner.py
http://programarcadegames.com/python_examples/f.php?file=platform_jumper.py
http://programarcadegames.com/python_examples/f.php?file=platform_scroller.py
http://programarcadegames.com/python_examples/f.php?file=platform_moving.py
http://programarcadegames.com/python_examples/sprite_sheets/

"""

import pygame
import time

# Global constants

# Colors
BLACK    = (   0,   0,   0)
WHITE    = ( 255, 255, 255)
BLUE     = (   0,   0, 255)
RED      = ( 255,   0,   0)
GREEN    = (   0, 255,   0)

# Screen dimensions
SCREEN_WIDTH  = 800
SCREEN_HEIGHT = 600

class Player(pygame.sprite.Sprite):
    """
    This class represents the bar at the bottom that the player controls.
    """

    # -- Attributes
    # Set speed vector of player
    change_x = 0
    change_y = 0

    # List of sprites we can bump against
    level = None

    # -- Methods
    def __init__(self):
        """ Constructor function """

        # Call the parent's constructor
        super().__init__()

        # Create an image of the block, and fill it with a color.
        # This could also be an image loaded from the disk.
        width = 40
        height = 60
        self.image = pygame.Surface([width, height])
        self.image.fill(RED)

        # Set a referance to the image rect.
        self.rect = self.image.get_rect()

    def update(self):
        """ Move the player. """
        # Gravity
        self.calc_grav()

        # Move left/right
        self.rect.x += self.change_x

        # See if we hit anything
        block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
        for block in block_hit_list:
            # If we are moving right,
            # set our right side to the left side of the item we hit
            if self.change_x > 0:
                self.rect.right = block.rect.left
            elif self.change_x < 0:
                # Otherwise if we are moving left, do the opposite.
                self.rect.left = block.rect.right

        # Move up/down
        self.rect.y += self.change_y

        # Check and see if we hit anything
        block_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
        for block in block_hit_list:

            # Reset our position based on the top/bottom of the object.
            if self.change_y > 0:
                self.rect.bottom = block.rect.top
            elif self.change_y < 0:
                self.rect.top = block.rect.bottom

            # Stop our vertical movement
            self.change_y = 0

    def calc_grav(self):
        """ Calculate effect of gravity. """
        if self.change_y == 0:
            self.change_y = 1
        else:
            self.change_y += .35

        # See if we are on the ground.
        if self.rect.y >= SCREEN_HEIGHT - self.rect.height and self.change_y >= 0:
            self.change_y = 0
            self.rect.y = SCREEN_HEIGHT - self.rect.height

    def jump(self):
        """ Called when user hits 'jump' button. """

        # move down a bit and see if there is a platform below us.
        # Move down 2 pixels because it doesn't work well if we only move down 1
        # when working with a platform moving down.
        self.rect.y += 2
        platform_hit_list = pygame.sprite.spritecollide(self, self.level.platform_list, False)
        self.rect.y -= 2

        # If it is ok to jump, set our speed upwards
        if len(platform_hit_list) > 0 or self.rect.bottom >= SCREEN_HEIGHT:
            self.change_y = -10

    # Player-controlled movement:
    def go_left(self):
        """ Called when the user hits the left arrow. """
        self.change_x = -6

    def go_right(self):
        """ Called when the user hits the right arrow. """
        self.change_x = 6

    def stop(self):
        """ Called when the user lets off the keyboard. """
        self.change_x = 0

class Platform(pygame.sprite.Sprite):
    """ Platform the user can jump on """

    def __init__(self, width, height):
        """ Platform constructor. Assumes constructed with user passing in
            an array of 5 numbers like what's defined at the top of this code.
            """
        super().__init__()

        self.image = pygame.Surface([width, height])
        self.image.fill(GREEN)

        self.rect = self.image.get_rect()

class Level():
    """ This is a generic super-class used to define a level.
        Create a child class for each level with level-specific
        info. """

    # Lists of sprites used in all levels. Add or remove
    # lists as needed for your game.
    platform_list = None
    enemy_list = None

    # How far this world has been scrolled left/right
    world_shift = 0

    def __init__(self, player):
        """ Constructor. Pass in a handle to player. Needed for when moving
            platforms collide with the player. """
        self.platform_list = pygame.sprite.Group()
        self.enemy_list = pygame.sprite.Group()
        self.player = player

    # Update everythign on this level
    def update(self):
        """ Update everything in this level."""
        self.platform_list.update()
        self.enemy_list.update()

    def draw(self, screen):
        """ Draw everything on this level. """

        # Draw the background
        screen.fill(BLUE)

        # Draw all the sprite lists that we have
        self.platform_list.draw(screen)
        self.enemy_list.draw(screen)

    def shift_world(self, shift_x):
        """ When the user moves left/right and we need to scroll everything: """

        # Keep track of the shift amount
        self.world_shift += shift_x

        # Go through all the sprite lists and shift
        for platform in self.platform_list:
            platform.rect.x += shift_x

        for enemy in self.enemy_list:
            enemy.rect.x += shift_x

# Create platforms for the level
class Level_01(Level):
    """ Definition for level 1. """

    def __init__(self, player):
        """ Create level 1. """

        # Call the parent constructor
        Level.__init__(self, player)

        self.level_limit = -1000

        # Array with width, height, x, and y of platform
        level = [[210, 70, 500, 500],
                 [210, 70, 800, 400],
                 [210, 70, 1000, 500],
                 [210, 70, 1120, 280],
                 ]


        # Go through the array above and add platforms
        for platform in level:
            block = Platform(platform[0], platform[1])
            block.rect.x = platform[2]
            block.rect.y = platform[3]
            block.player = self.player
            self.platform_list.add(block)

# Create platforms for the level
class Level_02(Level):
    """ Definition for level 2. """

    def __init__(self, player):
        """ Create level 1. """

        # Call the parent constructor
        Level.__init__(self, player)

        self.level_limit = -1000

        # Array with type of platform, and x, y location of the platform.
        level = [[210, 30, 450, 570],
                 [210, 30, 850, 420],
                 [210, 30, 1000, 520],
                 [210, 30, 1120, 280],
                 ]


        # Go through the array above and add platforms
        for platform in level:
            block = Platform(platform[0], platform[1])
            block.rect.x = platform[2]
            block.rect.y = platform[3]
            block.player = self.player
            self.platform_list.add(block)

def main():
    """ Main Program """
    pygame.init()

    # Set the height and width of the screen
    size = [SCREEN_WIDTH, SCREEN_HEIGHT]
    screen = pygame.display.set_mode(size)

    pygame.display.set_caption("Side-scrolling Platformer")

    # Create the player
    player = Player()

    # Create all the levels
    level_list = []
    level_list.append(Level_01(player))
    level_list.append(Level_02(player))

    # Set the current level
    current_level_no = 0
    current_level = level_list[current_level_no]

    active_sprite_list = pygame.sprite.Group()
    player.level = current_level

    player.rect.x = 340
    player.rect.y = SCREEN_HEIGHT - player.rect.height
    active_sprite_list.add(player)

    #Loop until the user clicks the close button.
    done = False

    # Used to manage how fast the screen updates
    clock = pygame.time.Clock()

    # -------- Main Program Loop -----------
    tick = 0
    current_milli_time = lambda: int(round(time.time() * 1000))
    mtime = current_milli_time()
    while not done:
        for event in pygame.event.get(): # User did something
            if event.type == pygame.QUIT: # If user clicked close
                done = True # Flag that we are done so we exit this loop

            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    player.go_left()
                if event.key == pygame.K_RIGHT:
                    player.go_right()
                if event.key == pygame.K_UP:
                    player.jump()

            if event.type == pygame.KEYUP:
                if event.key == pygame.K_LEFT and player.change_x < 0:
                    player.stop()
                if event.key == pygame.K_RIGHT and player.change_x > 0:
                    player.stop()

        # Update the player.
        active_sprite_list.update()

        # Update items in the level
        current_level.update()

        # If the player gets near the right side, shift the world left (-x)
        if player.rect.right >= 500:
            diff = player.rect.right - 500
            player.rect.right = 500
            current_level.shift_world(-diff)

        # If the player gets near the left side, shift the world right (+x)
        if player.rect.left <= 120:
            diff = 120 - player.rect.left
            player.rect.left = 120
            current_level.shift_world(diff)

        # If the player gets to the end of the level, go to the next level
        current_position = player.rect.x + current_level.world_shift
        if current_position < current_level.level_limit:
            player.rect.x = 120
            if current_level_no < len(level_list)-1:
                current_level_no += 1
                current_level = level_list[current_level_no]
                player.level = current_level

        # ALL CODE TO DRAW SHOULD GO BELOW THIS COMMENT
        current_level.draw(screen)
        active_sprite_list.draw(screen)

        # ALL CODE TO DRAW SHOULD GO ABOVE THIS COMMENT

        if tick %30 == 0:
            print (current_milli_time() - mtime)
            mtime = current_milli_time()
        tick+=1
        # Limit to 30 frames per second
        clock.tick(30)

        # Go ahead and update the screen with what we've drawn.
        pygame.display.flip()

    # Be IDLE friendly. If you forget this line, the program will 'hang'
    # on exit.
    pygame.quit()

if __name__ == "__main__":
    main()
“”“
Python/Pygame示例程序
辛普森学院计算机科学
http://programarcadegames.com/
http://simpson.edu/computer-science/
发件人:
http://programarcadegames.com/python_examples/f.php?file=platform_scroller.py
解说视频:http://youtu.be/QplXBw_NK5Y
系列的一部分:
http://programarcadegames.com/python_examples/f.php?file=move_with_walls_example.py
http://programarcadegames.com/python_examples/f.php?file=maze_runner.py
http://programarcadegames.com/python_examples/f.php?file=platform_jumper.py
http://programarcadegames.com/python_examples/f.php?file=platform_scroller.py
http://programarcadegames.com/python_examples/f.php?file=platform_moving.py
http://programarcadegames.com/python_examples/sprite_sheets/
"""
导入pygame
导入时间
#全局常数
#颜色
黑色=(0,0,0)
白色=(255,255,255)
蓝色=(0,0255)
红色=(255,0,0)
绿色=(0,255,0)
#屏幕尺寸
屏幕宽度=800
屏幕高度=600
职业玩家(pygame.sprite.sprite):
"""
此类表示玩家控制的底部的条。
"""
#--属性
#设置玩家的速度向量
改变x=0
改变y=0
#我们可以碰撞的精灵列表
级别=无
#--方法
定义初始化(自):
“构造函数”
#调用父级的构造函数
super()。\uuuu init\uuuuu()
#创建块的图像,并用颜色填充。
#这也可能是从磁盘加载的映像。
宽度=40
高度=60
self.image=pygame.Surface([宽度,高度])
self.image.fill(红色)
#设置对图像矩形的引用。
self.rect=self.image.get_rect()
def更新(自我):
“”“移动播放机。”“”
#重力
self.calc_grav()
#向左/向右移动
self.rect.x+=self.change\u x
#看看我们有没有击中什么
block\u hit\u list=pygame.sprite.spritecollide(self,self.level.platform\u list,False)
对于block_命中列表中的block_:
#如果我们走对了,
#将我们击中的物品的右侧设置为左侧
如果self.change_x>0:
self.rect.right=block.rect.left
elif self.change_x<0:
#否则,如果我们向左移动,则执行相反的操作。
self.rect.left=block.rect.right
#上移/下移
self.rect.y+=self.change\u y
#看看我们有没有碰到什么东西
block\u hit\u list=pygame.sprite.spritecollide(self,self.level.platform\u list,False)
对于block_命中列表中的block_:
#根据对象的顶部/底部重置我们的位置。
如果self.change_y>0:
self.rect.bottom=block.rect.top
elif self.change_y<0:
self.rect.top=block.rect.bottom
#停止我们的垂直运动
self.change_y=0
def calc_grav(自身):
“”“计算重力的影响。”“”
如果self.change_y==0:
self.change_y=1
其他:
自我改变y+=0.35
#看看我们是否在地面上。
如果self.rect.y>=屏幕高度-self.rect.HEIGHT和self.change\u y>=0:
self.change_y=0
self.rect.y=屏幕高度-self.rect.HEIGHT
def跳转(自):
“”“当用户点击“跳转”按钮时调用。”“”
#向下移动一点,看看我们下面是否有平台。
#向下移动2个像素,因为如果只向下移动1个像素,效果不好
#当工作平台向下移动时。
自校正y+=2
platform\u hit\u list=pygame.sprite.spritecollide(self,self.level.platform\u list,False)
自校正y-=2
#如果可以跳,就把速度调高
如果len(平台点击列表)>0或self.rect.bottom>=屏幕高度:
self.change_y=-10
#玩家控制的移动:
def go_左(自):
“”“当用户点击左箭头时调用。”“”
self.change_x=-6
def向右(自):
“”“当用户点击右箭头时调用。”“”
自我改变x=6
def停止(自):
“”“当用户松开键盘时调用。”“”
self.change_x=0
类平台(pygame.sprite.sprite):
“”“用户可以跳到的平台”“”
定义初始值(自身、宽度、高度):
“”“平台构造函数。假定由用户传入构造
一个由5个数字组成的数组,类似于此代码顶部定义的数字。
"""
super()。\uuuu init\uuuuu()
self.image=pygame.Surface([宽度,高度])
self.image.fill(绿色)
self.rect=self.image.get_rect()
类级别():
“”“这是用于定义级别的泛型超类。
为每个具有特定级别的级别创建子类
信息。”“”
#所有级别中使用的精灵列表。添加或删除
#列出游戏所需的列表。
平台列表=无
敌人名单=无
#这个世界向左/向右滚动了多远
世界移动=0
定义初始(自我,玩家):
“”“构造函数。将句柄传递给播放机。移动时需要
平台与播放器碰撞。”“”
self.platform_list=pygame.sprite.Group()
self.敌军_list=pygame.sprite.Group()
自选球员=
1. CPU usage required for the game
2. Graphics card and their drivers
3. Random Access Memory aka RAM
1. Limit other processes or programs.
2. Compress game assets and variables.
3. Upgrade the amount of RAM.