1 Star 0 Fork 0

we / tank

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
1.html 15.25 KB
一键复制 编辑 原始数据 按行查看 历史
we 提交于 2022-01-17 16:30 . no commit message
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8">
<style>
*{margin:0;padding:0;border:none;}
</style>
</head>
<body>
<canvas id="canvas" class="canvas">当前浏览器不支持canvas标签,请更换浏览器重新尝试</canvas>
<script>
var canvas = document.getElementById('canvas');
var context = canvas.getContext('2d');
canvas.width = 520;
canvas.height = 520;
CanvasRenderingContext2D.prototype.cirRct = function (x, y, w, l, r, color)
{
this.beginPath();
this.moveTo(x + r, y);
this.lineTo(x + w - r, y);
this.arcTo(x + w, y, x + w, y + r, r);
this.lineTo(x + w, y + l - r);
this.arcTo(x + w, y + l, x + w - r, y + l, r);
this.lineTo(x + r, y + l);
this.arcTo(x, y + l, x, y + l - r, r);
this.lineTo(x, y + r);
this.arcTo(x, y, x + r, y, r);
this.fillStyle = color;
this.closePath();
this.fill();
this.stroke();
}
context.cirRct(50, 50, 50, 60, 0, '#f00');
var offobj = {
a:function(){
// 在离屏 canvas 上绘制
var offscreencanvas = document.createElement('canvas');
// 宽高赋值为想要的图片尺寸
offscreencanvas.width = 52;
offscreencanvas.height = 62;
// 裁剪
offscreencanvas.getContext('2d').cirRct(1, 1, 50, 60, 0, '#f00');
return offscreencanvas;
},
b:function(){
// 在离屏 canvas 上绘制
var offscreencanvas = document.createElement('canvas');
// 宽高赋值为想要的图片尺寸
offscreencanvas.width = 32;
offscreencanvas.height = 32;
// 裁剪
offscreencanvas.getContext('2d').cirRct(1, 1, 30, 30, 0, '#ff0');
return offscreencanvas;
}
}
// 在视图canvas中绘制
context.drawImage(offobj.a(), 111, 111);
context.drawImage(offobj.a(), 211, 211);
context.drawImage(offobj.b(), 311, 311);
</script>
<div>
<style>
#cas{display: block;background-color:rgba(0,0,0,0);margin:auto;border:1px solid;}
</style>
<canvas id='cas' width="800" height="600">浏览器不支持canvas</canvas>
<div style="text-align:center">使用了缓存,1000个圈圈对象也不卡</div>
</div>
<script>
// stats.js - http://github.com/mrdoob/stats.js
var Stats=function(){function f(a,e,b){a=document.createElement(a);a.id=e;a.style.cssText=b;return a}function l(a,e,b){var c=f("div",a,"padding:0 0 3px 3px;text-align:left;background:"+b),d=f("div",a+"Text","font-family:Helvetica,Arial,sans-serif;font-size:9px;font-weight:bold;line-height:15px;color:"+e);d.innerHTML=a.toUpperCase();c.appendChild(d);a=f("div",a+"Graph","width:74px;height:30px;background:"+e);c.appendChild(a);for(e=0;74>e;e++)a.appendChild(f("span","","width:1px;height:30px;float:left;opacity:0.9;background:"+
b));return c}function m(a){for(var b=c.children,d=0;d<b.length;d++)b[d].style.display=d===a?"block":"none";n=a}function p(a,b){a.appendChild(a.firstChild).style.height=Math.min(30,30-30*b)+"px"}var q=self.performance&&self.performance.now?self.performance.now.bind(performance):Date.now,k=q(),r=k,t=0,n=0,c=f("div","stats","width:80px;opacity:0.9;cursor:pointer");c.addEventListener("mousedown",function(a){a.preventDefault();m(++n%c.children.length)},!1);var d=0,u=Infinity,v=0,b=l("fps","#0ff","#002"),
A=b.children[0],B=b.children[1];c.appendChild(b);var g=0,w=Infinity,x=0,b=l("ms","#0f0","#020"),C=b.children[0],D=b.children[1];c.appendChild(b);if(self.performance&&self.performance.memory){var h=0,y=Infinity,z=0,b=l("mb","#f08","#201"),E=b.children[0],F=b.children[1];c.appendChild(b)}m(n);return{REVISION:14,domElement:c,setMode:m,begin:function(){k=q()},end:function(){var a=q();g=a-k;w=Math.min(w,g);x=Math.max(x,g);C.textContent=(g|0)+" MS ("+(w|0)+"-"+(x|0)+")";p(D,g/200);t++;if(a>r+1E3&&(d=Math.round(1E3*
t/(a-r)),u=Math.min(u,d),v=Math.max(v,d),A.textContent=d+" FPS ("+u+"-"+v+")",p(B,d/100),r=a,t=0,void 0!==h)){var b=performance.memory.usedJSHeapSize,c=performance.memory.jsHeapSizeLimit;h=Math.round(9.54E-7*b);y=Math.min(y,h);z=Math.max(z,h);E.textContent=h+" MB ("+y+"-"+z+")";p(F,b/c)}return a},update:function(){k=this.end()}}};"object"===typeof module&&(module.exports=Stats);
</script>
<script>
var stats = new Stats();
stats.setMode(0);
stats.domElement.style.position = 'absolute';
stats.domElement.style.right = '0px';
stats.domElement.style.top = '0px';
document.body.appendChild( stats.domElement );
var testBox = function(){
var canvas = document.getElementById("cas"),
ctx = canvas.getContext('2d'),
borderWidth = 2,
Balls = [];
var ball = function(x , y , vx , vy , useCache){
this.x = x;
this.y = y;
this.vx = vx;
this.vy = vy;
this.r = getZ(getRandom(20,40));
this.color = [];
this.cacheCanvas = document.createElement("canvas");
this.cacheCtx = this.cacheCanvas.getContext("2d");
this.cacheCanvas.width = 2 * this.r;
this.cacheCanvas.height = 2 * this.r;
var num = getZ(this.r / borderWidth);
for (var j = 0; j < num; j++){
this.color.push("rgba(" + getZ(getRandom(0, 255)) + "," + getZ(getRandom(0, 255)) + "," + getZ(getRandom(0, 255)) + ",1)");
}
this.useCache = useCache;
if (useCache){
this.cache();
}
}
function getZ(num){
var rounded;
rounded = (0.5 + num) | 0;
// A double bitwise not.
rounded = ~~ (0.5 + num);
// Finally, a left bitwise shift.
rounded = (0.5 + num) << 0;
return rounded;
}
ball.prototype = {
paint:function(ctx){
if (!this.useCache){
ctx.save();
var j = 0;
ctx.lineWidth = borderWidth;
for (var i = 1; i < this.r; i += borderWidth){
ctx.beginPath();
ctx.strokeStyle = this.color[j];
ctx.arc(this.x, this.y, i, 0, 2 * Math.PI);
ctx.stroke();
j++;
}
ctx.restore();
} else{
ctx.drawImage(this.cacheCanvas, this.x - this.r, this.y - this.r);
}
},
cache:function(){
this.cacheCtx.save();
var j = 0;
this.cacheCtx.lineWidth = borderWidth;
for (var i = 1; i < this.r; i += borderWidth){
this.cacheCtx.beginPath();
this.cacheCtx.strokeStyle = this.color[j];
this.cacheCtx.arc(this.r, this.r, i, 0, 2 * Math.PI);
this.cacheCtx.stroke();
j++;
}
this.cacheCtx.restore();
},
move:function(){
this.x += this.vx;
this.y += this.vy;
if (this.x > (canvas.width - this.r) || this.x < this.r){
this.x = this.x < this.r?this.r:(canvas.width - this.r);
this.vx = - this.vx;
}
if (this.y > (canvas.height - this.r) || this.y < this.r){
this.y = this.y < this.r?this.r:(canvas.height - this.r);
this.vy = - this.vy;
}
this.paint(ctx);
}
}
var Game = {
init:function(){
for (var i = 0; i < 2; i++){
var b = new ball(getRandom(0, canvas.width), getRandom(0, canvas.height), getRandom( - 10, 10), getRandom( - 10, 10), true)
Balls.push(b);
}
},
update:function(){
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (var i = 0; i < Balls.length; i++){
Balls[i].move();
}
},
loop:function(){
var _this = this;
this.update();
stats.update();
RAF(function(){
_this.loop();
})
},
start:function(){
this.init();
this.loop();
}
};
window.RAF = (function(){
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {window.setTimeout(callback, 1000 / 60); };
})();
return Game;
}();
function getRandom(a, b){
return Math.random() * (b - a) + a;
}
window.onload = function(){
testBox.start();
}
</script>
<script>
//地图寻路
var map = [
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 1, 1, 1, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 0, 2, 0, 1, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 1, 0, 0],
[0, 0, 0, 0, 1, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 1, 1, 0, 0, 0, 3],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
]
var paths = findPath([2, 3], [9, 6], map);
let newMap = map.slice();
paths.forEach(p => {
newMap[p[1]][p[0]] = 4;
});
console.log("path:",paths)
console.log("map:",newMap)
function findPath(startPoint, targetPoint, map, configs) {
// 配置
configs = configs || {};
// 判断地图格子是不是障碍
var getIsObstacle = configs.getIsObstacle || ((tileValue) => {
return tileValue == 1;
});
// 代价因子
var getCostFactor = configs.getCostFactor || ((tileValue,currentPoint, parentPoint) => {
if (!parentPoint) {
return 1;
}
return currentPoint[0] != parentPoint[0] && currentPoint[1] !== parentPoint[1] ? 1.5: 1;
});
var
row = map.length, //地图行高
col = map[0].length, //地图列宽
openList = [],//开放列表,存放待处理的节点
closeList = [],//关闭列表,存放已处理的节点
mapSet = map.map(d => new Array(col));
// 创建节点
function createNode(point, parentNode) {
let x2 = point[0], y2 = point[1];
let currentNode = mapSet[y2][x2];//获取当前节点
// // 如果已存在,就不在创建
// if (currentNode) {
// // return currentNode;
// }
currentNode = {};
let tileValue = map[y2][x2];// 地图对应的tile值
let cost = getCostFactor(tileValue,point, parentNode ? parentNode.point : null);// 代价因子
let isObstacle = getIsObstacle(tileValue, x2, y2);//是否障碍物
//G值 = 父节点的G值 + 父节点到当前点的移动代价
let g = parentNode ? (parentNode.g+cost): 0;//计算当前点与起始点的距离
// let g = parentNode ? (Math.abs(parentNode.x - x2) + Math.abs(parentNode.y - y2) * cost) + parentNode.g : 0;//计算当前点与起始点的距离
//H值 = 当前点到结束点的曼哈顿距离
let h = Math.abs(targetPoint[0] - x2) + Math.abs(targetPoint[1] - y2);//计算当前点与目标点的距离
let f = g + h;//代价
Object.assign(currentNode, {
value: tileValue,
isObstacle: isObstacle,
g: g,
h: h,
f: f,
x: x2,
y: y2,
point: point,
parent: parentNode
});
mapSet[y2][x2] = currentNode;
return currentNode;
}
// 获取目标节点
function getTargetNodePath(currentNode) {
// 从左上角开始计算
//从行到列
rowLoop:
for (let r = currentNode.y - 1, rlen = r + 3; r < rlen; r++) {
colLoop:
for (let c = currentNode.x - 1, clen = c + 3; c < clen; c++) {
// 如果不在范围内,跳过
if (!(c >= 0 && c < col && r >= 0 && r < row)) {
continue colLoop;
}
let point = [c, r];
let node = createNode(point, currentNode);
// 如果节点等于目标就直接返回
if (node.x == targetPoint[0] && node.y == targetPoint[1]) {
return node;
}
// 如果不存在openlist列表中或closelist列表,并且是非障碍
if (!node.isObstacle && openList.indexOf(node) == -1 && closeList.indexOf(node) == -1) {
openList.push(node);
}
}
}
//按最小代价升序排列
openList.sort((a, b) => {
return a.f - b.f;
})
}
var startNode = createNode(startPoint, null), targetNode;
openList.push(startNode);
while (openList.length) {
current = openList.shift();//获取当前列表最小代价节点
closeList.push(current);
targetNode = getTargetNodePath(current);
if (targetNode) {
break;
}
}
// 如果不等空,就找出所有路径
var paths = [];
if (targetNode) {
let current = targetNode.parent;
while (current) {
if (current !== startNode) {
paths.unshift(current.point);
}
current = current.parent;
}
}
return paths;
}
</script>
</body>
</html>
JavaScript
1
https://gitee.com/we-blog/tank.git
git@gitee.com:we-blog/tank.git
we-blog
tank
tank
master

搜索帮助