Python写王者荣耀小游戏

本文介绍了如何使用Python和socket创建一个简单的王者荣耀小游戏。通过TCP服务实现网络通信,涵盖用户匹配、英雄选择和战斗等环节。文章详细讲解了从socket创建到多进程、面向对象编程的实现过程,并提供了代码示例。

Python写王者荣耀小游戏


王者荣耀已经成为广大年轻群体的喜好,接下来我们用python来写一个简单的王者荣耀小游戏。

说明:

该小游戏,使用tcp服务进行网路通信,包含简单的用户匹配、英雄对抗和战绩显示等功能。该程序比较小,如果某些代码可以优化的,也可以在评论打出来。

一、socket创建

工欲善其事,必先利其器。我们要使得整个项目完成,就必须将基地打好,先来回顾一下socket创建TCP的流程:

  1. 创建套接字
  2. 绑定端口
  3. 如果是服务器则主动该被动和等待客户端连接
  4. 进行收发数据
  5. 关闭套接字

那么,我们先来完成王者小游戏服务器的搭建:

# Server.py
# -*- coding: utf-8 -*-
# @Auther:Summer
import socket


def main():
    # 创建套接字
    WangZhe_Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置当服务器先close 即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定相关端口
    WangZhe_Server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 绑定端口
    WangZhe_Server.bind(("", 8888))

    # 该主动为被动
    WangZhe_Server.listen(128)

    # 等待客户端连接accept
    while True:
        recv_data = client_socket.recv(1024)  # 接收24个字节
        if recv_data:
            print("接收的数据为:", recv_data.decode("gbk"))
            client_socket.send("Thank You!".encode("gbk"))
        else:
            break
    client_socket.close()
    WangZhe_Server.close()


if __name__ == '__main__':
    main()

测试可以下载一个TCP测试工具,用来查看Server是否可靠。

在这里插入图片描述

在这里插入图片描述

同样的,你也可以自己写一个客户端来验证:

# Client.py
# -*- coding: utf-8 -*-
# @Auther:Summer
import socket


def main():
    # 1.创建套接字
    WangZhe_Client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 2.绑定服务器
    WangZhe_Client.connect(("127.0.0.1", 8888))

    # 3.发送数据
    while True:
        send_data = input("请输入要发送的数据:")
        if send_data:
            WangZhe_Client.send(send_data.encode("gbk"))
            print(WangZhe_Client.recv(1024).decode('gbk'))  # 打印返回的信息,这个必须写,不然会在server中出现报错信息
        else:
            break
    # 4.关闭套接字
    WangZhe_Client.close()


if __name__ == '__main__':
    main()

当TCP的最基础完成之后,我们就需要将该代码进行升级一下。我们的代码如果按照现在这样,每次就只能给一个客户端服务,只有当一个客户端断开之后,才能进行第二个,因此,我们想要为多个客户端服务,那就必须使用多进程。

二、实现多进程

多进程使用multiprocessing库,在target放入对应的函数名称,tags放入想要的client即可。对于进程间的通信使用的是自己的队列,后面再进行赘述,这里就先展示最简单的一个多进程版本:

# -*- coding: utf-8 -*-
# @Auther:Summer
import socket
import multiprocessing


# 收发信息
def recv(client_socket):
    while True:
        recv_data = client_socket.recv(1024)  # 接收24个字节
        if recv_data:
            print("接收的数据为:", recv_data.decode("gbk"))
            client_socket.send("Thank You!".encode("gbk"))
        else:
            break
    client_socket.close()


def main():
    # 创建套接字
    WangZhe_Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 设置当服务器先close 即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定相关端口
    WangZhe_Server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    # 绑定端口
    WangZhe_Server.bind(("", 8888))

    # 该主动为被动
    WangZhe_Server.listen(128)

    try:
        # 等待客户端连接accept
        while True:
            # 接受相应
            wz_client, clint_addr = WangZhe_Server.accept()
            # 注册多进程,
            p = multiprocessing.Process(target=recv, args=(wz_client,))
            p.start()
            wz_client.close()
    except:
        # 关闭套接字
        WangZhe_Server.close()


if __name__ == '__main__':
    main()

以上就是最基础的一个socket的版本,为了适应后期的代码版本,我们把这个变成面向对象版本。

三、面向对象版本

面向对象还比较简单,首先是init的时候先设置最基础的socket配置,然后设置一个函数用来进行数据的收发:

# Server.py
# -*- coding: utf-8 -*-
# @Auther:Summer
import socket
import multiprocessing


class WangZheServer:
    def __init__(self):
        # 创建套接字
        self.WangZhe_Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        # 设置当服务器先close 即服务器端4次挥手之后资源能够立即释放,这样就保证了,下次运行程序时 可以立即绑定相关端口
        self.WangZhe_Server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

        # 绑定端口
        self.WangZhe_Server.bind(("", 8888))

        # 该主动为被动
        self.WangZhe_Server.listen(128)

    def runferver(self):
        try:
            # 等待客户端连接accept
            while True:
                # 接受相应
                wz_client, clint_addr = self.WangZhe_Server.accept()
                # 注册多进程,
                p = multiprocessing.Process(target=self.recv, args=(wz_client,))
                p.start()
                wz_client.close()
        except:
            # 关闭套接字
            self.WangZhe_Server.close()

    # 收发信息
    def recv(self, client_socket):
        while True:
            recv_data = client_socket.recv(1024)  # 接收24个字节
            if recv_data:
                print("接收的数据为:", recv_data.decode("gbk"))
                client_socket.send("Thank You!".encode("gbk"))
            else:
                break
        client_socket.close()


def main():
    wangzhe = WangZheServer()
    wangzhe.runferver()


if __name__ == '__main__':
    main()
# Client.py
# -*- coding: utf-8 -*-
# @Auther:Summer
import socket


class WangZheClient:
    def __init__(self):
        # 1.创建套接字
        self.WangZhe_Client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        # 2.绑定服务器
        self.WangZhe_Client.connect(("127.0.0.1", 8888))

    def runforver(self):
        # 3.发送数据
        while True:
            send_data = input("请输入要发送的数据:")
            if send_data:
                self.WangZhe_Client.send(send_data.encode("gbk"))
                print(self.WangZhe_Client.recv(1024).decode('gbk'))  # 打印返回的信息,这个必须写,不然会在server中出现报错信息
            else:
                break
        # 4.关闭套接字
        self.WangZhe_Client.close()


def main():
    wangzheClient = WangZheClient()
    wangzheClient.runforver()


if __name__ == '__main__':
    main()

四、主体部分搭建

1. 服务器主要步骤的实现

我们的主体部分就是要实现登录、选择模式、人员匹配、对战模式和最后的对战信息展示

由于socket无法传送字典和元组,因此我们就需要规定一下信息的传输格式:收发数据模式step:data

  • step表示现在是第几步
  • data表示传送的信息

然后来规定一下每一步都需要进行什么操作:

1. 登录 step == 0
2. 模式选择 step == 1
3. 人员匹配(管道) step == 2
4. 英雄选择 step == 3
5. 开始对战 step == 4
6. 展示结果 step == 5 -> step == 0
7. 服务器内部错误 step == 500
8. 客户端主动退出 step == 1000
#  Server.py
# -*- coding: utf-8 -*-
# @Auther:Summer
import socket
import multiprocessing


class WangZheServer:
    step = 0
    data = ""

    def __init__(self):
        # 创建套接字
        self.WangZhe_Server = socket.socket(socket.AF_INET
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值