总体思路
我成功地配置了一个树莓派作为接入点,这样我就可以通过WIFI与我的移动的手机或笔记本电脑连接。现在,我想在连接到屏幕的raspberry pi上运行PyGame,并通过连接到raspberry pi的移动的手机或笔记本电脑控制游戏中的对象。
在下文中,我首先提供简单的工作示例,然后展示哪些不起作用。
测试WebSocket Server成功
为了向客户端提供一些内容,我在raspberry pi上安装了一个nginx服务器。当我用raspberry pi的IP地址(192.168.4.1)打开浏览器时,会出现索引页面。
然后,为了测试WebSocket服务器,我编写了一个基于websockets package的简单python脚本:
import websockets
import asyncio
# handler processes the message and sends "Success" back to the client
async def handler(websocket, path):
async for message in websocket:
await processMsg(message)
await websocket.send("Success")
async def processMsg(message):
print(f"[Received]: {message}")
async def main():
async with websockets.serve(handler, "192.168.4.1", 6677):
await asyncio.Future() # run forever
if __name__ == "__main__":
asyncio.run(main())
我通过设置一个HTML页面来测试服务器,该页面通过JavaScript文件连接到WebSocket服务器,并实现了一个按钮来向服务器发送字符串:
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket Test</title>
<script type="text/javascript" src="static/client.js"></script>
</head>
<body>
<div>
<h2>WebSocket Test</h2>
<input type="button" name="send" value="Send Hello!" onClick="sendHello()">
</div>
</body>
</html>
client.js文件:
let socket = new WebSocket("ws://192.168.4.1:6677/");
socket.onopen = function(e) {
console.log("[open] Connection established");
console.log("[send] Sending to server");
socket.send("Web connection established")
};
socket.onmessage = function(event) {
console.log(`[message] Data received from server: ${event.data}`);
};
socket.onclose = function(event) {
if (event.wasClean) {
console.log(`[close] Connection closed cleanly, code=${event.code} reason=${event.reason}`);
} else {
console.log('[close] Connection died!')
}
};
socket.onerror = function(error) {
console.log(`[error] ${error.message}`);
};
function sendHello() {
console.log("[send] Sending to server");
socket.send("Hello!");
};
通过这些简单的示例文件,我可以成功地在服务器和客户端之间建立持久连接并交换数据。
PyGame添加WebSocket Server失败
为了用PyGame测试WebSocket服务器,我设置了一个简单的游戏,只显示一个蓝色的圆圈:
# import and init pygame library
import pygame
pygame.init()
# screen dimensions
HEIGHT = 320
WIDTH = 480
# set up the drawing window
screen = pygame.display.set_mode([WIDTH,HEIGHT])
# run until the user asks to quit
running = True
while running:
# did the user close the window
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
# fill the background with white
screen.fill((255,255,255))
# draw a solid blue circle in the center
pygame.draw.circle(screen, (0,0,255), (int(WIDTH/2),int(HEIGHT/2)), 30)
# flip the display
pygame.display.flip()
pygame.quit()
游戏正在正常运行,在白色背景上显示一个蓝色圆圈。
问题是,当我想将WebSocket服务器添加到游戏中时,其中一个正在阻止另一部分的执行,即,我只能在没有活动服务器的情况下运行游戏,或者我可以运行WebSocket服务器,但游戏不显示。例如,将WebSocket服务器放在游戏循环前面,如下所示
# WS server
async def echo(websocket, path):
async for message in websocket:
msg = message
print(f"[Received] {message}")
await websocket.send(msg)
async def server():
async with websockets.serve(echo, "192.168.4.1", 6677):
await asyncio.Future()
asyncio.ensure_future(server())
或者包括服务器内部的游戏循环:
async def server():
async with websockets.serve(echo, "192.168.4.1", 6677):
#await asyncio.Future()
# set up the drawing window
screen = pygame.display.set_mode([WIDTH,HEIGHT])
# run until the user asks to quit
running = True
while running:
#pygame code goes here
通过广泛的Google搜索,我发现PyGame和Penccio包(websockets基于Penccio)不能简单地一起工作,因为我必须以某种方式手动处理Penccio循环和游戏循环。
我希望有人能帮助我解决这个问题...
1条答案
按热度按时间zc0qhyus1#
感谢我的一位同事,我想出了让Pygame运行的解决方案,包括一个Websockets服务器和响应移动的客户端上的按钮。重要的一点是在不同的线程中运行Websockets服务器并正确处理事件。
下面是server.py的代码。我改变了IP地址到本地主机(127.0.0.1),以测试我的笔记本电脑上的代码.
这里重要的部分是触发Pygame事件的方法
pygame.fastevent.post
。然后,在game.py中,服务器在不同的线程中启动:
当你想退出Pygame时,请注意正确关闭运行Websockets服务器的线程!
现在,当你使用包含我在问题中发布的client.js脚本的HTML文件时,蓝色的圆圈应该在你每次按下“Send hello”按钮时变成红色并向右移动。
我希望这能帮助每个试图使用Pygame设置在线多人游戏的人。