利用CocosCreator编辑器制作Animation动画

1.拖曳相关动画图集中任意一张小图片到层级管理器中。

2.把层级管理器中相关资源拖曳回资源管理器相应文件夹中,形成相应的预制链接。

3.在属性检查器中,添加Animation组件。

4.在资源管理器中新建一个AnimationClip

5.把AnimationClip拖曳进Animation组件的Clip中。

6.打开动画编辑器,并点击左上角进行编辑。

7.点击动画编辑器的add property按钮,添加cc.Sprite.spriteFrame属性。

8.在结束帧加入事件。

9.双击事件,添加相关触发函数。

10.添加相应帧的图片

1人点赞日记本

作者:ElectricRomeo
链接:https://www.jianshu.com/p/2bd2f39610f1
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

Cocos Creator网络游戏开发中的短连接HTTP和长连接Websocket

在游戏行业中,网络游戏相比单机游戏的市场份额要大很多。而网络游戏的用户交互性、用户粘性会好很多。所以,绝大部分游戏都需要进行网络连接来存储数据、实现玩家之间互动等。在项目中,主要使用两种网络操作,短连接http和长连接websocket,下面就对这两种进行详细说明。

  • 短连接http

HTTP:超文本传输协议。

在这里,使用XMLHttpRequest对象开发客户端,常用方法和属性如下:

1、open() 与服务器连接,创建新的连接请求。

2、send() 向服务器发送请求。

3、abort()退出当前请求。

4、readyState属性,提供当前请求的状态,其中4表示准备就绪。

5、status属性,提供当前的HTTP请求状态码,其中200表示请求成功。

6、responseText属性,服务器返回的请求响应文本。

7、onreadystatechange属性,设置回调函数。

其中,open和send函数,以及onreadystatechange属性是http请求的关键。

open函数有5个参数可以使用。(method,url,async,user,password)

Method:是指发送请求的类型,一般为GET或POST。

Url:要请求的链接url。

Async:是否为异步请求,该参数可选,默认是true。

User:如果该请求需要身份验证,这里指定用户名,无默认值。

Password:如果该请求需要身份验证,这里指定密码,无默认值。

  1.  XML HttpRequest中5种就绪状态

0:请求没有发出,在调用open()函数之前为该状态;

1:请求已经建立但还没有发出,在调用send()函数之前为该状态;

2:请求已经发出正在处理中;

3:请求已经处理,响应中通常有部分数据可用,但是服务器还没有完成响应;

4:响应已经完成,可以访问服务器响应并使用它。

  •  常见的HTTP状态码 

401:表示所访问数据禁止访问;

403:表示所访问数据受到保护;

404:表示错误的URL请求,表示请求的服务器资源不存在;

200:表示一切顺利;

如果就绪状态是4而且状态码是200即可处理服务器的数据。相信做过Web开发的,对这一块一定非常熟悉。有问题的同学,也不用担心首先必须熟练了解上面知识点。然后我们来看代码。

  •  GET请求
  •  POST请求

总体来看就很清晰了,首先得到XMLHttpRequest实例,然后通过open打开链接,之后监听下连接状态变化,在readyState=4而且status=200时,连接成功,这时候就可以得到网络的数据了。最后别忘了,要send一下。注意:如果请求数据是string类型,需要转为JSON,然后就可以当做表来用了。

当然,post请求和get请求有些许区别,比如参数,设置头等。

另外,为改善用户体验,我们要对请求超时进行相应处理,代码如下。

  • 网络请求超时处理

弱联网的游戏可以采用http连接,如果游戏中需要频繁交互、实时获取数据、状态同步等,我们一般采用长连接WebSocket。

  • 长连接websocket

具体WebSocket的使用可以参考如下网址,在此不在赘述。

https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket。

Cocos Creator游戏开发中实现多指触控缩放代码及原理解析

一、 UI设计

001.png

如上图,我们设计一个简单的界面来进行测试。新建OnMultiTouchCtrl.js ,挂载到OnMultiTouchCtrl节点上。

二、 OnMultiTouchCtrl.js实现如下

首先在onLoad方法中,给Canvas节点添加触摸移动的监听事件,在其回调方法中打印event得到结果如下:

002.png
003.png

由此,我们可以猜测_touches得到的就是多点触摸的信息。故可以通过event.getTouches()方法获取多点触控的信息。

三、 OnMultiTouchCtrl.js代码如下

cc.Class({

    extends: cc.Component,

    properties: {

        canvas: cc.Node,

        target: cc.Node

},

    onLoad: function () {

        var self = this, parent = this.node.parent;

        self.canvas.on(cc.Node.EventType.TOUCH_MOVE, function (event) {

            console.log(“event:”, event);

            console.log(“event._touches:”, event._touches);

            console.log(“event.getTouches():”, event.getTouches());

            var touches = event.getTouches();

            if (touches.length >= 2) {

                var touch1 = touches[0], touch2 = touches[1];

                var delta1 = touch1.getDelta(), delta2 = touch2.getDelta();

                var touchPoint1 = parent.convertToNodeSpaceAR(touch1.getLocation());

                var touchPoint2 = parent.convertToNodeSpaceAR(touch2.getLocation());

                //缩放

                var distance = touchPoint1.sub(touchPoint2);

                var delta = delta1.sub(delta2);

                var scale = 1;

                if (Math.abs(distance.x) > Math.abs(distance.y)) {

                    scale = (distance.x + delta.x) / distance.x * self.target.scale;

                }

                else {

                    scale = (distance.y + delta.y) / distance.y * self.target.scale;

                }

                self.target.scale = scale < 0.1 ? 0.1 : scale;

            }

        }, self.node);

    }

});

四、 缩放算法原理解析

我们首先考虑触摸的两点构成的向量偏水平的情况,也就是代码中Math.abs(distance.x) > Math.abs(distance.y)的情况。这种情况能够理解,偏垂直的情况就是一样的操作原理。

1.  放大

我们首先来看放大的情况,为了便于大家理解,我们假设其中一个触摸点不动(触摸点O不动),另一个触摸点动(A动)。如下图,touchPoint2为触摸点O,touchPoint1为触摸点A,则distance为向量OA。

假设触摸点A由A移动到B,触摸点O不动。则delta1=向量AB,delta2等于零向量。delta=delta1=向量AB。

004.png

如上图所示,由于假设的是偏水平向量,所以满足第一个分支。缩放的值scale就等于对象原来的缩放值乘以一个比例系数。这个比例系数就是线段OE的长比线段OD的长。也就是(distance.x + delta.x)/distance.x。

如果图片原来的对角线是OA,则缩放后图片的对角线就是OB。完美!

接下来缩小就是一样的道理了。

2. 缩小

缩小时,假设其中一个触摸点O不动,另一个触摸点由A点移动到B’点。如下图所示。此时向量delta=向量AB’。其delta.x为负数,distance.x+delta.x的值为线段OF的长度。所以,如果图片原来对角线是OA,缩放后,对角线会变成OB’。正确!

005.png

至于,偏垂直的向量情况,也就可以照葫芦画瓢了,所以上述代码就很好搞定了 。

五、 打包测试

1. 打包成微信小游戏

006.png

打包完成后,点击上图的【打开】找到导包好的项目路径,然后打开微信开发者工具,导入如下:

3. 微信开发者工具+手机测试

007.png

点击预览,生成二维码,打开手机微信,扫一扫,测试,双指触摸,张开放大图片,收拢缩小图片,测试效果如下:

008.png

所以,想使用“九阴白骨爪”切水果的朋友,应该知道如何写你的代码了。

vue项目使用websocket技术

一、为什么需要websocket?

  前端和后端的交互模式最常见的就是前端发数据请求,从后端拿到数据后展示到页面中。如果前端不做操作,后端不能主动向前端推送数据,这也是http协议的缺陷。

  因此,一种新的通信协议应运而生—websocket,他最大的特点就是服务端可以主动向客户端推送消息,客户端也可以主动向服务端发送消息,实现了真正的平等。

websocket其他特点如下:

(1)建立在 TCP 协议之上,服务器端的实现比较容易。

(2)与 HTTP 协议有着良好的兼容性。默认端口也是80和443,并且握手阶段采用 HTTP 协议,因此握手时不容易屏蔽,能通过各种 HTTP 代理服务器。

(3)数据格式比较轻量,性能开销小,通信高效。

(4)可以发送文本,也可以发送二进制数据。

(5)没有同源限制,客户端可以与任意服务器通信。

(6)协议标识符是ws(如果加密,则为wss),服务器网址就是 URL。

二、vue项目如何引用websocket?

vue使用websocket需要注意以下几点:

(1)首先需要判断浏览器是否支持websocket,关于如何解决兼容性问题可以参考 这里这里

(2)在组件加载的时候连接websocket,在组件销毁的时候断开websocket

(3)后端接口需要引入socket模块,否则不能实现连接

不废话了,直接附上完整代码:

复制代码
<template>
    <div>
        <button @click="send">发消息</button>
    </div>
</template>

<script>
export default {
    data () {
        return {
            path:"ws://192.168.0.200:8005/qrCodePage/ID=1/refreshTime=5",
            socket:""
        }
    },
    mounted () {
        // 初始化
        this.init()
    },
    methods: {
        init: function () {
            if(typeof(WebSocket) === "undefined"){
                alert("您的浏览器不支持socket")
            }else{
                // 实例化socket
                this.socket = new WebSocket(this.path)
                // 监听socket连接
                this.socket.onopen = this.open
                // 监听socket错误信息
                this.socket.onerror = this.error
                // 监听socket消息
                this.socket.onmessage = this.getMessage
            }
        },
        open: function () {
            console.log("socket连接成功")
        },
        error: function () {
            console.log("连接错误")
        },
        getMessage: function (msg) {
            console.log(msg.data)
        },
        send: function () {
            this.socket.send(params)
        },
        close: function () {
            console.log("socket已经关闭")
        }
    },
    destroyed () {
        // 销毁监听
        this.socket.onclose = this.close
    }
}
</script>

<style>

</style>
复制代码

麒麟子Cocos Creator 3D研究笔记四:天空盒动态更换与IBL效果

麒麟子Cocos Creator 3D研究笔记之材质IBL与天空盒动态切换

在线演示地址: https://showcase.ukylin.net/skybox/


天空盒对于3D渲染场景来说,有着不个忽视的地位。天空盒决定了整个场景的氛围。

晴天、雨夜、黄昏、黎明等场景,只要换上一个天空盒,瞬间达到60%的效果。

Cocos Creator 3D作为一款高端引擎,这东西自然是要提供的。官方文档如下:https://docs.cocos.com/creator3d/manual/zh/concepts/scene/skybox.html

本文介绍了Cocos Creator 3D中天空盒的使用,以及各项参数的含义。并提供了十套可直接用于项目的天空盒素材。文末有获取链接


由于 官方文档讲得比较全了,并且这个东西的使用也比较简单。我就来说一下文档中没有讲到的部分。

一、动态切换天空盒

动态切换天空盒是一个多场景游戏或者天气系统所必须拥有的能力。它将用在以下几种情况。

时段变换,比如魔兽世界里面的时间就是和现实对应的,你是白天,它就是白天。你是黄昏,它就是黄昏。你是黑夜它就是黑夜。

PS:麒麟子一开始玩魔兽世界的时候,都是晚上玩,我一直以为魔兽世界里面都是黑夜呢。哈哈。

动态切换天空盒代码示例:

loader.loadRes('skybox/cubemap_sky' + skyboxName, TextureCube, (err, cubemap: TextureCube) => {    director.getScene().globals.skybox.envmap = cubemap;});

值得说明的是,下图里面所有的参数,都可以通过 director.getScene().globals进行修改,如果你要实现一个动态的天气系统,那里面的参数可能都得动。不仅是更换天空盒图片。

有的朋友运行的时候,发现天空盒看不到。那是因为Camera默认是不使用天空盒的,按下图进行设置即可

二、UseIBL开关 

IBL是Image Based Lighting的缩写,就是基于图像的光照。当这个开关打开后,你会发现,物体表面会映射出天空盒的样子。至于映射强度,就需要调节PBR材质的各项参数,如粗糙度,金属度等。 如果要细节控制不同位置的反射强度,则需要制作 PBR贴图。

关于Image Based Lighting我找到了一篇文章供大家进阶:https://blog.csdn.net/i_dovelemon/article/details/79091105

三、IsRGBE开关

这个开关在别的引擎中叫 IsHDR 。 用于标记你所给的立方体纹理是不是采用了HDR贴图。

但HDR贴图不止一种格式,常见的有两种。RadianceRGBE(.hdr) 或 OpenEXR(.exr)格式。RadianceRGBE是 32位格式,而OpenEXR是48位格式。

这个开关不叫IsHDR的原因,我想可能是只支持.hdr这种格式的文件吧。具体是什么原因,有待考证。目前大家只要明白是啥意思就行。

关于HDR相关内容,我也给大家找了一篇 文章:http://www.zf3d.com/news.asp?Id=23189

四、本文总结

天空盒比较简单,但配合各项参数和漂亮的天空盒素材,能让场景氛围和画面带入感增强不少。

如果想要动态天空盒,分层天空盒,目前需要自己使用引擎接口来处理。

源码获取链接:https://gitee.com/qilinzi/creator3ddemos/skybox/

注意!!!cubemap要与图片文件在同一文件夹下面,否则会出现黑屏情况

CocosCreator3D制作CubeMap 给场景添加天空盒

1.创建img文件夹 将准备好的天空盒六张图片放入其中

2.制作与应用 CubeMap

右键事先建好的cubemaps文件夹 选择新建 CubeMap

3.将六张图片拖入到右侧 如图所示 CubeMap制作完成

4.点击scene 在右侧属性检查器中 skybox — 选中 Enabled 并将制作好的CubeMap 拖入到Envmap中

5. 点击Camera 在属性检查器中 将ClearFlags 选为SKYBOX

cocos creator 3D学习(一)载入的模型注意事项+画布上查看模型的鼠标键盘操作方法

一、格式

模型文件需要是fbx的格式,贴图文件放在和fbx文件同级的文件夹中,一起发过来。
比如:文件夹model里面有着一个model1.fbx和一个叫model1的文件夹,我们只需要将model拽到cocos cretor3D中的assets里新建的texure文件夹中即可

二、设计软件

注意:在cocos creator 3D中的模型最好别用3dmax做,因为3dmax导出的fbx贴图有问题,用maya或者c4d都可以,如果已经用3dmax做完了,就让他们用别的3d软件转一下

三、亮度

如果对模型亮度有要求,最好是让做模型的人调整一下贴图材质,会比cocos creator 3D中打光的效果均匀(因为本人刚接触,关于这方面技术很菜)

四、命名要求

贴图中的名称不能有全角和中文,否则拽到cocos3D里贴图贴不上

五、鼠标键盘移动

因为刚接触3D的时候蒙了一天,甚至给自己转的都恶心了,所以还是写一下吧
、按住鼠标右键移动鼠标,是基于鼠标按住的点进行720°旋转
、按住鼠标左键+键盘Alt键,移动鼠标,是对画布模型进行旋转
、滑动鼠标滚轮控制画布放大缩小
、按住鼠标右键,同时按住键盘的w/a/s/d,分别是平移视角向前/左/后/右
、按住鼠标右键,同时按住键盘的w/a/s/d,再移动鼠标,会根据鼠标移动进行带旋转角度的位移(慎用,容易给自己转晕)
以上几条其实做完这个项目发现常用的就是①②③,这几个基本就够用了

最后

cocos creator 3D学习(二)总是浮在屏幕最前面的操作按钮及其他
cocos creator 3D学习(三)一些常用的声明
cocos creator 3D学习(四)刚体
cocos creator 3D学习(五)射线—点击按钮
cocos creator 3D学习(六)光照+阴影

在哪npm install log4js

我们也可以在代码中,用console.log()打印一些控制台日志。 修改routes/index.js…二、配置log4js与express框架集成 1、安装 npm install log4js

1.安装位置: npm install moduleName ,则是将模块下载到当前命令行所在目录。 npm install moduleName -g ,模块将被下载安装到全局目录中,即Node的安装目录下的node_modules下 2.调用方式: 在代码中,本地安装可以直接通过require()的方式

把代理设置为空 npm config set proxy null 设置代理 npm install -g express-generator 安装express

PHP提取富文本字符串中的纯文本,并进行进行截取

/**
* 提取富文本字符串的纯文本,并进行截取;
* @param $string 需要进行截取的富文本字符串
* @param $int 需要截取多少位
*/
public static function StringToText($string,$num){
if($string){
//把一些预定义的 HTML 实体转换为字符
$html_string = htmlspecialchars_decode($string);
//将空格替换成空
$content = str_replace(” “, “”, $html_string);
//函数剥去字符串中的 HTML、XML 以及 PHP 的标签,获取纯文本内容
$contents = strip_tags($content);
//返回字符串中的前$num字符串长度的字符
return mb_strlen($contents,’utf-8′) > $num ? mb_substr($contents, 0, $num, “utf-8”).’….’ : mb_substr($contents, 0, $num, “utf-8”);
}else{
return $string;
}
}

Cocos Creator 3D 打砖块教程(二) | 子弹发射与摄像机平滑移动

在线体验链接:
http://example.creator-star.cn/block3d/

前面一篇文章,我们讲了【打砖块】游戏中的3D物体的场景布局、材质资源、物理刚体与碰撞组件,接下来本篇文章重点介绍“子弹的发射”与“摄像机移动”,有了这两部分我们的【打砖块】游戏就可以初步玩起来了。

子弹的发射

子弹是由 3D 物体 Sphere 球体创建,并将节点改名为 bullet,看下图:

在层级管理器中将 bullet 节点拖动到资源管理器中,将它创建成一个 Prefab 预制体。同时在 bullet 子弹节点上挂载球体碰撞组件(cc.SphereColliderComponent)和刚体组件 (cc.RigidBodyComponent),如下图所示:

有了 bullet 预制体,我们就可以用代码去实例化它,并将他发射出去,创建一个 shoot 的TypeScript 脚本并将它挂载到 Camera 摄像机节点上:

将shoot组件的子弹预制体拖动过去,子弹的移动速度设置为 50,我们通过点击屏幕来进行发射,下面是具体的代码:

import { _decorator, Component, Node, CCObject, Prefab, instantiate, RigidBodyComponent, Vec3 } from "cc";
const { ccclass, property } = _decorator;

@ccclass("shoot")
export class shoot extends Component {
  
    @property(Prefab)
    bullet: Prefab;

    @property(cc.Float)
    speed = 0;
 
    start () {
		//注册全局触摸点击事件
        cc.systemEvent.on(Node.EventType.TOUCH_END, () => {
            this.shoot();
        });
    }

    shoot() {
        //实例化 bullet 预制体
        let node = instantiate(this.bullet);
        node.parent = this.node.parent;
        node.position = this.node.position;
        //为刚体施加冲量
        let bullet:RigidBodyComponent = node.getComponent(RigidBodyComponent);
        bullet.applyImpulse(new Vec3(0, 2.29, -1 * this.speed));
    }

这里需要注意两点:

  1. 触摸事件是使用cc.systemEvent进行注册的;
  2. 工程中没有代码提示,需要从引擎安装目录中复制cc.d.ts文件到工程中,我是在Mac系统上,可以用下面命令复制:
cp /Applications/CocosCreator3D.app/Contents/Resources/resources/3d/engine/bin/.declarations/cc.d.ts ./

预制体的实例化使用instantiate 与我们在Creator 2D中使用的API完全相同,就不在赘述。这时我们就可以运行预览,通过点击鼠标或触摸屏幕发射子弹了。

摄像机移动

在3D游戏中,通常的做法是使用WSAD四个键进行上下左右的移动,其核心是控制摄像机节点的位置。在我们这个游戏中为了简化游戏操作,我们只控制摄像的 x 和 y 方向的移动:

  • w:y方向增加
  • s:y方向减小
  • a:x方向减小
  • d:x方向增加

创建一个 movement 的脚本用于控制摄像机的移动,下面是组件的设置:

下面重点分析使用键盘控制摄像机移动的相关代码:

//使用 cc.systemEvent.on 注册全局键盘事件
start() {
    cc.systemEvent.on(Node.EventType.KEY_DOWN, this.onKeyDown, this);
    cc.systemEvent.on(Node.EventType.KEY_UP, this.onKeyUp, this);
		... 
}

在按钮下键盘事件 onKeyDown 中标记移动的方向:

onKeyDown(event) {
    cc.log(event);
    let rotation = this.node.eulerAngles;
    let position = this.node.getPosition();
    switch(event.keyCode) {
        case cc.macro.KEY.w:
            this.offset.y = 1;
            break;
        case cc.macro.KEY.s:
            this.offset.y = -1;
            break;
        case cc.macro.KEY.a:
            this.offset.x = -1;
            break;
        case cc.macro.KEY.d:
            this.offset.x = 1;
            break;
    }
}

当按键松开时,将 offset 变量归 0:

onKeyUp() {
    this.offset.x = 0;
    this.offset.y = 0;    
    this.offset.z = 0;    
}

重点是在组件的每帧事件 update 中真正控制摄像机节点的移动:

update (deltaTime: number) { 
    //计算要移动的目标位置
    Vec3.add(this.point, this.node.position, this.offset);
		//插值计算
    Vec3.lerp(this.point, this.node.position, this.point, deltaTime * this.speed);
		//移动节点
    this.node.setPosition(this.point);
}

为了平滑移动,Shawn这里参考了官方Demo案例中的做法,使用 Vec3.lerp 对当前坐标到要移动的坐标进行插值计算。