HTML5趣味台球案例html5 canvas撞球动画示例 碰撞检测,演示过程中,在页面上始终显示FPS AVG: 84.61 CUR: 83.42 number:1等信息,可定义缓冲和不缓冲,点击“buffer”后可看到,很多小球在无规则运动,撞到边缘会自动弹回,对canvas的理解有帮助。

<!DOCTYPE HTML>
<html>
<title>html5 canvas撞球实例 碰撞检测</title>
<body>
<div style="width:400px;margin:0 auto">
<canvas id="main" style="background-color:green;width:400px;height:400px"></canvas>
<div id="fps"></div>
<input type="button" value="stop" onclick="cancel()"/>
<input type="button" value="noBuffer" onclick="addCreatures(10)"/>
<input type="button" value="Buffer" id="buf"/>
</div>
</body>
<script>
var ctx;
var width;
var height;
var delta;
var lastTime;
var frames;
var totalTime;
var updateTime;
var updateFrames;
var creats = new Array();
var id;
var nobufferArr = [],bufferArr = [];
var manipulate = {
    MAX : 300,
    head : 0,
    tail : 0,
    history : [],
    id : -1,
    clickHander : function(e){
        this.history[this.head] = 1;
        this.head = (this.head + 1 + this.MAX) % this.MAX;
    },
    init : function(){
        for(var i = 0; i < 300; i++){
            this.history[i] = 0;
        }
        that = this;
        this.id = setInterval(function(){
           var len = (that.head - that.tail + that.MAX) % that.MAX;
            if(len > 0){
                
                for(var i = 0; i<len; i++){
                    that.tail = that.tail % that.MAX;
                    if(that.history[that.tail]==1){
                         addCreatures(10);
                         that.history[that.tail]=0;
                         if(this.head>300) clearInterval(this.id);
                    }
                    that.tail++;
                }
            }
        },0)
    }

}
manipulate.init();
var buf = document.getElementById("buf");
buf.onclick = function(e){
    manipulate.clickHander(e);
}
function cancel(){

   if(id)
   clearInterval(id)
}
function addCreatures(count){
    for(var i=0;i<count;i++){
        addCreature(i);
    }
}
function init() {
    var canvas =document.getElementById('main');
    width = canvas.width = 400;
    height = canvas.height = 400; 
   // alert(width+" "+height)
    ctx = canvas.getContext('2d');
    for(var i=0; i < 1; ++i) {
        addCreature();
    }
    lastTime = (new Date()).getTime();
    frames = 0;
    totalTime = 0;
    updateTime = 0;
    updateFrames =0;
    id = setInterval(update, 10);
}

function delay(time){
    var st = new Date;
    while(new Date - st < time);
}

function addCreature() {
    var c = new Creature(Math.random()*100,Math.random()*200);
    //delay(3000);
    creats.push(c);
}
function update() {
    var now = (new Date()).getTime();
    delta = now-lastTime;
    lastTime = now;
    totalTime+=delta;
    frames++;
    updateTime+=delta;
    updateFrames++;
    if(updateTime > 1000) {
        document.getElementById('fps').innerHTML = "FPS AVG: " + (1000*frames/totalTime).toFixed(2) + " CUR: " + (1000*updateFrames/updateTime).toFixed(2)+" number:"+creats.length;
        updateTime = 0;
        updateFrames =0;
    }
    for(var i=0; i < creats.length; ++i) {
        creats[i].move();
    }

    draw();
   // if(totalTime>5000) cancel();
}
function draw() {
    ctx.clearRect(0,0,width,height);
    creats.forEach(drawCreat);
}
function drawCreat(c,i,a) {
    if (!onScreen(c)) {
        return;
    }
    ctx.strokeStyle = "#FFFFFF";
    ctx.fillStyle="red";
    ctx.beginPath();
    ctx.arc(c.x, c.y, 5, 0, Math.PI*2, true); 
    ctx.closePath();
    ctx.stroke();
    ctx.fill();
}

function onScreen(o) {
    return o.x >= 0 && o.y >= 0 && o.x <= width && o.y <=height;
}
function Creature(x1,y) {
    this.x = x1;
    this.y = y;
    this.dx = Math.random()*2;
    this.dy = Math.random()*2;
    this.move = function() {
        this.x+=this.dx;
        this.y+=this.dy;
        if(this.x < 0 || this.x > width) {
            this.dx*=-1;
        }
        if(this.y < 0 || this.y > height) {
            this.dy*=-1;
        }
    }
}
init();
</script>
</html>