JS/HTML5游戏常用跟踪算法示例详解
本文给出了一个例子来描述JS/HTML5游戏中常用算法的跟踪算法。分享给大家参考,如下:
追踪算法在动作游戏中非常常见,从非常早期的游戏《吃豆人》到大型街机游戏,追踪效果随处可见。一个好的跟踪算法会大大提高游戏的可玩性和玩家的兴趣。
[简单算法]
我们先来看一个简单的跟踪算法,如下图所示。假设画布坐标系中存在物体A和B,物体A会以B为跟踪目标。物体在二维空间中的运动可以分解为X轴和Y轴在坐标系中的运动,其在X和Y方向上的速度决定了物体的方向和速度。别忘了,速度是有方向和大小的,所以物体A的速度在X轴和Y轴上分解为vx和vy,物体B也是如此,所以如果物体A想要跟踪B,只需要比较两个物体在X和Y方向上的速度即可。设物体A的坐标为(x1,y1),A的速度分解为(vx,vy),物体B的坐标为(x2,y2),B的速度分解为(vx1,vy1)。对于水平X方向分量,如果x2x1表示B在A的右侧,此时vx必须设置为某个正值;否则,需要进行设置
基于这个简单算法的原理,我们可以尝试一个简单的例子。
!DOCTYPE html html lang=' en ' head meta name=' viewport ' content=' width=device-width,initial-scale=1.0,maximum-scale=1.0,User-scalable=0 ' metacarset=' utf-8 ' title tracking算法/title/head dycanvas id=' stage '/canvas/bodyscriptwindow . onload=function(){ var stage=document . queryselector(' # stage '),CTX=stage . getcontext(' 2d ');stage.width=400舞台高度=400;balls=[];var ball={ x : stage . width/2-20,y: stage.height/2 - 20,r: 20,c : ' red ' };球。推(球);for(var I=0;i 30I){ var trace={ x : math . ceil(math . random()*(stage . width-20)10),y : math . ceil(math . random()*(stage . height-20)10),r: 10,c 3360 ' blue ' };balls . push(trace);}函数createBall(x,y,r,c){ CTX . BeginPath();CTX . FillStyle=c;ctx.arc(x,y,r,0,Math。PI * 2);CTX . fill();} stage.addEventListener('click ',function(event){ var x=event . clientx-stage . getboundingclientrect()。向左;var y=event . clienty-stage . getboundingclientrect()。顶部;球[0]。x=x球[0]。y=y});函数update() { ctx.clearRect(0,0,400,400);ctx.fillStyle=' blackctx.rect(0,0,400,400);CTX . fill();创建球(球[0])。x,balls[0]。y,balls[0]。r,balls[0]。c);for (var i=1,len=balls.length我透镜;I) {//简单算法球[I]。x-=(balls [0]。x球[I]。x)?-1:1;球[我]。y -=(balls[0]。yball[I]。y)?-1:1;createBall(balls[i])。x,balls[i]。y,balls[i]。r,balls[i]。c);} requestAnimationFrame(更新);} update();};/script/html感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试运行上述代码并观察运行效果。
使用这种算法的方块动作比较突兀,方块的方向变化突然,效果看起来不是很理想,于是产生了下面的视线跟踪算法。
[视线跟踪算法]
视线跟踪算法。通过这种算法,跟踪器将始终与目标对象保持直线移动。如下图所示,它看起来像是在追踪一只捕食的猎豹,盯着目标。
如果我们想达到这种效果,实际上意味着在任何时候,A的速度方向都必须保持在连接AB的直线上,那么此时如何获得A在X轴和Y轴方向的速度分量呢?
这里我们可以采用向量来解决问题,向量是一种只有方向和大小而没有位置的概念,由向量的知识可知,假设任意时刻物体A向量表示为v1(x1,y1),物体B向量表示为v2(x2,y2),则由A指向B位置的向量v3=(x2 x1,y2 y1)。这3个向量的关系可以由图6-4 表示出来,设向量v3的长度为VLen=(x2 x1)(y2 y1),则向量v3标准化后可以用v4=((x2 x1)/VlEN,(y2 y1)/VlEN)表示。最后得到的v4在x轴方向上的分量就可以作为物体A在该时刻X轴方向上的分量,v4在Y轴方向上的分量就可以作为物体A在该时刻Y轴方向上的分量。
将上面的简单算法,按照视线追踪算法进行改写:
!DOCTYPE html html lang=' en ' head meta name=' viewport ' content=' width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=0 ' meta charset=' UTF-8 ' title追踪算法/title/head dy canvas id=' stage '/canvas/body脚本窗口。onload=function(){ var stage=document。queryselector(' # stage '),CTX=stage。get context(' 2d ');舞台宽度=400舞台高度=400;balls=[];var ball={ x : stage。宽度/2 - 20,y: stage .高度/2-20,r: 20,c : ' red ' };球。推(球);for(var I=0;i 30I){ var trace={ x : math。天花板(数学。random()*(阶段。宽度-20)10),y :数学。天花板(数学。random()*(阶段。高度-20)10),r: 10,c 3360 '蓝色' };球。推送(跟踪);}函数createBall(x,y,r,c){ CTX。begin path();CTX。FillStyle=c;(x,y,r,0,数学.PI * 2);CTX。fill();} stage.addEventListener('click ',function(event){ var x=event。clientx-stage。getboundingclientrect().向左;var y=事件。客户阶段。getboundingclientrect().顶部;球[0]。x=x球[0]。y=y });函数update() { ctx.clearRect(0,0,400,400);ctx.fillStyle=' blackctx.rect(0,0,400,400);CTX。fill();创建球(球[0])。x,balls[0].y,balls[0].r,balls[0].c);for (var i=1,len=balls.length我透镜;i ) { //视线追踪算法var vx=balls[i].x球[0]。x,vy=球[i].y球[0]。y,rlen=Math.sqrt(vx * vx vy * vy),dx=vx/rlen,dy=vy/rlen;球[我]。x-=dx;球[我]。y-=dy;createBall(balls[i]).x,balls[i].y,球[i].r,balls[i].c);} requestAnimationFrame(更新);} update();};/script/html使用在线HTML/CSS/JavaScript代码运行工具:http://工具。JB 51。net/code/HTMljsrun测试运行上述代码,可得到如下运行结果:
开源代码库地址:https://github。com/krapnikkk/JS-游戏数学
更多关于Java脚本语言相关内容感兴趣的读者可查看本站专题: 《JavaScript数学运算用法总结》 、 《JavaScript数据结构与算法技巧总结》 、 《JavaScript数组操作技巧总结》 、 《JavaScript排序算法总结》 、 《JavaScript遍历算法与技巧总结》 、 《JavaScript查找算法技巧总结》 及《JavaScript错误与调试技巧总结》
希望本文所述对大家Java脚本语言程序设计有所帮助。
版权声明:JS/HTML5游戏常用跟踪算法示例详解是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。