pygame联网飞机大战游戏实现
客户端
import pygame
import socket
import json
import threadingclass GameClient:def __init__(self):pygame.init()self.screen_width = 600 # 宽度减小self.screen_height = 800 # 高度增加self.screen = pygame.display.set_mode((self.screen_width, self.screen_height))pygame.display.set_caption("竖版飞机大战")self.client_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)self.server_address = ('localhost', 5555)self.player_id = Noneself.game_state = {'players': {},'bullets': [],'enemies': []}self.input_state = {'up': False,'down': False,'left': False,'right': False,'shoot': False}# 连接服务器self.connect_to_server()self.running = True# 启动接收线程threading.Thread(target=self.receive_data).start()# 游戏主循环self.clock = pygame.time.Clock()self.game_loop()def connect_to_server(self):join_message = {'type': 'join'}self.client_socket.sendto(json.dumps(join_message).encode(), self.server_address)def receive_data(self):while self.running:try:data, _ = self.client_socket.recvfrom(4096)message = json.loads(data.decode())if message['type'] == 'welcome':self.player_id = message['id']elif message['type'] == 'update':self.game_state = messageexcept:passdef game_loop(self):while self.running:# 处理输入事件for event in pygame.event.get():if event.type == pygame.QUIT:self.running = Falseelif event.type == pygame.KEYDOWN:if event.key == pygame.K_UP:self.input_state['up'] = Trueelif event.key == pygame.K_DOWN:self.input_state['down'] = Trueelif event.key == pygame.K_LEFT:self.input_state['left'] = Trueelif event.key == pygame.K_RIGHT:self.input_state['right'] = Trueelif event.key == pygame.K_SPACE:self.input_state['shoot'] = Trueelif event.type == pygame.KEYUP:if event.key == pygame.K_UP:self.input_state['up'] = Falseelif event.key == pygame.K_DOWN:self.input_state['down'] = Falseelif event.key == pygame.K_LEFT:self.input_state['left'] = Falseelif event.key == pygame.K_RIGHT:self.input_state['right'] = Falseelif event.key == pygame.K_SPACE:self.input_state['shoot'] = False# 发送输入状态到服务器if self.player_id is not None:input_message = {'type': 'input','id': self.player_id,**self.input_state}self.client_socket.sendto(json.dumps(input_message).encode(), self.server_address)# 渲染游戏self.render()self.clock.tick(60)pygame.quit()def render(self):self.screen.fill((0, 0, 0))# 绘制玩家for player_id, player in self.game_state['players'].items():color = (0, 255, 0) if int(player_id) == self.player_id else (0, 0, 255)pygame.draw.rect(self.screen, color, (player['x'], player['y'], player['width'], player['height']))# 显示生命值if 'health' in player:font = pygame.font.SysFont(None, 24)health_text = font.render(f"HP: {player['health']}", True, (255, 255, 255))self.screen.blit(health_text, (player['x'], player['y'] - 20))# 显示分数if 'score' in player:font = pygame.font.SysFont(None, 24)score_text = font.render(f"Score: {player['score']}", True, (255, 255, 255))self.screen.blit(score_text, (player['x'], player['y'] - 40))# 绘制子弹for bullet in self.game_state['bullets']:pygame.draw.rect(self.screen, (255, 255, 0), (bullet['x'], bullet['y'], bullet['width'], bullet['height']))# 绘制敌机for enemy in self.game_state['enemies']:pygame.draw.circle(self.screen, (255, 0, 0), (enemy['x'], enemy['y']), enemy['radius'])pygame.display.flip()if __name__ == "__main__":client = GameClient()
服务器
import socket
import threading
import json
import random
import timeclass GameServer:def __init__(self):self.players = {}self.bullets = []self.enemies = []self.last_enemy_spawn = 0self.server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)self.server_socket.bind(('0.0.0.0', 5555))self.running = True# 游戏参数self.screen_width = 600 # 宽度可以小一些self.screen_height = 800 # 高度增加self.player_speed = 5self.bullet_speed = 7self.enemy_speed = 3# 启动接收线程threading.Thread(target=self.receive_data).start()threading.Thread(target=self.game_loop).start()def receive_data(self):while self.running:try:data, addr = self.server_socket.recvfrom(1024)message = json.loads(data.decode())if message['type'] == 'join':player_id = len(self.players)# 玩家初始位置改为底部self.players[player_id] = {'x': 200 if player_id == 0 else 400,'y': self.screen_height - 100,'width': 40,'height': 40,'addr': addr,'last_shot': 0}response = {'type': 'welcome', 'id': player_id}self.server_socket.sendto(json.dumps(response).encode(), addr)elif message['type'] == 'input':player_id = message['id']if player_id in self.players:player = self.players[player_id]if 'up' in message and message['up']:player['y'] = max(0, player['y'] - self.player_speed)if 'down' in message and message['down']:player['y'] = min(self.screen_height - player['height'], player['y'] + self.player_speed)if 'left' in message and message['left']:player['x'] = max(0, player['x'] - self.player_speed)if 'right' in message and message['right']:player['x'] = min(self.screen_width - player['width'], player['x'] + self.player_speed)if 'shoot' in message and message['shoot']:current_time = time.time()if current_time - player['last_shot'] > 0.2: # 射击冷却# 子弹改为向上发射self.bullets.append({'x': player['x'] + player['width'] // 2 - 5,'y': player['y'],'width': 5,'height': 10,'speed': -self.bullet_speed, # 负值表示向上'owner': player_id})player['last_shot'] = current_timeexcept:passdef game_loop(self):while self.running:# 生成敌机(从顶部)current_time = time.time()if current_time - self.last_enemy_spawn > 2.0: # 每2秒生成一个敌机self.enemies.append({'x': random.randint(0, self.screen_width - 20),'y': -20, # 从屏幕外顶部生成'radius': 10,'speed': self.enemy_speed})self.last_enemy_spawn = current_time# 更新子弹位置for bullet in self.bullets[:]:bullet['y'] += bullet['speed'] # 速度可以是正或负if bullet['y'] < -10 or bullet['y'] > self.screen_height + 10:self.bullets.remove(bullet)# 更新敌机位置(向下移动)for enemy in self.enemies[:]:enemy['y'] += enemy['speed']if enemy['y'] > self.screen_height + 20:self.enemies.remove(enemy)# 碰撞检测self.check_collisions()# 广播游戏状态self.broadcast_state()time.sleep(0.016) # 约60FPSdef check_collisions(self):# 子弹与敌机碰撞for bullet in self.bullets[:]:for enemy in self.enemies[:]:if (bullet['x'] < enemy['x'] + enemy['radius'] andbullet['x'] + bullet['width'] > enemy['x'] andbullet['y'] < enemy['y'] + enemy['radius'] andbullet['y'] + bullet['height'] > enemy['y']):# 增加玩家分数if bullet['owner'] in self.players:if 'score' not in self.players[bullet['owner']]:self.players[bullet['owner']]['score'] = 0self.players[bullet['owner']]['score'] += 1if bullet in self.bullets:self.bullets.remove(bullet)if enemy in self.enemies:self.enemies.remove(enemy)break# 玩家与敌机碰撞for player_id, player in self.players.items():for enemy in self.enemies[:]:if (player['x'] < enemy['x'] + enemy['radius'] andplayer['x'] + player['width'] > enemy['x'] andplayer['y'] < enemy['y'] + enemy['radius'] andplayer['y'] + player['height'] > enemy['y']):# 减少玩家生命值if 'health' not in player:player['health'] = 3player['health'] -= 1if enemy in self.enemies:self.enemies.remove(enemy)if player['health'] <= 0:# 玩家死亡,重置位置player['x'] = 200 if player_id == 0 else 400player['y'] = self.screen_height - 100player['health'] = 3def broadcast_state(self):game_state = {'type': 'update','players': self.players,'bullets': self.bullets,'enemies': self.enemies}for player_id, player in self.players.items():try:self.server_socket.sendto(json.dumps(game_state).encode(), player['addr'])except:passif __name__ == "__main__":server = GameServer()input("Press Enter to stop the server...\n")server.running = False
相关文章:
pygame联网飞机大战游戏实现
客户端 import pygame import socket import json import threadingclass GameClient:def __init__(self):pygame.init()self.screen_width 600 # 宽度减小self.screen_height 800 # 高度增加self.screen pygame.display.set_mode((self.screen_width, self.screen_heigh…...

SEMI E40-0200 STANDARD FOR PROCESSING MANAGEMENT(加工管理标准)-(二)
8 行为规范 8.1 本章定义监督实体(Supervisor)与加工资源(Processing Resource)为实现物料加工所需的高层级通信逻辑,不涉及具体消息细节(详见第10章消息服务)。 8.2 加工任务通信 8.2.1 加工…...

根据窗口大小自动调整页面缩放比例,并保持居中显示
vue 项目 直接上代码 图片u1.png 是个背景图片 图片u2.png 是个遮罩 <template><div id"app"><div class"viewBox"><divclass"screen":style"{ transform: translate(-50%,-50%…...
如何在Jmeter中调用C程序?
在JMeter中调用C语言程序可以通过以下几种方式实现: 方法一:使用OS Process Sampler JMeter的“OS Process Sampler”可以用来调用外部程序,包括C语言编写的可执行文件。 步骤: 准备C语言程序: 编写C语言代码并编译…...

Android SDK 国内镜像及配置方法(2025最新,包好使!)
2025最新android sdk下载配置 1、首先你需要有android sdk manager2、 直接上教程修改hosts文件配置域名映射即可(不用FQ)2.1 获取ping dl.google.com域名ip地址2.2 配置hosts文件域名映射2.3 可以随意下载你需要的sdk3、 总结:走过弯路,踩过坑!!!大家就不要踩了!避坑1…...

【Python开源】深度解析:一款高效音频封面批量删除工具的设计与实现
🎵 【Python开源】深度解析:一款高效音频封面批量删除工具的设计与实现 🌈 个人主页:创客白泽 - CSDN博客 🔥 系列专栏:🐍《Python开源项目实战》 💡 热爱不止于代码,热情…...

OpenStack Yoga版安装笔记(26)实例元数据笔记
一、实例元数据概述 1.1 元数据 (官方文档:Metadata — nova 25.2.2.dev5 documentation) Nova 通过一种叫做元数据(metadata)的机制向其启动的实例提供配置信息。这些机制通常通过诸如 cloud-init 这样的初始化软件…...

【Linux】swap交换分区管理
目录 一、Swap 交换分区的功能 二、swap 交换分区的典型大小的设置 2.1 查看交换分区的大小 2.1.1 free 2.1.2 cat /proc/swaps 或 swapon -s 2.1.3 top 三、使用交换分区的整体流程 3.1 案例一 3.2 案例二 一、Swap 交换分区的功能 计算机运行一个程序首先会将外存&am…...
Spring IoC (Inversion of Control) 控制反转是什么?
我们分析一下 IoC (Inversion of Control) 控制反转的核心思想。 核心思想: IoC 是一种设计原则(Design Principle),它描述了一种软件设计模式,其中组件(对象)的创建、依赖关系的管理和生命周…...
互联网大厂Java求职面试:核心技术点深度解析
互联网大厂Java求职面试:核心技术点深度解析 在互联网大厂的Java岗位面试中,技术总监级别的面试官通常会从实际业务场景出发,层层深入地考察候选人的技术能力。本文通过一个严肃专业的技术总监与搞笑但有技术潜力的程序员郑薪苦之间的互动对…...

VirtualBox 创建虚拟机并安装 Ubuntu 系统详细指南
VirtualBox 创建虚拟机并安装 Ubuntu 系统详细指南 一、准备工作1. 下载 Ubuntu 镜像2. 安装 VirtualBox二、创建虚拟机1. 新建虚拟机2. 分配内存3. 创建虚拟硬盘三、配置虚拟机1. 加载 Ubuntu 镜像2. 调整处理器核心数(可选)3. 启用 3D 加速(图形优化)四、安装 Ubuntu 系统…...
【算法基础】递归算法 - JAVA
一、递归基础 1.1 什么是递归算法 递归算法是一种通过函数调用自身来解决问题的方法。简单来说,就是"自己调用自己"。递归将复杂问题分解为同类的更简单子问题,直到达到易于直接解决的基本情况。 1.2 递归的核心要素 递归算法由两个关键部…...

触想CX-3588工控主板应用于移动AI数字人,赋能新型智能交互
一、行业发展背景 随着AI智能、自主导航和透明屏显示等技术的不断进步,以及用户对“拟人化”、“沉浸式”交互体验的期待,一种新型交互终端——“移动AI数字人”正在加速实现规模化商用。 各大展厅展馆、零售导购、教学政务甚至家庭场景中,移…...

【深入浅出MySQL】之数据类型介绍
【深入浅出MySQL】之数据类型介绍 MySQL中常见的数据类型一览为什么需要如此多的数据类型数值类型BIT(M)类型INT类型TINYINT类型BIGINT类型浮点数类型float类型DECIMAL(M,D)类型区别总结 字符串类型CHAR类型VARCHAR(M)类型 日期和时间类型enum和set类型 …...

Vue3响应式:effect作用域
# Vue3响应式: effect作用域 什么是Vue3响应式? 是一款流行的JavaScript框架,它提供了响应式和组件化的视图组织方式。在Vue3中,响应式是一种让数据变化自动反映在视图上的机制。当数据发生变化时,与之相关的视图会自动更新。 作用…...

25.5.4数据结构|哈夫曼树 学习笔记
知识点前言 一、搞清楚概念 ●权:___________ ●带权路径长度:__________ WPL所有的叶子结点的权值*路径长度之和 ●前缀编码:____________ 二、构造哈夫曼树 n个带权值的结点,构造哈夫曼树算法: 1、转化成n棵树组成的…...

RabbitMQ 深度解析:从核心组件到复杂应用场景
一.RabbitMQ简单介绍 消息队列作为分布式系统中不可或缺的组件,承担着解耦系统组件、保障数据可靠传输、提高系统吞吐量等重要职责。在众多消息队列产品中,RabbitMQ 凭借其可靠性和丰富的特性,在企业级应用中获得了广泛应用。 二.RabbitMQ …...
Python高级技巧及案例分析:提升编程能力的实践指南
目录 Python高级技巧及案例分析:提升编程能力的实践指南1. Python高级特性概述2. 函数式编程技巧2.1 高阶函数2.2 函数柯里化2.3 不可变数据结构3. 元编程与反射3.1 动态属性访问3.2 类装饰器3.3 元类应用4. 并发与异步编程4.1 多线程与线程池4.2 协程与asyncio4.3 多进程处理…...

【Linux笔记】系统的延迟任务、定时任务极其相关命令(at、crontab极其黑白名单等)
一、延时任务 1、概念 延时任务(Delayed Jobs)通常指在指定时间或特定条件满足后执行的任务。常见的实现方式包括 at 和 batch 命令,以及结合 cron 的调度功能。 2、命令 延时任务的命令最常用的是at命令,第二大节会详细介绍。…...
转换算子和行动算子的区别
转换算子和行动算子主要是在分布式计算框架(如 Apache Spark)里常用的概念,它们在功能、执行机制、返回结果等方面存在明显区别,以下为你详细介绍: 定义与功能 返回结果 如何在使用转换算子和行动算子时避免出现内存溢…...

使用阿里AI的API接口实现图片内容提取功能
参考链接地址:如何使用Qwen-VL模型_大模型服务平台百炼(Model Studio)-阿里云帮助中心 在windows下,使用python语言测试,版本:Python 3.8.9 一. 使用QVQ模型解决图片数学难题 import os import base64 import requests# base 64 …...
告别散乱的 @ExceptionHandler:实现统一、可维护的 Spring Boot 错误处理
Spring Boot 的异常处理机制一直都烂得可以。即便到了 2025 年,有了这么多进步和新版本,开发者们发现自己还是在跟 ControllerAdvice、分散各处的 ExceptionHandler 方法以及五花八门的响应结构较劲。这真的是一团糟。 无论你是在构建 REST API、微服务…...
MariaDB 与 MySQL 的关系:从同源到分道扬镳
MariaDB 与 MySQL 的关系:从同源到分道扬镳 1. 起源:MySQL 的辉煌与危机 MySQL 是最流行的开源关系型数据库之一,由瑞典公司 MySQL AB 开发,并于 1995 年 首次发布。由于其高性能、易用性和开源特性,MySQL 迅速成为 L…...

从零开始搭建你的个人博客:使用 GitHub Pages 免费部署静态网站
🌐 从零开始搭建你的个人博客:使用 GitHub Pages 免费部署静态网站 在互联网时代,拥有一个属于自己的网站不仅是一种展示方式,更是一种技术能力的体现。今天我们将一步步学习如何通过 GitHub Pages 搭建一个免费的个人博客或简历…...

C#串口通信
在C#中使用串口通信比较方便,.Net 提供了现成的类, SerialPort类。 本文不对原理啥的进行介绍,只介绍SerialPort类的使用。 SerialProt类内部是调用了CreateFile,WriteFile等WinAPI函数来实现串口通信。 在后期的Windows编程系…...
Qt 显示QRegExp 和 QtXml 不存在问题
QRegExp 和 QtXml 问题 在Qt6 中 已被弃用; 1)QRegExp 已被弃用,改用 QRegularExpression Qt5 → Qt6 重大变更:QRegExp 被移到了 Qt5Compat 模块,默认不在 Qt6 核心模块中。 错误类型解决方法QRegExp 找不到改用 Q…...
【训练】Qwen2.5VL 多机多卡 Grounding Box定位
之前的相关文章: 【深度学习】LLaMA-Factory微调sft Qwen2-VL进行印章识别 https://www.dong-blog.fun/post/1661 使用LLaMA-Factory微调sft Qwen2-VL-7B-Instruct https://www.dong-blog.fun/post/1762 构建最新的LLaMA-Factory镜像 https://www.dong-blog.f…...

服务器配置llama-factory问题解决
在配置运行llama-factory,环境问题后显示环境问题。这边给大家附上连接,我们的是liunx环境但是还是一样的。大家也记得先配置虚拟环境。 LLaMA-Factory部署以及微调大模型_llamafactory微调大模型-CSDN博客 之后大家看看遇到的问题是不是我这样。 AI搜索…...

Spring Boot + Vue 实现在线视频教育平台
一、项目技术选型 前端技术: HTML CSS JavaScript Vue.js 前端框架 后端技术: Spring Boot 轻量级后端框架 MyBatis 持久层框架 数据库: MySQL 5.x / 8.0 开发环境: IDE:Eclipse / IntelliJ IDEA JDK&…...

使用Jmeter进行核心API压力测试
最近公司有发布会,需要对全链路比较核心的API的进行压测,今天正好分享下压测软件Jmeter的使用。 一、什么是Jmeter? JMeter 是 Apache 旗下的基于 Java 的开源性能测试工具。最初被设计用于 Web 应用测试,现已扩展到可测试多种不同的应用程…...