はじめに
つい最近、ハッカソンに参加した際、初めてオンライン対戦ゲームに挑戦したのでその時の記録を残します。Waffleのゲーム開発部は部員を常時募集しております~🤝
使用技術
- pygame:pythonのゲーム開発特化のライブラリ
- Tornado:WebSocket通信をサポートしているPythonのウェブフレームワーク
- websockets:ウェブブラウザとウェブサーバー間で双方向にリアルタイムの通信をするためのプロトコル
- nginx:高性能なHTTPサーバーおよびリバースプロキシサーバー
#使用したバージョン pip installしてください
pygame==2.6.1
tornado==6.4.1
websockets==13.1
実装
私自身の環境はWSLです。
1. Tornadoサーバーの設定
server.pyなどファイルを作成して以下を記入します。
import tornado.ioloop
import tornado.web
import tornado.websocket
class WebSocketHandler(tornado.websocket.WebSocketHandler):
def open(self):
#接続が開始された後の処理を書く
#プレイヤーの初期状態、ルーム分けetc
def on_message(self, message):
#プレイヤーからメッセージを受信したときの処理
#JSONなどを使ってクライアントからデータを受け取ったり、
#プレイヤーの状態を更新したり、
#更新された状態を他のプレイヤーに送信したり
def on_close(self):
#接続が終了された後の処理
def make_App():
return tornado.web.Application([
#/websocketにアクセスしたときにWebSocketHandlerを使用
(r"/websocket", WebSocketHandler)
])
#サーバーの起動
if __name__ == "__main__":
app = make_app()
app.listen(8080)
print("Server started on http://localhost:8888")
tornado.ioloop.IOLoop.instance().start()#イベントループを開始
2. nginxの設定
1.nginxをインストール
sudo apt update
sudo apt install nginx
2.設定ファイルの作成
/etc/nginx/sites-available/の下にdefault(違う名前でもいい)ファイルを作り、
sudo nano /etc/nginx/sites-available/default
そのまま以下のコードを記入します。
server {
#サーバーがポート80でリッスンすることを指定
listen 80;
#localhostまたは、サーバーのパブリックIPやドメイン名
server_name localhost;
#ルートURL(/)に対するリクエストを処理するための設定を定義
location / {
proxy_pass http://127.0.0.1:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
}
}
リバースプロキシとして機能します。今回は、クライアントからのリクエストをローカルホストのポート3001でリッスンしているサーバーに転送してます。
そして、設定を保存出来たら再起動します。
sudo nginx -t #sucsessなど出てきたらok
sudo systemctl restart nginx
今回はpygameを利用して、ローカルのexeファイルなどから実行することを想定しているので、EC2など実際のオンラインサーバーで動かすにはEC2上にserver.pyとnginxの設定を置きます。
3. pygameでゲームを作る
game.pyなどファイルを作ってゲームを作っていきます。
import pygame
from pygame.locals import *
import websockets
class Main:
async def main(self):
# ゲームの初期化
pygame.init()
# ゲーム画面の設定
screen = pygame.display.set_mode((800, 600))
pygame.display.set_caption("ゲームタイトル")
#オンラインの時は"localhost:8080"をパブリックIPにする
uri = "ws://localhost:8080/websocket"
async with websockets.connect(uri) as websocket:
# ゲームループ
while True:
#ゲーム内処理を記述
# 画面を更新
pygame.display.flip()
# ゲームの終了
pygame.quit()
# asyncio.run()を使用して非同期関数を実行
if __name__ == "__main__":
main_instance = Main()
asyncio.run(main_instance.main())
ここまで出来たら、
まずサーバーを起動して
python server.py
そのまま別のターミナルを開いてゲームを起動します。
2人以上でプレイするとき、ターミナルを2つ以上新しく開いて起動します
python game.py
記事ではゲーム周りは詳しく書いていないのですが、pygameはたくさん資料があるので誰でもゲームを作りやすいと思います!
さいごに
EC2を使うことが初めてだったので、私はハッカソン中そこに苦戦してました。nginxの辺りなどもっと理解するために、またゲーム開発できたらなって思っています。
Waffleアドベントカレンダー実現していただけて嬉しいです。ありがとうございます!