游戏完成了,今天移植了一下android平台,我勒个去,问题还真是不少啊,让我再次明白win32下的成功运行不代表android也很顺利,看来移植的问题得好好重视下哈。所有的代码完成以后vs下的代码结构是这样的。

小塔1024——移植android

先说下第一个问题,移植android平台,点击开始按钮,游戏闪退,使用logcat调试一下,发现是资源找不到,就是那个cube_i.png资源,这个资源不是从.plist文件中读到的吗?原来我把资源文件都改成了小写的,人家原来都是大写,在win下是不区分大小写的,但是在android下是区分的,因为android本来是linux系统的内核,linux是区分的啊。所以,如果你采用的是我的做法,资源文件改成了小写的,那你的.plist文件中使用的那个.png文件也应该弄成小写的,如下图所示,总之就是要注意大小写的问题,这个在移植的过程中经常出错,有个哥们因为这个大小写的问题搞了三天,呵呵。

小塔——1024移植android

第二个问题就是移植过去是横屏,而我们的游戏是竖屏,要改一下横竖屏的问题,这个问题很好解决,找到android工程下的AndroidManifest.xml配置文件,将下图中我画的那句话改成我的样子。android:screenOrientation="landscape" 为横屏;   android:screenOrientation="portrait"为竖屏。

小塔——1024移植android第三个问题有位仁兄反应是声音的问题,这个在我移植的过程中倒是没有错误,不过大家注意一下路径,如果你的声音文件是在一个文件夹中,在写代码的时候,加声音路径那要用/而不是win下的\,这就是android和win的区别啊。像大小写路径这些都是细节问题,大家平时写代码的时候应该注意一下。

第四个问题是新手引导那滑动到第三张图片的时候就动不了了,搞了我好长时间,现在解决了但我自己不是很满意,大家有什么方法贡献一下吧。我先说下我的方法,先来看下有问题的代码。

bool GuidScene::ccTouchBegan(CCTouch * touch,CCEvent * evt)
{
	cc_timeval tv;
	CCTime::gettimeofdayCocos2d(&tv,NULL);
	m_sec = tv.tv_sec*1000000+tv.tv_usec;

	//将刚开始点击的位置保存下来
	this->m_firstPoint = touch->getLocation();
	//保存原来的偏移量
	m_offset = this->m_guidView->getContentOffset();

	//以下的这一点特别要注意,大家可以先注释掉以下的这句话然后运行程序,会发现如果触摸不是很快
	//的时候不会有什么问题,但是如果触摸进行的很快,关卡的位置偏移的就不会正确,以下的代码正是解决这个问题到
	//代码的含义是只有偏移量为宽度的整数倍时才往下传递消息,放在最终的偏移动作没有执行完毕就再次接受触摸,导致错误
	if(((int)this->m_offset.x)%((int)m_size.width) == 0)
	{
		return true;
	}

	return false;
}

这是因为当我们移植android的时候屏幕的大小在变,用((int)this->m_offset.x)%((int)m_size.width)的方法计算的结果可能不为0,原来他们都是float类型,在你强转int以后相比不一定就是整数倍的,这个时候问题就来了。所以我的解决方法是设置一个变量,在ccTouchBegan中判断,ccTouchEnd中改变变量的值,代表一次触摸完成,代码是这样的。

bool GuidScene::ccTouchBegan(CCTouch * touch,CCEvent * evt)
{
	cc_timeval tv;
	CCTime::gettimeofdayCocos2d(&tv,NULL);
	m_sec = tv.tv_sec*1000000+tv.tv_usec;

	//将刚开始点击的位置保存下来
	this->m_firstPoint = touch->getLocation();
	//保存原来的偏移量
	m_offset = this->m_guidView->getContentOffset();

	//以下的这一点特别要注意,大家可以先注释掉以下的这句话然后运行程序,会发现如果触摸不是很快
	//的时候不会有什么问题,但是如果触摸进行的很快,关卡的位置偏移的就不会正确,以下的代码正是解决这个问题到
	//代码的含义是只有偏移量为宽度的整数倍时才往下传递消息,放在最终的偏移动作没有执行完毕就再次接受触摸,导致错误
	/*if(((int)this->m_offset.x)%((int)m_size.width) == 0)
	{
		return true;
	}*/

	//这里是为了解决上边存在的bug
	if(!this->m_run)
	{
		m_run = true;
		return true;
	}

	return false;
}

但是这样任然存在着问题,如果手指点击的很快,俩次的触摸事件都到来了,他们都会去判断这个m_run,这个时候m_run都是false,也就是说俩次触摸都会得到响应,所以这样做不是一个好方法,但是我也没有想到其他的好的方法,虽然想了很长的时间,大家有好的办法就贡献一下吧,我们一块进步。为了解决这个bug,我就只能让偏移的时间小一点了,我改成了0.1秒,测试了一下,这次没什么问题了。

//最后一个参数是偏移过去的时间,时间参数设置的小一点就不会出现bug了
	this->m_guidView->setContentOffsetInDuration(adjustPoint,0.1f);

第五个问题是用户体验的问题,当我们的游戏移植android平台的时候用户点击棋盘滑动卡片,如果用户的点击点不是在棋盘上,这个时候是接受不到用户的触摸的,因为在android上棋盘是很小的,如果把用户的点击点限制在棋盘那么小的区域的话用户会很不方便,这个时候就不要判断点击点在棋盘上了,直接处理用户的触摸就可以了,改动如下。

bool Chess::ccTouchBegan(CCTouch * touch,CCEvent * evt)
{
	//如果卡片正在移动,则不再进行移动,防止用户点击屏幕过快,导致坐标错误
	if(this->m_cubeManager->getCubeRun() == true)
	{
		return false;
	}

	CCPoint clickPoint = touch->getLocation();
	//CCRect rect = this->m_chess->boundingBox();
	//判断点击点是否在棋盘上
	//if(rect.containsPoint(clickPoint))
	//{
		//将刚开始的触摸点保存下来,过会进行手势的判断
		this->m_firstPoint = clickPoint;

		//播放触摸屏幕的声音
		SimpleAudioEngine::sharedEngine()->playEffect(m_audio->getEffect((EFFECT_TYPE)0));
		return true;
	//}

	//return false;
}

这个时候在本层的触摸优先级是0,而那个暂停按钮也是0,暂停按钮就会得不到响应了,所以我们可以把暂停按钮的优先级设置的大些,我改成了-128,用到的函数是pause->setTouchPriority(-128);

最后的最后我不得不说还存在一个bug,当应用程序点击返回主菜单的按钮的时候会闪退,我logcat了一下,报的错是这样的。

小塔1024——移植androidrelease发生错误,但是在win32下没什么错误啊,找了老半天了,也没搞定,就留给大家吧,大家一定要搞定哈,然后给我留言,呵呵。

好了,最后我们的1024到这里就结束了,博客断断续续写了俩个礼拜,其实不应该这么长时间的,中间有点事就耽搁了,还请各位见谅。剩下的就是源代码和apk包了,这里为了宣传一下我的群,我把他们上传到群共享了,大家加了我的群(小塔cocos2d-x群298136329)去下载吧,最后关于1024的问题以及其他知识点的问题,欢迎大家加群或者加本人QQ讨论,我们共同进步吧!