
Shinkai005
V1
2022/04/23阅读:44主题:红绯
canvas小球碰撞,拿来即用~
矩形直线运动+反弹效果
“没实现互相碰撞呢.明天搞
”
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Vue.js</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="stylesheet" href="style.css" />
<script src="vue.js"></script>
</head>
<body onload="draw()">
<div id="vue-app"></div>
<canvas id="canvas" width="400" height="300">
你这浏览器不支持这玩意啊
</canvas>
<script src="app.js"></script>
<script>
function draw() {
// 让vscode可以显示canvas智能提示
/** @type {HTMLCanvasElement} */
const canvas = document.getElementById('canvas')
if (canvas.getContext) {
const ctx = canvas.getContext('2d')
/**
* canvas 动画原理
* 1.绘制图像
* 2.清除图像
* 3.更新位置
* 4.重绘
*/
let x = 0,
y = 0,
width = 10,
height = 10
ctx.fillRect(x, y, width, height)
// x+=20
// y+=20
// ctx.fillRect(x, y, width, height)
//速度
let speedX = 20
let speedY = 20
setInterval(function(){
// 2.清除图像
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 3.更新位置
x += speedX
if (x > canvas.width - width) {
// rebound
speedX *= -1
} else if(x<0) {
speedX *= -1
}
y += speedY
if (y > canvas.height - height) {
// rebound
speedY *= -1
} else if (y<0) {
speedY *= -1
}
// 4.绘制图像
ctx.fillRect(x, y, width, height)
},60)
//添加弹回动画
}
}
</script>
</body>
</html>
想要实现多个怎么操作? 下面代码千万别运行,会笑死你.
“有小球捣乱! 这是因为 随机生成的值太大了,卡在了判定范围内.
”
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Vue.js</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="stylesheet" href="style.css" />
<script src="vue.js"></script>
</head>
<body onload="draw()">
<div id="vue-app"></div>
<canvas id="canvas" width="500" height="500">
你这浏览器不支持这玩意啊
</canvas>
<script src="app.js"></script>
<script>
function draw() {
// 让vscode可以显示canvas智能提示
/** @type {HTMLCanvasElement} */
const canvas = document.getElementById('canvas')
if (canvas.getContext) {
const ctx = canvas.getContext('2d')
/**
* canvas 动画原理
* 1.绘制图像
* 2.清除图像
* 3.更新位置
* 4.重绘
*/
let width = 10,
height = 10
// 写个函数自动生成xy
function createAxis(elements, num) {
for (let i = 0; i < num; i++) {
//随机生成位置
elements[i] = {
//Math.floor(Math.random() * (max - min + 1) ) + min;
//10-290
x: Math.floor(Math.random() * (canvas.width-width -width + 1) + width),
y: Math.floor(Math.random() * (canvas.height-width-height + 1) + height),
}
}
}
const elements = []
createAxis(elements, 2)
console.log('old', elements)
//渲染最初图像
renderEle(elements)
//绘制图像
function renderEle(elements) {
const colors = ['blue','yellow','green','lightgreen','lightblue', 'darkred']
for (let i = 0; i < elements.length; i++) {
ctx.fillStyle = colors[Math.floor(Math.random()*(colors.length-1+1)+1)]
ctx.fillRect(elements[i].x, elements[i].y, width, height)
}
}
//速度
// let speedX = 10,
// speedX1 = 15
// let speedY = 10,
// speedY1 = 15
randomSpeed(elements,4)
function randomSpeed(elements,max) {
for (let i = 0; i < elements.length; i++) {
//随机生成速度
elements[i].speedX = Math.floor((Math.random()*max)+1);
elements[i].speedY = Math.floor((Math.random()*max)+1);
}
}
// console.log(elements)
setInterval(function () {
// 2.清除图像
// ctx.clearRect(0, 0, canvas.width, canvas.height)
// 3.更新位置
for (let i = 0; i < elements.length; i++) {
elements[i].speedX = determineXPosition(
elements[i].x,
elements[i].speedX
)
elements[i].x += elements[i].speedX
elements[i].speedY = determineYPosition(
elements[i].y,
elements[i].speedY
)
elements[i].y += elements[i].speedY
}
// console.log('new',elements)
function determineYPosition(axis, orientation) {
if (axis > canvas.height - height) {
// rebound
orientation *= -1
} else if (axis < 0) {
orientation *= -1
}
return orientation
}
function determineXPosition(axis, orientation) {
if (axis > canvas.width - width) {
// rebound
orientation *= -1
} else if (axis < 0) {
orientation *= -1
}
return orientation
}
// 4.绘制图像
renderEle(elements)
}, 30)
}
}
</script>
</body>
</html>
小bug
这个后面不可以写(),因为并不是立即执行的
好看点的+优化啦
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Vue.js</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<link rel="stylesheet" href="style.css" />
<script src="vue.js"></script>
</head>
<body onload="draw()">
<div id="vue-app"></div>
<canvas id="canvas" width="500" height="500">
你这浏览器不支持这玩意啊
</canvas>
<script src="app.js"></script>
<script>
function draw() {
// 让vscode可以显示canvas智能提示
/** @type {HTMLCanvasElement} */
const canvas = document.getElementById('canvas')
if (canvas.getContext) {
const ctx = canvas.getContext('2d')
/**
* canvas 动画原理
* 1.绘制图像
* 2.清除图像
* 3.更新位置
* 4.重绘
*/
//矩形小球宽高不变
let width = 10,height = 10
//创建小球
const elements = []
createAxis(elements, 8)
renderEle(elements)
randomSpeed(elements, 4)
// 随机生成xy
function createAxis(elements, num) {
for (let i = 0; i < num; i++) {
//随机生成位置
elements[i] = {
//Math.floor(Math.random() * (max - min + 1) ) + min;
//10-290
x: Math.floor(
Math.random() * (canvas.width - width - width + 1) + width
),
y: Math.floor(
Math.random() * (canvas.height - width - height + 1) + height
),
}
}
}
// 随机生成速度
function randomSpeed(elements, max) {
for (let i = 0; i < elements.length; i++) {
elements[i].speedX = Math.floor(Math.random() * max + 1)
elements[i].speedY = Math.floor(Math.random() * max + 1)
}
}
//绘制图像
function renderEle(elements) {
const colors = [
'blue',
'yellow',
'green',
'lightgreen',
'lightblue',
]
for (let i = 0; i < elements.length; i++) {
ctx.fillStyle =
colors[Math.floor(Math.random() * (colors.length - 1 + 1) + 1)]
ctx.fillRect(elements[i].x, elements[i].y, width, height)
}
}
function optimize() {
// 2.清除图像
ctx.clearRect(0, 0, canvas.width, canvas.height)
// 3.更新位置
for (let i = 0; i < elements.length; i++) {
elements[i].speedX = determineXPosition(
elements[i].x,
elements[i].speedX
)
elements[i].x += elements[i].speedX
elements[i].speedY = determineYPosition(
elements[i].y,
elements[i].speedY
)
elements[i].y += elements[i].speedY
}
// 判断y坐标是否超越边界
function determineYPosition(axis, orientation) {
if (axis > canvas.height - height) {
// rebound
orientation *= -1
} else if (axis < 0) {
orientation *= -1
}
return orientation
}
// 判断x坐标是否超越边界
function determineXPosition(axis, orientation) {
if (axis > canvas.width - width) {
// rebound
orientation *= -1
} else if (axis < 0) {
orientation *= -1
}
return orientation
}
// 4.绘制图像
renderEle(elements)
//递归调用
window.requestAnimationFrame(optimize);
}
optimize()
}
}
</script>
</body>
</html>
“最后这个很顺滑了~
”
作者介绍

Shinkai005
V1
公众号:深海笔记Shinkai