处理:与轨迹的碰撞

Processing: collisions with trails

在 Processing 中处理冲突很简单。但是,如何识别与轨迹的碰撞?

示例:想象一下 Tron 中的光周期,如果您愿意,可以更改为 derezzed 光周期的轨迹不会消失。在 Tron 中,如果一个循环与另一个循环(包括它本身)曾经存在过的任何点相交,它 'dies'。如何在处理中有效地找到此事件?

Stack Overflow 并不是真正为一般 "how do I do this" 类型的问题设计的。这是针对特定 "I tried X, expected Y, but got Z instead" 类型的问题。话虽如此,我会尽力提供一般意义上的帮助。

您可以只跟踪由循环形成的线,形式为 ArrayList 玩家转身的所有点。然后在每一步,您可以检查玩家是否与这些线中的任何一条相交。

更具体地说,您可能希望在前一个玩家坐标和下一个玩家坐标之间形成另一条线。然后使用我确定您可以通过一两次 google 搜索找到的公式检查该线是否与其他任何线相交。

你可能不需要做比这更聪明的事情,除非你谈论的是非常非常大的竞争环境(例如,数百万行)。所以现在问效率有点早

当然还有很多其他方法可以解决这个问题。您还可以使用一个 2D 数组来跟踪轨迹,或者您可以使用基于像素的碰撞,或者可能使用任何数量的其他解决方案。关键是你需要尝试一些东西,如果你遇到困难, post 一个 MCVE 以及一个具体的问题,我们将从那里开始。祝你好运。

一个 hacky 解决方法是将线绘制到 PImage 中并检查某个位置的颜色是否与背景相同(例如,预先存在的线,因此发生碰撞)。

这是一个粗略的(并且效率稍低(由于 get()/set() 调用)概念证明:

PImage buffer;

//how mutch we scale down = how pixely this will look
int multiplier = 8;
//scaled down width/height
int w,h;
//cursor position
int px,py;
//cursor velocity;
int vx,vy;


void setup(){
  size(400,400);
  noSmooth();

  w = width / multiplier;
  h = height / multiplier;

  buffer = createImage(w,h,RGB);
  clear();
}
void clear(){
  java.util.Arrays.fill(buffer.pixels,color(0));
  buffer.updatePixels();
}
void draw(){
  //update cursor
  px += vx;
  py += vy;
  //check edges
  if(px < 0){
    px = w-1;
  }
  if(px > w){
    px = 0;
  }
  if(py < 0){
    py = h-1;
  }
  if(py > h){
    py = 0;
  }
  //check collision
  if(keyPressed){
    if(keyCode == UP || keyCode == DOWN || keyCode == LEFT || keyCode == RIGHT){
      checkSelfIntersection();
    }
  }
  //paint cursor
  buffer.set(px,py,color(0,192,0));

  //render on screen
  image(buffer,0,0,width,height);
}
void checkSelfIntersection(){
  //if the pixel ahead is not the same colour as the background
  if(buffer.get(px+vx,py+vy) > color(0)){
    clear();  
    println("Cycle go BOOM!");
  }
}
void keyPressed(){
  if(keyCode == UP){
    vy = -1;
  }
  if(keyCode == DOWN){
    vy = +1;
  }
  if(keyCode == LEFT){
    vx = -1;
  }
  if(keyCode == RIGHT){
    vx = +1;
  }
}
void keyReleased(){
  vx = vy = 0;
}

可以做一个类似的概念来跟踪列表中的点并检查新点是否已经是该列表的一部分(碰撞):

ArrayList<PVector> path = new ArrayList<PVector>();


//cursor position
int px,py;
//cursor velocity;
int vx,vy;

void setup(){
  size(400,400);
  noFill();
  strokeWeight(10);
}
void draw(){
  //update cursor
  px += vx;
  py += vy;
  //check edges
  if(px < 0){
    px = 0;
  }
  if(px > width){
    px = width;
  }
  if(py < 0){
    py = 0;
  }
  if(py > height){
    py = height;
  }
  //check collision
  if(keyPressed){
    if(keyCode == UP || keyCode == DOWN || keyCode == LEFT || keyCode == RIGHT){
      checkSelfIntersection();
    }
  }

  background(255);
  beginShape();
  for(int i = 0 ; i < path.size(); i++){
    PVector p = path.get(i);
    vertex(p.x,p.y);
  }
  endShape();
}
void checkSelfIntersection(){
  PVector cursor = new PVector(px,py);
  if(path.contains(cursor)){
    path.clear();
    println("Cycle go BOOM!");
  }else{
    path.add(cursor);
  }
}
void keyPressed(){
  if(keyCode == UP){
    vy = -5;
  }
  if(keyCode == DOWN){
    vy = +5;
  }
  if(keyCode == LEFT){
    vx = -5;
  }
  if(keyCode == RIGHT){
    vx = +5;
  }
}
void keyReleased(){
  vx = vy = 0;
}

这个概念与 Snake/Volfied/etc 之类的游戏没有什么不同。检查自我交叉点。

注意 我在小速度上更新键上的 "cursor" 有点作弊:这避免了线条中的间隙。如果您尝试用鼠标替换,您会注意到如果鼠标快速移动,碰撞检查可能会失败,因为它会根据记录点列表检查一个点。另一种方法可能是将点列表拆分为成对的线,并检查新点是否与它们中的任何一条相交。

您可能还想查看此 similar question