PIXI 宝物猎人(7)
介绍 ,本实例来自官网
代码结构
打开 treasureHunter.html
文件,你将会看到所有的代码都在一个大的文件里。下面是一个关于如何组织所有代码的概览:
//Setup Pixi and load the texture atlas files - call the `setup` //function when they've loadedfunction setup() { //Initialize the game sprites, set the game `state` to `play` //and start the 'gameLoop' } function gameLoop(delta) { //Runs the current game `state` in a loop and renders the sprites } function play(delta) { //All the game logic goes here } function end() { //All the code that should run at the end of the game } //The game's helper functions: //`keyboard`, `hitTestRectangle`, `contain` and `randomInt`
把这个当作你游戏代码的蓝图,让我们看看每一部分是如何工作的。
创建游戏场景
setup
函数创建了两个被称为gameScene
和 gameOverScene
的 Container
分组。他们都被添加到了舞台上。
gameScene = new Container(); app.stage.addChild(gameScene); gameOverScene = new Container(); app.stage.addChild(gameOverScene);
尽管它是在 setup
函数中添加的,但是 gameOverScene
不应在游戏一开始的时候显示,所以它的 visible
属性被初始化为 false
。
gameOverScene.visible = false;
你会在后面看到,为了在游戏结束之后显示文字,当游戏结束gameOverScene
的 visible
属性会被设置为 true
。
制造泡泡怪们
六个泡泡怪是被循环创建的。每一个泡泡怪都被赋予了一个随机的初始位置和速度。每个泡泡怪的垂直速度都被交替的乘以 1
或者 -1
,这就是每个怪物和相邻的下一个怪物运动的方向都是相反的原因,每个被创建的怪物都被放进了一个名为 blobs
的数组。
let numberOfBlobs = 6,spacing = 48,xOffset = 150, speed = 2, direction = 1; //An array to store all the blob monsters blobs = []; //Make as many blobs as there are `numberOfBlobs` for (let i = 0; i < numberOfBlobs; i++) { //Make a blob let blob = new Sprite(id["blob.png"]); //Space each blob horizontally according to the `spacing` value. //`xOffset` determines the point from the left of the screen //at which the first blob should be added let x = spacing * i + xOffset; //Give the blob a random `y` position let y = randomInt(0, stage.height - blob.height); //Set the blob's position blob.x = x; blob.y = y; //Set the blob's vertical velocity. `direction` will be either `1` or //`-1`. `1` means the enemy will move down and `-1` means the blob will //move up. Multiplying `direction` by `speed` determines the blob's //vertical direction blob.vy = speed * direction; //Reverse the direction for the next blob direction *= -1; //Push the blob into the `blobs` array blobs.push(blob); //Add the blob to the `gameScene` gameScene.addChild(blob); }
制作血条
当你玩儿宝藏猎人的时候,你会发现当猎人碰到其中一个敌人时,场景右上角的血条宽度会减少。这个血条是如何被制作的?他就是两个相同的位置的重叠的矩形:一个黑色的矩形在下面,红色的上面。他们被分组到了一个单独的 healthBar
分组。 healthBar
然后被添加到 gameScene
并在舞台上被定位。
//Create the health bar healthBar = new PIXI.DisplayObjectContainer(); healthBar.position.set(stage.width - 170, 4) gameScene.addChild(healthBar); //Create the black background rectangle let innerBar = new PIXI.Graphics(); innerBar.beginFill(0x000000); innerBar.drawRect(0, 0, 128, 8); innerBar.endFill(); healthBar.addChild(innerBar); //Create the front red rectangle let outerBar = new PIXI.Graphics(); outerBar.beginFill(0xFF3300); outerBar.drawRect(0, 0, 128, 8); outerBar.endFill(); healthBar.addChild(outerBar); healthBar.outer = outerBar;
你会看到 healthBar
添加了一个名为 outer
的属性。它仅仅是引用了 outerBar
(红色的矩形)以便于过会儿能够被很方便的获取。
healthBar.outer = outerBar;
你可以不这么做,但是为什么不呢?这意味如果你想控制红色 outerBar
的宽度,你可以像这样顺畅的写如下代码:
healthBar.outer.width = 30;
这样的代码相当整齐而且可读性强,所以我们会一直保留它!
制作消息文字
当游戏结束的时候, “You won!” 或者 “You lost!” 的文字会显示出来。这使用文字纹理制作的,并添加到了 gameOverScene
。因为 gameOverScene
的 visible
属性设为了 false
,当游戏开始的时候,你看不到这些文字。这段代码来自 setup
函数,它创建了消息文字,而且被添加到了 gameOverScene
。
let style = new TextStyle({fontFamily: "Futura", fontSize: 64, fill: "white" }); message = new Text("The End!", style); message.x = 120; message.y = app.stage.height / 2 - 32; gameOverScene.addChild(message);
控制运动的范围
一个新的地方的是,探险者的运动是被包裹在地牢的墙体之内的。绿色的轮廓表明了探险者运动的边界。
通过一个名为 contain
的自定义函数可以帮助实现。
contain(explorer, {x: 28, y: 10, width: 488, height: 480});
contain
接收两个参数。第一个是你想控制的精灵。第二个是包含了 x
, y
, width
和height
属性的任何一个对象。在这个例子中,控制对象定义了一个区域,它稍微比舞台小了一点,和地牢的尺寸一样。
这里是实现了上述功能的 contain
函数。函数检查了精灵是否跨越了控制对象的边界。如果超出,代码会把精灵继续放在那个边界上。 contain
函数也返回了一个值可能为"top", "right", "bottom" 或者 "left" 的 collision
变量,取决于精灵碰到了哪一个边界。(如果精灵没有碰到任何边界,collision
将返回 undefined
。)
function contain(sprite, container) {let collision = undefined; //Left if (sprite.x < container.x) { sprite.x = container.x; collision = "left"; } //Top if (sprite.y < container.y) { sprite.y = container.y; collision = "top"; } //Right if (sprite.x + sprite.width > container.width) { sprite.x = container.width - sprite.width; collision = "right"; } //Bottom if (sprite.y + sprite.height > container.height) { sprite.y = container.height - sprite.height; collision = "bottom"; } //Return the `collision` value return collision; }
你会在接下来看到 collision
的返回值在代码里是如何让怪物在地牢的顶部和底部之间来回反弹的。
移动怪物
play
函数也能够移动怪物,保持它们在地牢的墙体之内,并检测每个怪物是否和玩家发生了碰撞。如果一只怪物撞到了地牢的顶部或者底部的墙,它就会被设置为反向运动。完成所有这些功能都是通过一个 forEach
循环,它每一帧都会遍历在 blobs
数组里的每一个怪物。
blobs.forEach(function(blob) {//Move the blob blob.y += blob.vy; //Check the blob's screen boundaries let blobHitsWall = contain(blob, {x: 28, y: 10, width: 488, height: 480}); //If the blob hits the top or bottom of the stage, reverse //its direction if (blobHitsWall === "top" || blobHitsWall === "bottom") { blob.vy *= -1; } //Test for a collision. If any of the enemies are touching //the explorer, set `explorerHit` to `true` if(hitTestRectangle(explorer, blob)) { explorerHit = true; } });
你可以在上面这段代码中看到, contain
函数的返回值是如何被用来让怪物在墙体之间来回反弹的。一个名为 blobHitsWall
的变量被用来捕获返回值:
let blobHitsWall = contain(blob, {x: 28, y: 10, width: 488, height: 480});
blobHitsWall
通常应该是 undefined
。但是如果怪物碰到了顶部的墙,blobHitsWall
将会变成 "top"。如果碰到了底部的墙,blobHitsWall
会变为 "bottom"。如果它们其中任何一种情况为 true,你就可以通过给怪物的速度取反来让它反向运动。这是实现它的代码:
if (blobHitsWall === "top" || blobHitsWall === "bottom") { blob.vy *= -1; }
把怪物的 vy
(垂直速度)乘以 -1
就会反转它的运动方向。
检测碰撞
在上面的循环代码里用了 hitTestRectangle
来指明是否有敌人碰到了猎人。
if(hitTestRectangle(explorer, blob)) {explorerHit = true; }
如果 hitTestRectangle
返回 true
,意味着发生了一次碰撞,名为 explorerHit
的变量被设置为了 true
。如果 explorerHit
为 true
, play 函数让猎人变为半透明,然后把 health
条减少1像素的宽度。
if(explorerHit) {//Make the explorer semi-transparentexplorer.alpha = 0.5; //Reduce the width of the health bar's inner rectangle by 1 pixel healthBar.outer.width -= 1; } else { //Make the explorer fully opaque (non-transparent) if it hasn't been hit explorer.alpha = 1; }
如果 explorerHit
是 false
,猎人的 alpha
属性将保持1,完全不透明。
这段代码实现了上述效果:
if (hitTestRectangle(explorer, treasure)) {treasure.x = explorer.x + 8; treasure.y = explorer.y + 8; }
转载于:https://www.cnblogs.com/congxueda/p/9388342.html
PIXI 宝物猎人(7)相关推荐
- js pixi框架 极其详细到位(入门)-----转载
pixi是一个js 的轻量级的游戏类库框架,很适用于做H5的一些canvas动画特效. 这篇文章是关于pixi的入门教程 ,里面的讲解非常的到位细致,是我看到过的文章里讲解的算是最好的了. 去年快过年 ...
- pixi.js # 中文版基础教程
本篇博客为转载文章,原文地址:https://github.com/Zainking/LearningPixi Pixi教程 基于官方教程翻译:水平有限,如有错误欢迎提PR,转载请注明出处.翻译者为h ...
- PIXI 下落文字消除(3)
图片示例,简陋的图,记录下落过程, 1.创建应用实例并添加到DOM元素上. (会看到一个黑色画布,没有任何元素,接下来会在画布上创建文字) 2.创建 TextStyle 用来设置要显示字体样式 3. ...
- sound.js # pixi辅助插件 — 中文翻译教程
本篇博客为中文翻译博客,转载请注明出处 sound.js-pixi的交互性插件[版本3.0.11] 安装配置 加载声音文件 初始化加载的声音 播放和控制加载的声音 更改回放速率 添加回声 添加混响 产 ...
- (原)用pixi.js 实现 方块阵点击后原地自转效果
源码 各位,请教一个问题,我这个还有BUG,我是想实现,点击一下可以 停止转动,然后再点一下重新转动.而不是一直加速,有没有什么好办法? PS:问题已经解决,谢谢评论的大神@Antineutrino ...
- html设置自定义光标,pixi.js 自定义光标样式
pixi 介绍 Pixi是一个超快的2D渲染引擎,通过Javascript和Html技术创建动画或管理交互式图像,从而制作游戏或应用. 游戏中都会做一些跟整个游戏画面风格相符的定制光标,比如英雄联盟中 ...
- PIXI.JS兼容微信小游戏
来自:PIXI兼容微信小游戏 - 天之道利而不害 - 博客园 PIXI兼容微信小游戏 首先导入官方的weapp-adapter,然后导入pixi.min.js,微信小程序使用ES6的module引用模 ...
- 数独动态解题演示小网站 - 基于Vue/pixi.js/Flask
解数独不难,但如果能动态演示解题步骤就更好了. 参考:最难数独的快速解法 - python https://www.jianshu.com/p/1b2ee6539d4b 功能 读取公开网站的数独题目 ...
- pixi 小游戏_手把手教你制作一款小游戏【超好玩!】
想必大家小时候都听说过或玩过4399小游戏(这句话好像暴露了年龄),在当时电脑不算很普及,且没有那么多网游.大型单机游戏的时代,数量众多且种类丰富的网页小游戏使我们的童年增添了非常多的乐趣.诸如黄金矿 ...
- WebGis——Pixi开发vue项目之创建pixi应用并显示一个精灵(一)
Pixi中文网:Pixi.js中文网 使用vue-cli初始化一个vue项目我就不多说了,在我的这边文章里已经写过: 从零开始vue项目使用cesium开发三维地图(一)_yinzisang的博客-C ...
最新文章
- numpy使用[]语法索引二维numpy数组中指定行列位置的数值内容(access value at certain row and column in numpy array)
- ubuntu14.04.5装cuda7.5记录(解决unable to locate the kernel source,装cuda黑屏问题,装cuda循环登录问题)
- 宿松长铺程集高中2021年高考成绩查询,2017宿松程集中学录取分数线(附2017高考成绩喜报)...
- java 的序列化和反序列化的问题
- Python 技术篇-1行代码实现语音识别,speech库快速实现简单的语音对话
- 短视频Gif快手-有点意思 | 手摸手产品研究院
- Debug docker: docker: Error response from daemon: could not select device driver ““ with capabilitie
- 实录 | 平安人寿资深算法工程师姚晓远:对话生成模型的探析与创新
- hell 12 21 filename重定向的含义和区别
- js时间搓化为今天明天_秋冬国产搓背神器!360°无死角,让你搓背不求人,太舒服了...
- Redis——史上最强【集群】入门实践教程
- linux mint php mysql_linux mint 下mysql中文支持问题
- ACM-ICPC 2018 南京赛区网络预赛 B. The writing on the wall
- java版mc植物生长条件_植物生长三大必要条件
- wire routing 网格寻址
- SKNode的子类和常用的Action
- java推箱子游戏源代码_java实现推箱子小游戏(附源码)
- MCE | 线粒体和能量代谢的关系
- MediCool天使投资计划
- [实用代码] 基于CH554电容触摸屏IIC转USB转IIC方案代码分享
热门文章
- TGA格式图像文件分析
- 计算机毕业设计 SSM健康知识信息平台 健康自检平台 健康体检管理系统Java
- fastdfs上传图片成功,用内网下载失败(超时、404)
- 201771010112罗松《面向对象程序设计(java)》第十二周学习总结
- C++编程第一步:判断一个数字是不是整数
- react 类暴露_React 组件暴露自身 API 的方法
- python——字符串
- 中小企业OA系统视频教程(更新程度:完毕)送ppt源码
- Innovator Admin 一个aras的管理器,又一个package安装方法
- 一只青蛙跳向三个台阶_青蛙跳台阶-递归思想解算