在所有事情之前,我要说我不是在python编程中,因为我在其他语言中。我对寻找其他解决方案感到非常恼火,所以请事先感谢你的帮助。
我喜欢在空闲时间制作Roguelike游戏,所以我尝试了很多方法来使用C ++,C,C#,HTML5等自己的“引擎”实现和我自己的游戏引擎。我从来没有以前在LibTCOD工作过,因为我从来没有能够在C ++中使用它是我最喜欢的编程语言,这是一个我现在不会在C ++线程中讨论的问题。
非常好,LibTCOD看起来很棒,但提及和文档准确性太少,所以我几乎一个人工作。最后几天我做了一个小python包来轻松管理python和windows的LibTCOD功能,并使主游戏代码尽可能小。
我尝试添加的最终实现是将主游戏循环传递给线程,处理每个基本游戏功能(如键盘/鼠标更改和屏幕更新),并通过函数调用运行它。
一切正常......但不是在第一个循环步骤之后,因为它冻结一切并停止工作。
基本上这是有问题的代码:
def ioHandler(l):
lastx = 0
lasty = 0
lastk = None
c = 0
noEvent = 0
casted = False
while not tcod.console_is_window_closed():
l.acquire()
try:
tcod.sys_check_for_event(tcod.EVENT_KEY_PRESS|tcod.EVENT_MOUSE,key,mouse)
finally:
l.release()
if mouse.lbutton_pressed:
casted = True
l.acquire()
try:
onClick(mouse, 'left')
finally:
l.release()
if mouse.rbutton_pressed:
casted = True
l.acquire()
try:
onClick(mouse, 'right')
finally:
l.release()
if mouse.cx != lastx or mouse.cy != lasty:
casted = True
l.acquire()
try:
lastx = mouse.cx
lasty = mouse.cy
onMouseMove(mouse)
finally:
l.release()
if key != lastk:
casted = True
l.acquire()
try:
lastk = key
onKeyPress(key)
finally:
l.release()
if not casted: noEvent += 1
l.acquire()
try:
onTickFrame(c+1)
finally:
l.release()
这里使用的大多数变量都是为了更清晰的调试理解目的,(即使它的“干净”功能也冻结了)所以我要将它们放在那里。
从这里调用上面的'def':
def main_loop():
l = threading.Lock()
tr = threading.Thread(target=ioHandler, args=(l,))
#tr.daemon=True
tr.start()
对于'赛事'系统,我在互联网上找到了这个:
class Event:
handlers = set()
def __init__(self):
self.handlers = set()
def handle(self, handler):
self.handlers.add(handler)
return self
def unhandle(self, handler):
try:
self.handlers.remove(handler)
except:
raise ValueError("Handler is not handling this event, so cannot unhandle it.")
return self
def fire(self, *args, **kargs):
for handler in self.handlers:
handler(*args, **kargs)
def getHandlerCount(self):
return len(self.handlers)
__iadd__ = handle
__isub__ = unhandle
__call__ = fire
__len__ = getHandlerCount
作为一个注释:我正在使用Python 2.7,这是唯一适用于库的版本,真可惜。
我认为事件系统可能是主要问题。再次读取代码,我想我也应该对while条件应用一个锁,因此对整个循环,或者这是不是必要的?锁是否以适当的方式应用?或者我应该使用其他方法使线程有效吗?
提一下,如果主游戏循环在没有线程的主脚本上进行,一切正常,但是当作为线程调用时一切都失败,或者即使它不是一个线程本身,但它从其他任何其他地方被调用包中的函数,所以它不能成为库问题(我认为)。
我不得不说,我只使用Python中的LibTCOD,因为我无法在它上面工作(至少在Windows上)。如果它有帮助,我已经看到python库的代码只是原始C库的'bind',所以理解python代码并不是什么大问题。对于最后一个声明,我认为这也是python线程的问题,或者我错了?如果我能做些什么来修复线程工具,请帮助我!
谢谢大家!我希望我的谈话不会让你感到无聊。
答案 0 :(得分:0)
你的例子中有足够的遗漏,我无法及时运行,所以我没有一个已知的解决方案,但我确实有一些建议:
l = threading.RLock()
而不是:
l.acquire():
try:
tcod.sys_check_for_event(
tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, key, mouse)
finally:
l.release()
尝试:
with l:
tcod.sys_check_for_event(
tcod.EVENT_KEY_PRESS | tcod.EVENT_MOUSE, key, mouse)