Pygame窗口一段时间不刷新时没有响应

时间:2019-06-25 05:16:11

标签: python pygame reinforcement-learning

我正在尝试通过自己制作的“游戏”进行一些强化学习。

在我的主循环中,当我玩游戏时,如果定期刷新窗口,一切都会正常。

但是,在一集之后,我想训练我的特工,但是如果训练时间太长,则pygame窗口只会显示“控制栏”(带有X的栏用于关闭窗口),并且如果我尝试关闭它,程序只会崩溃。

有没有一种简单的方法可以应对? 其他解决方案告诉我,我应该定期调用一些pygame函数,但是如果我不得不暂停培训以不时进行操作,则代码将变得有些混乱。

2 个答案:

答案 0 :(得分:0)

通常在while / for循环中使用围绕环境和代理的包装程序来定义强化学习训练循环。

一种流行的设计是将游戏包装在OpenAI体育馆中,并使用动作作为输入来调用步骤功能,以在该时间步骤中检索下一个状态,奖励,最终状态和其他统计信息:

示例:

import UserNotifications
import FirebaseMessaging





class AppDelegate: UIResponder, MessagingDelegate, UIApplicationDelegate {

        func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        UNUserNotificationCenter.current().delegate = self
                Messaging.messaging().delegate = self
        }

        func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {

                let dataDict:[String: Bool] = [fcmToken: true]

                NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)

                DataService.run.saveFCMToken(tokenDict: dataDict, fcmtoken: fcmToken) { (success) in

                    if success {
                        print("FCM Token Saved: \(fcmToken)")
                        DEVICEID_FCMTOKEN = fcmToken
                        self.connectToFCM()
                    }//end if

                }//end saveFCMToken

            }//end func

        }

    }

我认为您的环境健身室没有包裹,但是这样做很容易。您也可以创建自定义代码,但是应用程序的一般流程应如示例代码所示。

答案 1 :(得分:0)

是的,您必须定期致电pygame.event.get;否则,事件队列将填满,并且您的窗口将停止响应。

如果您必须在游戏中运行长时间运行的任务,则可以使用以下选项:

你是协程

如果可以将长时间运行的任务分解为更小的,更快速的步骤,则可以使用协程通过yield来使控件返回主循环:

import pygame
import time

def long_running_task():
    i = 0
    while i < 300:
        time.sleep(0.01)
        print(i)
        i += 1
        yield i

def main():
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    clock = pygame.time.Clock()
    rect = pygame.Rect((10, 250, 32, 32))
    direction = 1
    generator = None
    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return
            if e.type == pygame.KEYDOWN:
                if e.key == pygame.K_SPACE:
                    generator = long_running_task()

        screen.fill(pygame.Color('darkgrey'))
        rect.move_ip(5 if direction else -5, 0)
        pygame.draw.rect(screen, pygame.Color('dodgerblue'), rect)
        if not screen.get_rect().contains(rect):
            direction = not direction

        if generator:
            try: next(generator)
            except StopIteration: generator = None

        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    main()

这可能对您不起作用,但是当您有一种算法可以计算结果并且希望在该算法的步骤之间绘制屏幕时,这是一个不错的解决方案。

在另一个线程或进程中运行任务

Python使在另一个进程中运行一个函数变得非常容易。这是一个使用multiprocessing包的简单示例。

import pygame
import time
import multiprocessing

def long_running_task():
    i = 0
    while i < 50:
        time.sleep(0.1)
        print(i)
        i += 1
    return i

def main():
    pygame.init()
    screen = pygame.display.set_mode((640, 480))
    clock = pygame.time.Clock()
    rect = pygame.Rect((10, 250, 32, 32))
    direction = 1
    process = None
    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                if process:
                    process.terminate()
                    process.join()
                return
            if e.type == pygame.KEYDOWN:
                if e.key == pygame.K_SPACE:
                    process = multiprocessing.Process(target=long_running_task) 
                    process.start()

        screen.fill(pygame.Color('darkgrey'))
        rect.move_ip(5 if direction else -5, 0)
        pygame.draw.rect(screen, pygame.Color('dodgerblue'), rect)
        if not screen.get_rect().contains(rect):
            direction = not direction

        pygame.display.flip()
        clock.tick(60)

if __name__ == '__main__':
    main()