话说这只是一个简单的DEMO。游戏性,游戏规则什么的我都没怎么考虑,如果有兴趣细化的朋友可以细化一下,比如细化一下规则,游戏开关,加个声音,细化一下进球检测,更严谨甚至可以去查下击球力度、桌面真实摩擦力等来把游戏弄的更像游戏。我只是给个编程思路哈,随便坐个DEMO而已,玩起来估计还是不会很爽快的~~
桌球游戏
整个桌球游戏就两个类,一个是球,一个是辅助瞄准线。如果想把改游戏弄的更复杂,还可以再抽象一个形状类,用于检测球与边角的碰撞以及进球。我做的这个游戏采取了最简单的墙壁碰撞检测,所以没有进行球与不规则形状的碰撞检测,如果想玩更复杂的碰撞,可以戳 关于简单的碰撞检测 岑安大大讲的还是很好的。好,接下来就一步一步来:
【球】
先贴代码:
[/code]var Ball = function(x , y , ismine){
this.x = x;
this.y = y;
this.ismine = ismine;
this.oldx = x;
this.oldy = y;
this.vx = 0;
this.vy = 0;
this.radius = ballRadius;
this.inhole = false;this.moving = true;
}
Ball.prototype = {
constructor:Ball,
_paint:function(){
var b = this.ismine?document.getElementById("wb") : document.getElementById("yb")
if(b.complete) {
ctx.drawImage(b , this.x-this.radius , this.y-this.radius , 2*this.radius , 2*this.radius);
}
else {
b.onload = function(){
ctx.drawImage(b , this.x-this.radius , this.y-this.radius , 2*this.radius , 2*this.radius);
}
}
},
_run:function(t){
this.oldx = this.x;
this.oldy = this.y;
this.vx = Math.abs(this.vx)<0.1? 0 : (this.vx>0? this.vx-mcl*t : this.vx+mcl*t);
this.vy = Math.abs(this.vy)<0.1? 0 : (this.vy>0? this.vy-mcl*t : this.vy+mcl*t);
// this.vx += this.vx>0? -mcl*t : mcl*t;
// this.vy += this.vy>0? -mcl*t : mcl*t;
this.x += t * this.vx * pxpm;
this.y += t * this.vy * pxpm;
if((this.x<50 && this.y<50) || (this.x>370 && this.x<430 && this.y<50) || (this.x > 758 && this.y<50) || (this.x<46 && this.y>490) || (this.x>377 && this.x<420 && this.y>490) || (this.x > 758 && this.y>490)){
this.inhole = true;
if(this.ismine){
var that = this;
setTimeout(function(){
that.x = 202;
that.y = canvas.height/2;
that.vx = 0;
that.vy = 0;
that.inhole = false;
} , 500)
}
else {
document.getElementById("shotNum").innerHTML = parseInt(document.getElementById("shotNum").innerHTML)+1
}
}
else {
if(this.y > canvas.height - (ballRadius+tbw) || this.y < (ballRadius+tbw)){
this.y = this.y < (ballRadius+tbw) ? (ballRadius+tbw) : (canvas.height - (ballRadius+tbw));
this.derectionY = !this.derectionY;
this.vy = -this.vy*0.6;
}
if(this.x > canvas.width - (ballRadius+tbw) || this.x < (ballRadius+tbw)){
this.x = this.x < (ballRadius+tbw) ? (ballRadius+tbw) : (canvas.width - (ballRadius+tbw));
this.derectionX = !this.derectionX;
this.vx = -this.vx*0.6;
}
}
this._paint();
if(Math.abs(this.vx)<0.1 && Math.abs(this.vy)<0.1){
this.moving = false;
}
else {
this.moving = true;
}
}
}[/code]
球类的属性:x,y球的位置,vx,vy球的水平速度以及求得垂直速度,ismine代表是白球还是其他球(不同球在_paint方法中绘制的图片不一样),oldx,oldy用于保存球的上一帧位置,不过暂时还没用上,应该有用吧。_paint方法没什么好说的,_run方法就是跟踪小球位置,根据小球每一帧的时间来算出小球的位移增量以及速度增量,mcl和pxpm都是常量,mcl是摩擦力,pxpm是大概算个像素和现实转换比例。。。。然后就是碰撞检测,这个很容易理解了,就计算小球的位置有没有超过边界,超过了就反弹。不过这种碰撞检测很不严谨,如果真要做游戏建议用更复杂一些的。还有就是根据小球的速度来让小球静止。
新闻热点
疑难解答