• cocos2dx for wp 之Box2D游戏是男人就坚持60M(bug篇)(二)


    在上一篇里,我们已经实现了用手指控制属于你的精灵了,同时可以让它与篮球相互碰撞。

    现在是该加上一些判断条件了。比如说:只允许玩家与周围墙壁碰撞,和其他小球碰撞就游戏失败等。

    在tick函数里加上游戏失败判断条件:

    View Code
     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:但在这里我也不知道是什么原因,是因为我给球设置的冲力太大了还是又(“为什么说又呢,因为后面有好多奇怪不能解释的问题。继续看就知道了。”)因为平台移植的问题,在每对碰撞中的检测总是存在一定时间的延迟(有时候又很快),我也不知道为什么。明明按照上面的代码是可以判断出指定的小球是否发生判断。但是有的时候就是判断不出来。

    胜利条件:

    View Code
    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()里加上按钮

    View Code
    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)

    View Code
     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多,至于为什么这么多可以去看我上一篇随笔)

  • 相关阅读:
    会议安排最优算法
    Python Singleton
    Android HandlerThread 源代码分析
    [Android]_[0基础]_[adb 有用命令]
    使用sshfs将远程目录挂载到本地
    Netty 中ChannelOption的含义以及使用的场景
    netty4.0 Server和Client的通信
    Netty重要概念介绍
    Zookeeper单机伪集群
    整数集合
  • 原文地址:https://www.cnblogs.com/dieaz5/p/2991666.html
Copyright © 2020-2023  润新知