2016-12-05 18 views
0

私は、パイソンasyncioでベアボーンのスケルトンファイティングゲームを作ろうとしています。Python asyncio:割り込み可能なタスク

class Skeleton(Creature): 
    pass 

class SkeletonAI(): 
    def __init__(self, skeleton,loop = None): 
     self.loop = loop or asyncio.new_event_loop() 
     self.skeleton = skeleton 
     self.action_task = None 


    async def run(self): 
     while True: 
      #print(self.action_task,) 
      if self.skeleton.alive and self.skeleton.target.alive: 
       if self.skeleton.state == 'idle': 
        #ATTACK 
        self.skeleton.begin_attack() 
        self.action_task = self.loop.call_later(3, self.skeleton.action_complete) 

      else: 
       break 


class Player(Creature): 
    def attack_target(self, target): 
     target.take_damage(self.damage) 
     if target.state == 'attacking': 
      target.state = 'idle' 
      #interrupt attack 

class Game(): 

    #Super simple game 

    #The skeleton launches an attack, press anything to interrupt it 
    async def handle_sending(self): 
     loop = asyncio.get_event_loop() 
     executor = concurrent.futures.ThreadPoolExecutor(
      max_workers=1, 
     ) 
     while True: 
      msg = await loop.run_in_executor(executor, input) 
      print('got a message') 
      if self.skeleton_ai.action_task: 
       print('cancelling attack') 
       self.skeleton_ai.action_task.cancel() 
       self.skeleton_ai.skeleton.machine.set_state('idle') 

       print('cancelled attack') 
       self.skeleton_ai.action_task = None 

    async def game_loop(self): 
     player_task = asyncio.ensure_future(self.handle_sending()) 
     skeleton_task = asyncio.ensure_future(self.skeleton_ai.run()) 
    def __init__(self): 
     self.task = None 
     self.loop = asyncio.get_event_loop() 
     self.player = Player(name='ply') 
     self.skeleton_ai = SkeletonAI(skeleton=Skeleton(name='bobby')) 
     self.skeleton_ai.skeleton.target = self.player 
     self.loop.run_until_complete(self.game_loop()) 
     try: 
      self.loop.run_forever() 
     finally: 
      pass 
     loop.close() 

Game() 

ここで私が何をしようとしていますものです:

  1. プレーヤーの入力とゲーム出力が非同期されているので、input()はブロックされません。これは機能します。
  2. スケルトンは攻撃を準備します.3秒以内に中断されなければ、攻撃はプレイヤーにダメージを与えます。
  3. プレーヤーは、任意のテキストを入力して、スケルトン攻撃を中断できます。

どのようにスケルトンの攻撃を行うことができますか?割り込み可能なタスクが必要で、コールバックを後で呼び出すことができます。現在のところ、すべてが止まってしまいます。 call_laterは決して呼び出しません。

+0

これは特にasyncioの良いユースケースではありません。 – Goodies

答えて

0

タイムアウトとコールバック機能を持つ非同期関数のパターンです。手掛かりは、asyncio.TimeoutErrorを捕まえてタイムアウトロジックを行うことです。現在の位置を待ってから取り消された機能は継続しません。

import asyncio 

async def slow_function(seconds): 
    print('starting slow computations') 
    await asyncio.sleep(seconds) 
    print('slow computations done') 

async def timeout_callback(): 
    print('timeout called') 

async def timeout_with_cb(fut, timeout, timeout_fut): 
    try: 
     await asyncio.wait_for(fut, timeout) 
    except asyncio.TimeoutError: 
     await timeout_fut 

loop = asyncio.get_event_loop() 
loop.run_until_complete(asyncio.ensure_future(
         timeout_with_cb(slow_function(2), 1, 
         timeout_callback()))) 

これが印刷されます:

starting slow computations 
timeout called 

私は、これは(提供される例がコンパイルされません)あなたの例を適応させるためにあなたを助けることができますね。

関連する問題