Html5版飞机大战游戏中(Boss战)制作

news2025/1/16 8:17:53

内容在“60行代码,制作飞机大战游戏”的基础上,继续追加入了Boss战的功能。

boss的血量默认设置为100了,可以二次开发调整……(^_^)

玩起来有一定难度哈。 试玩地址:点击试玩

实现功能

  1. 添加玩家飞机,并进行控制
  2. Boss能够左右移动
  3. Boss发射三种子弹
  4. 子弹击中玩家飞机
  5. 子弹击中Boss,血量计算

项目源码:http://pro.youyu001.com 

待优化的功能

1)内存优化,子弹图片需要回收

(随着子弹数量增多,计算量一直增大,会卡死,设备发热,

想拼机器性能可以长时间运行试试)

2)血条的制作

(根据血量数值,控制血条图片宽度)

 

3)激光与玩家飞机的碰撞

(激光所在的区域范围,这里不能去)

代码说明

1)通过帧频计算时间相关

定义两个变量,用于记录帧频

var fireSpeed1 = 30;//boss发射子弹的间隔帧数
var fireSpeedSub1 = 0;//记录发射子弹后的帧数

在帧频函数中,执行下面代码。每0.5秒发射一次子弹

//boss定时发射子弹(方式1)
if(fireSpeedSub1 >= fireSpeed1) {
    boss_fire1();//发射子弹
    fireSpeedSub1 = 0;
}
fireSpeedSub1 ++;

2)发射多个子弹并控制

定义存放子弹图片的数组

var bulletList = [];//boss子弹存放在这个数组

当发射子弹时,将子弹图片push到数组中

function boss_fire1() {
    var bullet = new PIXI.Sprite.fromImage("res/bullet/img_bullet_17.png");
    bullet.anchor.set(0.5);//设置锚点为中心
    app.stage.addChild(bullet);
    bulletList.push(bullet);
    bullet.x = boss.x;
    bullet.y = boss.y;
}

给子弹图片添加更多的属性,这样在子弹移动时可以做到差异化。(Javascript的特性)

bullet.speedR = 0.1; //利用javascript对象的特性,临时记录下子弹旋转速度
bullet.speedY = 3; //利用javascript对象的特性,临时记录下子弹y方向的速度

在帧频函数中,让bulletList数组中的子弹进行移动

//boss子弹移动
for(var i = 0; i < bulletList.length; i ++) {
	var bullet = bulletList[i];
    bullet.y += bullet.speedY;
    if(bullet.speedX) { //判断如果子弹有x方向速度,则进行横向移动
        bullet.x += bullet.speedX;
    }
    if(bullet.speedR) { //判断如果子弹有旋转速度,则进行旋转
        bullet.rotation += bullet.speedR;//自转
    }
}

完整代码

<body></body>
<script src="pixi.js"></script>     
<script>

    //####### boss战 帧频控制 数组循环
    //散发子弹
    //1、boss左右移动
    //2、间隔一段时间发射子弹(两种子弹:直线、散弹)
    //3、利用数组循环处理多子弹
    //4、计算血量

    //创建应用
    var app = new PIXI.Application(512,768);
    document.body.appendChild(app.view);
    app.view.style.height = "100%";

    //添加背景
    var bg = new PIXI.Sprite.fromImage("res/bg/img_bg_level_3.jpg");
    app.stage.addChild(bg);

    //创建飞机图片
    var plane = new PIXI.Sprite.fromImage("res/plane_blue_01.png");
    app.stage.addChild(plane); //将图片放置到舞台
    plane.anchor.x = 0.5; //设置图片锚点为图片中心
    plane.anchor.y = 0.5;
    plane.x = 200; //设置图片的位置
    plane.y = 600;

    var planeBullet = new PIXI.Sprite.fromImage("res/bullet/img_bullet_13.png");
    app.stage.addChild(planeBullet);
    planeBullet.anchor.x = 0.5;   //设置飞机图片锚点为图片中心
    planeBullet.anchor.y = 0.5;

    bg.interactive = true;//背景图片允许接受控制信息
    bg.on("pointermove", movePlane); //滑动控制
    function movePlane(event) {
        var pos = event.data.getLocalPosition(app.stage); //获取鼠标当前位置
        plane.x = pos.x;
        plane.y = pos.y;
    }

    //创建boss图片
    var boss = new PIXI.Sprite.fromImage("res/plane/main/img_plane_boss_12.png");
    app.stage.addChild(boss); //将图片放置到舞台
    boss.anchor.x = 0.5; //设置图片锚点为图片中心
    boss.anchor.y = 0.5;
    boss.x = 300; //设置图片的位置
    boss.y = 150;

    //Boss血量
    var bossHp = 100; 
    var bossHpTxt = new PIXI.Text("Boss HP:" + bossHp);
    app.stage.addChild(bossHpTxt); //将文本添加到舞台

    var bossSpeed = 2;//boss左右移动速度

    var isGameOver = false; //是否游戏结束
    app.ticker.add(animate); //指定帧频函数
    function animate() {
        if(isGameOver == true) { //如果游戏结束,则不执行下面动画
            return;
        }

        //背景移动
        bg.y += 2;
        if(bg.y >= 0) {
            bg.y = -768;
        }

        //子弹移动
        planeBullet.y -= 40;
        if(planeBullet.y < -50) {
            planeBullet.x = plane.x;
            planeBullet.y = plane.y;
        }

        //击中Boss判断
        var pos = (planeBullet.x - boss.x) * (planeBullet.x - boss.x) + (planeBullet.y - boss.y) * (planeBullet.y - boss.y);
        if(pos < 100 * 100) { 
            planeBullet.x = plane.x;
            planeBullet.y = plane.y;
            //boss -hp
            bossHp --;
            bossHpTxt.text = "Boss HP:" + bossHp;
            if(bossHp <= 0) {
                isGameOver = true;
                //通关
                if (confirm("Success!, restart?")==true){  
                    window.location.reload();
                } 
            }
        }

        //boss左右移动
        boss.x += bossSpeed;
        if(boss.x > 400) {
            bossSpeed = -2;
        }
        if(boss.x < 100) {
            bossSpeed = 2;
        }

        //boss定时发射子弹(方式1)
        if(fireSpeedSub1 >= fireSpeed1) {
            boss_fire1();//发射子弹
            fireSpeedSub1 = 0;
        }
        fireSpeedSub1 ++;

        //boss定时发射子弹(方式2)
        if(fireSpeedSub2 >= fireSpeed2) {
            boss_fire2();//发射子弹
            fireSpeedSub2 = 0;
        }
        fireSpeedSub2 ++;

        //boss定时发射子弹(方式3)
        if(fireSpeedSub3 >= fireSpeed3) {
            boss_fire3();//发射子弹
            fireSpeedSub3 = 0;
        }
        fireSpeedSub3 ++;
        //如果激光已经发射
        if(bulletLeft.visible == true) {
            if(fire3TimeSub >= fire3Time) {
                bulletLeft.visible = false;
                bulletRight.visible = false;
                fire3TimeSub = 0;
            }
            fire3TimeSub ++;
        }
        
        //boss子弹移动
        for(var i = 0; i < bulletList.length; i ++) {
            var bullet = bulletList[i];
            bullet.y += bullet.speedY;
            
            if(bullet.speedX) { //判断如果子弹有x方向速度,则进行横向移动
                bullet.x += bullet.speedX;
            }
            if(bullet.speedR) { //判断如果子弹有旋转速度,则进行旋转
                bullet.rotation += bullet.speedR;//自转
            }
        }

        //碰撞子弹Game Over
        for(var i = 0; i < bulletList.length; i ++) {
            var bullet = bulletList[i];
            var pos = (bullet.x - plane.x) * (bullet.x - plane.x) + (bullet.y - plane.y) * (bullet.y - plane.y);
            if(pos < 30 * 30) { //这里调小一点,变的更简单
                //游戏结束标记
                isGameOver = true;
                //是否重玩
                if (confirm("Game Over, restart?")==true){  
                    window.location.reload();
                }
            }
        }

    }



    var bulletList = [];//boss子弹存放在这个数组

    //子弹1
    var fireSpeed1 = 30;//boss发射子弹的间隔帧数
    var fireSpeedSub1 = 0;//记录发射子弹后的帧数
    //boss子弹发射方式1
    function boss_fire1() {
        var bullet = new PIXI.Sprite.fromImage("res/bullet/img_bullet_17.png");
        bullet.anchor.set(0.5);//设置锚点为中心
        app.stage.addChild(bullet);
        bulletList.push(bullet);
        bullet.x = boss.x;
        bullet.y = boss.y;
        bullet.speedR = 0.1; //利用javascript对象的特性,临时记录下子弹旋转速度
        bullet.speedY = 3; //利用javascript对象的特性,临时记录下子弹y方向的速度

        var bullet = new PIXI.Sprite.fromImage("res/bullet/img_bullet_17.png");
        bullet.anchor.set(0.5);//设置锚点为中心
        app.stage.addChild(bullet);
        bulletList.push(bullet);
        bullet.x = boss.x;
        bullet.y = boss.y;
        bullet.speedX = 1; //利用javascript对象的特性,临时记录下子弹x方向的速度
        bullet.speedR = 0.1; //利用javascript对象的特性,临时记录下子弹旋转速度
        bullet.speedY = 3; //利用javascript对象的特性,临时记录下子弹y方向的速度

        var bullet = new PIXI.Sprite.fromImage("res/bullet/img_bullet_17.png");
        bullet.anchor.set(0.5);//设置锚点为中心
        app.stage.addChild(bullet);
        bulletList.push(bullet);
        bullet.x = boss.x;
        bullet.y = boss.y;
        bullet.speedX = -1; //利用javascript对象的特性,临时记录下子弹x方向的速度
        bullet.speedR = 0.1; //利用javascript对象的特性,临时记录下子弹旋转速度
        bullet.speedY = 3; //利用javascript对象的特性,临时记录下子弹y方向的速度
    }

    //boss子弹发射方式2
    var fireSpeed2 = 60;//boss发射子弹的间隔帧数
    var fireSpeedSub2 = 0;//记录发射子弹后的帧数
    function boss_fire2() {
        var bullet = new PIXI.Sprite.fromImage("res/bullet/img_bullet_15.png");
        bullet.anchor.set(0.5);//设置锚点为中心
        bullet.rotation = Math.PI;
        app.stage.addChild(bullet);
        bulletList.push(bullet);
        bullet.x = boss.x + 100;
        bullet.y = boss.y + 60;
        bullet.speedY = 8; //利用javascript对象的特性,临时记录下子弹y方向的速度

        var bullet = new PIXI.Sprite.fromImage("res/bullet/img_bullet_15.png");
        bullet.anchor.set(0.5);//设置锚点为中心
        bullet.rotation = Math.PI;
        app.stage.addChild(bullet);
        bulletList.push(bullet);
        bullet.x = boss.x - 100;
        bullet.y = boss.y + 60;
        bullet.speedY = 8; //利用javascript对象的特性,临时记录下子弹y方向的速度
    }

    //boss子弹发射方式3 激光
    var fireSpeed3 = 600;//boss发射子弹的间隔帧数
    var fireSpeedSub3 = 0;//记录发射子弹后的帧数
    var fire3Time = 300;//激光发射时长
    var fire3TimeSub = 0;//记录激光发射后的帧数

    var bulletLeft = new PIXI.Sprite.fromImage("res/bullet/img_bullet_laser_01.png");
    bulletLeft.anchor.x = 0.5;//设置锚点为中心
    bulletLeft.anchor.y = 1;//设置锚点为中心
    bulletLeft.scale.x = 2;
    bulletLeft.scale.y = 2;
    bulletLeft.rotation = Math.PI;
    boss.addChild(bulletLeft); //添加到boss图片上
    bulletLeft.x = 180;
    //隐藏激光图片
    bulletLeft.visible = false;

    var bulletRight = new PIXI.Sprite.fromImage("res/bullet/img_bullet_laser_01.png");
    bulletRight.anchor.x = 0.5;//设置锚点为中心
    bulletRight.anchor.y = 1;//设置锚点为中心
    bulletRight.scale.x = 2;
    bulletRight.scale.y = 2;
    bulletRight.rotation = Math.PI;
    boss.addChild(bulletRight); //添加到boss图片上
    bulletRight.x = -180;
    //隐藏激光图片
    bulletRight.visible = false;

    function boss_fire3() {
        bulletRight.visible = true;
        bulletLeft.visible = true;
    }



</script>

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

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

相关文章

vue+MapboxGL:从0 到1 搭建开发环境

本系列教程是在vue2.X的基础上加载mapbox 程序,来开发各种示例程序。 安装顺序 1,下载安装nodejs 下载地址:https://nodejs.org/en/download/ 根据用户自己的机器情况进行选择不同版本的软件下载。 本教程示例采用是是windows 64位系统软件。 安装过程很简单,一路下一步…

vue-router3.0处理页面滚动部分源码分析

在使用vue-router3.0时候&#xff0c;会发现不同的路由之间来回切换&#xff0c;会滚动到上次浏览的位置&#xff0c;今天就来看看这部分的vue-router中的源码实现。 无论是基于hash还是history的路由切换&#xff0c;都对滚动进行了处理&#xff0c;这里分析其中一种即可。 无…

TeeChart Pro ActiveX 2023.3.20 Crack

TeeChart Pro ActiveX 图表组件库提供数百种 2D 和 3D 图形样式、56 种数学和统计函数供您选择&#xff0c;以及无限数量的轴和 14 个工具箱组件。图表控件可以有效地用于创建多任务仪表板。 插件的多功能性 ActiveX 图表控件作为服务器端库中的 Web 图表、脚本化 ASP 图表或桌…

0201概述和结构-索引-MySQL

文章目录1 概述1.1 介绍1.2 优缺点2 索引结构2.1 BTree索引2.2 hash索引2.3 对比3 索引分类3.1 通用分类3.2 InnoDB存储引擎分类4 思考题后记1 概述 1.1 介绍 索引是帮忙MySQL 高效获取数据的数据结构&#xff08;有序&#xff09;。在数据之外&#xff0c;数据系统还维护着满…

【CF1764C】Doremy‘s City Construction(二分图,贪心)

【题目描述】 有nnn个点&#xff0c;每个点的点权为aia_iai​&#xff0c;你可以在任意两个点之间连边&#xff0c;最终连成的图需要满足&#xff1a;不存在任意的三个点&#xff0c;满足au≤av≤awa_u\le a_v\le a_wau​≤av​≤aw​&#xff08;非降序&#xff09;且边(u,v)(…

『pyqt5 从0基础开始项目实战』06. 获取选中多行table 重新初始化数据(保姆级图文)

目录导包和框架代码重新初始化绑定点击事件获取当前选中的所有行id实现初始化数据完整代码main.pythreads.py总结欢迎关注 『pyqt5 从0基础开始项目实战』 专栏&#xff0c;持续更新中 欢迎关注 『pyqt5 从0基础开始项目实战』 专栏&#xff0c;持续更新中 导包和框架代码 请查…

案例分享 | 金融业智能运维AIOps怎么做?看这一篇就够了

​构建双态IT系统&#xff0c;AIOps已经是必然的选择。运维数字化转型已是大势所趋&#xff0c;实体业务的逐步线上化对IT系统的稳定与安全提出更高要求&#xff0c;同时随着双态IT等复杂系统的建立&#xff0c;如何平衡IT运维效率与成本成为区域性银行面临的重要问题&#xff…

Windows编程基础

Windows编程基础 Unit1应用程序分类 控制台程序&#xff1a;Console Dos程序&#xff0c;本身没有窗口&#xff0c;通过windows Dos窗口执行 窗口程序 拥有自己的窗口&#xff0c;可以与用户交互 库程序 存放代码、数据的程序&#xff0c;执行文件可以从中取出代码执行和获取…

【MySQL】索引事务

摄影分享~ 文章目录索引概念使用场景使用事务概念使用事务的特性索引 概念 索引是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引并指定索引的类型&#xff0c;各类索引有各自的数据结构实现。 通过目录&#xff0c;就可以…

如何使用数字示波器

本文介绍以鼎阳SIGLENT SDS1122E数字示波器为例。 带了一根电源线&#xff1b;两根信号线&#xff0c;每根信号线都有几个小配件&#xff0c;如下所示&#xff1a; 使用概述 我们都知道万用表&#xff08;又称欧姆表&#xff09;是工程师最常用的调试电路的工具&#xff0c;但万…

技术+商业“双轮”驱动,量旋科技加速推进全方位的量子计算解决方案

【中国&#xff0c;深圳】4月14日&#xff0c;在第三个“世界量子日”&#xff0c;以“‘双轮’驱动 加速未来”为主题的量旋科技2023战略发布会在线上举办。 本次发布会&#xff0c;量旋科技全线升级了三大业务线产品&#xff1a;其中重点布局的超导量子计算体系产品&#xf…

监控系统 Prometheus 的说明

一、Prometheus 是什么&#xff1f; ELK Stack 日志收集和检索平台想必大家应该比较熟悉&#xff0c;Elasticsearch Filebeat Logstash Kibana。 而 Prometheus 就相当于一整个 ELK&#xff0c;但是它其实并不是适合存储大量日志&#xff0c;也不适合长期存储&#xff08;默…

【AI绘图学习笔记】transformer

台大李宏毅21年机器学习课程 self-attention和transformer 文章目录Seq2seq实现原理EncoderDecoderAutoregressive自回归解码器Non-Autoregressive非自回归解码器Corss-attention总结TrainingtrickCopy MechanismGuided AttentionBeam Search强化学习&#xff08;Reinforcement…

AVL树,红黑树,红黑树封装map和set

文章目录AVL树AVL树的实现AVL树的节点AVL树的平衡因子AVL树的插入AVL树的旋转左单旋右单旋左右正旋右左正旋中序遍历打印节点判断子树是否平衡整体代码验证代码红黑树概念性质&#xff08;规则&#xff09;红黑树的实现结点定义插入parent在grandparent的左情况一&#xff1a;u…

登录认证功能的统一拦截技术(拦截器)

目录 1.说明 2.使用方法 (1) 定义拦截器 (2)注册配置拦截器 (3)示例&#xff1a; 3.interceptor详细说明 (1)拦截路径 (2)执行流程 (3)过滤器和拦截器的区别 4.登录校验的拦截器实现 5.全局异常处理(补充说明) 1.说明 拦截器是一种动态拦截方法调用的机制&#xff0…

3年功能测试被辞,待业3个月,2023不会自动化测试真的找不到工作吗?

前言 来自一位粉丝的投稿&#xff0c;在测试行业已近打拼了3年&#xff0c;一直兢兢业业&#xff0c;前不久被公司以人员优化的理由辞退&#xff0c;到现在已近过去了3个月还没有找到测试工作&#xff0c;让她很焦虑&#xff0c;我通过和她的交流才发现她最大的问题就是技术方…

从零开始学习Python中UnitTest测试框架:实现高效自动化测试流程

目录&#xff1a;导读 引言 1.白盒测试原理 2.自动化测试用例编写 3.UnitTest测试框架 3.1UnitTest组件&#xff08;测试固件&#xff09; 3.1.2测试套件 3.1.3测试运行 3.1.4测试断言 3.1.5测试结果 3.2unittest测试固件的详解 3.2.1测试固件每次均执行 3.2.2测试…

【JavaEE】CAS机制(比较并交换)

哈喽&#xff0c;大家好~我是你们的老朋友保护小周ღ&#xff0c;本期为大家带来的是 CAS (compare and swap) 比较并交换&#xff0c;CAS 是物理层次支持程序的原子操作&#xff0c;CAS 是一种完全不同于 synchronized 锁保证多线程安全问题的机制&#xff0c;可以用来进行无锁…

Java基础——Stream流

&#xff08;1&#xff09;Stream流概述&#xff1a; 1.什么是Stream流&#xff1f; 用于简化集合和数组操作的API。结合了Lambda表达式。方便操作集合/数组的手段&#xff08;集合/数组才是开发的目的&#xff09;。2.体验Stream流的作用&#xff1a; import java.util.Arr…

高并发场景I/O优化

大家好&#xff0c;我是易安&#xff01; Java I/O是一个众所周知的概念。它常被用于读写文件、实现Socket信息传输等操作&#xff0c;这些都是系统中最常见的与I/O相关的任务。 我们都了解&#xff0c;I/O的速度相较于内存速度较慢。在当前大数据时代背景下&#xff0c;I/O性能…