175211ll0ibjwozz50arn0.png
  在线体验的游戏链接: 定点投篮游戏。 (点我呀, 点我呀, ^_^!)模型抽象:

  游戏的主场景, 由篮板, 篮框, 篮球和地面组成。 篮球需投进篮框才能得分。 辅助线用于瞄准和定位, 简单触发即可投篮。

  由于是2维场景, 同时涉及到简单物理碰撞和处理。 但还是决定杀鸡用牛刀------使用box2d来构建物理模型。 box2d是对真实物理世界的模拟, 其谐调单位为米-千克-秒(MKS), 因此使用真实的数据去设定大小即可, 只要设定好与像素的对应缩放系数即可。

  为了体现专业性, 特地参考了真实篮球场的尺寸参数。

1752123n6b3p9dddr999dd.png
  我们设定如下参数: 篮板高1。05米, 篮球半径为0。123米, 篮框中心半径为0。19米(比真实要小一些)。 用尽量真实的数据, 在物理世界中模拟。

  篮板是个静态刚体, 忽略其宽长, 简单设定为一条竖直的边。

 

 

  1. // *) 创建篮板
  2. var bodyDef = new b2BodyDef;
  3. bodyDef.type = b2Body.b2_staticBody;
  4.  
  5. var fixDef = new b2FixtureDef;
  6. fixDef.shape = new b2PolygonShape;
  7. fixDef.shape.SetAsEdge(
  8.   new b2Vec2(1, 3),
  9.   new b2Vec2(1, 4.05)
  10. );
  11. fixDef.restitution = 1;
  12. world.CreateBody(bodyDef).CreateFixture(fixDef);

 

  1. var bodyDef = new b2BodyDef;
    • var fixDef = new b2FixtureDef;
      • bodyDef.type = b2Body.b2_staticBody;
        •  
        • // 左框点
          • bodyDef.position.x = 1.09;
            • bodyDef.position.y = 3.05;
              • fixDef.shape = new b2CircleShape(0.01);
                • world.CreateBody(bodyDef).CreateFixture(fixDef);
                  •  
                  • // 右框点
                    • bodyDef.position.x = 1.5;
                      • bodyDef.position.y = 3.05;
                        • fixDef.shape = new b2CircleShape(0.01);
                          • world.CreateBody(bodyDef).CreateFixture(fixDef);

  具体算法, 可参见如下博文: 判断两线段是否相交。 引入了快速测试和跨立试验这两个阶段。

  这边的大致算法代码描述如下:

 

 

  1. collideWith:function(ball) {
    •   // *)
      •   var px1 = ball.prevposx;
        •   var py1 = ball.prevposy;
          •   var px2 = ball.posx;
            •   var py2 = ball.posy;
              •  
              •   var qx1 = 1.1, qx2 = 1.5;
                •   var qy1 = 3.05, qy2 = 3.05;
                  •  
                  •   // *) 快速测试,
                    •   if (!(Math.min(px1, px2) <= Math.max(qx1, qx2)
                      •        Math.min(qx1, qx2) <= Math.max(px1, px2)
                        •        Math.min(py1, py2) <= Math.max(qy1, qy2)
                          •        Math.min(qy1, qy2) <= Math.max(py1, py2))) {
                            •     return false;
                              •   }
                                •  
                                •   // *) 交叉判定
                                  •   var d1 = (px1 - qx1) * (qy2 - qy1) - (qx2 - qx1) * (py1 - qy1);
                                    •   var d2 = (px2 - qx1) * (qy2 - qy1) - (qx2 - qx1) * (py2 - qy1);
                                      •   
                                        •   var d3 = (qx1 - px1) * (py2 - py1) - (px2 - px1) * (qy1 - py1);
                                          •   var d4 = (qx2 - px1) * (py2 - py1) - (px2 - px1) * (qy2 - py1);
                                            •  
                                            •   if (d1 * d2 < 0 d3 * d4 < 0) {
                                              •     return true;
                                                •   } else if ( d1 == 0 this.isOnSegline(qx1, qy1, qx2, qy2, px1, py1) ) {
                                                  •     return true;
                                                    •   } else if ( d2 == 0 this.isOnSegline(qx1, qy1, qx2, qy2, px2, py2) ) {
                                                      •     return true;
                                                        •   } else if ( d3 == 0 this.isOnSegline(px1, py1, px2, py2, qx1, qy1) ) {
                                                          •     return true;
                                                            •   } else if ( d4 == 0 this.isOnSegline(px1, py1, px2, py2, qx2, qy2) ) {
                                                              •     return true;
                                                                •   }
                                                                  •   return false;
                                                                    • },
                                                                      • isOnSegline: function(px1, py1, px2, py2, px3,py3) {
                                                                        •   var minx = Math.min(px1, px2);
                                                                          •   var maxx = Math.max(px1, px2);
                                                                            •   var miny = Math.min(py1, py2);
                                                                              •   var maxy = Math.max(py1, py2);
                                                                                •   return px3 >= minx px3 <= maxx py3 >= miny py3 <= maxy;
                                                                                  • }
复制代码
  总结:

  朋友玩了一把, 吐槽不少, 不过还是很开心, 能体验就是种肯定。 后期一定好好再改善一把, 使得其用户体验上, 更加友好。

  相关阅读:H5版俄罗斯方块游戏开发:需求分析和框架实现

锐亚教育

锐亚教育,游戏开发论坛|游戏制作人|游戏策划|游戏开发|独立游戏|游戏产业|游戏研发|游戏运营| unity|unity3d|unity3d官网|unity3d 教程|金融帝国3|8k8k8k|mcafee8.5i|游戏蛮牛|蛮牛 unity|蛮牛