Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

pixi.jsの判定処理、及びcontainerの扱い

インタラクティブ性のあるゲームを作るなら避けては通れない衝突判定。
pixiでやる場合、自分で用意するしかありません。

実際のところ

猫が虎を吸収合併して大きくなる塊魂的なクソゲーモックアップを考えます。

キモとなるヒット関数はこんな感じ。
参考もとをベースに、好みに書き換えました。
まだまだリファクタリングの必要が有る感じですが。

function hitRectangle(r1, r2) {                                                      
    var hit, cmbWth, cmbHgh, vx, vy                                                  
    hit = false                                                                      
                                                                                     
    r1.hlfW  = r1.width  / 2                                                         
    r1.hlfH  = r1.height / 2                                                         
    r2.hlfW  = r2.width  / 2                                                         
    r2.hlfH  = r2.height / 2                                                         
                                                                                     
    r1.cX = r1.x + r1.hlfW;                                                          
    r1.cY = r1.y + r1.hlfH;                                                          
    r2.cX = r2.x + r2.hlfW;                                                          
    r2.cY = r2.y + r2.hlfH;
                                                                                    
    vx = r1.cX - r2.cX                                                               
    vy = r1.cY - r2.cY                                                               
                                                                                     
    cmbWth = r1.hlfW + r2.hlfW;                                                      
    cmbHgh = r1.hlfH + r2.hlfH;                                                      
                                                                                     
    if ((Math.abs(vx) < cmbWth) && (Math.abs(vy) < cmbHgh)) { hit = true }

   return hit
}

これを踏まえて、他の部分も実装します。

コンテナを追加

まず、これまで一つだったコンテナにplayerを示すコンテナを追加します。
プレイヤーキャラは猫のアイコンなので、setup時に猫だけplayerに追加。
その後、stageにaddChildする形でマップに描画させます。

//コンテナを追加                                                                     
var player = new PIXI.Container()                                                    
var stage  = new PIXI.Container() 
// ……

function setup() {                                                                   
    var id;                                                                          
    id = PIXI.loader.resources["views/images/animals.json"].textures                 
                                                                                                                               
    cat = new Sprite(id["cat.png"])                                                  
    cat.position.set(oneChip, oneChip)                                               
    cat.vx = 0                                                                       
    cat.vy = 0                                                                       
    player.addChild(cat)                                                             
                                                                                     
    tiger = new Sprite(id["tiger.png"])                                              
    tiger.position.set(oneChip * 5, oneChip * 5)                                     
    stage.addChild(tiger)


  //…
}

//…

function gameLoop() {                                                                
    //1fps毎に呼び出し                                                               
    requestAnimationFrame(gameLoop)                                                  
    state();                                                                         
    //Render the stage                                                               
    stage.addChild(player)                                                           
    renderer.render(stage)                                                           
} 

衝突判定はplay関数でやります。
虎アイコンに接触したらくっ付く形で。
位置決定は……今回は楽するために直打ちしましたスミマセン。

function play() {                                                                    
    cat.x += cat.vx                                                                  
    cat.y += cat.vy                                                                  
                                                                                     
    function gather(boss,follower,posX,posY) {                                       
        stage.removeChild(follower)                                                  
        player.addChild(follower)                                                    
        follower.position.set(boss.x + posX, boss.y + posY)                          
    }                                                                                
                                                                                     
    //check for a collision between the cat and the box                              
    if (hitRectangle(cat, tiger) ) { gather(cat,tiger, 10, 10) }                     
    if (hitRectangle(cat, tiger2)) { gather(cat,tiger2, 8, -8) }                     
                                                                                     
}

動作の様子

近づいて……
f:id:shuzo_kino:20160414230745p:plain
一定距離になるとくっ付く。
……うーん、クソゲーだ。
f:id:shuzo_kino:20160414230753p:plain