前言

phaser作为一款流行的游戏/动画框架,受到很多web开发者的青睐,最近笔者在逛意大利开发者:emanueleferonato论坛的时候发现了这款小游戏,所以就照着说明做了一下,在这里记录下来.

开发准备

nodejs+npm
http-server插件
phaser脚本
飞刀和靶子的图像

或者

git clone https://github.com/YexChen/canvas_game.git

这个项目里面有phaser的脚本和需要的图像文件

开始制作

搭建基本的phaser项目

创建一个基本的html文件,引入phaser文件

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="js/phaser.js"></script>
</head>
<body><script></script>
</body>
</html>

别忘了在当前目录下启动http-server,启动服务器.打开localhost:8080(或其他端口)来查看项目

那么现在,我们需要干什么呢?
我们现在需要在页面加载时加载一个游戏实例,代码如下:

let game,knifeGroup
let gameConfig = {rotateSpeed : 5,throwSpeed : 150,minAngle : 10
}
window.onload = function(){game = new Phaser.Game({type: Phaser.CANVAS,width: 600,height: 700,backgroundColor: 0xdddddd,scene: [playGame]})
}

Phaser.Game 是phaser游戏的构建函数,定义了实例的类型,宽高,背景颜色,场景等信息,大家可以console.log(Phaser)看一下定义.
playGame是接下来的场景.
gameConfig 是游戏的参数,方便修改

接下来我们定义一下我们的场景:

class playGame extends Phaser.Scene{constructor(){super("playGame")}preload(){}create(){}update(){}}

场景在游戏中相当于戏曲中的每一幕,通过Phaser.Scene.start来进行调用.

在Phaser游戏中,场景创建时会先运行preload函数,用来预加载图片模型.然后运行create函数,执行初始化代码,最后在每一步中调用update函数更新

预加载图片

preload(){this.load.image("target","image/target.png")this.load.image("knife","image/knife.png")
}

在preload中加入以上代码,把图片注册进来.

加载物体

create(){this.target = this.add.image(game.config.width/2,game.config.height/5 *2,"target").setScale(0.5,0.5)this.target.depth = 1this.knife = this.add.image(game.config.width/2,game.config.height/5*4,"knife").setScale(0.5,0.5)this.knifeGroup = this.add.group()console.log(this)
}

this.add.image通过提供的宽高和上一步中提供的url来生成Image类型的对象(和原生的不一样!),
对象的原型链上的setScale(x,y)函数可以调整图像的缩放.
knifeGroup 是空的group对象,用来存放之后的飞刀集合

让我们的图像动起来

修改update函数:

update(){this.target.angle += gameOptions.rotateSpeed
}

好的,至此我们的项目基础就结束了,接下来来做飞刀的逻辑吧

扔飞刀逻辑

我们首先需要监听用户的鼠标事件,可以使用Phaser内置的函数来实现,在created中加入:

    this.canThrow = truethis.input.on("pointerdown",this.throwKnife,this)

throwKnife 是我们扔飞刀的处理函数,我们写在update后面:

throwKnife(){if(!this.canThrow){return}this.canThrow = falsethis.tweens.add({targets: [this.knife],y: this.target.y+this.knife.height/8 * 3,duration: gameOptions.throwSpeed,callbackScope: this,onComplete: function(tween){},})}

我们在用户按下鼠标左键时,检测是否可扔,如果可扔的话就让我们的飞刀做一个tweens动画,this.tweens是一个tweens管理器,官方文档比较残废,部分参数如下:

target : tweens动画目标
y : 目标的y坐标,
duration: 动画时间
callbackScope: 回调函数的this值
onComplete: 完成时的回调函数

飞刀插上去以后,我们要判断这个飞刀是不是和其它飞刀的重合,笔者这里的判断方式是在每一个飞刀插到盘面上时把当前轮盘的角度保存下来,当下一次投掷的时候判断当前盘面旋转度和以往的旋转度距离是否小于最小值,如果小于最小值就游戏结束,否则就插一次飞刀.

我们在上面的onComplete函数里面写下代码:

let isLegal = true
let children = this.knifeGroup.getChildren()
for(var i=0;i<children.length;i++){let child = children[i]if(Math.abs(Phaser.Math.Angle.ShortestBetween(this.target.angle,child.impactAngle))<gameOptions.minAngle){isLegal = falsebreak}
}
if(isLegal){this.canThrow =  truelet newKnife = this.add.image(this.target.x,this.target.y+this.knife.height/8 * 3,"knife").setScale(0.5,0.5)newKnife.impactAngle = this.target.anglethis.knifeGroup.add(newKnife)this.knife.y = game.config.height/5 * 4
}
else{this.tweens.add({targets: [this.knife],y: game.config.height+this.knife.height,rotation: 5,duration: gameOptions.throwSpeed*4,callbackScope: this,onComplete(tween){this.scene.start("playGame")}})
}

我们判断之前所有飞刀的impactAngle值,如果没有和当前角度相差10度的,我们就插入新的飞刀,否则播放动画以后重启游戏.

更新每一把飞刀的位置

好的,我们扔飞刀的逻辑已经完成了,接下来我们只需要遍历每一个knifeGroup里面的子飞刀的位置,并在update更新函数里面更新他们的位置,游戏就算做完了.
在update函数里面添加:

update(){this.target.angle += gameOptions.rotateSpeedlet children = this.knifeGroup.getChildren()for(var i=0;i< children.length;i++){let child = children[i]child.angle += gameOptions.rotateSpeedlet ang = Phaser.Math.DegToRad(child.angle)child.x = this.target.x - Math.sin(ang) * this.target.width/4child.y = this.target.y + Math.cos(ang) * this.target.width/4}}

我们在飞刀移动时计算每一步偏移的角度,从而判断出子飞刀child的x,y位移.

我们的小游戏就做完了,完整代码如下,顺便做了下记分牌:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><script src="js/phaser.js"></script>
</head>
<body><script>let game,knifeGroup,scoreText,scorelet gameOptions = {rotateSpeed : 5,throwSpeed : 150,minAngle : 10}window.onload = function(){game = new Phaser.Game({type: Phaser.CANVAS,width: 600,height: 700,backgroundColor: 0xdddddd,scene: [playGame]})}class playGame extends Phaser.Scene{constructor(){super("playGame")}preload(){this.load.image("target","image/target.png")this.load.image("knife","image/knife.png")}create(){this.target = this.add.image(game.config.width/2,game.config.height/5 *2,"target").setScale(0.5,0.5)this.target.depth = 1this.knife = this.add.image(game.config.width/2,game.config.height/5*4,"knife").setScale(0.5,0.5)this.knifeGroup = this.add.group()console.log(this)this.canThrow = truethis.input.on("pointerdown",this.throwKnife,this)score = 0scoreText = this.add.text(16,16,"score:0",{fontSize:"32px",fill:"#000"})}update(){this.target.angle += gameOptions.rotateSpeedlet children = this.knifeGroup.getChildren()for(var i=0;i< children.length;i++){let child = children[i]child.angle += gameOptions.rotateSpeedlet ang = Phaser.Math.DegToRad(child.angle)child.x = this.target.x - Math.sin(ang) * this.target.width/4child.y = this.target.y + Math.cos(ang) * this.target.width/4}}throwKnife(){if(!this.canThrow){return}this.canThrow = falsethis.tweens.add({targets: [this.knife],y: this.target.y+this.knife.height/8 * 3,duration: gameOptions.throwSpeed,callbackScope: this,onComplete: function(tween){let isLegal = truelet children = this.knifeGroup.getChildren()for(var i=0;i<children.length;i++){let child = children[i]if(Math.abs(Phaser.Math.Angle.ShortestBetween(this.target.angle,child.impactAngle))<gameOptions.minAngle){isLegal = falsebreak}}if(isLegal){this.canThrow =  truelet newKnife = this.add.image(this.target.x,this.target.y+this.knife.height/8 * 3,"knife").setScale(0.5,0.5)newKnife.impactAngle = this.target.anglethis.knifeGroup.add(newKnife)this.knife.y = game.config.height/5 * 4score += 100scoreText.setText("score:" +score)}else{this.tweens.add({targets: [this.knife],y: game.config.height+this.knife.height,rotation: 5,duration: gameOptions.throwSpeed*4,callbackScope: this,onComplete(tween){this.scene.start("playGame")}})}},})}}</script>
</body>
</html>

[phaser3学习]使用phaser3做一款飞刀小游戏相关推荐

  1. 初识cocos creator,做一款H5小游戏

    分享内容预览 小游戏体验. cocos creator 前世今生. 基本开发环境的了解. 小游戏场景制作相关知识. 基础语法讲析. sunlands-cow demo的讲解. 构建,发布.(h5, 微 ...

  2. unity的学习,准备搞一款mmo小游戏,服务器和客户端从零学

    先学一下unity,mmo服务器框架到时候在学习一下,暂时服务器简单做一下 unity中生命周期 如代码所示,简单了解一下. using System.Collections; using Syste ...

  3. 我的小白同事接触白鹭引擎4天,成功做了一款足球小游戏

    写在前面:我的同事"熊猫少女"刚刚入职白鹭,之前从未接触过白鹭引擎,也从未做过游戏,经过4天时间的学习,他成功做了一款足球小游戏,这篇文章主要是记录他的开发过程: 正文如下: 在接 ...

  4. 学习飞刀小游戏案例(cocos creator)

    学习飞刀小游戏案例(cocos creator) 首先,我们先进行布局,搭建好靶点与小刀节点,小刀位置(0,-300),靶点位置(0,300),小刀生成预制体,一会需要用到. [截图] 1.在onLo ...

  5. html小游戏代码_研发实践:Mozilla分享如何开发一款WebVR小游戏

    文章相关引用及参考:mozvr 本文来自Mozilla的Josh Marinacci (映维网 2019年02月06日)在倡导新技术时,我总是尝试采用现实世界开发者的方式,而对于WebVR,开发一款游 ...

  6. 计算机里没有四款小游戏,90后最爱玩的4款“4399”小游戏,一个都没玩过的太可怜!...

    原标题:90后最爱玩的4款"4399"小游戏,一个都没玩过的太可怜! 对于90后的小伙伴们来说,现在的很多东西都属于童年的回忆了,而在我们那个年代,电脑游戏还不是非常的盛行.正式流 ...

  7. 整理了30款Python小游戏附源码,五一有的玩了

    快到五一了,整理了 30 款 Python 小游戏源码分享给大家,具体内容可以点击下方视频号查看: 点击上方视频后,源码获取方式:①关注上方视频号.②点赞当前视频.③在当前视频评论区扣1 友情提示:获 ...

  8. python应用学习(六)——tkinter制作连连看小游戏

    python 制作连连看小游戏 前言 一.准备 二.游戏简单介绍 1.游戏规则 2.游戏设计所需的图片库: 三.游戏设计 I.创建Point点类 II.定义函数 III.游戏的主函数逻辑 IV.完整代 ...

  9. 两款在线小游戏-e梦迷宫、恐龙跳一跳

    简介: 一共两款在线小游戏-e梦迷宫.恐龙跳一跳 都是有趣的html小游戏源码 大多数完美的网站也都会有一个有趣404页面,所以这两款都可以做成404有趣的404页面哈 网盘下载地址: http:// ...

最新文章

  1. 类似QQ右上角选项弹框
  2. APP远程调试及网络自动化测试
  3. solver.prototxt参数说明(三)
  4. 央视曝光紫砂锅名单_大家看今天中午《每周质量报告》没,美的牌 紫砂锅含有剧毒。家里有这牌子...
  5. 并发编程实践之公平有界阻塞队列实现
  6. 华为上机试---购物单(算法:背包问题)
  7. 30岁+程序员职场攻略:找到自己的“职业锚”乘风破浪
  8. PyTorch 1.0 中文官方教程:PyTorch 介绍
  9. 点击area不出现黑框_一切小黑屋,都能被黑框玻璃门治愈 | 附安装法则
  10. 绑定事件和解绑事件的方法
  11. stm32采集交流电压信号_基于STM32的交流电压检测
  12. 神州微型计算机,神舟笔记本序列号查维修-怎样根据神舟笔记本电脑的序列号查询...
  13. Linux生成掩码的计算,谈子网掩码及其计算
  14. 三星堆的青铜机器人_三星堆“青铜大立人”,手里原来握的是什么东西,至今困扰考古界...
  15. PX4:【sensor_combined】
  16. 微型计算机硬件系统中PROM是,1微型计算机硬件系统中最核心的部件是CPU.doc
  17. forms 身份验证(授权)详解
  18. 从零开始学python第12天,每天至少半小时
  19. android 切凹凸图,Android实现边缘凹凸的View
  20. MATLAB牛拉法计算潮流,matlab潮流计算

热门文章

  1. mysql数据库服务器cpu_哪个用户正在占用MySQL数据库服务器的CPU?
  2. python爬取InterfaceLIFT壁纸,下载到本地,数据存入数据库(mysql,mongodb)
  3. python怎么找项目做小生意_三个投资小回报大的项目,让你没钱也能做买卖!
  4. matplotlib如何设置xlabel以及ylabel的位置和大小
  5. PPT视频自动播放?
  6. 基于RS和GIS的北京土地利用变化监测--笔记
  7. 2019 China Collegiate Programming Contest Qinhuangdao Onsite F. Forest Program
  8. go mod 删除包_迁移到 mod 只需 3 个步骤
  9. linux最新bbr加速,[centos]bbr加速网络
  10. Mac 下投屏软件Vysor安装及破解