日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

H5版定点投篮游戏编程设计--物理模型抽象

發布時間:2024/8/26 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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版定点投篮游戏编程设计--物理模型抽象的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。