H5版定點投籃遊戲(1)--物理模型抽象

來源:互聯網
上載者:User

標籤:


前言:
  前幾天目睹了大學同學開了個微店, 算是間接體驗公眾平台的使用. 覺得非常便捷和方便, 於是自己也想搗鼓一個. 公眾號取名: "木目的H5遊戲世界", 定位做成一個, 個人H5遊戲的小網站, 同時分享遊戲技術博文. 你的體驗, 是對我最大的肯定.
  本文將講述一下定點投籃遊戲的編寫, 主要闡述其物理模型的抽象, 後續慢慢的完善和迭代.

構思和體驗:
  當初設想, 是做一個簡單的H5遊戲, 可在移動端運行. 而且入手簡單, 一看即會. 但不知道做啥好? 後來看到朋友中有人以背身投籃照作為頭像, 覺得很向上又美好. 於是想到, 是不是做個簡單的定點投籃遊戲呢?
  說幹就幹, 因為有類似的投籃遊戲App可供參考, 遊戲創意不需要自己來構思, 因此算是一個模仿實現之作.
  
  線上體驗的遊戲連結: 定點投籃遊戲. (點我呀, 點我呀, ^_^!)

模型抽象:
  遊戲的主情境, 由籃板, 籃框, 籃球和地面組成. 籃球需投進籃框才能得分. 輔助線用於瞄準和定位, 簡單觸發即可投籃.
  由於是2維情境, 同時涉及到簡單物理碰撞和處理. 但還是決定殺雞用牛刀------使用box2d來構建物理模型. box2d是對真實物理世界的類比, 其諧調單位為米-千克-秒(MKS), 因此使用真實的資料去設定大小即可, 只要設定好與像素的對應縮放係數即可.
  為了體現"專業性", 特地參考了真實籃球場的尺寸參數.
  
  我們設定如下參數: 籃板高1.05米, 籃球半徑為0.123米, 籃框中心半徑為0.19米(比真實要小一些). 用盡量真實的資料, 在物理世界中類比.
  籃板是個靜態剛體, 忽略其寬長, 簡單設定為一條豎直的邊.

// *) 建立籃板var bodyDef = new b2BodyDef;bodyDef.type = b2Body.b2_staticBody;var fixDef = new b2FixtureDef;fixDef.shape = new b2PolygonShape;fixDef.shape.SetAsEdge(  new b2Vec2(1, 3),  new b2Vec2(1, 4.05));fixDef.restitution = 1;world.CreateBody(bodyDef).CreateFixture(fixDef);

  籃框的設定, 所見非所得, 其用了個很trick的方法. 它的圓框在物理世界中, 並不存在, 其所擁有的就兩個點: 左框點和右框點.
  

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);

  籃球是個球體, 其實動態剛體.

var bodyDef = new b2BodyDef();bodyDef.type = b2Body.b2_dynamicBody;var fixDef = new b2FixtureDef;fixDef.density = 1.5;fixDef.shape = new b2CircleShape(0.123);world.CreateBody(bodyDef).CreateFixture(fixDef);

核心演算法:
  除了物理引擎本身的以外, 還有兩個重要的核心要點. 一個是輔助拋物線, 另一個是籃球判進演算法.
  • 輔助拋物線
  有人曾評論到, 為何"憤怒的小鳥"火極一時, 是因為人們對"拋物線"的癡迷. 因此輔助拋物線也成了這個遊戲本身的核心要點. 輔助拋物線, 隱藏了投籃的角度和力量設定, 使得遊戲非常容易入手. 其採用類比描點法來進行繪製. 而不是反過來算的拋物線方程, 再來計算軌道點.

var dt = 0.62;for (var i = 0; i < dlevel; i++) {  var tx = spx * dt * i + this.posx * scaleFactor;  var ty = spy * dt * i - 0.5 * gavity * dt * dt * i * i + this.posy * scaleFactor;  this.tracklines[i].drawCircle(cc.p(tx, ty), 2, cc.degreesToRadians(180), 100, false, cc.color(0, 0, 0, 255));}

  注: 由物理公式得: Sx = Vx * t, Sy = Vy * t + 1/2 * a * t^2; Vx, Vy由投擲點決定.
  • 籃球判進判定演算法
  問題的本質就是如何判定籃球球心通過球框的直徑線段? 這個問題, 可以稍作變換. 記錄運動籃球的前後兩個時間點的圓心位置, 若該兩個點構成的線段, 與 藍框直徑構成的線段相交. 則認為籃球球心過了直徑線段. 即進球了.
  所以問題最終演化為, 求解兩個線段相交的判斷問題了?
  
  具體演算法, 可參見如下博文: 判斷兩線段是否相交. 引入了快速測試和跨立實驗這兩個階段.
  這邊的大致演算法代碼描述如下:

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遊戲世界
  

 

H5版定點投籃遊戲(1)--物理模型抽象

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.