4

使用 python 3 制作回合制游戏。我想要 2 个角色(敌人和敌人)攻击,根据随机 + 速度暂停,如果他们还活着,则再次攻击。

我遇到的问题是 time.sleep 冻​​结了两个模块,而不是 1 或其他。有什么建议可以有效地完成这项工作吗?

from multiprocessing import Process
import time
import random

def timing1():  
    speed=60#SPEED IS NORMALLY A KEY FROM LIST, USING 60 FOR EXAMPLE  
    sleeptime=36/((random.randint(1,20)+speed)/5)  
    print (sleeptime)  
    time.sleep(sleeptime)  
    input('HERO ACTION')  

def timing2():  
    speed=45  
    sleeptime=36/((random.randint(1,20)+speed)/5)  
    print (sleeptime)  
    time.sleep(sleeptime)  
    input('FOE ACTION')  

if __name__ == '__main__':  
    p1=Process(target=timing1)  
    p1.start()  
    p2=Process(target=timing2)  
    p2.start()  
    p1.join()  
    p2.join()
4

2 回答 2

0

转一圈后,进程退出您的代码。您的主进程通过调用它们等待两个进程退出,.join()time.sleep()不会冻结其他进程。

while True:在函数顶部添加timing*()以进行多次移动。

您在这里不需要多个进程。您可以使用线程甚至单个线程来实现转弯。

于 2012-11-07T09:32:06.347 回答
0

详细说明 JF

我对线程的一般建议是仅在绝对必要时才引入它。

  • 您实际上是在低级 I/O 上阻塞,除了使用本机线程之外别无选择。
  • 您正在达到计算限制并且需要使用更多内核,在这种情况下,由于它的GIL的 python可能对您不利。

作为替代方案,使用一个库,该库提供一个调度程序,如twistedgevent,它不依赖本机线程来调度事件。

事件

您可以在编写游戏时考虑到线程模型,而不必担心线程之间的资源争用。您必须记住在您的示例中使用各种功能的 gevent 版本,例如sleep

import random
import gevent


def hero():
    speed = 60
    sleeptime = 36 / ((random.randint(1, 20) + speed) / 5)
    print (sleeptime)
    gevent.sleep(sleeptime)
    input('HERO ACTION')


def foe():
    speed = 45
    sleeptime = 36 / ((random.randint(1, 20) + speed) / 5)
    print (sleeptime)
    gevent.sleep(sleeptime)
    input('FOE ACTION')


if __name__ == "__main__":
    heroThread = gevent.Greenlet(hero)
    foeThread = gevent.Greenlet(foe)

    heroThread.start()
    foeThread.start()

    gevent.joinall([heroThread, foeThread])

扭曲的

提供一个事件反应器,它是用纯 python 编写的,并且不假装比单线程事件反应器(又名事件循环)更多或更少。这将需要对您的示例进行更大的重写。

import random
from twisted.internet import reactor


def heroAction():
    input('HERO ACTION')


def heroStart():
    speed = 60
    sleeptime = 36 / ((random.randint(1, 20) + speed) / 5)
    print (sleeptime)
    reactor.callLater(sleeptime, heroAction)


def foeAction():
    input('FOE ACTION')


def foeStart():
    speed = 45
    sleeptime = 36 / ((random.randint(1, 20) + speed) / 5)
    print (sleeptime)
    reactor.callLater(sleeptime, foeAction)


if __name__ == "__main__":
    # Call when the reactor has started.
    reactor.callWhenRunning(heroStart)
    reactor.callWhenRunning(foeStart)
    reactor.run()

请注意,扭曲反应堆在无事可做时不会关闭,这是明确留给程序员的。

滚动你自己的

出于学习目的编写自己的调度程序可能会很有趣,或者您可能在游戏中有要求,例如需要它的公平性。一个很好的起点是从另一个简约的调度程序中寻找灵感。

于 2012-11-17T14:25:01.163 回答