与物体碰撞(墙)

时间:2020-10-27 12:37:03

标签: javascript canvas

检测2个对象(墙壁)碰撞的好方法。是的,不仅仅是检测,而是进一步移动,以使物体不会互相进入。也就是说,当它们碰撞时,它们彼此抵靠,但不进入。

CODE

import javax.faces.view.ViewScoped;
import javax.inject.Named;

@Named(value = "vehiTypeListMngr")
@ViewScoped
public class VehicleTypeListManager extends CommonUtilsJSF implements Serializable {

   private static final long serialVersionUID = 4966431989099484036L;
   private static Logger _logger = LogManager.getLogger(VehicleTypeListManager.class);
   @EJB
   private TravelService travelService;
   private String searchString = "";

   private List<VehicleTypeTO> vehiTypes;
   private VehicleTypeTO selectedVehiType;

   public void deletVehicleType() {
       try {
           travelService.deleteVehicleType(selectedVehiType.getVehicleTypeId());
           vehiTypes.remove(selectedVehiType);
           addInfoMessage(String.format("Vehicle Type %s deleted.", selectedVehiType.getType()));
           selectedVehiType = null;
       } catch(CabSysAppException ex) {
           String errMsg = String.format("Error while deleting Vehicle Type : %s -> %s",
           selectedVehiType.getType(), ex.getMessage());
           _logger.debug(errMsg);
           addExceptionMessageError(errMsg);
   }
}

1 个答案:

答案 0 :(得分:2)

天真的方法是检查x和y:

let ctx = mycan.getContext("2d");
let objects = [];

class player 
{
  constructor()
  {
    this.position = {x:50,y:50};
   this.color = "blue";
    this.size = 32;
    this.stop= false;
    this.prevpos=this.position;
    window.addEventListener("keydown",(e)=>{
      if(this.stop) this.position=this.prevpos;
      else this.displacement(e);
    });
  }
  
   displacement(e)
   {
      this.prevpos = this.position;
      this.position.x+=(e.key=="ArrowRight");
      this.position.x-=(e.key=="ArrowLeft");
      this.position.y+=(e.key=="ArrowDown");
      this.position.y-=(e.key=="ArrowUp");
   }
  
  draw()
  {
    ctx.fillStyle = this.color;  ctx.fillRect(this.position.x,this.position.y,this.size,this.size);
  }
};

class wall
{
  constructor(posx,posy)
  {
   this.position = {x:posx,y:posy};
   this.color = "red";
   this.size = 32;
   }
   
   draw(){
    ctx.fillStyle = this.color;
    ctx.fillRect(this.position.x,this.position.y,this.size,this.size);
   }
};

for(let i = 0; i<mycan.width;i+=32)
{
  objects.push(new wall(i,0));
  objects.push(new wall(i,mycan.height-32));
}

for(let j = 0; j<mycan.height;j+=32)
{
  objects.push(new wall(0,j));
  objects.push(new wall(mycan.width-32,j));
}

let playr=new player;


let collision = (colider)=>{
let colx = false;
let coly = false;
/*******************************************************
here we check if the top left point from our current
wall object is inferior to the top left point of our
player and if the top rignt point of the wall object is
superior to the player top left point.
we need to repeat this for the player top right point 
(so we compare the player top right point is superior
to the wall top left point and inferior to the wall 
top right point)
then we repeat this for y
*******************************************************/
  for(let object of objects)
  {
    colx = (
    (
    (object.position.x<=colider.position.x) && 
    (
    (object.position.x+object.size)>=
    (colider.position.x)
    )
    )||(
 (
 (colider.position.x+colider.size)>=object.position.x) && 
 (
 (colider.position.x+object.size)<=(object.position.x+object.size)
 )
 )
 )
    coly = (
    (
    (object.position.y<=colider.position.y) && 
    (
    (object.position.y+object.size)>=
    (colider.position.y)
    )
    )||(
 (
 (colider.position.y+colider.size)>=object.position.y) && 
 (
 (colider.position.y+object.size)<=(object.position.y+object.size)
 )
 )
 )
 if(colx&&coly) return true;
  }
  return false;
};

setInterval(()=>{
  ctx.clearRect(0,0,mycan.width,mycan.height);
  playr.stop = collision(playr);
  playr.draw();
  for(let obj of objects)
    obj.draw();
},1000/30);
<canvas id="mycan" width=400 height=250></canvas>

一种更好的方法是将2D世界切成区域,在该区域中,可能碰撞的对象的密度或多或少重要(四叉树)。

像这样:

enter image description here

一种更简单的方法是查看被腐蚀的​​物体是否在球体中(这意味着墙壁具有球体碰撞,几乎不能表示为正方形),但是我们可以说玩家是球体,检查是否有物体进入他的半径。

https://studiofreya.com/3d-math-and-physics/sphere-vs-aabb-collision-detection-test/