游戏碰撞测试,游戏中的碰撞检测常用方法

  游戏碰撞测试,游戏中的碰撞检测常用方法

  游戏效果图

  通过鼠标拖拽在画布上添加墙壁,通过方向键控制多边形上下左右移动,遇到墙壁则无法前进。需要解决的问题

  鼠标按下,鼠标拖动,鼠标释放事件的检测

  多边形的绘制

  墙壁的绘制

  多边形和墙壁的碰撞检测(实质上是圆和线段的相交判断)MYCode: 复制代码代码如下:

  超文本标记语言

  头

  标题迷宫/标题

  脚本

  var canvas _宽度=900

  var canvas _ height=350

  var ctx

  定义变量画布;

  var everything=[];

  var曲线壁

  可变墙宽;

  var wall_style=rgb(200,0,200);

  var walls=[];

  变量运动=假

  定义变量单位=10;

  函数令牌(sx,sy,rad,style_string,n)

  {

  this.sx=sx

  这. sy=sy

  this.rad=rad

  这个. draw=draw _ token

  这个。n=n

  this.angle=(2 *数学. PI)/n;

  this.move=移动令牌

  this.fill _ style=style _ string

  }

  函数draw_token()//绘制正n边形

  {

  CTX。fill _ style=this。填充_样式;

  CTX。begin path();

  var I;

  var rad=this.rad

  CTX。移到(这个。sx rad * math。cos(-0.5 *这个。角度),这个。赛拉德*数学。sin(-0.5 *这个。角度));

  for(I=1;我这个我)

  CTX。行到(这个。sx rad * math。cos((I-0.5)*这个。角度),这个。赛拉德*数学。sin((I-0.5)*这个。角度));

  CTX。fill();

  }

  函数move_token(dx,dy)

  {

  this.sx=dx

  this.sy=dy

  var I;

  定义变量墙;

  for(I=0;我。墙壁。长度;我)

  {

  wall=walls[I];

  if (intersect(wall.sx,wall.sy,wall.fx,wall.fy,this.sx,this.sy,this.rad))

  {

  这个。sx-=dx;

  这个。sy-=dy;

  打破;

  }

  }

  }

  函数墙(sx,sy,fx,fy,width,styleString)

  {

  this.sx=sx

  这. sy=sy

  this.fx=外汇

  this.fy=fy

  this.width=宽度;

  this.draw=draw _ line

  这个。stroke style=样式字符串;

  }

  函数draw_line()

  {

  CTX。线宽=这个。宽度;

  CTX。笔画风格=这个。笔画风格;

  CTX。begin path();

  ctx.moveTo(this.sx,this。sy);

  ctx.lineTo(this.fx,this。fy);

  CTX。笔画();

  }

  //注意

  var mypent=new Token(100,100,20, rgb(0,0,250),5);

  一切。push(mypent);

  函数初始化()

  {

  画布=文档。getelementbyid(“canvas”);

  CTX=画布。获取上下文(“2d”);

  //注意

  画布。addevent侦听器( mousedown ,start_wall,false);

  画布。addevent侦听器( mousemove ,stretch_wall,false);

  画布。addevent侦听器( mouseup ,finish_wall,false);

  窗户。addevent侦听器( keydown ,getkey_and_move,false);

  draw _ all();

  }

  函数开始_墙壁(电动)

  {

  var mx

  var my

  如果(电动层rX 电动层rx==0)

  {

  mx=ev.layerX

  my=ev.layerY

  }

  else if(ev。offsetx ev。offsetx==0)

  {

  mx=ev.offsetX

  我的=ev。关闭sety

  }

  cur_wall=new Wall(mx,my,mx 1,my 1,wall_width,Wall _ style);

  运动中=真

  一切。push(cur _ wall);

  draw _ all();

  }

  函数伸展_墙壁(电动)

  {

  如果(运动中)

  {

  var mx

  var my

  如果(电动层rX 电动层rX==0)

  {

  mx=ev.layerX

  my=ev.layerY

  }

  else if(ev。offsetx ev。offsetx==0)

  {

  mx=ev.offsetX

  我的=ev。关闭sety

  }

  cur _ wall.fx=mx

  cur _ wall.fy=my

  draw _ all();

  }

  }

  函数饰面_墙壁(电动)

  {

  动态=假

  墙壁。push(cur _ wall);

  }

  函数draw_all()

  {

  ctx.clearRect(0,0,canvas_width,canvas _ height);

  var I;

  for(I=0;我一切。长度;我)

  {

  一切[我]。draw();

  }

  }

  函数getkey_and_move(事件)

  {

  定义变量键码;

  if (event==null)

  {

  键码=窗口。事件。关键代码;

  窗户。事件。防止默认();

  }

  其他

  {

  键码=事件。关键代码;

  事件。防止默认();

  }

  开关(键码)

  {

  案例37://左箭头

  mypent.move(-unit,0);

  打破;

  案例38://向上箭头

  mypent.move(0,-单位);

  打破;

  案例39://右箭头

  mypent.move(单位,0);

  打破;

  案例40:

  mypent.move(0,单位);

  打破;

  默认值:

  //窗口。removeeventlistener( keydown ,getkey_and_move,false);

  }

  draw _ all();

  }

  函数交集(sx,sy,fx,fy,cx,cy,rad)

  {

  var dx

  var dy

  var t;

  var rt

  dx=FX-sx;

  dy=fy-sy;

  t=0.0-(((sx-CX)* dx(sy-cy)* dy)/(dx * dx dy * dy));

  如果(t 0.0)

  {

  t=0.0

  }

  else if (t 1.0)

  t=1.0

  var dx1=(sx t * dx)-CX;

  var dy1=(sy t * dy)-cy;

  var rt=dx1 * dx1 dy1 * dy1

  中频(rt rad * rad)

  返回true

  其他

  返回false

  }

  /脚本

  body onLoad= init();

  canvas id=canvas 宽度=900 高度=350/canvas

  /body

  /html

  困难

  和多边形线碰撞检测方法。

  intersect()函数负责检测多边形和线段是否相交。

  在线段上写下一个点p(x,y)。

  线段的两个端点是(sx,sy)和(fx,fy)。

  纪念

  dx=fx-sx

  dy=fy-sy

  x和y可以表示如下

  x=sx t*dx

  y=sy t*dy

  判断线段是否与多边形相交,转化为判断线段的外接圆是否与多边形相交。

  要做到这一点,需要找到线段上最靠近中心o的点P。

  如果op圆的半径,则可以判断线段与圆相交。

  否则,它们不会相交。

  如何找到线段上离圆心最近的点?

  从点P到点O的距离可以表示为

  距离=sqrt((x-CX)*(x-CX)(y-cy)*(y-cy));

  代替

  X=sx t*dx,y=sy t*dy

  可以得出结论,距离是t的函数。

  这个函数的导数

  函数值为0时,通过寻找对应的T值,可以得到离圆心最近的点。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: