加入收藏 | 设为首页 | 会员中心 | 我要投稿 河北网 (https://www.hebeiwang.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程 > 正文

JavaScript 打造的2D桌球小游戏

发布时间:2018-08-18 03:05:13 所属栏目:编程 来源:站长网
导读:本日在cnwander的博客看到一款很是棒的 桌球 小游戏,与众差异的是它并非是flash建造的,而是用 Java Script实现的,而且可以实现台球的力度、撞击点等,当鼠标按住时还可以看到右下角的力气进度条及时滑动,很是不错,先看一下演示: !DOCTYPE html PUBLI

本日在cnwander的博客看到一款很是棒的桌球小游戏,与众差异的是它并非是flash建造的,而是用JavaScript实现的,而且可以实现台球的力度、撞击点等,当鼠标按住时还可以看到右下角的力气进度条及时滑动,很是不错,先看一下演示:


提醒:可修改儿女码再运行!

贴出一些要害代码稍作表明,有乐趣的同窗看看。

// ball class
function Ball(type,x,y) {
...
this.type = type;
this.x = x; //位置
this.y = y;
this.angle = 0; //角度
this.v = 0; //速率(不包括偏向)
...
return this;
}
描写小球的四个信息,小球的范例(母球,方针球),坐标,角度,速率
在更新坐标时,读取小球的v,革新小球的位置
在与边缘碰撞时,变动小球angle

var formPos = getBallPos(cueBall.elem),
toPos = getBallPos(guideBall),
angle = Math.atan2(toPos[0] - formPos[0],toPos[1] - formPos[1]);
计较母球,与参考球之间的角度,其余恣意小球之间也是云云
值得留意的是我回收的是Math.atan2,而非Math.atan,这是由于Math.atan2返回的是(0 - Math.PI)和(-Math.PI - 0),可以确定独一的角度,而Math.atan不独一。

//边沿碰撞
if(ball.x < R || ball.x > W - R) {
ball.angle *= -1;
ball.v = ball.v * (1 - LOSS);
...
if(ball.type == "cue") {
if(ball.angle > 0) vy -= rollRight;
else vy += rollRight;
vx += rollUp;
rollUp *= 0.2;
rollRight *= 0.2;
ball.v = Math.sqrt(vx*vx + vy*vy);
ball.angle = Math.atan2(vx,vy);
}
...
if(ball.y < R || ball.y > H - R) {
ball.angle = ball.angle > 0 ? Math.PI - ball.angle : - Math.PI - ball.angle ;
...
不思量小球旋转时,边沿碰撞很简朴,变动小球angle即可
当小球旋转时,假如遇到牢靠不动的物体时,那将会把速率浸染给自身
而且自身旋转速率减小
我这里计较球与球之间碰撞,并没有将旋转转达,这是禁绝确的,有待改进

这一段是焦点,即小球与小球碰撞后各自的速率,着实并不难
先判定两球间隔
var dis = Math.sqrt(Math.pow(disX,2)+Math.pow(disY,2));
if(dis <= gap) {
//假如方针球是静止的,则添加到数组movingBalls
if(Math.round(obj.v) == 0)
movingBalls.push(obj);
//还原两球相切状态,用其余方法做我不知道,但用js来做,这一步相等要害,不然偏差将相等大
ball.x -= (gap - dis)*sin;
ball.y -= (gap - dis)*cos;
disX = obj.x - ball.x;
disY = obj.y - ball.y;
// 下面则是先将整个坐标系旋转到相撞的程度偏向
// 计较角度和正余弦值
var angle = Math.atan2(disY, disX),
hitsin = Math.sin(angle),
hitcos = Math.cos(angle),
objVx = obj.v * Math.sin(obj.angle),
objVy = obj.v * Math.cos(obj.angle);
//trace(angle*180/Math.PI);
// 旋转坐标
var x1 = 0,
y1 = 0,
x2 = disX * hitcos + disY * hitsin,
y2 = disY * hitcos - disX * hitsin,
vx1 = vx * hitcos + vy * hitsin,
vy1 = vy * hitcos - vx * hitsin,
vx2 = objVx * hitcos + objVy * hitsin,
vy2 = objVy * hitcos - objVx * hitsin;
// 碰撞后的速率和位置
var plusVx = vx1 - vx2;
vx1 = vx2;
vx2 = plusVx + vx1;
//母球加塞
if(ball.type == "cue") {
vx1 += rollUp;
rollUp *= 0.2;
}
x1 += vx1;
x2 += vx2;
// 将位置旋转返来
var x1Final = x1 * hitcos - y1 * hitsin,
y1Final = y1 * hitcos + x1 * hitsin,
x2Final = x2 * hitcos - y2 * hitsin,
y2Final = y2 * hitcos + x2 * hitsin;
obj.x = ball.x + x2Final;
obj.y = ball.y + y2Final;
ball.x = ball.x + x1Final;
ball.y = ball.y + y1Final;
// 将速率旋转返来
vx = vx1 * hitcos - vy1 * hitsin;
vy = vy1 * hitcos + vx1 * hitsin;
objVx = vx2 * hitcos - vy2 * hitsin;
objVy = vy2 * hitcos + vx2 * hitsin;
//最终速率
ball.v = Math.sqrt(vx*vx + vy*vy) * (1 - 0);
obj.v = Math.sqrt(objVx*objVx + objVy*objVy) * (1 - 0);
// 计较角度
ball.angle = Math.atan2(vx , vy);
obj.angle = Math.atan2(objVx , objVy);
}

坐标旋转的公式:
x1 = Math.cos(angle) * x - Math.sin(angle) * y;
y1 = Math.cos(angle) * y + Math.sin(angle) * x;

反坐标旋转:
x1 = Math.cos(angle) * x + Math.sin(angle) * y;
y1 = Math.cos(angle) * y - Math.sin(angle) * x;

稍作留意就会发明还存在许多题目,与真实桌球尚有相等差距,逐步改进吧,往后改用flash来作或者来得更流通吧,接待大伙多提意见。

(编辑:河北网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    热点阅读