视频操作地址:https://www.bilibili.com/video/BV1NN4y1V7Jy/?vd_source=0a0b591838e1a4cda6ec55da0e1c9019
源码地址:https://gitee.com/OnlyOneW/cocos-study/tree/master/cocos-cow
cococs官方脚本指南
已安装Cocos Creator 3.5.2
在资源管理器中新建文件夹用来保存对应的资源
会提供资源文件:res下的res-cow
竖屏 (适配屏幕高度):640*960,2D对象,sprite(精灵):spt_bgUI组件,Button(按钮):btn_capture拖到层级管理器spt_bg下,重命名为:cow在framework新建TypeScript,命名:CowSkin
import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;
@ccclass('CowSkin')
export class CowSkin {
@property(cc.SpriteFrame)
public cows : [cc.SpriteFrame] = [];
}
在scripts新建TypeScript,命名:cow
2. 牛的类型数组
import { CowSkin } from '../framework/CowSkin';
@property(CowSkin)
public cow_sets : [CowSkin] = [];
private _intervalTime = 0;
private _randomType = Math.floor(Math.random()*3);
update(deltaTime: number) {
let dt = deltaTime ;
// 间隔时间
this._intervalTime += dt;
let index = Math.floor(this._intervalTime / 0.2);
index = index%3;
// 获取一种牛的类型
let cowSet = this.cow_sets[this._randomType];
// 获取精灵组件
let sprite = this.node.getComponent(cc.Sprite);
sprite.spriteFrame = cowSet.cows[index];
}
在clips 文件夹下新建动画剪辑:runClip,层级管理器,选中cow,选择动画编辑器,关联新建的runClip文件,编辑动画,设置播放模式,加入尾帧事件,runCallback
cow.ts加入下面函数:
runCallback() {
cc.log("一个轮回结束!");
this._randomType = Math.floor(Math.random()*3);
}
选择Play on load
保存
退出动画编辑
层级管理器,选中cow,关联cow.ts,设置参数,并按顺序拖入图片
把cow节点拖到prefabs文件夹下,删除cow节点,把cow预制节点,拖到spt_bg下
选择Play on load
至此随机不同种的牛奔跑,已实现
新建game.ts当做全局脚本文件,挂载到Canvas下
拖动套绳图片:rope,至背景图片spt_bg下,默认不显示
选中,选矩形变化,移至牛头下,用于方便判断牛头是否套住,删除原来的cow,重新拖一下
@property(cc.Node)
public rope_node : cc.Node = null;
@property(cc.Node)
public cow_ins : cc.Node =null;
@property(cc.SpriteFrame)
public rope_imgs : [cc.SpriteFrame] = [];
@property(cc.Prefab)
public cow_prefab : cc.Prefab = null;
@property
public time = 0;
private _mainScene = 'Main';
并在Canvas里绑定
保存
注:此处容易忽略初始化绑定
start() {
let btn_capture_node = cc.find("Canvas/spt_bg/btn_capture");
btn_capture_node.on(NodeEventType.TOUCH_START, this._touchStart_btn_capture, this);
}
并定义
_touchStart_btn_capture (touch: Touch, event: EventTouch) {
}
具体请见最后
分数显示
在spt_bg下,新建2D对象,Label(文本):lb_score,来显示得分
设置初始值 : Score:0
设置大小 : 50
拖动到合适位置
倒计时
在spt_bg下,新建2D对象,Label(文本):lb_count_down,来显示倒计时
设置初始参数:60s
设置大小 : 50
并添加位图字体样式和字体颜色:#EB78E6
拖动到合适位置
去掉勾选:UseSystemFont
拖入已备好的字体资源,至Font
此步片段代码可忽略,直接查看总代码
start () {
// 定义初始化得分为0
this.scoreNum = 0;
}
// 捕捉成功,分数+1
this.scoreNum++;
let lb_score = cc.find("Canvas/spt_bg/lb_score").getComponent(cc.Label);
lb_score.string = "Score: " + this.scoreNum;
start () {
// 获得计时器组件
let countDownLabel = cc.find("Canvas/spt_bg/lb_count_down").getComponent(cc.Label);
let time = 60;
// 倒计时
this.schedule(function () {
time--;
countDownLabel.string = "Time: " + time + " s";
},1);
},
import { AudioSource, assert} from 'cc';
在Canvas里,添加组件 按钮,选择 Audio -> AudioSource
设置文件
设置播放方式
@property(cc.AudioClip)
public audio_clip : cc.AudioClip = null;
@property(AudioSource)
public audioSource: AudioSource = null!;
在Canvas里绑定属性 audio_clip
start() {
// 获取 AudioSource 组件
const audioSource_set = this.node.getComponent(AudioSource)!;
// 检查是否含有 AudioSource,如果没有,则输出错误消息
assert(audioSource_set);
// 将组件赋到全局变量 audioSource 中
this.audioSource = audioSource_set;
}
// 音效
this.audioSource.playOneShot(this.audio_clip, 1);
import { ParticleSystem2D} from 'cc';
在rope下,新建2D对象,ParticleSystem2D(粒子):pc2d_fireworks
不勾选 PlayOnLoad
勾选 Custom
设置 SpriteFrame
套中牛,显示粒子效果
// 粒子
let pc2d_fireworksNode = cc.find("Canvas/spt_bg/rope/pc2d_fireworks");
this.fireworks = pc2d_fireworksNode.getComponent(ParticleSystem2D)
this.fireworks.resetSystem()
倒计时为0时游戏结束,并根据玩家的最终得分显示成就;比如小于等于3分就是套牛青铜,大于三分小于6分就是套牛高手,大于6分以上就是套牛王者。
包含一个关闭按钮,标题和称号。
spt_result
Canvas下,新建2D对象,sprite(精灵):spt_result
设置背景图、尺寸、九宫格(Sliced)模式,
(九宫格编辑得选中图片去编辑)
默认不显示
close
拖入关闭按钮至spt_result 背景下,,命名为close
调整参数
调整位置:182 182
lb_title
在spt_result下,新建2D对象,Label(文本):lb_title,来显示等级
设置初始参数:60 #252323
调整位置
lb_content
在spt_result下,新建2D对象,Label(文本):lb_content,来显示分数
设置初始参数:80 #252323
调整位置
import { _decorator, Component, Node ,Vec3 , NodeEventType,Tween, AudioSource, assert,ParticleSystem2D} from 'cc';
_touchStart_btn_capture (touch: Touch, event: EventTouch) {
let bgNode = touch.currentTarget._parent;
let currentTarget = touch.currentTarget;
this.rope_node.active = true;
// 设置绳子在当前父节点的顺序
this.rope_node.setSiblingIndex(100);
let rope_node_p = this.rope_node.getPosition();
let rope_node_y_start = - 600 ;
let rope_node_y_up = 115 ;
let rope_node_y_down = -600 ;
// 设置绳子起始位置
this.rope_node.setPosition(rope_node_p.x,rope_node_y_start);
rope_node_p = this.rope_node.getPosition();
let that = this ;
let tao_num: number = 100;
let tween_node :cc.Node = this.rope_node ;
let tweenDuration: number = 0.5;
let t1 = cc.tween(tween_node)
.to(tweenDuration, { position: new Vec3(rope_node_p.x,rope_node_y_up,0) }
,{
onUpdate:(target:Vec3, ratio:number)=>{
this.rope_node = target;
}
}
)
// to 动作完成后会调用该方法
.call( ()=>{
// 获取当前牛儿的x点
let cow_ins_p = that.cow_ins.getPosition()
let currentX = cow_ins_p.x;
if (currentX > -tao_num && currentX < tao_num){
cc.log("捕捉成功!");
// 音效
this.audioSource.playOneShot(this.audio_clip, 1);
// 粒子
let pc2d_fireworksNode = cc.find("Canvas/spt_bg/rope/pc2d_fireworks");
this.fireworks = pc2d_fireworksNode.getComponent(ParticleSystem2D)
this.fireworks.resetSystem()
// 移除
bgNode.removeChild(that.cow_ins);
// 获取牛儿的类型
let cowType = that.cow_ins.getComponent("cow")
let ropeType = cowType._randomType +1;
that.rope_node.getComponent(cc.Sprite).spriteFrame = that.rope_imgs[ropeType];
// 生成新的牛节点
that.cow_ins = cc.instantiate(that.cow_prefab);
that.cow_ins.setPosition(cow_ins_p.x,0);
bgNode.addChild(that.cow_ins);
//
that.success = true;
// 分数+1
that.scoreNum ++;
} else {
cc.log("捕捉失败!")
}
})
let t2 = cc.tween(tween_node)
.to(tweenDuration, { position: new Vec3(rope_node_p.x,rope_node_y_down,0) }
,{
onUpdate:(target:Vec3, ratio:number)=>{
this.rope_node = target;
}
}
)
// to 动作完成后会调用该方法
.call( ()=>{
that.rope_node.getComponent(cc.Sprite).spriteFrame = that.rope_imgs[0];
// 判断是否捕捉成功
if (that.success == true) {
let scoreLabel = cc.find("Canvas/spt_bg/lb_score").getComponent(cc.Label);
scoreLabel.string = "Score:" + that.scoreNum;
that.success = false;
}
})
cc.tween(tween_node).sequence(t1, t2).start(); // 将 t1 和 t2 两个缓动加入到新的缓动队列内
}
start() {
// 获取 AudioSource 组件
const audioSource_set = this.node.getComponent(AudioSource)!;
// 检查是否含有 AudioSource,如果没有,则输出错误消息
assert(audioSource_set);
// 将组件赋到全局变量 audioSource 中
this.audioSource = audioSource_set;
let btn_capture_node = cc.find("Canvas/spt_bg/btn_capture");
btn_capture_node.on(NodeEventType.TOUCH_START, this._touchStart_btn_capture, this);
this.success = false;
// 初始分数
this.scoreNum = 0;
let countDownLabel = cc.find("Canvas/spt_bg/lb_count_down").getComponent(cc.Label);
countDownLabel.string = this.time + "s";
this.schedule(function () {
this.time --;
countDownLabel.string = this.time + "s";
if (this.time == 0) {
cc.log("游戏结束!");
// 获取弹窗节点
let resultNode = cc.find("Canvas/spt_result");
//绑定关闭事件
let closeNode = cc.find("Canvas/spt_result/close");
closeNode.on(NodeEventType.TOUCH_START, this._touchStart_close, this);
// 获取title和content两个节点
let titleNode = resultNode.getChildByName("lb_title");
let contentNode = resultNode.getChildByName("lb_content");
// 展示分数
titleNode.getComponent(cc.Label).string = "最终得分 " + this.scoreNum;
// 获取组件
let contentLabel = contentNode.getComponent(cc.Label);
switch (true) {
case this.scoreNum <= 3:
contentLabel.string = "套牛新手";
break;
case this.scoreNum < 6:
contentLabel.string = "套牛神手";
break;
case this.scoreNum >= 6:
contentLabel.string = "套牛圣手";
break;
}
resultNode.active = true;
let score = this.scoreNum;
cc.director.pause();
}
},1);
}
// 关闭按钮,继续游戏
_touchStart_close(touch: Touch, event: EventTouch) {
cc.log("继续游戏");
cc.director.resume();
cc.director.loadScene(this._mainScene);
}
错误:因为函数后有逗号
index.js:1 Error: Unable to resolve bare specifier ‘__unresolved_2’ from http://localhost:7456/scripting/x/chunks/34/341ab3341f38daa5d6eb502f45f16e9d150576f5.js (SystemJS Error#8 https://git.io/JvFET#8)
资源来源于网络各种免费分享,及自身学习总结,
若有不当可评论指正