2011年4月22日 星期五

html5實作套用box2d物理引擎效果

使用 https://github.com/jwagner/box2d2-js
實作範例教學:
Javascirpt canvas處理

//圖片位置
$('#imgPath').hide();
var img_path = $('#imgPath').attr('src');
//canvas dom
$('body').append(
    $('<div id="main"/>').append(
        $('<canvas id="canvas"/>').attr(
            {width:$(window).width(),height:$(window).height()}
        )
    )
);

var tmpImg = new Array();
var tmpPosTop = new Array();
var tmpPosLeft = new Array();
var screenTop;
var screenLeft;
var pHeight;
var pWidth;
var imgTop;
var imgLeft;
 
//抓下圖片貼到canvas
var canvasDom = $('#canvas').get(0);
var ctx = canvasDom.getContext('2d');
ctx.fillStyle= 'FFFFFF';
var img = new Image();
img.src = img_path;
img.onload = function(){
    var i = 0;
    screenTop = Math.floor(($(window).height())/2) - this.height;
    screenLeft = Math.floor(($(window).width())/2) - this.width;
    pHeight = Math.floor(this.height/10);
    pWidth = Math.floor(this.width/10);
    imgTop = screenTop;
    imgLeft = screenLeft;
    ctx.drawImage(img,imgLeft,imgTop);
    //把圖存到array裡
    while( imgTop < this.height+screenTop && imgLeft < this.width+screenLeft ){
        tmpImg[i] = ctx.getImageData(imgLeft,imgTop,pWidth,pHeight);
        tmpPosTop[i] = imgTop;
        tmpPosLeft[i] = imgLeft;
        i++;
        imgLeft += pWidth;
        if( imgTop < this.height+screenTop && imgLeft >= this.width+screenLeft ){
            imgLeft = screenLeft;
            imgTop += pHeight;
        }
    }
    init();
}


加上box2d

var c_width = Math.floor(($(window).width())/10);
var ppm = ($(window).width())/c_width;
var c_height = ($(window).height())/ppm;
var worldAABB = new b2AABB();
worldAABB.lowerBound.Set(-1000.0, -1000.0);
worldAABB.upperBound.Set(1000.0, 1000.0);
var world = new b2World(worldAABB, new b2Vec2(0.0, -9.8), true);
window.world = world;

var groundBodyDef = new b2BodyDef();
groundBodyDef.position.Set(c_width/2.0, 3.0);
var groundBody = world.CreateBody(groundBodyDef);
var groundShapeDef = new b2PolygonDef();
groundShapeDef.restitution = 0.0;
groundShapeDef.friction = 0.5;
groundShapeDef.density = 1.0;
groundBody.w = c_width*1.0
groundBody.h = 5.0
groundShapeDef.SetAsBox(groundBody.w, groundBody.h);
groundBody.CreateShape(groundShapeDef);
groundBody.SynchronizeShapes();
var bodies = [groundBody];

function init(){
    ctx.setTransform(ppm, 0, 0, -ppm, 0, $(window).height());  
    for( i=0; i<tmpImg.length; i++ ){
        var bodyDef = new b2BodyDef();
        bodyDef.position.Set(tmpPosLeft[i]/ppm, c_height-(tmpPosTop[i]/ppm));
        //bodyDef.position.Set(5, 5);
        var body = world.CreateBody(bodyDef);
        var shapeDef = new b2PolygonDef();
        shapeDef.SetAsBox(1.0, 1.0);
        body.w = pWidth/ppm;
        body.h = pHeight/ppm;
        shapeDef.restitution = 0.0;
        shapeDef.density = 1.0;
        shapeDef.friction = 0.9;
        body.CreateShape(shapeDef);
        body.SetMassFromShapes();
        bodies.push(body);
    }
}   

var frame = 0;
window.setInterval(function() {
    world.Step(1.0/60.0, 10);
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, $(window).width(), $(window).height());
    for(var i = 0; i < bodies.length; i++){
        var body = bodies[i];
        var t = body.m_xf;
        var posX = t.position.x;
        var posY = t.position.y;
        var angle = body.GetAngle();
        //if(tmpImg[i] != undefined){
        if(i>0){
            var x = $(window).width()-($(window).width()-(posX*ppm));
            var y = $(window).height()-(posY*ppm);
            ctx.putImageData(tmpImg[(i-1)],x,y);
        }else{
            ctx.fillStyle = 'white';
            ctx.translate(posX, posY)
            ctx.rotate(angle);
            ctx.fillRect(-body.w, -body.h, body.w*2, body.h*2);
            ctx.rotate(-angle);
            ctx.translate(-posX, -posY)
        }
    }
}, 1000/30); 

 
實作範例 : http://excite.978.tw/html5/particle_box2d.php
 
 

沒有留言:

張貼留言