《Python多人游戏项目实战》第三节 在窗口上显示玩家ID以及对话内容

这篇具有很好参考价值的文章主要介绍了《Python多人游戏项目实战》第三节 在窗口上显示玩家ID以及对话内容。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

3.1 显示不同的人物图片

3.2 显示玩家ID

3.3 显示玩家对话内容

3.4 完整代码下载地址


本节只是在上一节内容的基础上加一些小功能:显示不同的人物图片、在人物头顶上显示玩家ID以及人物头顶上显示一个聊天对话框。大家可以把这一节内容当做一个过渡,用来巩固下多人游戏程序中pickle的用法。程序完成后的运行结果如下:

《Python多人游戏项目实战》第三节 在窗口上显示玩家ID以及对话内容

本项目结构显示如下:

├── SimHei.ttf        # 字体文件
├── client.py         # 客户端代码
├── pics              # 图片文件夹
│   ├── 1.png
│   ├── 2.png
│   ├── 3.png
│   ├── 4.png
│   ├── 5.png
│   └── 6.png
├── player.py         # 包含Player类
└── server.py         # 服务端代码

在client.py中我们一共导入了以下模块或库:

import sys
import pygame
import pickle
import socket
from player import Player
from random import randint

在player.py中我们一共导入了以下模块或库:

import pygame
import random

在server.py中我们一共导入了以下模块或库:

import socket
import pickle
from player import Player
from threading import Thread

3.1 显示不同的人物图片

pics文件夹下有6个人物方位图,玩家打开游戏窗口时,程序都会从这6个方位图中随机选择一张进行显示。因为是随机的,所以其他玩家的人物图片可能跟当前玩家的一样,也可能不一样。

首先修改Player类:

# player.py
class Player:
    def __init__(self, p_id, x, y,  pic_num, frame_width, frame_height):
        self.id = p_id
        self.dis = 3
        self.x = x
        self.y = y

        self.pic_num = pic_num      # 1
        self.frame_width = frame_width
        self.frame_height = frame_height
        self.frame_num = 0
        self.frame_rect = (self.frame_num * self.frame_width, 0 * self.frame_height,
                           self.frame_width, self.frame_height)

        self.current_dir = "下"
        self.last_dir = self.current_dir
    
    ...

代码解释如下:

1. 在初始化函数中加一个pic_num变量用来保存玩家显示的人物图片编号,这样就能从服务端传送过来的数据中知道某个玩家用的什么人物图了。

接着修改GameWindow类:

# client.py
class GameWindow:
    def __init__(self):
        ...

        self.pic_dict = {                                   # 1
            1: pygame.image.load("./pics/1.png"),
            2: pygame.image.load("./pics/2.png"),
            3: pygame.image.load("./pics/3.png"),
            4: pygame.image.load("./pics/4.png"),
            5: pygame.image.load("./pics/5.png"),
            6: pygame.image.load("./pics/6.png")
        }
        frame_width = self.pic_dict[1].get_width() // 4     # 2
        frame_height = self.pic_dict[1].get_height() // 4

        self.player = Player(p_id=None,
                             x=randint(0, self.width-frame_width),
                             y=randint(0, self.height-frame_height),
                             pic_num=randint(1, 6),         # 3
                             frame_width=frame_width,
                             frame_height=frame_height)

        ...

    ...

    def update_window(self):
        self.window.fill((255, 255, 255))

        self.player.move()
        self.player.draw(self.window, self.pic_dict[self.player.pic_num])   # 4

        other_players_data = pickle.loads(self.send_player_data())
        self.update_other_players_data(other_players_data)

        pygame.display.update()

    def update_other_players_data(self, data):
        for player in data.values():
            player.draw(self.window, self.pic_dict[player.pic_num])         # 5

    ...

代码解释如下:

1. 创建一个pic_dict字典变量,用来保存各个人物方位图对象,字典的键就是图片编号。

2. 因为所有人物方位图的大小都是一样的,所以这里就直接通过第一张方位图获取帧的宽高值。

3. 随机获取1-6之间的整数,这样就可以随机选择一张人物方位图了。

4. & 5. 根据pic_num值从pic_dict字典中选择对应的人物方位图,然后绘制到窗口上。

运行结果如下:

《Python多人游戏项目实战》第三节 在窗口上显示玩家ID以及对话内容

3.2 显示玩家ID

很多游戏会把玩家的id或名称显示在人物图片上方,并跟随人物移动,如下图所示。

《Python多人游戏项目实战》第三节 在窗口上显示玩家ID以及对话内容

这点其实很好实现,因为我们已经将玩家id值保存在Player对象的id属性中,所以只需要将这个id值绘制到窗口上就可以了。

将Player类的draw()函数修改如下:

# player.py
def draw(self, win, pic):
    win.blit(pic, (self.x, self.y), self.frame_rect)

    font = pygame.font.SysFont("Arial", 10)          # 1
    id_text = font.render(self.id, True, (150, 150, 150))
    win.blit(id_text, (self.x + round(self.frame_width/2) - round(id_text.get_width()/2), self.y - id_text.get_height()))

代码解释如下:

1. 设置文字字体并将文本绘制到人物图片的正上方。

运行结果如下:

《Python多人游戏项目实战》第三节 在窗口上显示玩家ID以及对话内容

3.3 显示玩家对话内容

如果要聊天的话,玩家就会在文本输入框中输入消息,然后按下回车键发送,其他玩家随后也会收到该玩家发送的消息。Pygame没有提供一个文本输入框控件,如果要自己实现的话会增加很多跟本教程主题无关的代码。所以为了保持代码简洁,笔者就预先设置好一些聊天内容,然后随机发送一条。

修改Player类:

# player.py
class Player:
    def __init__(self, p_id, x, y,  pic_num, frame_width, frame_height):
        ...

        self.message = ""           # 1

    ...

    def speak(self):                # 2
        messages_list = ["你好", "最近咋样", "我在打怪呢", "你说的有道理", "你哪里人", "不玩了,去吃饭了", "待会再玩", "今天很开心"]
        self.message = random.choice(messages_list)

代码解释如下: 

1. message变量用来存储玩家要发送消息。

2. speak()函数会随机生成一条聊天消息,并保存在message变量中。

修改GameWindow类:

# client.py
class GameWindow:
    def __init__(self):
        ...

        self.all_players_messages = []      # 1
        self.max_messages_shown = 6         # 2

        self.port = 5000
        self.host = "127.0.0.1"
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        self.connect()

    ...

    def send_player_data(self):
        data = {
            "id": self.player.id,
            "player": self.player
        }
        self.sock.send(pickle.dumps(data))
        self.player.message = ""            # 3
        return self.sock.recv(2048)

    def update_window(self):
        self.window.fill((255, 255, 255))

        self.player.move()
        self.player.draw(self.window, self.pic_dict[self.player.pic_num])
        if randint(0, 1000) < 50:           # 4
            self.player.speak()
        self.update_messages(self.player)   # 5

        other_players_data = pickle.loads(self.send_player_data())
        self.update_other_players_data(other_players_data)

        pygame.display.update()

    def update_other_players_data(self, data):
        for player in data.values():
            player.draw(self.window, self.pic_dict[player.pic_num])
            self.update_messages(player)    # 6

    def update_messages(self, player):
        if player.message:
            self.all_players_messages.insert(0, f"{player.id}: {player.message}")
            if len(self.all_players_messages) > self.max_messages_shown:
                self.all_players_messages.pop()

        font_size = 12
        font = pygame.font.Font("SimHei.ttf", font_size)
        for i, msg in enumerate(self.all_players_messages):
            msg_text = font.render(msg, True, (150, 150, 150))
            self.window.blit(msg_text, (0, self.height-(font_size*(i+1))))

代码解释如下:

1. 所有玩家的消息都会存储在all_players_messages列表变量中。

2. max_messages_shown变量用来控制在窗口上显示的聊天消息数。

3. 当前玩家的数据被发送到服务器后,就要清空Player对象的message属性,否则其他玩家会重复收到一条不变的消息。

4. 使用随机数来模拟玩家聊天。

5. update_messages()函数是重点,在该函数中,我们首先判断玩家数据中的message变量是否有值,有的话说明有发送消息,那就将这个值插到all_players_messages列表开头。如果消息总数大于max_messages_shown变量的值,那就把列表中最后一条聊天消息删除掉,不再显示。最后将所有聊天内容都显示到窗口左下角。为了解决Pygame中文显示的问题,笔者这里使用了另外的SimHei.ttf字体,已放入到项目文件夹中。

6. 接收到其他玩家的数据后,要记得调用update_messages()函数更新聊天内容。

运行结果如下:

《Python多人游戏项目实战》第三节 在窗口上显示玩家ID以及对话内容

3.4 完整代码下载地址

链接:https://pan.baidu.com/s/1chQ5c94X07Oi3Iv_eX3xDg  

密码:9qbz文章来源地址https://www.toymoban.com/news/detail-411887.html

到了这里,关于《Python多人游戏项目实战》第三节 在窗口上显示玩家ID以及对话内容的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【零基础入门Python爬虫】第三节 Python Selenium

    Python Selenium 是一种自动化测试框架,可以模拟用户在浏览器中的交互行为。它是一个基于浏览器驱动程序的工具,可用于Web应用程序测试、数据采集等方面,能够让开发人员通过代码自动化地模拟用户在浏览器中的操作,并获取到所需的数据。 Selenium的主要优势是它可以模拟

    2024年02月04日
    浏览(61)
  • 【Python零基础学习入门篇③】——第三节:Python的字符串类型

    ⬇️⬇️⬇️⬇️⬇️⬇️ ⭐⭐⭐Hello,大家好呀我是陈童学哦,一个普通大一在校生,请大家多多关照呀嘿嘿😁😊😘 🌟🌟🌟 技术这条路固然很艰辛,但既已选择,该当坚毅地走下去,加油! 🌤️PUA: ” 你所看到的惊艳都曾平庸历练 **“**🚀🚀🚀 🍉🍉🍉 最后让我

    2024年02月04日
    浏览(46)
  • 【从零到一手撕脚手架 | 第三节】项目集成CommitLInt+ESLint+Prettier+StyleLint+LintStaged

    Hello大家好我是⛄,前两节教大家如何初始化一个脚手架项目以及如何封装Vue技术栈常用的工具库。本小节教大家如何向我们的脚手架中配置ESLint、Prettier、StyleLint、LintStage。帮助大家规范项目代码,能够更好的进行团队协作开发。 项目地址: GitHub :LonelySnowman/sv3-template 官方

    2024年04月16日
    浏览(69)
  • (数字图像处理MATLAB+Python)第七章图像锐化-第三节:高斯滤波与边缘检测

    高斯函数 :是一种常见的连续函数,通常用符号 G ( x ) G(x) G ( x ) 表示。它可以用下面的公式定义 G ( x ) = 1 σ 2 π e − x 2 2 σ 2 G(x)=frac{1}{sigma sqrt{ 2pi }}e^{-frac{x^{2}}{2sigma^{2}}} G ( x ) = σ 2 π ​ 1 ​ e − 2 σ 2 x 2 ​ 其中, x x x 是自变量, σ sigma σ 是一个正实数,表示高斯函

    2024年02月06日
    浏览(57)
  • 项目实训--Unity多人游戏开发(十一、PUN框架--游戏场景篇(加载与同步))

    本地加载 有许多方法,举几个例子: 本地加载 本地异步加载(场景内容过多时,防止卡顿异步加载) 多人游戏加载场景 pun2插件加载 这个异步加载起初是觉得场景内容如果过多会引起卡顿。所以把这个应用在了单机模式上。 至于多人游戏加载场景,可能用不到而且也没法

    2024年02月01日
    浏览(63)
  • (数字图像处理MATLAB+Python)第九章图像形态学运算-第三节:二值图像的形态学处理

    形态滤波 :是一种在数字图像处理中常用的图像处理技术,用于改善图像的质量、提取图像的特定特征或去除图像中的噪声。形态滤波主要基于形态学运算,通过结构元素(也称为模板)对图像进行局部区域的操作,从而改变图像的形状和结构。选择不同形状(如各向同性的

    2024年02月08日
    浏览(67)
  • 《树莓派项目实战》第十三节 使用ULN2003驱动板控制28BYJ-48单极步进电机

    目录 13.1 引脚介绍 13.2 控制电机以及计算旋转角度 13.3 连接到树莓派 13.4 编写代码 在本节,我们将学习如何使用ULN2003驱动板控制一个28BYJ-48单极

    2024年02月05日
    浏览(44)
  • Unity中相机中显示场景画面,游戏窗口就不显示怎么解决

            最近在学习Unity时碰到了这样一个问题:相机中显示场景画面,切换游戏窗口运行就不显示了,自己在网上查了各种方法都不行,今天自己鼓捣好了,下面给大家分享一下吧,希望对大家有帮助。 问题如下:   1.图层问题  首先考虑图层问题,我们将相机图层切换成与

    2024年02月11日
    浏览(45)
  • 100个Python实战项目(九)制作贪吃蛇游戏(评论抽奖送书)

    💂 个人网站:【海拥】【摸鱼小游戏】【开发文档导航】 🤟 风趣幽默的人工智能学习网站:👉人工智能 💅 想寻找共同学习交流的小伙伴,请点击【全栈技术交流群】 💬 免费且实用的计算机相关知识题库:👉进来逛逛 给大家安利一个免费且实用的 Python 刷题(面经大全

    2024年02月01日
    浏览(68)
  • 第三节——Vue 基础语法

    vue语法分为选项是API(Option api)和组合式api(Composition Api),我们以选项式Api入门 template、script、style三部分构成。template可以理解成编写html的地方,script编写逻辑js的地方,style编写样式的地方 1、概念 vue中,使用{{}}双花括号,在html标签的“内容区域”中表现数据,这个技术

    2024年02月08日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包