python 3でゼロから脳を焼く射撃ゲーム5を開発

3255 ワード

前回はゲームに弾丸が加わったと言いましたが、ゲームには一人しかいません.どうやって他のプレイヤーに打つことができますか?だから今日私たちがしなければならないのは、他のプレイヤーが私と一緒にこのゲームをすることができるようにすることです.しかし、人は他の人のパソコンで游んでいます.彼はどうして私が小さなブロックをコントロールしていることを知っていますか.また弾丸が発射されたのか、誰かが弾丸に撃たれたのか.彼が知らなければ、私は彼に教えてもいいですか.「彼に教えて」という通俗的な表現は、コンピュータ分野では通信と呼ばれ、コンピュータネットワークを媒介とする通信はネットワーク通信と呼ばれています.また、プレイヤーのこれまでの相互不信を避けるために、私たちはこのようなモードを採用しています:各プレイヤーは自分のすべての操作を1つのセンターサーバーに通知して各プレイヤーの操作に対して合法性の判断を行って、もし合法ならばこれらの操作の発生の過程を実現してシミュレーションすることを担当して、結果サーバーは絶えず自分の内部で発生したこれらの過程と結果をすべてのプレイヤーに通知しますこれがC/Sモード(クライアントclient/サーバーserver)です
次に、pythonコードでこのような通信を実現する方法を見てみましょう.正直に言うと、ネットワークプログラミングの原理は複雑ですが、pythonパッケージは完備しているので、以下の概念を理解して基礎的な開発を行うことができます.コンピュータネットワークでメッセージを送受信する過程を現実世界の送受信メッセージと見なすことができます.Aは自分の郵便番号と宛先Bに送る人(A)の郵便番号と住所を明記することを他の人に伝えます.それから郵便局の郵便配達人に渡して郵便番号と住所によって手紙をAの手に送ります
簡単ですね.コンピュータネットワークでは、コンピュータの世界の「受信アドレス」をsocketというもので記述し、「メッセージ」はバイナリデータです.
対応するコード実装import socket# socket を見てみましょう
クライアントについて(ある意味では「送信者」と理解できる)
ADDR = ("127.0.0.1", 11000)#         (ip   )
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)#    socket
clientsocket.connect(ADDR)#   socket    ,                   

#      
data = input(">>>")#           
clientsocket.send(bytes(data,'utf-8'))# utf-8      

サーバの場合(ある意味「受信者」と理解できる)
ADDR = ("127.0.0.1", 11000)#         (ip   )
serversocket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#    socket
serversocket.bind(ADDR)#socket      

バインドが完了すると、リモートのクライアント接続を待機します.
clientsocket,addr = serversocket.accept()
#     
data = clientsocket.recv(BUFSIZE)#            socket    

完全なコードここからサーバクライアントを取得
しかし、このモデルには2つの欠陥がある.サーバが起動すると、クライアントの接続をずっと待つ必要があります.また、クライアントがデータを送信するのを待つaccept()recv()という2つの関数は、クライアントの接続が成功したり、データが送信されたりするまで、プログラムの実行を停止させます.サービスには他にも重要なことがたくさんあるので、サーバの作業をクライアントを待つことにすべて遅れさせたくありません.サーバは1つのクライアントの接続しか受け入れられず、複数のクライアントの同時接続を処理できません.
この2つの問題を解決するには、非同期のライブラリ(asyncio)を使用するか、selectorライブラリでポーリングするなど、多くの方法がありますが、私はマルチスレッドの方法でこの問題を解決するつもりです.1.メインスレッド処理ゲームの表現2.いくつかのサブスレッドはネットワークの接続とクライアントのデータを処理し、サブスレッドはネットワークイベントを待つときに、メインスレッドのゲームロジックに影響を与えません.上記のパターンをよく理解していないと、コストはあなたが一人(メインスレッド)で働いていることを想像することができますが、多くのお客様が連絡しなければなりません.お客様のフィードバックを待たなければ、他の仕事を続けることができません.それからあなたは本当に待ちくたびれて、多くの手伝い(サブスレッド)を雇って、手伝いに取引先と連絡させて、それから彼らは得た結果をあなたにフィードバックして、このようにあなたは自分のことに専念することができます.アシスタントがあなたにフィードバックしたときに少し時間を割いてドッキングするだけです.
次に、コードの実装を見てみましょう.まず、待機メッセージの受信を処理する関数を定義します.
def deal_msg(client):
    while True:
        data = client.recv(1024)
        data = data.decode('utf-8')
        print(data)

クライアント待ちの接続を処理し、受信メッセージに接続する関数を定義します.
def acc_clt():
    while True:
        clt, addr = g_socket_server.accept()#        
        print("one client connect!")
        g_conn_pool.append(clt)#             
        thread = Thread(target=deal_msg,args=(clt,))#        ,                 
        thread.setDaemon(True)
        thread.start()#      

接続待ち関数を定義したら、スレッドを作成して専用にすることができます.
thread = Thread(target=acc_clt)#       
thread.setDaemon(True)
thread.start()

完全なコードここからサーバクライアントを取得
この文章の内容が少し多いため、どのようにこのネットの模型をゲームに応用して次の篇の中で述べます