cocos2d-x for wp 之Box2D游戏-是男人就坚持60M(bug篇)(二)
在上一篇里,我们已经实现了用手指控制属于你的精灵了,同时可以让它与篮球相互碰撞。
现在是该加上一些判断条件了。比如说:只允许玩家与周围墙壁碰撞,和其他小球碰撞就游戏失败等。
在tick函数里加上游戏失败判断条件:
1 foreach (var item in contactListener.contacts) 2 { 3 #region 两种方法判断玩家和球是否碰撞都存在一定时间的反应 4 5 //for (int i = 0; i < ballFixtureList.Count; i++) 6 //{ 7 // //gameover 8 // if ((item.fixtureA == playFixture && item.fixtureB == ballFixtureList[i]) || 9 // (item.fixtureA == ballFixtureList[i] && item.fixtureB == playFixture)) 10 // { 11 // CCScene pScene = new Screens.GameOver(false); 12 // CCDirector.sharedDirector().replaceScene(pScene); 13 // } 14 //} 15 16 Body bodyA = item.fixtureA.GetBody(); 17 Body bodyB = item.fixtureB.GetBody(); 18 if (bodyA.GetUserData() != null && bodyB.GetUserData() != null) 19 { 20 CCSprite spriteA = (CCSprite)bodyA.GetUserData(); 21 CCSprite spriteB = (CCSprite)bodyB.GetUserData(); 22 23 //Sprite A = ball, Sprite B = Block 24 if (spriteA.tag == 1 && spriteB.tag == 2) 25 { 26 CCScene pScene = new Screens.GameOver(false); 27 CCDirector.sharedDirector().replaceScene(pScene); 28 } 29 //Sprite B = block ,Sprite A = ball 30 else if (spriteA.tag == 2 && spriteB.tag == 1) 31 { 32 CCScene pScene = new Screens.GameOver(false); 33 CCDirector.sharedDirector().replaceScene(pScene); 34 } 35 } 36 #endregion 37 38 }
一般来说,游戏到这里基本逻辑就结束了。剩下的就是界面的美化和一些细节的细化了。比如我自己就多加了一些关卡。(我不会美工,随便搞了一些)
现在说下我在写这个小游戏遇到的一些难题或者bug
bug1:但在这里我也不知道是什么原因,是因为我给球设置的冲力太大了还是又(“为什么说又呢,因为后面有好多奇怪不能解释的问题。继续看就知道了。”)因为平台移植的问题,在每对碰撞中的检测总是存在一定时间的延迟(有时候又很快),我也不知道为什么。明明按照上面的代码是可以判断出指定的小球是否发生判断。但是有的时候就是判断不出来。
胜利条件:
1 if (Classes.Constant.time >= 60) 2 { 3 CCScene pScene = new Screens.GameOver(true); 4 CCDirector.sharedDirector().replaceScene(pScene); 5 }
bug2:但是我发现在wp里用box2d有个不算bug的bug。就是当游戏Tombstoning之后再切回游戏后,所有物体的运动都变得非常缓慢。
想了很久没发现为什么。但是问题既然来了还是得解决。解决方法如下:
我测试了AppDelegate类里面的applicationDidFinishLaunching() applicationDidEnterBackground() applicationWillEnterForeground()
发现applicationDidEnterBackground() applicationWillEnterForeground()根本不会触发。不知道为什么,就是不触发。
后来在Game1类里找到了解决方法:
重写OnActivated()函数,在Game1里设置一个静态变量,用来监测游戏是否进入了墓碑化。
1 protected override void OnActivated(object sender, EventArgs args) 2 { 3 isStart = false;//防止box2d模拟的物理世界失去“动力”的标记 4 base.OnActivated(sender, args); 5 }
然后在游戏里再根据这个标记来执行这句话
world.Step(dt, 10, 10);
在这里我用了一个按钮来触发这个事件:
在init()里加上按钮
1 CCMenuItem sMenu = CCMenuItemImage.itemFromNormalImage("images/Start", "images/Start", this, moving); 2 CCMenu menu = CCMenu.menuWithItems(sMenu); 3 menu.position = new CCPoint(winSize.width / 2, winSize.height / 2 + 50); 4 this.addChild(menu, 2, 201);
再在按钮的回调函数里执行线程schedule(tick)
1 /// <summary> 2 /// start按钮的回调函数 3 /// </summary> 4 /// <param name="sender"></param> 5 void moving(CCObject sender) 6 { 7 Game1.isStart = true; 8 CCMenuItem cm = (CCMenuItem)sender; 9 cm.visible = false; 10 this.schedule(tick); 11 }
在tick里判断isStart:
if (Game1.isStart) { world.Step(dt, 10, 10); }
这样设置的好处是,每次从墓碑化重新回来游戏界面时,不会出现“缓慢”物体的情况。
缺点是每次进来游戏都需要点击一次start按钮来"启动"游戏。
bug3:这个bug是让我烦了最久的一个!!!没有之一!为什么,因为居然是cocos2d-xna.dll这个文件的问题!这个bug就是触摸屏的bug。
在前面我们给游戏的失败结束判断是两球碰撞了,而一般这个时候,我们的手指在碰撞时还是处在一个持续移动的过程中。当两球碰撞之后我们程序是跳转到游戏结束界面的,但就在跳转了的同时,会触发touch事件的一个错误。
我没截图下来保存。
错误提示在这里面的“0.1.2\cocos2d-cocos2d-x-for-xna-5341c4a\cocos2d-xna\platform\CCApplication”有错误,
而且报错点在这里“movedTouches.Add(m_pTouchMap[touch.Id].Value);”
想了很久百思不得其解,甚至将代码改为了和fengyun1989一样(fengyun1989是将触摸事件写在layer界面的,我原先是独立出来在精灵类里的),将触摸事件也写在了layer层。但是还是不行。然后后来把我原先用的cocos2d-xna.dll替换会fengyun1989用的cocos2d-xna.dll才没问题。。。。
友情提示,我用的是0.1.2这个版本的dll。
但是,我也不知道是不是我人品有问题。
我在学习Nowpaper 十五英寸的世界的一篇文章Cocos2d-xna : 横版战略游戏开发实验2 Sprite和Scene场景制作里按照他的代码来实现plist时,居然又出问题!
问题如下:
System.Xml.XmlException”类型的异常在 System.Xml.ni.dll 中发生,但未在用户代码中进行处理
好吧,问题还是在cocos2d-xna.dll这个文件里,我又把原来fengyun1989的替换为Nowpaper里的dll。好吧,又没问题了。
至此,这次的编程就算告一段落了。
下面是一些外链:
我这个不算游戏的游戏在微软的市场应用链接:http://www.windowsphone.com/s?appid=6874ef0d-c942-4166-958b-bfc201572976
Nowpaper的Lib:http://dl.vmall.com/c0rgdp5h6r
我自己这个游戏的全代码:http://dl.vmall.com/c0pd4yv3s6(这个代码大小为11M多,至于为什么这么多可以去看我上一篇随笔)