Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

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