Can anyone help me with my shooting game?

I got a pretty good character with it shooting the bullet(when pressed the 'space' key) toward the enemies (red balls). It's obvious that the bullet is not with the character(shooting very far away from the character). I think basically my character has some problems. In void draw() my character was supposed to have scaleFactor and the //Debug, but it doesn't work with it to shoot the bullet. anyways how can I fix this problem?

-----------my long code--------------

Giraiffe myGiraiffe;

// Instead of adding xSpeed, and ySpeed to xPos and yPos as before,
// we can define PVectors for each direction the UFO can move in 
// and use the built in add method in PVector to add these vectors
// to the UFOs position vector.
float speed = 7;
PVector upVelocity = new PVector(0, -speed); // Moves UFO straight up
PVector downVelocity = new PVector(0, speed); // Moves UFO straight down
PVector leftVelocity = new PVector(-speed, 0); // Moves UFO straight to left
PVector rightVelocity = new PVector(speed, 0); // Moves UFO straight to right

PVector missileVelocity = new PVector(2*speed, 0);
ArrayList<Missile> missiles = new ArrayList<Missile>();

ArrayList<Enemy> enemies = new ArrayList<Enemy>();

// Boolean variables to track which key is currently being pressed
boolean up, down, left, right, space;

// Depending on which key was pressed, set the 
// corresponding boolean variable to true
void keyPressed() {
  if (key == CODED) {
    if (keyCode == UP) {
      up = true;
    } 
    else if (keyCode == DOWN) {
      down = true;
    } 
    else if (keyCode == LEFT) {
      left = true;
    } 
    else if (keyCode == RIGHT) {
      right = true;
    }
  }     
  else if (keyCode == ' ') {
    space = true;
  }
}

// Depending on which key was released, set the 
// corresponding boolean variable to false
void keyReleased() {
  if (key == CODED) {
    if (keyCode == UP) { 
      up = false;
    }
    else if (keyCode == DOWN) {
      down = false;
    }
    else if (keyCode == LEFT) {
      left = false;
    }
    else if (keyCode == RIGHT) {
      right = false;
    }
  }
} 

void setup() {
  size(800, 500); 
  stroke(200);
  strokeWeight(2);
  fill(63);

  // Create a new UFO object and pass its constructor
  // a 2d vector.
  myGiraiffe = new Giraiffe(new PVector(width/2, height/2));

}

void draw() {
  background(255);

  myGiraiffe.update();
  myGiraiffe.draw();

  // Depending on which key is pressed,
  // add the force vectors t
  if (up) {
    myGiraiffe.move(upVelocity);
  }
  if (down) {
    myGiraiffe.move(downVelocity);
  }
  if (left) {
    myGiraiffe.move(leftVelocity);
  }
  if (right) {
    myGiraiffe.move(rightVelocity);
  } 
  if (space) {
    // Create a new missile at the same location as the UFO and give it
    // velocity equal to missileVelocity. 
    // posVector.get() to make a copy of the constructor.
    missiles.add(new Missile(myGiraiffe.posVector.get(), missileVelocity));
    space = false;
  }

  // Randomly choose a number between 0 and 100. If it is less than 3
  // spawn an enemy.
  if (random(0, 100) < 3) {
    enemies.add(new Enemy(new PVector(width, random(0, height))));
  }

  // Draw and update all enemies
  for (int j = 0; j < enemies.size(); j++) {
    enemies.get(j).draw();
    enemies.get(j).update();
  }

  for (int i = 0; i < missiles.size(); i++) {
    // Draw and update all enemies
    missiles.get(i).draw();
    missiles.get(i).update();

    // Check for collisions between enemies and collisions.
    for (int j = 0; j < enemies.size(); j++) {
      if (missiles.get(i).collision(enemies.get(j))) {
        enemies.get(j).alive = false;
        missiles.get(i).alive = false;
      }
    }
  }


  // Remove enemies that are no longer alive
  for (int i = 0; i < enemies.size(); i++) {
    if (!enemies.get(i).alive) {
      enemies.remove(i);
    }
  }

  // Remove missiles that are no longer alive
  for (int i = 0; i < missiles.size(); i++) {
    if (!missiles.get(i).alive) {
      missiles.remove(i);
    }
  }
}



//a class to describe a subclass of Character called UFO
class Giraiffe {



  // Instead of storing the xposVector and yposVector separately,
  // we can store it as one object using a PVector.
  // You can picture a PVector as a vector (an entity with
  // direction an magnitude) on a catesian plane. Using the
  // PVector class makes it easy to perfrom vector math. For
  // this lab, we we simply be adding vectors, but we can do
  // more interesting things with vectors later.
  // We can access the x and y values of a vecotor myVector
  // using myVector.x and myVector.y
  PVector posVector;
  //float scaleFactor; 
  //float Giraiffe_WIDTH= 55, Giraiffe_HEIGHT=130;

  Giraiffe(PVector posVector) {
    this.posVector = posVector;
    //this.scaleFactor = scaleFactor; 
  }

  void move(PVector distance) {
    posVector.add(distance); // Add is a method in the PVector class.
  }

  // If the UFO goes off the screen, wrap it around to the
  // other side of the screen.
  void update() {
    if (posVector.x > width) {
      posVector.x = 0-10;
    }
    if (posVector.x < 0) {
      posVector.x = width;
    }
    if (posVector.y > height) {
      posVector.y = 0;
    }
    if (posVector.y < 0) {
      posVector.y = height;
    }
  }

  void draw() {
    pushMatrix ();
    translate (posVector.x, posVector.y);

    //scale(giraiffe1Scale);
    pushMatrix ();

    //draw neck
    pushMatrix();
    //scale(scaleFactor);
    scale(-1.0, 1.0);
    translate(30, 0);
    strokeWeight(0.5);
    stroke(227, 196, 16);
    fill(240, 227, 106);
    ellipse(-176, -139, 20, 75);
    //draw body
    stroke(227, 196, 16);
    fill(240, 227, 106);
    ellipse(-156, -110, 55, 30);
    //draw ears
    stroke(227, 196, 16);
    fill(240, 227, 106);
    ellipse(-170, -175, 10, 5);
    stroke(227, 196, 16);
    fill(240, 227, 106);
    ellipse(-200, -178, 10, 5);
    //draw horn
    stroke(98, 85, 10);
    strokeWeight(0.5);
    fill(142, 122, 11);
    ellipse(-190, -180, 5, 10);
    ellipse(-180, -180, 5, 10);
    //draw tail
    stroke(0);
    strokeWeight(0.2);
    noFill();
    curve(-140, -125, -130, -115, -120, -110, -140, -110);
    fill(170, 152, 62);
    ellipse(-120, -110, 5, 5);
    //draw head
    rotate(0.4);
    strokeWeight(0.5);
    stroke(227, 196, 16);
    fill(240, 227, 106);
    //rotate(0.4);
    ellipse(-236, -76, 33, 40);
    //draw mouth
    strokeWeight(0.5);
    stroke(98, 85, 10);
    fill(170, 152, 62);
    ellipse(-238, -61, 19, 12);
    //draw the eyes
    fill(64, 55, 5); 
    ellipse(-248, -70, 3, 5);
    fill(64, 55, 5);
    ellipse(-230, -70, 3, 5);
    //Draw texture
    rotate(-0.4);
    noStroke();
    fill(137, 101, 11);
    ellipse(-175, -120, 10, 15);
    noStroke();
    fill(137, 101, 11);
    ellipse(-178, -115, 5, 5);
    noStroke();
    fill(137, 101, 11);
    ellipse(-175, -145, 5, 10);
    noStroke();
    fill(137, 101, 11);
    ellipse(-155, -110, 15, 10);
    noStroke();
    fill(137, 101, 11);
    ellipse(-135, -115, 5, 5);
    noStroke();
    fill(137, 101, 11);
    ellipse(-170, -105, 5, 5);
    noStroke();
    fill(137, 101, 11);
    ellipse(-140, -103, 5, 5);
    noStroke();
    fill(137, 101, 11);
    ellipse(-178, -170, 5, 5);
    //draw legs
    stroke(227, 196, 16);
    strokeWeight(0.5);
    fill(240, 227, 106);
    arc(-180, -105, 5, 35, 1/8*PI, PI-1/8*PI);  // upper half of circle
    arc(-172, -98, 5, 25, 1/8*PI, PI-1/8*PI);
    arc(-140, -100, 5, 25, 1/8*PI, PI-1/8*PI);
    arc(-133, -107, 5, 40, 1/8*PI, PI-1/8*PI);
    popMatrix();

    popMatrix();

    // Debug
    stroke(99, 164, 252,40);
    noFill();
//    rect(
//        -3.2 * scaleFactor * Giraiffe_WIDTH, 
//        -1.5 * scaleFactor * Giraiffe_HEIGHT, 
//     3 * scaleFactor * Giraiffe_WIDTH/2, 
//        1.7 * scaleFactor * Giraiffe_HEIGHT/2);
// 
    popMatrix();
  }
}


//a class of enemy

class Enemy {

  int radius = 25;

  PVector velocityVector = new PVector(-7, 0);
  PVector posVector;

  boolean alive = true;

  Enemy(PVector posVector) {
    this.posVector = posVector;
  }

  // If the UFO goes off the screen, wrap it around to the
  // other side of the screen.
  void update() {
    posVector.add(velocityVector); // Add is a method in the PVector class.

    if (posVector.x > width) {
      alive = false;
    }
    if (posVector.x < 0) {
      alive = false;
    }
    if (posVector.y > height) {
      alive = false;
    }
    if (posVector.y < 0) {
      alive = false;
    }
  }

  void draw() {
    if (alive) {
      pushMatrix();
      translate(posVector.x, posVector.y);
      fill(128, 0, 0);
      ellipse(0, 0, radius*2, radius*2);
      popMatrix();
    }
  }
}

//class missile 


class Missile {
  PVector pos;
  PVector vel;
  boolean alive;

  Missile(PVector pos, PVector vel) {
    this.pos = pos;
    this.vel = vel;
    alive = true;
  }

  boolean collision(Enemy other) {
    if (dist(pos.x, pos.y, other.posVector.x, other.posVector.y) < other.radius) {
      alive = false;
      return true;
    }
    return false;
  }

  void update() {
    pos.add(vel);

    if (pos.y < 0 || pos.y > height) {
      alive = false;
    } 
    else if (pos.x < 0 || pos.x > width) {
      alive = false;
    }
  }

  void draw() {
    fill(63);
    if (alive) {
      pushMatrix();
      translate(pos.x, pos.y);
      ellipse(0, 0, 8, 8);
      popMatrix();
    }
  }
}

Thank You.

Answers

  • The key to finding solution is called origin

    Origin is a point on a character (in your case giraffe) by which it will be "nailed" to the screen.

    This is your giraffe at it's initial location (center of the screen).

    You can see that it was nailed at width/2 height/2 (center of the screen). But looks like giraffe's origin is actually some 200 pixels to the right to the bottom relative to the top left corner of the giraffe.

    image alt text

    image alt text

    You have to adjust the origin of giraffe to something you expect (center of the giraffe). You can do this by translating your giraffe drawing by -100, -100 pixels so that it points somewhere in the center of the giraffe.

    Giraiffe myGiraiffe;
    
    // Instead of adding xSpeed, and ySpeed to xPos and yPos as before,
    // we can define PVectors for each direction the UFO can move in 
    // and use the built in add method in PVector to add these vectors
    // to the UFOs position vector.
    float speed = 7;
    PVector upVelocity = new PVector(0, -speed); // Moves UFO straight up
    PVector downVelocity = new PVector(0, speed); // Moves UFO straight down
    PVector leftVelocity = new PVector(-speed, 0); // Moves UFO straight to left
    PVector rightVelocity = new PVector(speed, 0); // Moves UFO straight to right
    
    PVector missileVelocity = new PVector(2*speed, 0);
    ArrayList<Missile> missiles = new ArrayList<Missile>();
    
    ArrayList<Enemy> enemies = new ArrayList<Enemy>();
    
    // Boolean variables to track which key is currently being pressed
    boolean up, down, left, right, space;
    
    // Depending on which key was pressed, set the 
    // corresponding boolean variable to true
    void keyPressed() {
      if (key == CODED) {
        if (keyCode == UP) {
          up = true;
        } 
        else if (keyCode == DOWN) {
          down = true;
        } 
        else if (keyCode == LEFT) {
          left = true;
        } 
        else if (keyCode == RIGHT) {
          right = true;
        }
      }     
      else if (keyCode == ' ') {
        space = true;
      }
    }
    
    // Depending on which key was released, set the 
    // corresponding boolean variable to false
    void keyReleased() {
      if (key == CODED) {
        if (keyCode == UP) { 
          up = false;
        }
        else if (keyCode == DOWN) {
          down = false;
        }
        else if (keyCode == LEFT) {
          left = false;
        }
        else if (keyCode == RIGHT) {
          right = false;
        }
      }
    } 
    
    void setup() {
      size(800, 500); 
      stroke(200);
      strokeWeight(2);
      fill(63);
    
      // Create a new UFO object and pass its constructor
      // a 2d vector.
      myGiraiffe = new Giraiffe(new PVector(width/2,height/2));
    
    }
    
    void draw() {
      background(255);
    
      myGiraiffe.update();
      myGiraiffe.draw();
    
      // Depending on which key is pressed,
      // add the force vectors t
      if (up) {
        myGiraiffe.move(upVelocity);
      }
      if (down) {
        myGiraiffe.move(downVelocity);
      }
      if (left) {
        myGiraiffe.move(leftVelocity);
      }
      if (right) {
        myGiraiffe.move(rightVelocity);
      } 
      if (space) {
        // Create a new missile at the same location as the UFO and give it
        // velocity equal to missileVelocity. 
        // posVector.get() to make a copy of the constructor.
        missiles.add(new Missile(myGiraiffe.posVector.get(), missileVelocity));
        space = false;
      }
    
      // Randomly choose a number between 0 and 100. If it is less than 3
      // spawn an enemy.
      if (random(0, 100) < 3) {
        enemies.add(new Enemy(new PVector(width, random(0, height))));
      }
    
      // Draw and update all enemies
      for (int j = 0; j < enemies.size(); j++) {
        enemies.get(j).draw();
        enemies.get(j).update();
      }
    
      for (int i = 0; i < missiles.size(); i++) {
        // Draw and update all enemies
        missiles.get(i).draw();
        missiles.get(i).update();
    
        // Check for collisions between enemies and collisions.
        for (int j = 0; j < enemies.size(); j++) {
          if (missiles.get(i).collision(enemies.get(j))) {
            enemies.get(j).alive = false;
            missiles.get(i).alive = false;
          }
        }
    
         drawAxis();
      }
    
    
    
    
      // Remove enemies that are no longer alive
      for (int i = 0; i < enemies.size(); i++) {
        if (!enemies.get(i).alive) {
          enemies.remove(i);
        }
      }
    
      // Remove missiles that are no longer alive
      for (int i = 0; i < missiles.size(); i++) {
        if (!missiles.get(i).alive) {
          missiles.remove(i);
        }
      }
      drawAxis();
    }// end of draw
    
     void drawAxis(){
        pushStyle();
          stroke(128,100);
          strokeWeight(2);
          line(0, height/2, width, height/2);
          line(width/2, 0, width/2, height);
        popStyle();
     } 
    
    //a class to describe a subclass of Character called UFO
    class Giraiffe {
    
    
    
      // Instead of storing the xposVector and yposVector separately,
      // we can store it as one object using a PVector.
      // You can picture a PVector as a vector (an entity with
      // direction an magnitude) on a catesian plane. Using the
      // PVector class makes it easy to perfrom vector math. For
      // this lab, we we simply be adding vectors, but we can do
      // more interesting things with vectors later.
      // We can access the x and y values of a vecotor myVector
      // using myVector.x and myVector.y
      PVector posVector;
      //float scaleFactor; 
      //float Giraiffe_WIDTH= 55, Giraiffe_HEIGHT=130;
    
      Giraiffe(PVector posVector) {
        this.posVector = posVector;
        //this.scaleFactor = scaleFactor; 
      }
    
      void move(PVector distance) {
        posVector.add(distance); // Add is a method in the PVector class.
      }
    
      // If the UFO goes off the screen, wrap it around to the
      // other side of the screen.
      void update() {
        if (posVector.x > width) {
          posVector.x = 0-10;
        }
        if (posVector.x < 0) {
          posVector.x = width;
        }
        if (posVector.y > height) {
          posVector.y = 0;
        }
        if (posVector.y < 0) {
          posVector.y = height;
        }
      }
    
      void draw() {
        pushMatrix ();
        translate (posVector.x, posVector.y);
    
      // put extra translate here to 
       // "move" origin (because it's abstract concept)
        translate(130,110);
       // it turns out that 130,100  would position origin right in the center of the drawing
    
        //scale(giraiffe1Scale);
        pushMatrix ();
    
        //draw neck
        pushMatrix();
        //scale(scaleFactor);
        //scale(-1.0, 1.0);
        translate(30, 0);
        strokeWeight(0.5);
        stroke(227, 196, 16);
        fill(240, 227, 106);
        ellipse(-176, -139, 20, 75);
        //draw body
        stroke(227, 196, 16);
        fill(240, 227, 106);
        ellipse(-156, -110, 55, 30);
        //draw ears
        stroke(227, 196, 16);
        fill(240, 227, 106);
        ellipse(-170, -175, 10, 5);
        stroke(227, 196, 16);
        fill(240, 227, 106);
        ellipse(-200, -178, 10, 5);
        //draw horn
        stroke(98, 85, 10);
        strokeWeight(0.5);
        fill(142, 122, 11);
        ellipse(-190, -180, 5, 10);
        ellipse(-180, -180, 5, 10);
        //draw tail
        stroke(0);
        strokeWeight(0.2);
        noFill();
        curve(-140, -125, -130, -115, -120, -110, -140, -110);
        fill(170, 152, 62);
        ellipse(-120, -110, 5, 5);
        //draw head
        rotate(0.4);
        strokeWeight(0.5);
        stroke(227, 196, 16);
        fill(240, 227, 106);
        //rotate(0.4);
        ellipse(-236, -76, 33, 40);
        //draw mouth
        strokeWeight(0.5);
        stroke(98, 85, 10);
        fill(170, 152, 62);
        ellipse(-238, -61, 19, 12);
        //draw the eyes
        fill(64, 55, 5); 
        ellipse(-248, -70, 3, 5);
        fill(64, 55, 5);
        ellipse(-230, -70, 3, 5);
        //Draw texture
        rotate(-0.4);
        noStroke();
        fill(137, 101, 11);
        ellipse(-175, -120, 10, 15);
        noStroke();
        fill(137, 101, 11);
        ellipse(-178, -115, 5, 5);
        noStroke();
        fill(137, 101, 11);
        ellipse(-175, -145, 5, 10);
        noStroke();
        fill(137, 101, 11);
        ellipse(-155, -110, 15, 10);
        noStroke();
        fill(137, 101, 11);
        ellipse(-135, -115, 5, 5);
        noStroke();
        fill(137, 101, 11);
        ellipse(-170, -105, 5, 5);
        noStroke();
        fill(137, 101, 11);
        ellipse(-140, -103, 5, 5);
        noStroke();
        fill(137, 101, 11);
        ellipse(-178, -170, 5, 5);
        //draw legs
        stroke(227, 196, 16);
        strokeWeight(0.5);
        fill(240, 227, 106);
        arc(-180, -105, 5, 35, 1/8*PI, PI-1/8*PI);  // upper half of circle
        arc(-172, -98, 5, 25, 1/8*PI, PI-1/8*PI);
        arc(-140, -100, 5, 25, 1/8*PI, PI-1/8*PI);
        arc(-133, -107, 5, 40, 1/8*PI, PI-1/8*PI);
        popMatrix();
    
        popMatrix();
    
        // Debug
        stroke(99, 164, 252,40);
        noFill();
    //    rect(
    //        -3.2 * scaleFactor * Giraiffe_WIDTH, 
    //        -1.5 * scaleFactor * Giraiffe_HEIGHT, 
    //     3 * scaleFactor * Giraiffe_WIDTH/2, 
    //        1.7 * scaleFactor * Giraiffe_HEIGHT/2);
    // 
        popMatrix();
      }
    }
    
    
    //a class of enemy
    
    class Enemy {
    
      int radius = 25;
    
      PVector velocityVector = new PVector(-7, 0);
      PVector posVector;
    
      boolean alive = true;
    
      Enemy(PVector posVector) {
        this.posVector = posVector;
      }
    
      // If the UFO goes off the screen, wrap it around to the
      // other side of the screen.
      void update() {
        posVector.add(velocityVector); // Add is a method in the PVector class.
    
        if (posVector.x > width) {
          alive = false;
        }
        if (posVector.x < 0) {
          alive = false;
        }
        if (posVector.y > height) {
          alive = false;
        }
        if (posVector.y < 0) {
          alive = false;
        }
      }
    
      void draw() {
        if (alive) {
          pushMatrix();
          translate(posVector.x, posVector.y);
          fill(128, 0, 0);
          ellipse(0, 0, radius*2, radius*2);
          popMatrix();
        }
      }
    }
    
    //class missile 
    
    
    class Missile {
      PVector pos;
      PVector vel;
      boolean alive;
    
      Missile(PVector pos, PVector vel) {
        this.pos = pos;
        this.vel = vel;
        alive = true;
      }
    
      boolean collision(Enemy other) {
        if (dist(pos.x, pos.y, other.posVector.x, other.posVector.y) < other.radius) {
          alive = false;
          return true;
        }
        return false;
      }
    
      void update() {
        pos.add(vel);
    
        if (pos.y < 0 || pos.y > height) {
          alive = false;
        } 
        else if (pos.x < 0 || pos.x > width) {
          alive = false;
        }
      }
    
      void draw() {
        fill(63);
        if (alive) {
          pushMatrix();
          translate(pos.x, pos.y);
          ellipse(0, 0, 8, 8);
          popMatrix();
        }
      }
    }
    
  • This should help a bit to understand: image alt text

  • Thanks for your help! :D

    However, do you also know how to make the character to decrease its life when the enemies collide on it?

    I forgot to ask this question : (

  • Well you have to keep track of that life somehow. Which means you have to declare it as variable. Probably inside of Giraffe class.

    Then in your draw(), right before the end of the draw() method, when positions of all of the missiles and giraffe have been recalculated, you need to run a collision check. Meaning that you need to iterate through all of your active missiles and check if they overlap with the giraffe. If they overlap you will have to decrease life of the giraffe.

    HTH

  • thank you very much!

Sign In or Register to comment.