Having a vector maintain position once it hits ground.

Hi, I'm trying to create a bow and arrow simulator, it's very much in the early stages. Right now I can launch little rectangles out from a launch point, but when they hit the ground they lay flat. I would like the rectangle to maintain the same angle and position as when it hits the ground. (think of a arrow embedding itself into the ground.)

there are only two vectors involved, gravity and the launch vector. Right now when the rectangle reaches y=350 I multiply the vel and acc by 0 and set the pos.y to the ground's y value.

this is a gif. arrow launch

function Projectile(apos, angle, power) {

this.pos = createVector(apos.x,apos.y);
this.vel = p5.Vector.fromAngle(angle-(PI));
this.vel.mult(power/15);
this.acc = createVector(0,0);
this.applyForce = function(force){
this.acc.add(force);
}
this.update = function() {
this.vel.add(this.acc);
this.pos.add(this.vel);
this.acc.mult(0);
if (this.pos.y > 350){
  this.pos.y = 350;
  this.acc.mult(0);
  this.vel.mult(0);
}
}
this.render = function(){
  push();
    translate(this.pos.x,this.pos.y);
    rectMode(CENTER);
    rotate(this.vel.heading());
    fill(255);
    rect(0,0, 10, 6);
  pop();
}
}

P.S. I tried formatting the code, but it wasn't working. I feel like a noob.

Answers

  • ok the gif didn't auto run so here is a direct link to it. My issue is clearly evident.

    sta.sh/0p9y4p13oy2

  • Please edit your post (gear icon in the top right corner of your post), select your code and hit ctrl+o to format your code. Make sure there is an empty line above and below your code.

    Kf

  • Answer ✓

    The velocity vector defines the heading. Instead of setting it to zero, you should use a boolean field that defines if the projectile should be moving or if it reached the ground. When it reaches the ground, you changed your boolean field to false and then this false value is used so to stop any updates in the projectile position.

    Kf

  • edited May 2017

    Okay, so I created a boolean variable isMoving and set it to true, then ran the update only when it's true. Once the projectile reaches y=350 i set the boolean to be false. This works, but the projectile keeps moving in their the +x or -x direction based on it's angle.

    gif sta.sh/01t31s6m7yqc

    I feel like I need to grab the position values when it hits ground then reset to those?

       function Projectile(apos, angle, power) {
        var isMoving = true;
        this.pos = createVector(apos.x,apos.y);
        this.vel = p5.Vector.fromAngle(angle-(PI));
        this.vel.mult(power/15);
        this.acc = createVector(0,0);
        this.applyForce = function(force){
        this.acc.add(force);
        }
        if(isMoving){
        this.update = function() {
        this.vel.add(this.acc);
        this.pos.add(this.vel);
        this.acc.mult(0);
        if (this.pos.y > 350){
          this.pos.y = 350;
          this.acc.mult(0);
          isMoving = false;
        }
        }
        }
        this.render = function(){
          push();
            translate(this.pos.x,this.pos.y);
            rectMode(CENTER);
            rotate(this.vel.heading());
            fill(255);
            rect(0,0, 10, 6);
          pop();
        }
        }
    
  • edited May 2017 Answer ✓

    Your formatting is killing me. Learn about Ctrl + t to auto-format code, please.

    Once you do, the problem becomes apparent:

    function Projectile(apos, angle, power) {
    
      var isMoving = true;
      this.pos = createVector(apos.x, apos.y);
      this.vel = p5.Vector.fromAngle(angle-(PI));
      this.vel.mult(power/15);
      this.acc = createVector(0, 0);
    
      this.applyForce = function(force) {
        this.acc.add(force);
      }
    
      if (isMoving) { // <--- What is THIS doing HERE?
        this.update = function() {
          this.vel.add(this.acc);
          this.pos.add(this.vel);
          this.acc.mult(0);
          if (this.pos.y > 350) {
            this.pos.y = 350;
            this.acc.mult(0);
            isMoving = false;
          }
        }
      }
    
      this.render = function() {
        push();
        translate(this.pos.x, this.pos.y);
        rectMode(CENTER);
        rotate(this.vel.heading());
        fill(255);
        rect(0, 0, 10, 6);
        pop();
      }
    
    }
    

    Your check for if(isMoving) { should be INSIDE the update() function!

  • edited May 2017

    Haha, it worked thanks!!! Will work on formatting!

Sign In or Register to comment.