学习 Python 之 Pygame 开发坦克大战(五)

news2024/11/16 5:54:46

学习 Python 之 Pygame 开发坦克大战(五)

    • 坦克大战完善地图
      • 1. 创建砖墙
      • 2. 给砖墙增加子弹击中的碰撞效果
      • 3. 给砖墙坦克不能通过的碰撞效果

坦克大战完善地图

我的素材放到了百度网盘里,里面还有原版坦克大战素材,我都放在一起来,我的素材是从原版改的,各位小伙伴可以直接用或者自己改一下再用,做出适合自己的素材

素材链接:百度网盘
链接:https://pan.baidu.com/s/19sCyH7rp37f6DzRj0iXDCA?pwd=tkdz
提取码:tkdz

那我们就继续编写坦克大战吧

1. 创建砖墙

坦克大战中,砖墙是最常见的墙,子弹都可以轻松击穿,下面我们来加入到自己的坦克大战中

创建砖墙类

import pygame.image
from ParentObject import ParentObject

class BrickWall(ParentObject):
    def __init__(self, x, y):
        super().__init__()
        self.image = pygame.image.load('../Image/Wall/BrickWall.png')
        self.rect = self.image.get_rect()
        self.rect.left = x
        self.rect.top = y
        self.isDestroy = False

    def draw(self, window):
        window.blit(self.image, self.rect)

在主类中加入砖墙列表

class MainGame:
    ...
    # 砖墙
    brickWallList = []
    ...

在主类中加入初始化砖墙函数和显示砖墙函数

def drawBrickWall(self, brickWallList):
    for brickWall in brickWallList:
        if brickWall.isDestroy:
            brickWallList.remove(brickWall)
        else:
            brickWall.draw(MainGame.window)

def initBrickWall(self):
    for i in range(20):
        MainGame.brickWallList.append(BrickWall(i * 25, 200))

这里我在y = 200的位置,连续画出20个砖,砖的图片是25x25的,所以为了防止重叠,要间隔25个距离(像素)

在主函数startGame()函数中调用函数

def startGame(self):
    # 初始化展示模块
    pygame.display.init()
    # 设置窗口大小
    size = (SCREEN_WIDTH, SCREEN_HEIGHT)
    # 初始化窗口
    MainGame.window = pygame.display.set_mode(size)
    # 设置窗口标题
    pygame.display.set_caption('Tank Battle')

    # 初始化我方坦克
    MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1)

    # 播放开始音乐
    MainGame.startingSound.play()
    
    # 初始化场景
    self.initBrickWall()

    while 1:
        # 设置背景颜色
        MainGame.window.fill(BACKGROUND_COLOR)

        # 获取窗口事件
        self.getPlayingModeEvent()
        
        # 显示物体
        self.drawBrickWall(MainGame.brickWallList)

        # 展示敌方坦克
        self.drawEnemyTank()

        # 显示我方坦克
        MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])

        # 我方坦克移动
        if not MainGame.playerTank.stop:
            MainGame.playerTank.move()
            MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)

        # 显示我方坦克子弹
        self.drawPlayerBullet(MainGame.playerBulletList)

        # 展示敌方坦克子弹
        self.drawEnemyBullet()

        # 展示爆炸效果
        self.drawExplode()

        # 更新窗口
        pygame.display.update()

运行一下,看看结果
在这里插入图片描述
但是墙只是摆设,子弹可以穿过,坦克也可以穿过,下面给墙增加碰撞效果

2. 给砖墙增加子弹击中的碰撞效果

在子弹类中增加函数

def bulletCollideBrickWall(self, brickWallList, explodeList):
    for brickWall in brickWallList:
        # 子弹与墙发生碰撞
        if pygame.sprite.collide_rect(self, brickWall):
            self.isDestroy = True
            brickWall.isDestroy = True
            # 碰撞出现爆炸效果
            explode = Explode(brickWall, 25)
            explodeList.append(explode)
            # 出现爆炸播放音效
            Sound('../Sound/block.wav').play()

在主函数中调用
修改显示子弹的两个函数

def drawPlayerBullet(self, playerBulletList):
    # 遍历整个子弹列表,如果是没有被销毁的状态,就把子弹显示出来,否则从列表中删除
    for bullet in playerBulletList:
        if not bullet.isDestroy:
            bullet.draw(MainGame.window)
            bullet.move(MainGame.explodeList)
            bullet.playerBulletCollideEnemyTank(MainGame.enemyTankList, MainGame.explodeList)
            bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)
        else:
            playerBulletList.remove(bullet)
def drawEnemyBullet(self):
    for bullet in MainGame.enemyTankBulletList:
        if not bullet.isDestroy:
            bullet.draw(MainGame.window)
            bullet.move(MainGame.explodeList)
            bullet.enemyBulletCollidePlayerTank(MainGame.playerTank, MainGame.explodeList)
            bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)
        else:
            bullet.source.bulletCount -= 1
            MainGame.enemyTankBulletList.remove(bullet)

运行一下看看

在这里插入图片描述
可以看到墙可以被打掉了

3. 给砖墙坦克不能通过的碰撞效果

在敌方坦克类中加入函数,在我方坦克类中加入函数
collideBrickWall()

def collideBrickWall(self, brickWallList):
    for brickWall in brickWallList:
        if pygame.sprite.collide_rect(self, brickWall):
            self.rect.left = self.prvX
            self.rect.top = self.prvY

在主类中调用
在while循环中调用

while 1:
    # 设置背景颜色
    MainGame.window.fill(BACKGROUND_COLOR)

    # 获取窗口事件
    self.getPlayingModeEvent()

    # 显示物体
    self.drawBrickWall(MainGame.brickWallList)

    # 展示敌方坦克
    self.drawEnemyTank()

    # 显示我方坦克
    MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])

    # 我方坦克移动
    if not MainGame.playerTank.stop:
        MainGame.playerTank.move()
        MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)
        # 不能撞墙
        MainGame.playerTank.collideBrickWall(MainGame.brickWallList)

在主类的drawEnemyTank()中调用

def drawEnemyTank(self):
    ...
    for tank in MainGame.enemyTankList:
        # 坦克还有生命值
        if tank.life > 0:
            tank.draw(MainGame.window)
            tank.move()
            tank.collidePlayerTank(MainGame.playerTank)
            tank.collideEnemyTank(MainGame.enemyTankList)
            # 不能撞墙
            tank.collideBrickWall(MainGame.brickWallList)
            bullet = tank.shot()
            if bullet is not None:
                MainGame.enemyTankBulletList.append(bullet)
        # 坦克生命值为0,就从列表中剔除
        else:
            MainGame.enemyTankCurrentCount -= 1
            MainGame.enemyTankList.remove(tank)

运行一下,看看效果
在这里插入图片描述
确实是不能穿过了
那就完成啦,接下来就是添加其他的物体了
添加的过程跟添加砖墙是一样的

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/356221.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Blazor入门100天 : 身份验证和授权 (2) - 角色/组件/特性/过程逻辑

目录 建立默认带身份验证 Blazor 程序角色/组件/特性/过程逻辑DB 改 Sqlite将自定义字段添加到用户表脚手架拉取IDS文件,本地化资源freesql 生成实体类,freesql 管理ids数据表初始化 Roles,freesql 外键 > 导航属性完善 freesql 和 bb 特性 本节源码 https://github.com/…

Flink03: 集群安装部署

Flink支持多种安装部署方式 StandaloneON YARNMesos、Kubernetes、AWS… 这些安装方式我们主要讲一下standalone和on yarn。 如果是一个独立环境的话,可能会用到standalone集群模式。 在生产环境下一般还是用on yarn 这种模式比较多,因为这样可以综合利…

C++入门:引用

目录 一. 什么是引用 1.1 引用的概念 1.2 引用的定义 二. 引用的性质和用途 2.1 引用的三大主要性质 2.2 引用的主要应用 三. 引用的效率测试 3.1 传值调用和传引用调用的效率对比 3.2 值返回和引用返回的效率对比 四. 常引用 4.1 权限放大和权限缩小问题 4.2 跨…

【超好用】自定义的mybatis-plus代码生成器

BACKGROUND你是否也有这样的烦恼:每次写代码都需要创建很多包很多层很多类很多接口?耗时且费力姑且不谈,有时可能还大意了没有闪,搞出一堆bug这谁顶得住啊都3202年了,让程序自力更生吧!!教程 le…

原创|关于一次产品需求程序设计及优化的经历

文章目录一、流程梳理二、设计梳理三、技术方案3.1、下单接口扩展3.3.1、Request类新增deviceType3.3.2、申请单新增字段产品策略(productStrategy)3.3.3、下单产品策略的处理逻辑3.2、询价模块的设计3.2.1、Context设计3.2.2、ProductStrategy类设计3.2.2.1、AbstractProductS…

k8s篇之概念介绍

文章目录时光回溯什么是K8SK8S不是什么一、K8S构成组件控制平面组件(Control Plane Components)kube-apiserveretcdkube-schedulerkube-controller-managercloud-controller-managerNode 组件kubeletkube-proxy容器运行时(Container Runtime&…

Spring Cloud Nacos实战(七)- Nacos之Linux版本安装

Nacos之Linux版本安装 Linux版NacosMySql生产环境配置 ​ 已经给大家讲解过了Nacos生产环境下需要搭建集群配置,那么这里我们预计需要:1个Nginx3个Nacos注册中心1个MySql 具体配置: 在官网上下载NacosLinux版本:https://github…

基于SSM框架的CMS内容管理系统的设计与实现

基于SSM框架的CMS内容管理系统的设计与实现 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目…

并查集(高级数据结构)-蓝桥杯

一、并查集并查集(Disioint Set):一种非常精巧而实用的数据结构用于处理不相交集合的合并问题。用于处理不相交集合的合并问题。经典应用:连通子图。最小生成树Kruskal算法。最近公共祖先。二、应用场景有n个人,他们属于不同的帮派。 已知这些…

Kafka漏洞修复之CVE-2023-25194修复措施验证

Kafka漏洞修复之CVE-2023-25194修复措施验证前言风险分析解决方案AdoptOpenJDK Zookeeper Kafka多版本OpenJDK安装切换Zookeeper安装Kafka安装与使用其他Kafka消息发送流程Linux配置加载顺序参考链接前言 场景介绍 Kafka最近爆出高危漏洞CNNVD-202302-515,导致Apa…

LeetCode刷题复盘笔记—一文搞懂贪心算法之56. 合并区间(贪心算法系列第十四篇)

今日主要总结一下可以使用贪心算法解决的一道题目,56. 合并区间 题目:56. 合并区间 Leetcode题目地址 题目描述: 以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] [starti, endi] 。请你合并所有重叠的区间…

QXlsx(访问Excel)

再Qt中已经有了QAxObject来访问Excel,但访问的是微软的com,只能访问正版的Excl中的 .xls//xlsx ,而且使用起来及其不方便(本人亲测)。 在这里使用QXlsx,能更简单的访问Excel数据,但QXlsx这个类并没有在Qt Creator中&a…

《MySQL学习》 MySQL优化器选择如何选择索引

一.优化器的选择逻辑 建表语句 CREATE TABLE t (id int(11) NOT NULL AUTO_INCREMENT,a int(11) DEFAULT NULL,b int(11) DEFAULT NULL,PRIMARY KEY (id),KEY a (a),KEY b (b) ) ENGINEInnoDB;往表中插入10W条数据 delimiter ;; create procedure idata() begindeclare i in…

目标检测三大数据格式VOC,YOLO,COCO的详细介绍

注:本文仅供学习,未经同意请勿转载 说明:该博客来源于xiaobai_Ry:2020年3月笔记 对应的PDF下载链接在:待上传 目录 目标检测常见数据集总结 V0C数据集(Annotation的格式是xmI) A. 数据集包含种类: B. V0C2007和V0C2012的区别…

QT学习记录散件

fromLocal8Bit() qt中fromLocal8Bit()函数可以设置编码。 因为QT默认的编码是unicode,不能显示中文的 而windows默认使用(GBK/GB2312/GB18030) 所以使用fromLocal8Bit()函数,可以实现从本地字符集GB到Unicode的转换,从…

32-Golang中的map

Golang中的map基本介绍基本语法map声明的举例map使用的方式map的增删改查操作map的增加和更新map的删除map的查找map的遍历map切片基本介绍map排序map的使用细节基本介绍 map是key-value数据结构,又称为字段或者关联数组。类似其它编程语言的集合,在编程…

2023美赛ABCDEF思路汇总

注:以下每个题思路仅是个人所想所做,不代表他人。由于时间仓促完成这么多,难免有不足之处,还请谅解。 文章目录A题第一大问第二大问B题第一问第二问第三问C题第一问第二问第三问第四问D题第一问第二问第三问第四问第五问E题第一问…

#Paper Reading# Language Models are Unsupervised Multitask Learners

论文题目: Language Models are Unsupervised Multitask Learners 论文地址: https://life-extension.github.io/2020/05/27/GPT技术初探/language-models.pdf 论文发表于: OpenAI 2019 论文所属单位: OpenAI 论文大体内容: 本文主要提出了GPT-2(Gener…

Visual Studio 2022: 增加对虚幻引擎的支持

自 Visual Studio 2022 发布以来,我们一直专注于为游戏和大型项目开发人员提供一系列生产力和性能改进。今天,我们很高兴与大家分享下一组专门用来提高虚幻引擎开发效率的功能。我们听到并看到了来自你(我们的游戏开发人员)的大量…

Spring MVC之 一次请求响应的过程

Spring MVC 会创建两个容器,其中创建Root WebApplicationContext 后,调用其refresh()方法会触发刷新事件,完成 Spring IOC 初始化相关工作,会初始化各种 Spring Bean 到当前容器中我们先来了解一个请求是如何被 Spring MVC 处理的…