console
/****** 2017/7/19 by cK-round ******/
var canvas = document.getElementById("canvas"),
submit = document.getElementById("submit"),
h3 = document.getElementsByTagName("h3"),
infor = document.getElementById("box3"),
p = infor.getElementsByTagName("p"),
w = 550,
h = 690,
circles = [],
timer,
timer2,
timer3,
timer4,
flage = false,
lKey = false,
rKey = false,
tKey = false,
bKey = false,
timestamp1,
timestamp2;
// 创建背景(canvastext)对象
var ctx = canvas.getContext("2d");
// 创建渐变
var bgcChange = ctx.createLinearGradient(0, h, 0, 0);
bgcChange.addColorStop(0, "#aaa");
bgcChange.addColorStop(1, "#fff");
// 填充渐变
ctx.fillStyle = bgcChange;
ctx.fillRect(0, 0, w, h);
submit.onclick = function() {
clearInterval(timer);
clearTimeout(timer2);
//clearTimeout(timer3);
clearInterval(timer4);
canvas.style.cursor = "none";
infor.style.display = "none";
var setBallNum = document.getElementById("ballNum1"),
setRadius = document.getElementById("radius1"),
setSpeed = document.getElementById("speed1"),
ballNum, r, speed;
circles.splice(0, circles.length);
r = parseInt(setRadius.value);
var minX = r,
maxX = w - r,
minY = r,
maxY = h - r;
ballNum = parseInt(setBallNum.value);
speed = parseFloat(setSpeed.value);
if (isNaN(speed) || isNaN(ballNum) || isNaN(r) || speed <= 0 || ballNum <= 0 || r <= 0) {
h3[0].innerHTML = '提示:请输入有效参数!';
} else {
timestamp1 = new Date().getHours() * 3600 + new Date().getMinutes() * 60 +
new Date().getSeconds() + new Date().getMilliseconds() / 1000;
h3[0].innerHTML = '提示:开始后你有三秒的准备时间。';
timer3 = setTimeout(function() {
flage = true;
h3[0].innerHTML = '提示:你可以通过方向键或W/A/S/D进行控制。';
}, 2990);
if (!flage) {
began(circles, ballNum, r, speed, minX, maxX, minY, maxY, timestamp1);
}
}
return timestamp1;
};
canvas.onclick = function() {
if (!flage) {
submit.onclick();
}
};
function began(circles, ballNum, r, speed, minX, maxX, minY, maxY, timestamp1) {
//获取鼠标在canvas上的坐标
canvas.onmousemove = function(e) {
var loc = windowToCanvas(canvas, e.clientX || e.x, e.clientY || e.y);
circles[ballNum].x = loc.x;
circles[ballNum].y = loc.y;
};
function windowToCanvas(canvas, x, y) {
var bbox = canvas.getBoundingClientRect();
return {
x: x - bbox.left * (w / bbox.width),
y: y - bbox.top * (h / bbox.height)
};
}
for (var i = 0; i < ballNum + 1; i++) {
// 红球
circles[i] = {
x: w * Math.random(), //圆心的x轴坐标值
y: h * Math.random(), //圆心的y轴坐标值
velocityX: speed * Math.random(),
velocityY: speed * Math.random(),
color: 'red'
},
circles[i].x < minX || circles[i].x > maxX ? circles[i].x = minX : circles[i].x,
circles[i].y < minY || circles[i].y > maxY ? circles[i].y = minY : circles[i].y;
}
// 蓝球
circles[ballNum] = {
x: 1,
y: 1,
velocityX: 0,
velocityY: 0,
color: 'blue'
};
timer = setInterval(function() {
//清除画布内容
ctx.clearRect(0, 0, w, h);
// 填充渐变
ctx.fillStyle = bgcChange;
ctx.fillRect(0, 0, w, h);
ctx.shadowColor = 'rgb(0,0,0)';
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.shadowBlur = 8;
//填充球
circles.forEach(function(b) {
//开始一个新的绘制路径
ctx.beginPath();
ctx.arc(b.x, b.y, r, 0, Math.PI * 2, false);
ctx.fillStyle = b.color;
ctx.closePath();
ctx.fill();
collision(circles, r);
boundary(b);
timer2 = setTimeout(function() {
move(b);
}, 3000);
});
}, 1);
document.onkeydown = function(event) {
// console.log((event || window.event).keyCode + " is down");
var keyCode = (event || window.event).keyCode;
switch (keyCode) {
case 37: //left
lKey = true;
break;
case 38: //top
tKey = true;
break;
case 39: //right
rKey = true;
break;
case 40: //bottom
bKey = true;
break;
case 65: //left
lKey = true;
break;
case 87: //top
tKey = true;
break;
case 68: //right
rKey = true;
break;
case 83: //bottom
bKey = true;
break;
}
};
document.onkeyup = function(event) {
// console.log((event || window.event).keyCode + " is up");
var keyCode = (event || window.event).keyCode;
switch (keyCode) {
case 13:
if (!flage) {
submit.onclick();
}
break;
case 37: //left
lKey = false;
break;
case 38: //top
tKey = false;
break;
case 39: //right
rKey = false;
break;
case 40: //bottom
bKey = false;
break;
case 65: //left
lKey = false;
break;
case 87: //top
tKey = false;
break;
case 68: //right
rKey = false;
break;
case 83: //bottom
bKey = false;
break;
}
};
timer4 = setInterval(function() {
if (lKey) {
circles[ballNum].x = circles[ballNum].x - 2;
}
if (rKey) {
circles[ballNum].x = circles[ballNum].x + 2;
}
if (tKey) {
circles[ballNum].y = circles[ballNum].y - 2;
}
if (bKey) {
circles[ballNum].y = circles[ballNum].y + 2;
}
}, 1);
//边界判定
function boundary(b) {
if (b.x + b.velocityX > maxX) b.x = maxX;
if (b.x + b.velocityX < minX) b.x = minX;
if (b.y + b.velocityY > maxY) b.y = maxY;
if (b.y + b.velocityY < minY) b.y = minY;
if (b.x + b.velocityX > maxX || b.x + b.velocityX < minX) b.velocityX = -b.velocityX;
if (b.y + b.velocityY > maxY || b.y + b.velocityY < minY) b.velocityY = -b.velocityY;
}
//运动
function move(b) {
if (b != circles[ballNum]) {
b.x += b.velocityX;
b.y += b.velocityY;
}
}
//碰撞判定
function collision(circles, r) {
if (flage) {
circles.forEach(
function(b1) {
circles.forEach(
function(b2) {
var rc = Math.ceil(Math.sqrt(Math.pow(b1.x - b2.x, 2) + Math.pow(b1.y - b2.y, 2)));
if (b1 !== b2) {
if (rc < r * 2) {
//获取碰撞后的速度增量
var ax = ((b1.velocityX - b2.velocityX) * Math.pow((b1.x - b2.x), 2) +
(b1.velocityY - b2.velocityY) * (b1.x - b2.x) * (b1.y - b2.y)) / Math.pow(rc, 2),
ay = ((b1.velocityY - b2.velocityY) * Math.pow((b1.y - b2.y), 2) +
(b1.velocityX - b2.velocityX) * (b1.x - b2.x) * (b1.y - b2.y)) / Math.pow(rc, 2);
//将速度增量赋给碰撞小球
b1.velocityX -= ax;
b1.velocityY -= ay;
b2.velocityX += ax;
b2.velocityY += ay;
//修正小球碰撞距离
var clength = r - rc / 2;
var cx = clength * (b1.x - b2.x) / rc,
cy = clength * (b1.y - b2.y) / rc;
b1.x += cx;
b1.y += cy;
b2.x -= cx;
b2.y -= cy;
//碰到蓝球
if (b1 == circles[ballNum] && b2 != circles[ballNum] && Math.ceil(rc) < r * 2 ||
b1 != circles[ballNum] && b2 == circles[ballNum] && Math.ceil(rc) < r * 2) {
timestamp2 = new Date().getHours() * 3600 + new Date().getMinutes() * 60 +
new Date().getSeconds() + new Date().getMilliseconds() / 1000 - 3;
flage = false;
clearInterval(timer);
clearTimeout(timer2);
//clearTimeout(timer3);
clearInterval(timer4);
canvas.style.cursor = "pointer";
var duration = Math.floor((timestamp2 - timestamp1) * 1000) / 1000;
h3[0].innerHTML = '提示:你可以通过点击左边的游戏区再次进行游戏。';
p[0].innerHTML = '半径(像素): ' + r +
'<br/>挑战球数(个): ' + ballNum +
'<br/>最大初速度(像素/微秒): ' + speed +
'<br/>挑战计时(秒): ' + duration;
console.log({
'时间': duration,
'半径': r,
'球数': ballNum,
'速度': speed
});
infor.style.display = "block";
}
}
}
}
);
}
);
}
}
}
<div id="box1">
<canvas id='canvas' width='550' height='690'>
<h1>提示:你的浏览器不支持canvas标签!</h1>
</canvas>
</div>
</canvas>
<div id="box2">
<form>
<h1>躲避红球</h1>
<h2>参数设置</h2>
<p>
半径(像素):
</p>
<p>
<input id="radius1" type="text" placeholder="请输入半径" value="15">
</p>
<p>
红球数(个):
</p>
<p>
<input id="ballNum1" type="text" placeholder="请输入球数" value="6">
</p>
<p>
最大初速度(像素/微秒):
</p>
<p>
<input id="speed1" type="text" placeholder="" value="1.5">
</p>
<p>
<input id="submit" type="button" value="提交参数">
<input type="reset" value="重置参数">
<!-- <input type="reset" value="重置参数" onclick="history.go(0)"> -->
</p>
<h3>提示:你可以通过点击左边的游戏区进行游戏。</h3>
<hr>
<div id="box3">
<h1>游戏结束!</h1>
<p></p>
</div>
</form>
</div>
html,
body {
overflow: hidden;
width: 100%;
height: 100%;
background-color: #123;
color: #eee;
}
div {
display: inline-block;
}
#box1 {
width: 550px;
height: 690px;
}
#box2 {
margin-left: 68px;
position: absolute;
}
#box3 {
display: none;
}
#canvas {
cursor: pointer;
margin: 0;
padding: 0;
border: thin solid #eee;
}
#box3 p {
line-height: 2;
}