基于Cocos的猫狗大战
猫狗大战
- 游戏类型:塔防游戏
- 标签:卡通、休闲、2D、塔防、闯关
- 引擎:Cocos Creator
- 语言:JS
- 作者:未生畏死
- 注:美术资源来源于网络
游戏玩法:
一共有两种玩法。其一:在怪物到达堡垒前杀死它,否则堡垒会扣一点血。怪物消失。其二:怪物会沿着路循环移动,请在规定时间内杀死所有怪物。
场景描述
一共三个场景。
- Main:主场景,可开始、退出游戏。
- Opt:选择场景。可进行选关操作,返回Main场景。
- Pass1:游戏场景。加载对应关卡数据,生成对应物体,开始PLAY。
功能描述:
- 猫:堡垒。10hp。每有一只AI到达猫的位置时,hp-1。hp<=0时。游戏失败。循环关卡则hp恒定。技能:尖叫。消灭自身一定范围内的AI。
- 狗:出生点。所有AI的生成位置。
- AI:沿着路径移动,到达猫的位置时如果是普通关卡。猫hp-1,AI销毁。如果是循环关卡,则沿着路径继续移动。
- 炮台:炮台最高三级,每升一级会获得一定的属性提升。炮台会自动攻击在自己攻击范围内的敌人。可进行操作:创建、升级、售卖。
- 障碍物:占据地图位置的东西,拥有一定hp。只有将其清除后,才能使用其对应的格子进行炮台的创建等操作。消灭后,你会获得一定金币。
- 金币:你会获得一定的初始金币来进行炮台的创建、升级。消灭AI和障碍物是金币的来源。
- 标志物。你可以标记障碍物、使AI优先攻击他们。
- 等等…
具体功能实现:
地图生成。加载关卡数据,生成对应地图、猫、狗等。
this.PlayPass = cc.sys.localStorage.getItem("PlayPass")
this.PlayPass = 1
window.stageMission = window.mission[this.PlayPass]
// cc.log(this.PlayPass)
this.missionLoad()//任务信息加载
cc.loader.loadRes("tilemaps/stage-" + this.PlayPass, (err, tiled) => {
if (!err) {
cc.director.emit("levelUi", this.PlayPass)
this.titledMap.getComponent(cc.TiledMap).tmxAsset = tiled
// cc.log(tiled)
// cc.log(this.titledMap.getComponent(cc.TiledMap))
this.init()
}
})
- TiledMap数据解析
initData() {
this.mapSize = this.titledMap.getMapSize();
this.tileSize = this.titledMap.getTileSize();
this.road = this.titledMap.getLayer("road");
this.object = this.titledMap.getLayer("object");
this.tower = this.titledMap.getLayer("tower");
this.path = this.titledMap.getLayer("path");
this.obj = this.titledMap.getObjectGroup("obj");
this.tiledLayer = this.path
this.path.node.opacity = 0
this.life = this.obj.getObject("life");//线段路径层处理
this.chestpath = this.obj.getObject("chestpath");
this.pathline = this.obj.getObject("pathline");
this.end = this.obj.getObject("end");
this.aistart = this.obj.getObject("start");
// cc.log(this.life)
// cc.log(this.pathline)
this.pointArr = this.pathline.polylinePoints
for (let i = 0; i < this.pointArr.length; i++) {
this.pointArr[i] = cc.v2(this.pathline.x + this.pointArr[i].x, this.pathline.y - this.pointArr[i].y)
}
// uiBase: cc.Node,//猫、狗、生命值
// cc.director.emit("uibase", this.aistart, this.end, this.life)
cc.log("uibase")
this.uiBase.getComponent("Life").init(this.aistart, this.end, this.pointArr[0], this.life, window.stageMission.Hp)
cc.director.emit("coinDeal", window.stageMission.Money)
// this.scheduleOnce(()=>{
// cc.director.emit("settleSysyem")
// },6)
},
- TiledMap数据处理
initKu() {
// cc.log(it)
// cc.log(this.pointArr)
for (let i = 0; i < this.mapSize.width; i++) {
this.ku[i] = {}
for (let j = 0; j < this.mapSize.height; j++) {
this.ku[i][j] = {}
let gidPath = this.path.getTileGIDAt(i, j);//可走路径处理
// let tilePath = this.path.getTiledTileAt(i, j, true);
let cfgPath = this.titledMap.getPropertiesForGID(gidPath)
// cc.log(cfgPath)
if (cfgPath) {
this.ku[i][j].path = cfgPath.touchable//0红 1 绿2黄
}
// cc.log(this.object)
let gidObject = this.object.getTileGIDAt(i, j);//道具处理
if (gidObject) {
let tileObject = this.object.getTiledTileAt(i, j, true);
let cfgObject = this.titledMap.getPropertiesForGID(gidObject)
if (cfgObject) {
this.ku[i][j].tileObject = tileObject
this.ku[i][j].tileObject.node.tipsPos = cc.v2()
this.ku[i][j].tileObject.object = cfgObject
this.ku[i][j].tileObject.node.row = i
this.ku[i][j].tileObject.node.col = j
this.ku[i][j].tileObject.addComponent("Hinder")
}
}
// cc.log(this.tower)
if (this.tower == null) {
continue
}
let gidTower = this.tower.getTileGIDAt(i, j);//炮台处理
if (gidTower) {
let tileTower = this.tower.getTiledTileAt(i, j, true);
let cfgTower = this.titledMap.getPropertiesForGID(gidTower)
// cc.log("log:", cfgTower)
if (cfgTower) {
let it = cc.instantiate(this.towerPrefab)
it.x = tileTower.node.x + this.tileSize.width / 2
it.y = tileTower.node.y + this.tileSize.height / 2
it.parent = this.towerParent
it.cfg = cfgTower
// cc.log("cfgTower", cfgTower)
it.addComponent("TowerSet").init()
this.ku[i][j].tileTower = it
if (this.ku[i][j] == 1) {
this.ku[i][j].path = 5//是炮台 和障碍物的重合
}
else {
this.ku[i][j].path = 3//是炮台
}
}
}
}
}
if (this.tower == null) {
return
}
this.tower.node.destroy()
},
炮台。 根据具体id生成指定类型炮台
// Learn cc.Class:
// - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/class.html
// - [English] http://docs.cocos2d-x.org/creator/manual/en/scripting/class.html
// Learn Attribute:
// - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/reference/attributes.html
// - [English] http://docs.cocos2d-x.org/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
// - [Chinese] https://docs.cocos.com/creator/manual/zh/scripting/life-cycle-callbacks.html
// - [English] https://www.cocos2d-x.org/docs/creator/manual/en/scripting/life-cycle-callbacks.html
cc.Class({
extends: cc.Component,
properties: {
},
start() {
// this.myTower = null//炮台节点
// this.towerMold = 1//炮台模型
// this.loadTower() //加载炮台
// this.towerCreste()//生成炮台
// cc.log()
},
init(buildType) {//有参数的指定炮台
if (buildType) {
this.buildType = window.towerBuildTypeJson[buildType]
for (let i = 0; i < window.towerJson.length; i++) {
if (window.towerJson[i].Index == this.buildType.TowerBaseIndex) {
// this.towerData = window.towerJson[i]
this.towerIndex = i
this.Level = 1
cc.log(11)
}
}
this.towerCreste()//生成炮台
}
else {
cc.log("我没有")
this.loadTower() //加载炮台
// this.towerCreste()//生成炮台
}
},
loadTower() {//加载炮台数据
this.json = window.towerJson
// cc.log(this.json)
for (let i = 0; i < this.json.length; i++) {
let cfg = this.json[i]
if (cfg.Type == this.node.cfg.towertype && cfg.Level == this.node.cfg.towerlevel) {
// this.towerData = cfg//炮台数据
this.towerIndex = i
this.Level = cfg.Level
this.mapTowerCreate()//地图固定炮台生成
return
}
}
},
mapTowerCreate() {//地图固定炮台生成
let index = window.towerJson[this.towerIndex].Index - this.Level + 1
cc.log("inde:", index)
let buildTypeCfg = window.towerBuildTypeJson
for (let i = 0; i < buildTypeCfg.length; i++) {
this.buildType = buildTypeCfg[i]
if (this.buildType.TowerBaseIndex == index) {
let node = new cc.Node("myTower")
node.parent = this.node
node.group = "tower"//炮台
let it
if (this.buildType.ScriptName == "") {
it = node.addComponent("BottleTower")
} else {
it = node.addComponent(this.buildType.ScriptName)
}
it.towerData = window.towerJson[this.towerIndex]
it.init()
this.myTower = node
cc.log(it)
cc.log("我over")
return
}
}
},
towerCreste() {//更据图标生成炮台
let node = new cc.Node("myTower")
node.parent = this.node
node.group = "tower"//炮台
let it
if (this.buildType.ScriptName == "") {
it = node.addComponent("BottleTower")
} else {
it = node.addComponent(this.buildType.ScriptName)
}
it.towerData = window.towerJson[this.towerIndex]
it.init()
this.myTower = node
},
upGradeTower() {//升级炮台
this.towerIndex = this.towerIndex + 1
this.Level = this.Level + 1
// for (let i = 0; i < this.json.length; i++) {
// let cfg = this.json[i]
// if (cfg.Index == this.towerMold) {
// this.towerData = cfg
// // cc.log("hah")
// // cc.log(this.towerData)
// break
// }
// }
this.myTower.destroy()
this.myTower = null
this.towerCreste()//生成炮台
}
});
炮台的攻击列表
- 进入可攻击列表
onCollisionEnter: function (other, self) {
if (other.node.group == "ai") { //可攻击列表
this.attList[this.attList.length] = other.node
// cc.log(this.attList)
}
},
- 退出可攻击列表
onCollisionExit: function (other, self) {
for (let i = 0; i < this.attList.length; i++) {
if (this.attList[i] == other.node) {
this.attList.splice(i, 1)
// cc.log(this.attList)
return
}
}
},
- 攻击逻辑
lateUpdate() {
if (this.isInit) {
this.haveTarget() //查询是否有攻击物
}
this.waitTime = this.waitTime - 1 / 60
if (this.myTarget) {//有攻击目标
this.attackDeal() //攻击处理
// cc.log("旋转")
}
},
AI
- AI逻辑
update() {
if (this.isInit == true) {
if (this.isWait == false) {
this.moveAi() //ai移动
}
this.barLength.progress = this.node.hp / this.hpMax
if (this.node.hp < this.hpMax) {
this.hpBar.active = true
}
}
if (this.node.hp <= 0) {
this.scheduleOnce(() => {
cc.director.emit("aiOver")
cc.director.emit("coinDeal", 1)
cc.director.emit("TheExplode", this.node, "monsterexplode-", 4)
this.node.destroy()
}, 0)
}
},
- 加载AI信息
loadAni() {//加载ai信息
for (let i = 0; i < window.monsterJson.length; i++) {
// cc.log(i)
if (window.monsterJson[i].Index == this.index) {
this.aiData = window.monsterJson[i]
// cc.log(this.aiData)
this.addAni()
// this.moveAi() //ai移动
return
}
}
},
- AI移动
moveAi() {//ai移动
// cc.log(this.node.position, this.pointArr[this.moveIndex])
if (this.moveIndex == this.pointArr.length) {
// cc.log(this.life)
if (this.life == null) {
this.moveIndex = 0
}
else {
cc.director.emit("catHp")
this.node.destroy()
}
return
}
let pointB = this.pointArr[this.moveIndex]
// cc.log(pointB)
let fixedX = pointB.x - this.pointA.x
let fixedY = pointB.y - this.pointA.y
let fixedDis = cc.v2(fixedX, fixedY).mag()
let isx = this.pointA.x - this.node.x
let isy = this.pointA.y - this.node.y
let dis = cc.v2(isx, isy).mag()
// cc.log(this)
// cc.log("fixedDis", fixedDis)
if (dis < fixedDis) {
// cc.log(this.node.x, this.node.y)
let unit = cc.v2(fixedX, fixedY).normalizeSelf()
// cc.log("unit", unit)
this.node.x = this.node.x + unit.x * this.speed
this.node.y = this.node.y + unit.y * this.speed
// cc.log("==",this.x, this.y)
}
else {
this.moveIndex++
this.pointA = JSON.parse(JSON.stringify(this.node.position))
// this.pointA.x = this.x
// this.pointA.y = this.y
}
},
- 加载AI血条
loadHpBar() {//加载血条
this.hpBar = cc.instantiate(window.hpPrefab)
this.barLength = this.hpBar.getComponent(cc.ProgressBar)
// cc.log(this.barLength)
this.hpBar.parent = this.node
this.hpBar.active = true
this.hpBar.width = this.node.width
this.hpBar.x = 0
this.hpBar.y = -this.node.height / 2
this.hpBar.getComponent(cc.ProgressBar).totalLength = this.node.width
this.hpBar.getChildByName("bar").x = -this.node.width / 2
// cc.log(this)
},
- 加载AI动画。碰撞体等信息
addAni() {
let sp = this.node.addComponent(cc.Sprite);
let animation = this.node.addComponent(cc.Animation);
let collider = this.node.addComponent(cc.BoxCollider)
this.node.group = "ai"
let frames = [];
let name = this.aiData.Name
for (let i = 1; i < this.aiData.Frames + 1; i++) {
let itname = name + "-" + i
// cc.log(itname)
frames[i - 1] = sp.spriteFrame = window.monsterPic.getSpriteFrame(itname)
collider.size.width = this.node.width
collider.size.height = this.node.height
}
this.loadHpBar()//加载血条
let clip = cc.AnimationClip.createWithSpriteFrames(frames, 5);
clip.name = this.aiData.Name;
clip.wrapMode = cc.WrapMode.Loop;
// cc.log(clip)
animation.addClip(clip);
animation.play(clip.name)
},
源码
码云源码
基于Cocos的猫狗大战相关推荐
- cocos creator 方法数组_基于 Cocos 游戏引擎的音视频研发探索
本文转载自公众号:流利说技术团队(lls_tech) 版权归原作者所有 本文主要介绍了流利说团队基于 Cocos 游戏引擎进行音视频相关需求开发过程中所遇到的问题和解决方案.文章中将依次阐述 Coco ...
- 基于Cocos Creator的水果忍者游戏
基于cocos creater的水果忍者游戏 项目介绍 主界面 游戏界面 游戏详情界面 水果运动界面 刀片切割界面 游戏结束界面 下载方式 项目介绍 互联网技术不断革新,用户对于应用的要求在不断提高, ...
- 一款非常好玩的小程序游戏推荐给大家,基于cocos creator引擎开发的
一款非常好玩的小程序游戏推荐给大家,基于cocos creator引擎开发的,排名包含微信好友排行榜,全球榜,快邀请好友,一起来玩吧.
- 基于Cocos Studio和BMfont制作艺术字体
通常在游戏开发制作的过程中,我们常常要用到各式各样的艺术字体,适合游戏风格的.独特的艺术字体能让游戏看起来更加美观.更加生动活泼.但问题是很多新手并不知道这些字体是怎么来的,这篇文章主要讲一下如何基于 ...
- 基于Keras实现猫狗大战,25000张猫狗图像的精准分类
文章目录 1. 建立简单版CNN网络模型 1.1 将下载好的文件分为训练集.测试集.验证集. 1.2 构建神经网络 1.3 数据预处理 1.4 绘制训练过程中的损失曲线和精度曲线 2. 使用数据增强 ...
- Cocos 篇:基于 Cocos Creator v1.9,开始 Hello World 。。。
前言 身体好,才是真的好~ 从此之后,要会生活,努力活出自己想要的样子~!!! Enmmm,LZ 也是小白一枚,初入贵行,还望手下留情~ 本篇主要作用,或者说定位在于和 LZ 一样得小白,希望多多交流 ...
- 基于Cocos creator 实现坦克大战小游戏【100010131】
疯狂坦克 引言 坦克大战是一款曾经风靡一时的小游戏,本次的实训,就是要力图让经典历久弥新.因此在老师的帮助下,我们将尽力开发一款在原有基础上有突破的"疯狂坦克2",加入新的元素,融 ...
- 深度学习之基于AlexNet实现猫狗大战
这次实验的主角并不是猫狗大战,而是AlexNet网络,只不过数据集为猫狗大战数据集.本次实验利用自己搭建的AlexNet网络实现猫狗大战,测试一下AlexNet网络的性能. AlexNet网络作为Le ...
- 03_基于CNN的猫狗大战实现
文章目录 猫狗大战背景介绍 代码示例 step1 对模型的修改 step2 数据的输入 step3 模型的重新训练与存储 step4 模型的复用 猫狗大战背景介绍 猫狗大战数据集来源于Kaggle上的 ...
最新文章
- DNS 到底怎么工作的? (How does dns work?)
- VBA学习笔记(一):自动添加代码VBA修改注册表
- 【C语言简单说】十二:逻辑运算符
- Java并发编程实战~Copy-on-Write模式
- 字节数组和字符串的相互转化……
- 云栖独栋别墅_云栖没有玫瑰
- 剑指offer(C++)-JZ52:两个链表的第一个公共结点(数据结构-链表)
- 正确理解TensorFlow中的logits
- 客户答谢晚宴策划案例合集(共20份)
- Photon与Unity核心技术之角色更换武器
- android简单视频播放器,推荐用于Android超简单视频播放器的ArtPlayer
- iOS苹方字体使用说明
- python调用小票打印机_PyQt5中使用Qprinter打印热敏小票
- 税务总局:今年预计减税1.8万亿元!个体户能享受哪些税收优惠?
- 老卫带你学---使用cv2.imwrite保存的图像是全黑的
- Dart —— 函数 函数参数 匿名函数
- 鸿蒙系统暗黑2,《暗黑破坏神-不朽》究竟有那些改变?手游堪比3A大作
- 设置MySQL复制时,replicate-ignore-db模式下如何正常工作
- 数据库:简述对关系型数据库(RDBMS)的认识
- __attribute__的使用
热门文章
- 练习八:利用有限状态机进行时序逻辑的设计
- 每日一题之Vue数据劫持原理是什么?
- 通过BACnet物联网关实现楼宇自动化的物联网解决方案
- 深度剖析互联网金融的系统逻辑
- 充电池中热敏电阻作用
- 多媒体计算机室管理制度,教室多媒体使用管理制度
- 集合竞价如何买入_如何在集合竞价买卖股票
- 对某班学生成绩排序。从键盘依次输入某班学生的姓名和成绩(一个班级人数最多不超过50人)并保存,然后分别按学生成绩由高到低顺序输出学生姓名和成绩,成绩相同时,则按输入次序排序。
- html 源码_HTML实例之搜索栏(附源码)
- 2022-2028年中国循环经济产业深度调研及投资前景预测报告