Canvas 小游戏 台球

预览地址:点击预览

尚未完善,持续更新... /3.8/

操作方法:鼠标放到蓝球上点击拉动松开即可,顶部红色线条为力度,力度与该长度成正比。

请使用非IE内核浏览器。

//(2012.3.9)

1、鼠标移出画布清除线条和球杆。

2、记录桌面球体移动数量。(防止连续动作)

 

HTML部分:

<!DOCTYPE HTML>
<html>
<head>
<title>
Canvas 台球
</title>
</head>
<body>
</body>
</html>

 

JS部分:

(function(){
/*
Author:Jin.dh
Date:2012/3/8(最后更新2012/3/9)
Site:http://www.js63.net
Blog:hi.baidu.com/webstarting
*/

//创建标签
function $C(tag){
var ele = document.createElement(tag||"div");
return ele;
};

//创建DOM
function $D(tag,css,father){
if(!tag||!tag)return;
var obj = $C(tag);
$M(obj,css);
father = father || document.body;
father.appendChild(obj);
return obj;
};

//设置样式
function $M(o,css){
var me = o,m = me.style,x,y;
for(var i in css){
x = css[i];
y = x+"px";
switch(i){
case "t" : m.top = y;break;
case "w" : m.width = y;break;
case "h" : m.height = y;break;
case "t" : m.top = y;break;
case "i" : o.innerHTML = x;break;
case "bd": m.border = x;break;
case "d" : m.display = x;break;
case "c" : m.color = x;break;
case "bg": m.backgroundColor = x;break;
default : m[i] = x;break;
}
};
return me;
};

//台球画布
var canvasAttr ={
w:500,
h:500
}
//红球
var redBall = {
y:150,
x:150,
speedX:30,
timer:0,
speedY:30,
r:12,
speed:30,
b:"red",
move:false
};

//蓝球
var blueBall = {
y:120,
x:180,
show:true,
timer:0,
r:12,
speed:0,
drag:false,
b:"blue",
move:false
};

//白球
var blackBall = {
y:blueBall.x,
x:blueBall.y,
show:false,
timer:0,
r:12,
speed:0,
speedX:0,
speedY:0,
ang:0,
b:"#fff",
move:false,
lastX:0,
lastY:0
};

//敲击路线
var beatLine = {
w : 1,
l:0,
ad:50,
toX:0,
toY:0,
show:false,
c:"#333"
};

//敲击预测路线
var beatLine_ad = {
x:blueBall.x,
y:blueBall.y,
toX:0,
toY:0
};

//重量轴
var scale = {
w:10,
c:"red",
x:0,
y:0 ,
max_x:canvasAttr.w,
show:true,
fx:true,
timer:0
}

//画红球
function drewRed(){
ctx.beginPath();
ctx.arc(redBall.x,redBall.y,redBall.r,0,Math.PI*2,true);
ctx.fillStyle = redBall.b;
ctx.fill();
ctx.closePath();
};

//画蓝球
function drewBlue(){
if(blueBall.show){
ctx.beginPath();
ctx.arc(blueBall.x,blueBall.y,blueBall.r,0,Math.PI*2,true);
ctx.fillStyle = blueBall.b;
ctx.fill();
ctx.closePath();
};
};

//画白球
function drewBlack(){
if(blackBall.show){
ctx.beginPath();
ctx.arc(blackBall.x,blackBall.y,blackBall.r,0,Math.PI*2,true);
ctx.fillStyle = blackBall.b;
ctx.fill();
ctx.closePath();
};
};

//画重量轴
function drewScale(){
if(scale.show){
ctxSsale.beginPath();
ctxSsale.moveTo(0,0);
ctxSsale.lineTo(scale.x,0);
ctxSsale.lineWidth = scale.w;
ctxSsale.strokeStyle = scale.c;
ctxSsale.stroke();
ctxSsale.closePath();
}
};

//敲击路线
function drewLine(o){

if(beatLine.show){
ctx.beginPath();
ctx.moveTo(blackBall.x,blackBall.y);
ctx.lineTo(o.toX,o.toY);
ctx.lineWidth = beatLine.w;
ctx.strokeStyle = beatLine.c;
ctx.stroke();
ctx.closePath();
}
}

//瞄方向
function moveLine(e){
if(blackBall.show){
ctx.clearRect(0,0,canvasAttr.w,canvasAttr.h);
//画球
drewRed();
drewBlue();

//描路线
beatLine.show = true;
blackBall.x = e.clientX-canvas.offsetLeft;
blackBall.y = e.clientY-canvas.offsetTop;
beatLine.toX = blueBall.x;
beatLine.toY = blueBall.y;

var jiao =isDeat(blackBall,blueBall);//获取三角

//计算外加长度
blackBall.ang = Math.atan(jiao.h/jiao.w); //获取白球角度


//方向判断
if(jiao.fx=="x-y-"){
beatLine_ad.toX = blueBall.x-Math.cos(blackBall.ang)*beatLine.ad;
beatLine_ad.toY = blueBall.y-Math.sin(blackBall.ang)*beatLine.ad;
}else if(jiao.fx=="x-y+"){
beatLine_ad.toX = blueBall.x-Math.cos(blackBall.ang)*beatLine.ad;
beatLine_ad.toY = blueBall.y-Math.sin(blackBall.ang)*beatLine.ad;
}else if(jiao.fx=="x+y-"){
beatLine_ad.toX = blueBall.x+Math.cos(blackBall.ang)*beatLine.ad;
beatLine_ad.toY = blueBall.y+Math.sin(blackBall.ang)*beatLine.ad;
}else if(jiao.fx=="x+y+"){
beatLine_ad.toX = blueBall.x+Math.cos(blackBall.ang)*beatLine.ad;
beatLine_ad.toY = blueBall.y+Math.sin(blackBall.ang)*beatLine.ad;
};

drewLine(beatLine);
drewLine(beatLine_ad);
drewBlack();
}
}

//初始化
function init(){
ctx.clearRect(0,0,canvasAttr.w,canvasAttr.h);
drewRed();
drewBlue();
bindEvent();
};

//移动白球
function moveBlack(){
setMove("+"); //移动球数量+1
var startT = getT(); //记录时间
var jiao =isDeat(blackBall,blueBall);//获取三角
blackBall.speed = jiao.l*(scale.x/1500); //白球速度 ((斜边长度*重度/800)/一秒时间)
ctx.clearRect(0,0,canvasAttr.w,canvasAttr.h);
//方向判断
if(jiao.fx=="x-y-"){
blackBall.speedX = -blackBall.speed*Math.cos(blackBall.ang);
blackBall.speedY = -blackBall.speed*Math.sin(blackBall.ang);
}else if(jiao.fx=="x-y+"){
blackBall.speedX = -blackBall.speed*Math.cos(blackBall.ang);
blackBall.speedY = -blackBall.speed*Math.sin(blackBall.ang);
}else if(jiao.fx=="x+y-"){
blackBall.speedX = blackBall.speed*Math.cos(blackBall.ang);
blackBall.speedY = blackBall.speed*Math.sin(blackBall.ang);
}else if(jiao.fx=="x+y+"){
blackBall.speedX = blackBall.speed*Math.cos(blackBall.ang);
blackBall.speedY = blackBall.speed*Math.sin(blackBall.ang);
};
blackBall.timer =setInterval(function(){
var jiao_blueRed =isDeat(blackBall,blueBall);//获取三角
//移动
ctx.clearRect(0,0,canvasAttr.w,canvasAttr.h);
blackBall.speedX*=.9;
blackBall.speedY*=.9;
blackBall.speed*=.9;
if(Math.abs(blackBall.speedX)<=0.1){
blackBall.speedX = 0;
};
if(Math.abs(blackBall.speedY)<=0.1){
blackBall.speedY = 0;
};
blackBall.x += blackBall.speedX;
blackBall.y += blackBall.speedY;
setFx(blackBall);
drewBlack();
drewBlue();
drewRed();

//判断是否击中蓝球
if(jiao_blueRed.yes){
clearInterval(blackBall.timer);
setMove("-"); //移动球数量-1
blackBall.show = false;
blueBall.move = true;
moveBlue();
};


//是否已经停止
if(Math.abs(blackBall.speedX)===0&&Math.abs(blackBall.speedY)===0){
setMove("-"); //移动球数量-1
ctx.clearRect(0,0,canvasAttr.w,canvasAttr.h);
drewRed();
drewBlue();

blackBall.show = false;
clearInterval(blackBall.timer);
};

},20);

};

//移动蓝球
function moveBlue(){
setMove("+"); //移动球数量+1
blueBall.speed = blackBall.speed;
if(blueBall.move){
var jiao =isDeat(blueBall,redBall);//获取三角
canvas.onmousemove = null;
blueBall.speedX = blackBall.speedX;
blueBall.speedY = blackBall.speedY;
blueBall.timer = setInterval(function(){
var jiao =isDeat(blueBall,redBall);//获取三角
blueBall.speedX*=0.9;
blueBall.speedY*=0.9;
blueBall.speed *= 0.9
ctx.clearRect(0,0,canvasAttr.w,canvasAttr.h);
if(Math.abs(blueBall.speedX)<=0.1){
blueBall.speedX = 0;
};
if(Math.abs(blueBall.speedY)<=0.1){
blueBall.speedY = 0;
};
blueBall.x+=blueBall.speedX;
blueBall.y+=blueBall.speedY;
setFx(blueBall);
drewBlue();
drewBlack();
drewRed();

if(jiao.yes){
redBall.move = true;
moveRed();
};

if(Math.abs(blueBall.speedX)===0&&Math.abs(blueBall.speedY)===0){
clearInterval(blueBall.timer);
setMove("-"); //移动球数量-1
};
},30);

};

};

//移动红球
function moveRed(){
setMove("+"); //移动球数量+1
var jiao =isDeat(blueBall,redBall);//获取三角
redBall.speed = blueBall.speed;
//方向判断

if(jiao.fx=="x-y-"){
redBall.speedX = -redBall.speed*Math.cos(jiao.ang);
redBall.speedY = -redBall.speed*Math.sin(jiao.ang);
}else if(jiao.fx=="x-y+"){
redBall.speedX = -redBall.speed*Math.cos(jiao.ang);
redBall.speedY = -redBall.speed*Math.sin(jiao.ang);
}else if(jiao.fx=="x+y-"){
redBall.speedX = redBall.speed*Math.cos(jiao.ang);
redBall.speedY = redBall.speed*Math.sin(jiao.ang);
}else if(jiao.fx=="x+y+"){
redBall.speedX = redBall.speed*Math.cos(jiao.ang);
redBall.speedY = redBall.speed*Math.sin(jiao.ang);
};


ctx.clearRect(0,0,canvasAttr.w,canvasAttr.h);
if(redBall.move){
redBall.timer = setInterval(function(){
redBall.speedX*=0.95;
redBall.speedY*=0.95;
if(Math.abs(redBall.speedX)<=0.1){
redBall.speedX = 0;
};
if(Math.abs(redBall.speedY)<=0.1){
redBall.speedY = 0;
};
ctx.clearRect(0,0,canvasAttr.w,canvasAttr.h);
redBall.x+=redBall.speedX;
redBall.y+=redBall.speedY;
setFx(redBall);
drewRed();
drewBlue();
drewBlack();

if(Math.abs(redBall.speedX)===0&&Math.abs(redBall.speedY)===0){
clearInterval(redBall.timer);
setMove("-"); //移动球数量-1
};
},20);

}
}


//判断是否相撞,测算角度,移动方向(三角函数算出斜边来判断)
function isDeat(obj1,obj2){
var x,y,r,ang,fx,o,l,yes = false;//l为三角斜线长度
x = obj1.x - obj2.x;
y = obj1.y - obj2.y;
r = obj1.r + obj2.r;

if(Math.abs(x*x+y*y) <= r*r){ //斜边2 = 直角边长平方之和
yes = true;
};

l = Math.abs(Math.sqrt(x*x+y*y));
ang = Math.atan(x/y);
if(x>0 && y>0){ //右下
fx = "x-y-";
}else if(x>0 && y<0){ //右上
fx = "x-y+";
}else if(x<0 && y>0){ //左下
fx = "x+y-";
}else if(x<0 && y<0){ //左上
fx = "x+y+";
};
return o ={w:x,h:y,fx:fx,yes:yes,l:l,ang:ang};

};

//移动重量轴
function setScale(){
if(scale.show){
clearInterval(scale.timer);
scale.timer = setInterval(function(){
ctxSsale.clearRect(0,0,canvasAttr.w,scale.w);
if(scale.fx && scale.x >= scale.max_x){
scale.fx = false;
}else if(!scale.fx && scale.x <= 0){
scale.fx = true;
};
if(scale.fx){
scale.x+=5;
}else if(!scale.fx){
scale.x-=5;
};
drewScale();
},30);
}
}

//改变方向
function setFx(o){
if(o.x>=canvasAttr.w-o.r){
o.x = canvasAttr.w-o.r;
o.speedX*=-1;
};
if(o.x<=o.r){
o.x = o.r;
o.speedX*=-1;
}
if(o.y>=canvasAttr.h-o.r){
o.y = canvasAttr.h-o.r;
o.speedY*=-1;
}
if(o.y<=o.r){
o.y = o.r;
o.speedY*=-1;
};
};

//花费时间
function getT(){
var now = new Date();
var t = now.getTime();
return t;
};

function showMsg(a){
document.title = a;
};

var isMove = 0;//记录移动球数量
//设置状态
function setMove(o){
switch(o){
case "+" :
isMove +=1 ;
canvas.onmousedown = null;
canvas.onmousemove = null;
canvas.onmouseout = null;
canvas.onmouseup = null;

break;
case "-" :
isMove -=1;
if(isMove<=0){
bindEvent();
};
break;
default : ;
}

};

//绑定事件
function bindEvent(){
canvas.onmousedown = function(e){
blackBall.lastX = blackBall.x;
blackBall.lastY = blackBall.y;
setScale();
blackBall.show = true;
beatLine.show = true;
canvas.onmousemove = function(e){
moveLine(e);
}
};


canvas.onmouseup = function(e){
if(blackBall.show){
beatLine.show = false;
clearInterval(scale.timer);
moveBlack();
canvas.onmousemove = null;
};
};

canvas.onmouseout = function(e){
if(blackBall.show){
ctx.clearRect(0,0,canvasAttr.w,canvasAttr.h);
ctxSsale.clearRect(0,0,canvasAttr.w,scale.w);
drewBlue();
drewRed();
//beatLine.show = false;
blackBall.show = false;
clearInterval(scale.timer);
scale.x = 0;
drewScale();
canvas.onmousemove = null;
};
};

}

//创建重力轴
var scaleCanvas = $D("canvas",{bg:"#111",d:"block",marginBottom:"1px"});
scaleCanvas.width = canvasAttr.w;
scaleCanvas.height = scale.w;
var ctxSsale = scaleCanvas.getContext("2d");


//创建台球画布
var canvas = $D("canvas",{bg:"#ccc"});
canvas.width = canvasAttr.w;
canvas.height= canvasAttr.h;
var ctx = canvas.getContext("2d");
//初始化
init();
})();





posted on 2012-03-08 18:22  向我开炮  阅读(285)  评论(0编辑  收藏  举报