木雪 1230 2023-06-28 11:49 采纳率: 0%
浏览 53

用Pygame写了一个贪吃蛇,运行不起来,怎样修改?

用Pygame写了一个贪吃蛇多人游戏,但是完全跑不起来。
代码如下。
服务端

import asyncio
import socket
import pickle

# 服务器地址和端口
SERVER_ADDRESS = '127.0.0.1'
SERVER_PORT = 2000

# 定义玩家ID计数器
player_id_counter = 1

# 初始化事件循环和服务器数据
loop = asyncio.get_event_loop()
game_state = {'player_snakes': {}}

# 辅助函数:处理客户端消息
def handle_client_message(client_socket, address):
    global player_id_counter

    try:
        while True:
            # 接收客户端消息
            message = client_socket.recv(1024).decode()

            if message == "GET_PLAYER_ID":
                # 分配玩家ID
                player_id = player_id_counter
                player_id_counter += 1

                # 发送玩家ID
                client_socket.sendall(str(player_id).encode())
            else:
                # 更新玩家蛇的位置
                player_snake = game_state['player_snakes'].get(player_id, [])
                player_snake.clear()

                # 解析消息并更新蛇位置
                parts = message.split(",")
                for i in range(0, len(parts) - 1, 2):
                    x = int(parts[i])
                    y = int(parts[i + 1])
                    player_snake.append((x, y))

            # 序列化游戏状态并发送给客户端
            serialized_game_state = pickle.dumps(game_state)
            client_socket.sendall(serialized_game_state)

    except (ConnectionResetError, ConnectionAbortedError):
        # 处理客户端连接断开的情况
        print(f"客户端 {address} 连接已关闭")
        if player_id in game_state['player_snakes']:
            del game_state['player_snakes'][player_id]

# 异步任务:监听客户端连接
async def listen_for_clients():
    # 创建服务器Socket
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server_socket.bind((SERVER_ADDRESS, SERVER_PORT))
    server_socket.listen()

    print("服务器已启动,等待客户端连接...")

    while True:
        # 接受客户端连接
        client_socket, address = await loop.sock_accept(server_socket)
        print(f"客户端 {address} 已连接")

        # 创建任务以处理客户端消息
        asyncio.create_task(handle_client_message(client_socket, address))

# 启动异步任务
loop.run_until_complete(listen_for_clients())

客户端

import asyncio
import socket
import pickle
import pygame

# 服务器地址和端口
SERVER_ADDRESS = '127.0.0.1'
SERVER_PORT = 2000

# 游戏区域大小
GRID_SIZE = 20
GRID_WIDTH = 30
GRID_HEIGHT = 30

# 蛇的移动速度
SNAKE_SPEED = 0.1

# 初始化Pygame
pygame.init()

# 创建游戏区域窗口
window_size = (GRID_WIDTH * GRID_SIZE, GRID_HEIGHT * GRID_SIZE)
window = pygame.display.set_mode(window_size)
pygame.display.set_caption('贪吃蛇')

# 定义颜色
WHITE = (255, 255, 255)
GREEN = (0, 255, 0)

# 辅助函数:绘制游戏区域
def draw_grid():
    for x in range(0, window_size[0], GRID_SIZE):
        pygame.draw.line(window, WHITE, (x, 0), (x, window_size[1]))
    for y in range(0, window_size[1], GRID_SIZE):
        pygame.draw.line(window, WHITE, (0, y), (window_size[0], y))

# 辅助函数:绘制蛇
def draw_snake(snake_positions):
    for snake_part in snake_positions:
        x, y = snake_part
        pygame.draw.rect(window, GREEN, (x * GRID_SIZE, y * GRID_SIZE, GRID_SIZE, GRID_SIZE))

# 创建Socket连接
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 用于异步任务的函数
async def sync_game_state():
    try:
        # 连接到服务器
        client_socket.connect((SERVER_ADDRESS, SERVER_PORT))
        print("已连接到服务器")

        # 发送获取玩家ID的请求
        client_socket.sendall(b"GET_PLAYER_ID")

        # 接收玩家ID
        player_id = int(client_socket.recv(1024))

        while True:
            # 接收更新后的游戏状态
            serialized_game_state = await loop.sock_recv(client_socket, 4096)
            game_state = pickle.loads(serialized_game_state, encoding='latin1')

            # 获取本玩家的蛇位置
            player_snake = game_state['player_snakes'].get(player_id, [])

            # 清空窗口
            window.fill((0, 0, 0))

            # 绘制游戏区域网格
            draw_grid()

            # 绘制蛇
            draw_snake(player_snake)

            # 更新显示
            pygame.display.flip()

            await asyncio.sleep(0.1)

    except ConnectionRefusedError:
        print("连接失败,正在尝试重新连接...")
        # 绘制重新连接提示
        font = pygame.font.Font(None, 36)
        text = font.render("重新连接失败,正在尝试重新连接...", True, WHITE)
        text_rect = text.get_rect(center=(window_size[0] // 2, window_size[1] // 2))
        window.blit(text, text_rect)
        pygame.display.flip()
        await asyncio.sleep(1)
        await sync_game_state()

# 异步任务的主函数
async def main():
    await asyncio.gather(sync_game_state())

# 启动异步任务
pygame.display.set_mode(window_size)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

求解答

  • 写回答

1条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-06-28 14:46
    关注
    • 这个问题的回答你可以参考下: https://ask.csdn.net/questions/7809676
    • 这篇博客你也可以参考下:【Pygame实战】射击游戏推荐:入局即巅峰?精品类休闲射击游戏《无敌狙击手》等你来。
    • 除此之外, 这篇博客: [Pygame]用Pygame做简单有好玩的小游戏系列1:鼠标捉球中的 最终代码 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • import random
      import sys
      
      import pygame
      from pygame.locals import *
      
      pygame.init()
      
      screen = pygame.display.set_mode((1820, 980))
      clock = pygame.time.Clock()
      FPS = 100
      ball_pos = (random.randint(0, 1770), random.randint(0, 930))
      ball_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
      is_down = False
      score = 0
      font = pygame.font.Font("Mojangles.ttf", 48)
      
      
      def core():
          global ball_color, ball_pos, score
          if is_down:
              mouse = pygame.mouse.get_pos()
              if ball_pos[0] + 50 > mouse[0] > ball_pos[0] - 50 and ball_pos[1] + 50 > mouse[1] > ball_pos[1] - 50:
                  score += 1
                  ball_color = (random.randint(0, 255), random.randint(0, 255), random.randint(0, 255))
                  ball_pos = (random.randint(0, 1770), random.randint(0, 930))
      
              else:
                  pygame.draw.circle(screen, (255, 255, 0), mouse, 30)
      
      
      def show_score(score):
          text = font.render("{0}".format(score), True, (0, 0, 0))
          screen.blit(text, (1700, 10))
      
      
      def init(screen):
          screen.fill((255, 255, 255))
          pygame.draw.circle(screen, ball_color, pos, 50)
      
      
      while True:
          for event in pygame.event.get():
              if event.type == QUIT:
                  pygame.quit()
                  sys.exit(0)
              if event.type == MOUSEBUTTONDOWN:
                  is_down = True
              else:
                  is_down = False
          init(screen)
          core()
          show_score(score)
          pygame.display.update()
      
      
    • 您还可以看一下 程序员学院老师的Python专项训练 巩固语法+数据分析+商城开发课程中的 Pygame开发实战之游戏简介与分析小节, 巩固相关知识点
    评论

报告相同问题?

问题事件

  • 创建了问题 6月28日

悬赏问题

  • ¥15 单纯型python实现编译报错
  • ¥15 c++2013读写oracle
  • ¥15 c++ gmssl sm2验签demo
  • ¥15 关于模的完全剩余系(关键词-数学方法)
  • ¥15 有没有人懂这个博图程序怎么写,还要跟SFB连接,真的不会,求帮助
  • ¥15 PVE8.2.7无法成功使用a5000的vGPU,什么原因
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音
  • ¥30 Pytorch深度学习服务器跑不通问题解决?
  • ¥15 部分客户订单定位有误的问题