【问题标题】:Pygame application runs slower on Mac than on PCPygame 应用程序在 Mac 上的运行速度比在 PC 上慢
【发布时间】:2015-10-19 13:51:21
【问题描述】:

我和一个朋友正在 Python (2.7) 中使用 Pygame 模块制作游戏。到目前为止,我主要完成了游戏的美术工作,而他主要完成了编码工作,但最终我计划在完成大部分美术工作后帮助他编写代码。我使用的是 Mac(最新版本的 OS X),而我的朋友使用的是 PC。

他一直在他的 PC 上构建和运行游戏,到目前为止,它一直在他的 PC 上按计划运行(完美的 60fps)。然而,每当我从 GitHub 上提取代码(我肯定拥有我们代码的最新版本)并尝试运行游戏时,游戏的运行速度都会减半。

我们已尝试将代码中的 fps 提高一倍至 120,然后它在 PC 上的运行速度提高了一倍,但当我在 Mac 上提取该代码时,它似乎仍然被限制在 30fps 左右。

我们在其他任何地方都没有真正找到任何令人信服的答案,但是我们都是 Pygame 和 Python 的新手,所以我们可能会遗漏一些非常明显的东西。

import pygame as pg
import os

os.environ['SDL_VIDEO_CENTERED'] = '1'

class Wombat:
    def __init__(self, screen_rect, image, starting_loc):
        self.screen_rect = screen_rect
        self.image = image
        self.width = 192
        self.height = 96
        self.starting_loc = starting_loc
        self.rect = self.image.get_rect(bottomleft=starting_loc)
        self.speed = 5
        self.grav = .5

        self.jumping = False
        self.y_vel = 0

    def update(self):
        self.rect.clamp_ip(self.screen_rect)
        self.jump_update()

    def render(self, screen):
        screen.blit(self.image, self.rect)

    def move(self, x, y):
        self.rect.x += x * self.speed
        self.rect.y += y * self.speed

    def jump_update(self):
        if self.jumping:
            self.y_vel += self.grav
            self.rect.y += self.y_vel
            if self.is_touching_ground():
                self.jumping = False

    def is_touching_ground(self):
        return self.rect.y >= self.screen_rect.height - self.height - 50

    def jump(self):
        if not self.jumping:
            self.y_vel = -12
            self.jumping = True


class Control:
    def __init__(self):
        self.screensize = (1000,500)
        self.screen = pg.display.set_mode(self.screensize, pg.DOUBLEBUF)
        self.screen_rect = self.screen.get_rect()
        try:
            self.bg = pg.image.load("res\\bg.png")
            self.wb11 = pg.image.load("res\BlueWombat\BlueStay.png")
            self.wb1 = pg.image.load("res\BlueWombat\BlueWalk.gif").convert_alpha()
            self.wb2 = pg.image.load("res\GreenWombat\GreenStay.png")
            self.wb21 = pg.image.load("res\GreenWombat\GreenWalk.gif")
        except:
            self.bg = pg.image.load("res/bg.png")
            self.wb1 = pg.image.load("res/BlueWombat/BlueStay.png")
            self.wb11 = pg.image.load("res/BlueWombat/BlueWalk.gif")
            self.wb2 = pg.image.load("res/GreenWombat/GreenStay.png")
            self.wb21 = pg.image.load("res/GreenWombat/GreenWalk.gif")
        self.wb2 = pg.transform.flip(self.wb2, True, False)
        self.clock = pg.time.Clock()
        self.fps = 60
        self.quit = False
        self.keys = pg.key.get_pressed()

        self.wombat_one = Wombat(self.screen_rect, self.wb1, (0,450))
        self.wombat_two = Wombat(self.screen_rect, self.wb2, (1000-192,450))

    def run(self):
        while not self.quit:
            now = pg.time.get_ticks()
            self.held_keys(self.keys)
            self.event_loop()
            self.update()
            self.render()
            pg.display.update()

            self.clock.tick(self.fps)

    def event_loop(self):
        for event in pg.event.get():
            if event.type == pg.QUIT:
                self.quit = True
            elif event.type in (pg.KEYDOWN, pg.KEYUP):
                self.keys = pg.key.get_pressed()
                if event.type == pg.KEYDOWN:
                    if event.key == pg.K_w:
                        self.wombat_one.jump()
                    if event.key == pg.K_UP:
                        self.wombat_two.jump()

    def held_keys(self, keys):
        if keys[pg.K_a]:
            self.wombat_one.move(-1, 0)
        if keys[pg.K_d]:
            self.wombat_one.move(1, 0)
        if keys[pg.K_LEFT]:
            self.wombat_two.move(-1, 0)
        if keys[pg.K_RIGHT]:
            self.wombat_two.move(1, 0)

    def render(self):
        self.screen.blit(self.bg, (0,0))
        self.wombat_one.render(self.screen)
        self.wombat_two.render(self.screen)

    def update(self):
        self.wombat_one.update()
        self.wombat_two.update()


app = Control()
app.run()

【问题讨论】:

  • PC 和 Mac 之间的硬件是否完全相同?有一百万个因素可能会影响这一点。对于 Stack Overflow,这真的不是一个好问题。
  • 硬件几乎不会对这种微不足道的代码产生影响,是吗?无论如何,即使这样也无济于事,因为 Mac 驱动程序往往比 PC 驱动程序差得多(我在同一台笔记本电脑上的 Windows 下运行的游戏帧速率提高了一倍)。
  • 它似乎在代码中,因为我可以以 60 fps 的速度运行大量合法游戏,例如 League 和 Minecraft,这是一个非常简单的程序
  • @MorganThrapp - 不过你打到了它的头上。涉及的因素太多。
  • 可能是你们每个人在各自的计算机上花费了相同的金额,在这种情况下,PC 可以轻松运行得更快。

标签: python python-2.7 pygame


【解决方案1】:

嘿,嗯,我遇到了同样的问题,但现在我的 pygame 代码以 60 fps 运行,这很好。我正在将 Idle 与 Python 3.6.3 和适当的 pygame 一起使用。这是我修复它的方法:

  1. 运行你的 pygame 程序
  2. 在码头,您会看到一条蛇,嘴里叼着控制器。右键点击他。
  3. 转到选项并单击“在 Finder 中显示”
  4. Finder 将打开,您将看到一个 python 应用程序。(我的是火箭形状,上面有空闲符号。)
  5. 右键单击 python 应用程序,然后单击“获取信息”。
  6. 选中“以低分辨率打开”复选框,它现在应该以 60 fps 左右的速度运行。

【讨论】:

  • 天哪!
  • 你救了我的命兄弟 :)
  • 截至 2019 年仍然有帮助*:D 应该被接受的答案
  • 我在 macOS catalina 上看不到该选项
  • 你的救命稻草,这个答案值得更多喜欢
【解决方案2】:

我建议您阅读pygame.time.Clock 的文档,尤其是以下内容:

请注意,此函数使用 SDL_Delay 函数,该函数在每个平台上并不准确,但不会使用太多 cpu。如果您想要一个准确的计时器,请使用 tick_busy_loop,并且不介意咀嚼 CPU。

问题可能是由于在run 函数中调用self.clock.tick(self.fps)SDL_Delay() 出现问题。

【讨论】:

  • 我稍后会研究这个。这似乎正在解决问题所在。使用“tick_busy_loop”会消耗大量 CPU 还是一点点?我们的游戏只是一个小 2D 格斗游戏,所以我不希望它占用大量 CPU
  • 我会说你最好不要亲自使用,而是使用你自己的更严格的控制循环。
  • 我们将如何做到这一点?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
  • 2015-07-08
  • 1970-01-01
相关资源
最近更新 更多