cocos2d::DrawPrimitives和DrawNode分别实现画板功能

cocos2d::DrawPrimitives和DrawNode分别实现画板功能,第1张

概述才开始了解cocos2dx几天,只是觉得学习还是得边用边学,所以才想实现点什么,下面提到的有什么问题请指出,谢谢 我想实现简单的画板功能,就看了官方cpp_test的Node:Draw测试代码,遗憾的是我先看到的是DrawPrimitives,所以就研究了一下,简单的实现了我的功能,当我写的差不多的时候才发现DrawPrimitives应该尽量不再使用,而使用DrawNode来实现。 代码都写的差

才开始了解cocos2dx几天,只是觉得学习还是得边用边学,所以才想实现点什么,下面提到的有什么问题请指出,谢谢

我想实现简单的画板功能,就看了官方cpp_test的Node:Draw测试代码,遗憾的是我先看到的是DrawPrimitives,所以就研究了一下,简单的实现了我的功能,当我写的差不多的时候才发现DrawPrimitives应该尽量不再使用,而使用DrawNode来实现。

代码都写的差不多了,而且测试效果感觉还特别好,还是在这里留存一下吧:

#pragma once#include "cocos2d.h"struct Segment {	cocos2d::Point p1;	cocos2d::Point p2;};class BoardLayer : public cocos2d::Layercolor{public:	BoardLayer();	virtual ~BoardLayer();	CREATE_FUNC(BoardLayer);	virtual bool init();	virtual bool ontouchBegan(cocos2d::touch *touch,cocos2d::Event *unused_event);	virtual voID ontouchmoved(cocos2d::touch *touch,cocos2d::Event *unused_event);	virtual voID ontouchended(cocos2d::touch *touch,cocos2d::Event *unused_event);	virtual voID ontouchCancelled(cocos2d::touch *touch,cocos2d::Event *unused_event);	virtual voID draw(cocos2d::Renderer *renderer,const cocos2d::Mat4 &transform,uint32_t flags);private:	Segment _bufferSegment;	cocos2d::Point _originPoint;	cocos2d::Point _prevIoUsPoint;	std::vector<Segment> _drawSegment;	std::vector<cocos2d::Point> _drawPoint;	cocos2d::DrawNode* _drawNode;	cocos2d::color4F _drawcolor;	float _drawSize;};

#include "BoardLayer.h"USING_NS_CC;BoardLayer::BoardLayer(){}BoardLayer::~BoardLayer(){}bool BoardLayer::init(){	Size visibleSize = Director::getInstance()->getVisibleSize();	if (!Layercolor::initWithcolor(color4B(255,255,255),visibleSize.wIDth,visibleSize.height))		return false;	this->settouchMode(touch::dispatchMode::ONE_BY_ONE);	this->settouchEnabled(true);	_drawNode = DrawNode::create();	this->addChild(_drawNode);	_drawcolor = color4F(1,1);	_drawSize = 2;	return true;}bool BoardLayer::ontouchBegan(cocos2d::touch *touch,cocos2d::Event *unused_event){	Point location = touch->getLocation();	_originPoint = _prevIoUsPoint = location;	return true;}voID BoardLayer::ontouchmoved(cocos2d::touch *touch,cocos2d::Event *unused_event){	Point location = touch->getLocation();	// 新点与原点X和Y存在相同	if (_originPoint.x == location.x || 		_originPoint.y == location.y) {		_prevIoUsPoint = location;		// 缓冲线段		_bufferSegment.p1 = _originPoint;		_bufferSegment.p2 = _prevIoUsPoint;	} else {		Segment segment;		segment.p1 = _originPoint;		segment.p2 = _prevIoUsPoint;		_drawSegment.push_back(segment);		// 存在新点与记忆点X和Y均不同		if (_prevIoUsPoint.x != location.x ||			_prevIoUsPoint.y != location.y) {			Segment segment;			segment.p1 = location;			segment.p2 = _prevIoUsPoint;			_drawSegment.push_back(segment);			// 重置原点及记忆点			_originPoint = _prevIoUsPoint = location;		} else {			_originPoint = _prevIoUsPoint;			_prevIoUsPoint = location;		}	}}voID BoardLayer::ontouchended(cocos2d::touch *touch,cocos2d::Event *unused_event){	// 处理点击	Point location = touch->getLocation();	if (_originPoint == location && _prevIoUsPoint == location)		return _drawPoint.push_back(location);	// 处理MOVE到该点	this->ontouchmoved(touch,unused_event);	// 此时若存在有效缓冲线段	if (!_bufferSegment.p1.isZero() ||		!_bufferSegment.p2.isZero()) {		Segment segment;		segment.p1 = _bufferSegment.p1;		segment.p2 = _bufferSegment.p2;		_drawSegment.push_back(segment);		// 重置有效缓冲线段		_bufferSegment.p1.setZero();		_bufferSegment.p2.setZero();	}}voID BoardLayer::ontouchCancelled(cocos2d::touch *touch,cocos2d::Event *unused_event){}voID BoardLayer::draw(cocos2d::Renderer *renderer,uint32_t flags){	gllinewidth(2);	DrawPrimitives::setPointSize(2);	DrawPrimitives::setDrawcolor4B(255,255);	// 画缓冲线段	if (!_bufferSegment.p1.isZero() || !_bufferSegment.p2.isZero()) {		DrawPrimitives::drawline(_bufferSegment.p1,_bufferSegment.p2);		CHECK_GL_ERROR_DEBUG();	}	// 画所有线段	for (auto segment : _drawSegment) {		DrawPrimitives::drawline(segment.p1,segment.p2);		CHECK_GL_ERROR_DEBUG();	}	// 画所有点	for (auto point : _drawPoint) {		DrawPrimitives::drawPoint(point);		CHECK_GL_ERROR_DEBUG();	}}


之后代码统一换成DrawNode实现,代码竟然精简了如此之多,基本没有什么逻辑:

#pragma once#include "cocos2d.h"class BoardLayer : public cocos2d::Layercolor{public:	BoardLayer();	virtual ~BoardLayer();	CREATE_FUNC(BoardLayer);	virtual bool init();	virtual bool ontouchBegan(cocos2d::touch *touch,cocos2d::Event *unused_event);private:	cocos2d::Point _originPoint;	cocos2d::DrawNode* _drawNode;	cocos2d::color4F _drawcolor;	float _drawSize;};

#include "BoardLayer.h"USING_NS_CC;BoardLayer::BoardLayer(){}BoardLayer::~BoardLayer(){}bool BoardLayer::init(){	Size visibleSize = Director::getInstance()->getVisibleSize();	if (!Layercolor::initWithcolor(color4B(255,cocos2d::Event *unused_event){	_originPoint = touch->getLocation();	return true;}voID BoardLayer::ontouchmoved(cocos2d::touch *touch,cocos2d::Event *unused_event){	Point location = touch->getLocation();		_drawNode->drawSegment(_originPoint,location,_drawSize / 2,_drawcolor);	_originPoint = location;}voID BoardLayer::ontouchended(cocos2d::touch *touch,cocos2d::Event *unused_event){	if (_originPoint == touch->getLocation())		_drawNode->drawPoint(_originPoint,_drawSize,_drawcolor);}

这里作一下对比,这里需要提到两个指标,GL Verts 和 GL Calls,概念的含义也是我朋友给我说的,前者是绘图的顶点数量,后者是opengl的调用次数,朋友还特意给我说了这两个值都是越小越好。

当我使用DrawPrimitives实现画板的时候,我每画一个点,GL Verts 值加1,GL Calls 值加1,我每画一条线,GL Verts 值加2(两个顶点),GL Calls 值加1。

当我使用DrawNode实现的时候,我每画一个点,GL Verts 值加1,我每画一条线,GL Verts 这个值是一直累加的(每次累加18),GL Calls 值始终为1。

可能这里也就从一定层面上说明DrawNode早晚会取代DrawPrimitives的原因,DrawPrimitives迟早会被淘汰。


但是这里也有一个疑问是,当使用DrawNode的为什么GL Verts累加的时候每次累加18呢,按我上面给出的参数我怎么想都想不到18啊?

这里也再多说明一个问题,当使用DrawPrimitives的时候,我是在draw实现绘画功能的,但是draw函数我后来发现是被循环调用的,应该是和刷新频率有关,就像MFC程序一样界面每隔一段时间刷新一次,当然这个时间很短,也也就导致了我看到的GL Verts 和 GL Calls 的值永远在我的计算当中,因为每次刷新这两个值都应该会重新计算的吧。若是按照刷新次数去计算这两个值,只会更大吧。

总结

以上是内存溢出为你收集整理的cocos2d::DrawPrimitives和DrawNode分别实现画板功能全部内容,希望文章能够帮你解决cocos2d::DrawPrimitives和DrawNode分别实现画板功能所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1058221.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-25
下一篇 2022-05-25

发表评论

登录后才能评论

评论列表(0条)

保存