cocos creator 小游戏区域截图功能实现
截图是游戏中非常常见的一个功能,在cocos中可以通过摄像机和 RenderTexture 可以快速实现一个截图功能,具体API可参考:https://docs.cocos.com/creator/manual/zh/render/camera.html?h=%E6%88%AA%E5%9B%BE,其中官方也提供了比较完整的例子。
实际上不用官网提供的全屏截图的例子,一般在网页中我们也能将页面截图保存,比如通过htmltocanvas,cocos开发的小游戏在网页中打开实际就是一个canvas,前端是可以通过将canvas保存为图片的,这里就不细说了。
我们还是来看下如何把屏幕中某一区域的内容生成图片并保存到本地。
1、创建RenderTexture
//新建一个 RenderTexture,并且设置 camera 的 targetTexture 为新建的 RenderTexture,这样 camera 的内容将会渲染到新建的 RenderTexture 中。
let texture = new cc.RenderTexture();
let gl = cc.game._renderContext;
//如果截图中不含mask组件可以不加第三个参数,不过建议加上
texture.initWithSize(this.node.width, this.node.height, gl.STENCIL_INDEX8);//这里的宽高直接决定了截图的宽高,如果是全屏截图就是cc.visibleRect.width, cc.visibleRect.height,该处可以设置为截图目标区域的宽高
this.camera = this.node.addComponent(cc.Camera); this.camera.targetTexture = texture; this.texture = texture;
2、绘制canvas
createSprite() {
let width = this.texture.width;
let height = this.texture.height;
//截图的本质是创建一个canvas,然后通过canvas生成图片材质
if (!this._canvas) {
this._canvas = document.createElement('canvas');
this._canvas.width = width;
this._canvas.height = height;
} else {
this.clearCanvas();
}
let ctx = this._canvas.getContext('2d');
this.camera.render();//相机绘制,将屏幕上的内容更新到renderTexture中
let data = this.texture.readPixels();//读取renderTexture中的数据 let rowBytes = width * 4;
for (let row = 0; row < height; row++) {
let srow = height - 1 - row;
let imageData = ctx.createImageData(width, 1);
let start = srow * width * 4;
for (let i = 0; i < rowBytes; i++) {
imageData.data[i] = data[start + i];
} ctx.putImageData(imageData, 0, row);
}
return this._canvas;
},
上述代码中用到了canvas 的createImageData() 和putImageData()方法,createImageData() 方法创建新的空白 ImageData 对象,putImageData() 方法将图像数据(从指定的 ImageData 对象)放回画布上。
3、获取图片
initImage(img) {
// return the type and dataUrl
var dataURL = this._canvas.toDataURL("image/png");
var img = document.createElement("img");
img.src = dataURL;
return img;
},
生成canvas就可以通过canvas.toDataURL()方法将canvas转换为图片
4、生成截图效果,将上一步生成的图片当做材质挂载到新建的node
showSprite(img) {
let y = this.getTargetArea().y;
let x = this.getTargetArea().x;
let rect = new cc.Rect(x, y, 770, 800)
let texture = new cc.Texture2D();
texture.initWithElement(img); let spriteFrame = new cc.SpriteFrame();
spriteFrame.setTexture(texture);
spriteFrame.setRect(rect) let node = new cc.Node();
let sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = spriteFrame; node.zIndex = cc.macro.MAX_ZINDEX;
node.parent = cc.director.getScene();
// set position
let width = cc.winSize.width;
let height = cc.winSize.height;
node.x = width / 2;
node.y = height / 2;
node.on(cc.Node.EventType.TOUCH_START, () => {
node.parent = null;
node.destroy();
});
this.captureAction(node, width, height);
},
5、截图动画(类似手机截图,截图后有个缩略图动画)
captureAction(capture, width, height) {
let scaleAction = cc.scaleTo(1, 0.3);
let targetPos = cc.v2(width - width / 6, height / 4);
let moveAction = cc.moveTo(1, targetPos);
let spawn = cc.spawn(scaleAction, moveAction); let finished = cc.callFunc(() => {
capture.destroy();
})
let action = cc.sequence(spawn, finished);
capture.runAction(action);
},
6、下载图片到本地,动态生成a标签,模拟点击后移除
downloadImg() {
this.createSprite();
var img = this.initImage();
this.showSprite(img)
var dataURL = this._canvas.toDataURL("image/png")
var a = document.createElement("a")
a.href = dataURL;
a.download = "image";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
},
完整代码如下:
cc.Class({
extends: cc.Component, properties: {
_canvas: null,
targetNode: cc.Node
},
onLoad() {
this.init();
}, init() {
let texture = new cc.RenderTexture();
let gl = cc.game._renderContext;
texture.initWithSize(this.node.width, this.node.height, gl.STENCIL_INDEX8);
this.camera = this.node.addComponent(cc.Camera);
this.camera.targetTexture = texture;
this.texture = texture;
},
// create the img element
initImage(img) {
// return the type and dataUrl
var dataURL = this._canvas.toDataURL("image/png");
var img = document.createElement("img");
img.src = dataURL;
return img;
},
// create the canvas and context, filpY the image Data
createSprite() {
let width = this.texture.width;
let height = this.texture.height;
if (!this._canvas) {
this._canvas = document.createElement('canvas');
this._canvas.width = width;
this._canvas.height = height;
} else {
this.clearCanvas();
}
let ctx = this._canvas.getContext('2d');
this.camera.render();
let data = this.texture.readPixels();
// write the render data
let rowBytes = width * 4;
for (let row = 0; row < height; row++) {
let srow = height - 1 - row;
let imageData = ctx.createImageData(width, 1);
let start = srow * width * 4;
for (let i = 0; i < rowBytes; i++) {
imageData.data[i] = data[start + i];
} ctx.putImageData(imageData, 0, row);
}
return this._canvas;
},
getTargetArea() {
let targetPos = this.targetNode.convertToWorldSpaceAR(cc.v2(0, 0))
let y = cc.winSize.height - targetPos.y - this.targetNode.height / 2;
let x = cc.winSize.width - targetPos.x - this.targetNode.width / 2;
return {
x,
y
}
},
downloadImg() {
this.createSprite();
var img = this.initImage();
this.showSprite(img)
var dataURL = this._canvas.toDataURL("image/png")
var a = document.createElement("a")
a.href = dataURL;
a.download = "image";
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
},
// show on the canvas
showSprite(img) {
let y = this.getTargetArea().y;
let x = this.getTargetArea().x;
let rect = new cc.Rect(x, y, 770, 800)
let texture = new cc.Texture2D();
texture.initWithElement(img); let spriteFrame = new cc.SpriteFrame();
spriteFrame.setTexture(texture);
spriteFrame.setRect(rect) let node = new cc.Node();
let sprite = node.addComponent(cc.Sprite);
sprite.spriteFrame = spriteFrame; node.zIndex = cc.macro.MAX_ZINDEX;
node.parent = cc.director.getScene();
// set position
let width = cc.winSize.width;
let height = cc.winSize.height;
node.x = width / 2;
node.y = height / 2;
node.on(cc.Node.EventType.TOUCH_START, () => {
node.parent = null;
node.destroy();
});
this.captureAction(node, width, height);
},
// sprite action
captureAction(capture, width, height) {
let scaleAction = cc.scaleTo(1, 0.3);
let targetPos = cc.v2(width - width / 6, height / 4);
let moveAction = cc.moveTo(1, targetPos);
let spawn = cc.spawn(scaleAction, moveAction); let finished = cc.callFunc(() => {
capture.destroy();
})
let action = cc.sequence(spawn, finished);
capture.runAction(action);
}, clearCanvas() {
let ctx = this._canvas.getContext('2d');
ctx.clearRect(0, 0, this._canvas.width, this._canvas.height);
}
});
cocos creator 小游戏区域截图功能实现的更多相关文章
- Cocos开发小游戏如何实现微信排行榜
当游戏开发进入尾声,要引入微信数据的时候,需要了解和微信相关的接口了. 关系数据链 开放数据域 相关接口如下: wx.getFriendCloudStorage() 获取当前用户也玩该小游戏的好友的用 ...
- Cocos Creator采坑:原来使用Cocos Creator做游戏,是有服务器!!!
我傻傻的以为,我们没有服务器. 今天上传测试代码,测试才发现! 原来我们真的是有服务器的!只不过是一个本地的服务器~!需要服务器打开,然后,扫码才能访问!! 为了证明我们是有服务器的,我做了一下测试 ...
- Cocos Creator经典游戏制作之:信使(The Messenger)
版权声明: 本文原创发布于博客园"优梦创客"的博客空间(网址:http://www.cnblogs.com/raymondking123/)以及微信公众号"优梦创客&qu ...
- cocos 微信小游戏切后台卡住
1.cocos 安装目录下搜索以下代码并注掉opts["preserveDrawingBuffer"] = true;”2.CocosCreator\resources\engin ...
- 新编辑器Cocos Creator发布:对不起我来晚了!
1月19日,由Cocos创始人王哲亲手撰写的一篇Cocos Creator新品发布稿件在朋友圈被行业人士疯狂转载,短短数小时阅读量突破五位数.Cocos Creator被誉为“注定将揭开Cocos开发 ...
- cocos creator主程入门教程(一)—— 初识creator
五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 我们在cocos creator新建一个Hello TypeScript项目,都会有一个assets/S ...
- cocos creator 入门理解点
简单解释, [来源:官方文档] Cocos是触控科技推出的游戏开发一站式解决方案,包含了从新建立项.游戏制作.到打包上线的全套流程.开发者可以通过cocos快速生成代码.编辑资源和动画,最终输出适合于 ...
- 一个js小游戏----总结
花了大概一天左右的功夫实现了一个js小游戏的基本功能,类似于“雷电”那样的小游戏,实现了随即怪物发生器,碰撞检测,运动等等都实现了,下一个功能是子弹轨迹,还有其他一些扩展功能,没有用库,也没有用web ...
- h5小球走迷宫小游戏源码
无意中找到的一个挺有意思的小游戏,关键是用h5写的,下面就分享给大家源码 还是先来看小游戏的截图 可以用键盘的三个键去控制它,然后通关 下面是源代码 <!doctype html> < ...
随机推荐
- VS2010使用c++、gSOAP创建WebService 图文教程
VS2010使用c++.gSOAP创建的WebService 图文教程 环境 操作系统:Windows 7gsoap版本:2.8.32C++编译器/开发环境:Visual Studio 2010 gS ...
- bootstrap组件和插件
一.用node.js读取文件 //引入fs模块 var fs= require ('fs'); // console.log(fs); //调用fs模块的readFile方法 fs.readFile( ...
- 章节十四、7-如何切换到iFrame
以下案例使用https://jqueryui.com/网站为例. 一.如何确定元素是否包含在iFarme中? 1.按F12打开发者选项,定位到指定的元素. 2.向上查找元素是否被包含在ifarme标签 ...
- ORACLE(student)表习题与答案
因为答案都是小编自己写的,解法可能有多种,如果您觉得我的解法有误,希望您有时间给我留言. 题目:1. 查询student表中的所有记录的sname.ssex和class列. SELECT sname, ...
- ListView背景色突变问题
ListView中加入 android:cacheColorHint="#00000000" 的属性即可
- VB程序逆向常用的函数
本文转载!!! 原文地址:http://www.cnblogs.com/bbdxf/p/3780187.html 1) 数据类型转换: a) __vbaI2Str 将一个字符串转为8 位(1个字 ...
- [Vue 牛刀小试]:第十四章 - 编程式导航与实现组件与 Vue Router 之间的解耦
一.前言 在上一章的学习中,通过举例说明,我们了解了 Vue Router 中命名路由.命名视图的使用方法,以及如何通过 query 查询参数传参,或者是采用 param 传参的方式实现路由间的参数传 ...
- Redis 密码设置和查看密码(二)
Redis 密码设置和查看密码 redis没有实现访问控制这个功能,但是它提供了一个轻量级的认证方式,可以编辑redis.conf配置来启用认证. 1.初始化Redis密码: 在配置文件中有个参数: ...
- centos7 中安装 htop
首先启用 EPEL Repository: yum install -y epel-release 启用 EPEL Repository 后, 可以用 yum 直接安裝 Htop: yum insta ...
- Centos7.3搭建DNS服务器--BIND
1.系统环境说明 [root@dns-server etc]# cat /etc/redhat-release CentOS Linux release (Core) 防火墙和Selinux关闭 [r ...