碰撞后弹跳将不起作用,并且物体会穿过地形进行剪切

问题描述 投票:0回答:1

EDIT我将代码更改为以下代码,但有时仍会剪切地形。它还喜欢在应该滑落的角落弹跳。我尝试为自己制作的一款小游戏实现自己的碰撞。这是我的足球课的代码。

class Ball {
  //config
  float gforce = 1;
  float friction = 0.8;
  float elasticity = 0.5;
  //vars
  PVector position;
  PVector velocity = new PVector(0, 0);

  Ball(PVector p) {position = p;}

  void render(){fill(255, 255, 0); noStroke(); circle(position.x, height-position.y, 16);}

  PVector bounce(PVector v, PVector n){  //calculate velocity after bounce
    PVector u = PVector.mult(n,v.dot(n)/n.dot(n));
    PVector w = PVector.sub(v, u);
    return PVector.sub(PVector.mult(w, friction), PVector.mult(u, elasticity));
  }
  Boolean intersect(PVector c, PVector p1, PVector p2, float r){
    if (c.dist(p1)<=r || c.dist(p2)<=r){return true;}
    float len = p1.dist(p2);
    float dot = ( ((c.x-p1.x)*(p2.x-p1.x)) + ((c.y-p1.y)*(p2.y-p1.y)) )/(len*len);
    PVector closest = PVector.add(p1, PVector.mult(PVector.sub(p2, p1), dot));
    float d1 = closest.dist(p1);
    float d2 = closest.dist(p2);
    if (d1+d2>=len-0.1 && d1+d2<=len+0.1){if(closest.dist(c)<=r){return true;}}
    return false;
  }
  Boolean intersect(PVector p1, PVector p2, PVector p3, PVector p4){  //if the line p1p2 intersects line p3p4
    float uA = ((p4.x-p3.x)*(p1.y-p3.y) - (p4.y-p3.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x) - (p4.x-p3.x)*(p2.y-p1.y));
    float uB = ((p2.x-p1.x)*(p1.y-p3.y) - (p2.y-p1.y)*(p1.x-p3.x))/((p4.y-p3.y)*(p2.x-p1.x) - (p4.x-p3.x)*(p2.y-p1.y));
    if (uA>=0 && uA<=1 && uB>=0 && uB<=1){return true;}else{return false;}
  }

  void moveBall(){
    //if the ball is stationary
    if(velocity.mag()==0 || velocity.mag()==1 || velocity.mag()==2){
      PVector v = new PVector(min(280, max(-280, mX-mouseX)), min(280, max(-280, mouseY-mY))).div(28);
      int n = int(max(abs(v.x), abs(v.y)));
      v.normalize().mult(25);
      //render arrow
      if(mX!=0 && mousePressed){
        strokeWeight(5); stroke(#75D5FD); line(mX, mY, mouseX, mouseY);
        for (int i=0; i<n+1; i++){
          noStroke(); fill(510*(float)i/12, 510*(1-(float)i/12), 0, 55+200*(1-(float)i/12)); circle(mX+(v.x*i), mY-(v.y*i), 15);
        }
      }
      if(mX==0 && mouseP){mX=mouseX; mY=mouseY; mouseP=false;} 
      if(mX!=0 && mouseR){b.velocity = new PVector(min(280, max(-280, mX-mouseX)), min(280, max(-280, mouseY-mY))).div(8); mX=0; mouseR=false;}  //apply velocity
    }else {
      //if the ball is still, do not allow additional movement
      if(mX!=0 && mousePressed){stroke(200); line(mX, mY, mouseX, mouseY);}
      if(mX==0 && mouseP){mX=mouseX; mY=mouseY; mouseP=false;} 
      if(mX!=0 && mouseR){mX=0; mouseR=false;}
    }
  }

  void collision(){
    //test collision with terrain
    for (int i=1; i<l.points.length; i++){
      PVector centerout = PVector.div(velocity, velocity.mag()).mult(8);
      strokeWeight(5); stroke(255,0,0); line(position.x, height-position.y, position.x+centerout.x+velocity.x, height-position.y-centerout.y-velocity.y);
      if(intersect(position, l.points[i-1], l.points[i], 7) || intersect(position, PVector.add(position,velocity,centerout), l.points[i-1], l.points[i])){
        velocity = bounce(velocity, l.normals[i-1]);
      }
    }
  }

  void move() {
    moveBall();
    collision();
    position.add(velocity);
    if(velocity.y>-10){velocity.y-=gforce;}
    if(velocity.mag()<0.5){velocity.x=0; velocity.y=0;}
  }
}

[还有另一个对象,l(是地形),它存储了数组点[],其中包含地形的所有坐标。有一条线连接每个点,并且球检测其速度矢量是否与该线相交,或者球本身是否与该线相交。

当我拖动并释放鼠标时,它会将速度更改为鼠标所拖入的任何矢量。然后,它会检测到碰撞,并根据其当前速度和地形法线来更改速度。但是,这样做时,它会以相反的方向飞行并自行穿过地板。

如何修复代码,以使碰撞和弹跳按预期工作?此外,如果反弹一会后速度最终变为0,那将是很好的选择。

哦,通常y位置随着您向下移动的距离增加而升高,但我更改了它,以便y位置随着您向下移动的距离减小而下降。因此,在最底部,y位置为0,而不是画布的高度。

processing game-physics collision
1个回答
0
投票

关于您当前的问题,我实际上有2个不同的建议

© www.soinside.com 2019 - 2024. All rights reserved.