[cocos2dx]又来问问CCTableView与CCScrollView的滑屏问题(问题有点长)

yxlovemoney 2014-08-14 11:55:53
还是先放上些关键代码吧

// 实现滑屏的关键代码
CCTableViewCell *CColorBox::tableCellAtIndex(CCTableView *table, unsigned int idx)
{
// 格式化相应的图片名称
CCString *pString = CCString::createWithFormat("%d.png", idx + 1);
CCTableViewCell *pCell = table->dequeueCell();// 返回空闲的子项
if (!pCell)
{
pCell = new CCTableViewCell();
pCell->autorelease();
CCSprite *penSprite = CCSprite::createWithSpriteFrameName(pString->getCString());
penSprite->setAnchorPoint(CCPointZero);
penSprite->setPosition(CCPointZero);
penSprite->setTag(TABLEVIEW_ICON_TAG); // 此处要设置相同的TAG,不然就取不对该图片精灵
pCell->addChild(penSprite);
}
retrun pCell;
}

首先这是作为单独的一个类(这里用类B代表),用于实现,加入到另一个界面上,通过点击就弹出这个滑屏对象。
这个在我单独使用时,加入到一个新建的项目界面上,是正常的没有任何问题。

现在问题就出现在加入到我的项目中就有问题了,
首先我这项目,是在界面上(这个以类A来代表),继承了CCLayer, CCScrollViewDelegate, 以实现一个横向滑屏的功能,界面上还添加了COCOSTUDIO做的UI界面(也就两个按钮), 然后在界面上通过点击某个元素,就加入上面说的类B对象,以弹出一个相当于工具栏的竖向滑屏对象。

因为在这里出现问题,所以下面是后来想的两个解决方案

第一。我直接把这类B滑屏对象加到类A的界面上去,并增加一个新的背景,而让类A原先的点击行为都不可用,初看起来一切都没有问题,但当对类B滑屏对象不停进行滚动时,就出现了这个情况。
类B滑屏对象上的子项,被不断地addChild进去,也就是一开始给出的代码 pCell->addChild(penSprite); 这里



滚动就添加,添加到一定程度时程序就崩溃了。后面想了好多原因,也改动了好多次,也不行,最后猜想是不是 CCScrollView,和CCTableView是否不能同时出现在同一个界面上时,就去尝试,干脆转场,在一个新的场景,去显示类B这个滑屏对象(这里必须是通过类A的场景转场到类B),
结果也让我很奇怪,在转到这个新场景时,一滑动类B的滑屏对象,就出错了。
(图2)
实在是想不通为什么,难道类A还带了些什么问题到新的场景来了吗? 但我类A的场景中最主要的就是 一些 精灵帧缓存,已经在析构函数里面释放了,还有加载了一些音效,这个应该是不用释放的吧? 还有就是COCOSTUIDO的UI界面了,这也应该不用做什么释放操作吧?

然而在类A中也把原先对类B的滑屏对象的 相关操作全部注释掉,但还是会出现图2的错误。

感觉已经无计可施了,求给些解决思路,整个人都快疯了。在此谢过
...全文
416 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
笨木头 2014-08-27
  • 打赏
  • 举报
回复
引用 10 楼 yxlovemoney 的回复:
已经弄出来了,后来实在找不到办法 ,就新建个项目一句句代码重新敲,后来发现不停滚动精灵就不停被添加的问题, 原来是之前为了判断点击中哪个图片,通过像素取色的方法去判断,那里的逻辑没写好导致的。 然后一滚就崩溃就是8楼说的。 都是因为自己的疏忽大意导致。
恭喜喇~这类问题确实只能自己慢慢调试喇,旁人只能胡乱猜测(捣乱~)
yxlovemoney 2014-08-27
  • 打赏
  • 举报
回复
已经弄出来了,后来实在找不到办法 ,就新建个项目一句句代码重新敲,后来发现不停滚动精灵就不停被添加的问题, 原来是之前为了判断点击中哪个图片,通过像素取色的方法去判断,那里的逻辑没写好导致的。 然后一滚就崩溃就是8楼说的。 都是因为自己的疏忽大意导致。
职业炒股 2014-08-17
  • 打赏
  • 举报
回复
CCSprite *penSprite = CCSprite::createWithSpriteFrameName(pString->getCString()); 这个是要把资源先预加载的,你打一下断点跟踪一下代码在哪一句断言失败 肯定是精灵cache不存在的
yxlovemoney 2014-08-15
  • 打赏
  • 举报
回复
引用 7 楼 musicvs 的回复:
【就是在转场前我把这个新场景以这种方式添加到这个旧场景当中, 然后再转场到 CPaintLayer】这句话是啥意思? 新场景添加到旧场景?
就是旧场景中先调用了 m_paintLayer = CPaintLayer::create(); this->addChild(m_paintLayer, HIGH); 然后我再 转场 CCDirector::sharedDirector()->replaceScene(CPaintLayer::scene());
笨木头 2014-08-15
  • 打赏
  • 举报
回复
【就是在转场前我把这个新场景以这种方式添加到这个旧场景当中, 然后再转场到 CPaintLayer】这句话是啥意思? 新场景添加到旧场景?
yxlovemoney 2014-08-15
  • 打赏
  • 举报
回复
引用 5 楼 musicvs 的回复:
但你断点的地方确实是图片问题(表面上看),不是应该从这断点入手么? 你调试的时候看看pszSpriteFrameName是不是正常,是不是你存在的图片名称? 我的意思并不是说你没有加载图片~ 断点的地方应该是这个函数吧?我拿的是2.1.2的代码,不知道一不一样:

CCSprite* CCSprite::createWithSpriteFrameName(const char *pszSpriteFrameName)
{
    CCSpriteFrame *pFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(pszSpriteFrameName);
    
#if COCOS2D_DEBUG > 0
    char msg[256] = {0};
    sprintf(msg, "Invalid spriteFrameName: %s", pszSpriteFrameName);
    CCAssert(pFrame != NULL, msg);
#endif
    
    return createWithSpriteFrame(pFrame);
}
这地方就只能有一种情况,所以先从这里入手吧,我现在猜测是pszSpriteFrameName路径不对,可能是你不存在的图片
先感谢提供的思路,但后来发现,确实不是这个问题,而最后发现问题确实是出在,转场前的那个界面。 下面说说这个情况: 首先我前面说的,最后没办法了,直接转到新的场景,尝试在新场景显示这个CCTableView滑屏道具栏,结果在这个新场景中一滚动滑屏就出错了。定位在那句createWithSpriteFrame上。(所以你说应该是图片的问题。) (先注明下我这个新场景是用CPaintLayer类来处理) 我重新回到转场前的场景,再查看里面点击后转场的处理代码中,发现有这么两句

m_paintLayer = CPaintLayer::create();
this->addChild(m_paintLayer, HIGH);
就是在转场前我把这个新场景以这种方式添加到这个旧场景当中, 然后再转场到 CPaintLayer,就是这两句导致出错了。 现在知道了出错的原因,但还是没理解为什么会出错,不是转场后,旧有场景的所有资源都会被释放掉吗?为啥会因为这两句 而出错呢? 其二,另外一个问题还是没解决, 就是滑屏对象不停进行滚动时,就出现了这个情况。 滑屏对象上的子项,被不断地addChild进去(就是2.X左下角的第一项) 不断添加到一个相当大的值时,就崩溃了。 无论是把滑屏对象添加在旧场景,还是添加到转场后的新场景。 唉,困难重重。
笨木头 2014-08-14
  • 打赏
  • 举报
回复
但你断点的地方确实是图片问题(表面上看),不是应该从这断点入手么? 你调试的时候看看pszSpriteFrameName是不是正常,是不是你存在的图片名称? 我的意思并不是说你没有加载图片~ 断点的地方应该是这个函数吧?我拿的是2.1.2的代码,不知道一不一样:

CCSprite* CCSprite::createWithSpriteFrameName(const char *pszSpriteFrameName)
{
    CCSpriteFrame *pFrame = CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(pszSpriteFrameName);
    
#if COCOS2D_DEBUG > 0
    char msg[256] = {0};
    sprintf(msg, "Invalid spriteFrameName: %s", pszSpriteFrameName);
    CCAssert(pFrame != NULL, msg);
#endif
    
    return createWithSpriteFrame(pFrame);
}
这地方就只能有一种情况,所以先从这里入手吧,我现在猜测是pszSpriteFrameName路径不对,可能是你不存在的图片
yxlovemoney 2014-08-14
  • 打赏
  • 举报
回复
引用 3 楼 musicvs 的回复:
可能是因为我没有用过TableView吧,所以理解起来就多了一层障碍... 先抛开其他问题,在这句报错,不就只能是图片路径错了、图片不存在、图片未加载,三种情况么?~
图片的问题我认为是不可能的,我还是把我这个滚屏的全部代码贴出来吧


#include "ColorBox.h"
#include "assist/PrioritySetting.h"
#include "PublicData.h"



#define TABLEVIEW_ICON_TAG		100        // CCTableView中加入的精灵设置的TAG




CColorBox::CColorBox(void) : m_frameCache(NULL), m_pTableView(NULL)
{
}


CColorBox::~CColorBox(void)
{
	// 删除精灵帧缓存
	CCSpriteFrameCache::sharedSpriteFrameCache()->removeSpriteFramesFromFile("shoeDrawing/pen.plist");
}




CCScene *CColorBox::scene()
{
	// 场景
	CCScene *scene = CCScene::create();
	// 层
	CColorBox *layer = CColorBox::create();
	// 层加入场景
	scene->addChild(layer);

	return scene;
}


bool CColorBox::init()
{
	if (!CCLayer::init())
	{
		return false;
	}

	// 将图片加载到精灵帧缓存池
	m_frameCache = CCSpriteFrameCache::sharedSpriteFrameCache();
	m_frameCache->addSpriteFramesWithFile("shoeDrawing/pen.plist", "shoeDrawing/pen.png");

	// 滑屏相关操作
	m_pTableView = CCTableView::create(this, CCSizeMake(98, 450));
	// 设置滚动方向
	m_pTableView->setDirection(kCCScrollViewDirectionVertical);
	m_pTableView->setPosition(ccp(WINSIZE_WIDTH - 130, 30));
	m_pTableView->setDelegate(this);
	// 决定VIEW的单元如何填充
	m_pTableView->setVerticalFillOrder(kCCTableViewFillTopDown);
	m_pTableView->setScale(0.8f);
	//pTableView->setAnchorPoint(ccp(0.5f, 0));
	this->addChild(m_pTableView, HIGH);

	// 刷新VIEW
	m_pTableView->reloadData();

	return true;
}


void CColorBox::tableCellTouched(CCTableView* table, CCTableViewCell* cell)
{
	CCLOG("cell touched at index: %i", cell->getIdx());
}


CCSize CColorBox::cellSizeForTable(CCTableView *table)
{
	return CCSizeMake(97, 72);
}


CCTableViewCell *CColorBox::tableCellAtIndex(CCTableView *table, unsigned int idx)
{
	// 格式化相应的图片名称
	CCString *pString = CCString::createWithFormat("%d.png", idx + 1);
	CCTableViewCell *pCell = table->dequeueCell();// 返回空闲的子项?
	if (!pCell)
	{
		pCell = new CCTableViewCell();
		pCell->autorelease();
		CCSprite *penSprite = CCSprite::createWithSpriteFrameName(pString->getCString());
		penSprite->setAnchorPoint(CCPointZero);
		penSprite->setPosition(CCPointZero);
		penSprite->setTag(TABLEVIEW_ICON_TAG); // 此处要设置相同的TAG,不然就取不对该图片精灵
		pCell->addChild(penSprite);     // 这里会出现不断添加的问题
	}
	else
	{
// 		CCTexture2D *texture = CCTextureCache::sharedTextureCache()->addImage(pString->getCString());
// 		CCSprite *penSprite = static_cast<CCSprite *>(pCell->getChildByTag(TABLEVIEW_ICON_TAG));
// 		penSprite->setTexture((CCSprite::createWithSpriteFrameName(pString->getCString()))->getTexture());
		
	}

	return pCell;
}


unsigned int CColorBox::numberOfCellsInTableView(CCTableView *table)
{
	return 18;
}


void CColorBox::scrollViewDidScroll(CCScrollView* view)
{
	CCLOG("scroll");
}


void CColorBox::scrollViewDidZoom(CCScrollView* view)
{
	;
}



void CColorBox::tableCellHighlight(CCTableView* table, CCTableViewCell* cell)
{
	CCSprite *temp = (CCSprite *)(cell->getChildByTag(1));
}


void CColorBox::tableCellUnhighlight(CCTableView* table, CCTableViewCell* cell)
{

}

从代码中能看出来,图片已经在init上面加载了,而且也像我 在1楼上所说的,我把这一楼贴出来的代码的代码,用在一个新建的工程上,是完全没有问题的。 所以,我不认为是图片没加载之类的问题。 唉,我也不怎么确定,已经把代码番.来番.去好多遍,还是没找到一点线索。
笨木头 2014-08-14
  • 打赏
  • 举报
回复
引用 2 楼 yxlovemoney 的回复:
[quote=引用 1 楼 musicvs 的回复:] 我看了好久,还是不太理解你的意思。。。 不过,这个中断的意思,是因为找不到图片资源吧,你调试的结果如何?
没看懂么?已经尽量描述详细些了,看来我要录个像才行了。 总的来说是没调出结果,一拖动跑到CCSprite *penSprite = CCSprite::createWithSpriteFrameName(pString->getCString()); 这里就死,但怎么想也不会是这句的问题。因为只是从我类A场景转到新场景才会有这问题, 而不断加大的精灵数,完全找不出原由。[/quote] 可能是因为我没有用过TableView吧,所以理解起来就多了一层障碍... 先抛开其他问题,在这句报错,不就只能是图片路径错了、图片不存在、图片未加载,三种情况么?~
yxlovemoney 2014-08-14
  • 打赏
  • 举报
回复
引用 1 楼 musicvs 的回复:
我看了好久,还是不太理解你的意思。。。 不过,这个中断的意思,是因为找不到图片资源吧,你调试的结果如何?
没看懂么?已经尽量描述详细些了,看来我要录个像才行了。 总的来说是没调出结果,一拖动跑到CCSprite *penSprite = CCSprite::createWithSpriteFrameName(pString->getCString()); 这里就死,但怎么想也不会是这句的问题。因为只是从我类A场景转到新场景才会有这问题, 而不断加大的精灵数,完全找不出原由。
笨木头 2014-08-14
  • 打赏
  • 举报
回复
我看了好久,还是不太理解你的意思。。。 不过,这个中断的意思,是因为找不到图片资源吧,你调试的结果如何?

8,303

社区成员

发帖
与我相关
我的任务
社区描述
游戏开发相关内容讨论专区
社区管理员
  • 游戏开发
  • 呆呆敲代码的小Y
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧