Rotation breaks my game

edited November 2013 in Questions about Code

Whenever I try to rotate anything, almost all entities on my screen rotate and my game seemingly breaks. Everything flies out of place and rotates to seemingly random angles. Using formulas or simply rotate(5); my game still breaks. I'm trying to create a rock that makes a fist that punches it when clicked. I have this working, except for the fist image to rotate towards the rock. Here is the code of the fist class.

class Fist {
  boolean delete;
  float fistX, fistY, speed, velocityX, velocityY, direction, targetX, targetY;
  float distance, radius, angle, rotateAngle;

  Fist() { 
     speed = 1;
     targetX = myRock.rockX;
     targetY = myRock.rockY;
     velocityX = cos(direction)*speed;
     velocityY = sin(direction)*speed;
     radius = 200;
     angle = degrees(random(0,360));
     fistX = myRock.rockX + (radius * cos(angle));
     fistY = myRock.rockY + (radius * sin(angle));
     direction = (atan2(targetY-fistY, targetX-fistX));

  }

  void draw() {
    update();
    display();
  }
  void update() {

    velocityX = cos(direction)*speed;
    velocityY = sin(direction)*speed;

    fistX += velocityX;
    fistY += velocityY;

    rotateAngle = (atan2(targetY-fistY, targetX-fistX));
  }

  void display() {
    imageMode(CENTER);
    image(fist, fistX, fistY);
   // rotate(rotateAngle); everything goes to shit when this is added
  }
}
Tagged:

Answers

  • _vk_vk
    edited November 2013

    Can't run the code, but seems that you need to "encapsulate" the rotation between push/popMatrix(), like

    pushMatrix();
    rotate(angle);
    image(fist, x, y);
    popMatrix()
    

    But be aware, rotation use origin as axis, so you need to shift origin, look at this:

    http://processing.org/tutorials/transform2d/

  • Thanks _vk for your help. I looked at the tutorial you sent me, and I edited my code as follows.

      void display() {
        imageMode(CENTER);
       pushMatrix();
       //move the coordinate system origin to rotation point
       translate(fistX,fistY);
       rotate(rotateAngle);
       image(fist, fistX, fistY);
       popMatrix();
      }
    

    For some reason this doesn't seem to be working, the fists fly off in vectors that don't go towards the "rock" and seems to be very similar to the error I started with, except it only effects fists instead of everything else.

  • Answer ✓

    I haven't followed the whole discussion, but looking at the latest code snippet, there is something wrong: if you use translate, put 0, 0 as coordinates, not the same coordinate than in translate()! It doubles the displacement, otherwise...

  • I tried your suggestion, but the "fist" class still seems to be broken. Without any rotation the class works fine (besides the orientation of the image), but after adding that snippet of code, the fists all act irrationally.

  • Can you post a runnable snipet?

  • Okay. This is part of a bigger game, so my apologies if it doesn't run, but it should work.

    ArrayList <Fist> myFists;
    
    void setup(){
    myFists = new ArrayList<Fist>();
    }
    
    void draw(){
       for (int i = myFists.size()-1; i >= 0; i--) {
          Fist fist = myFists.get(i);
          fist.update();
          fist.display();
    
          if (fist.delete) {
            myFists.remove(i);
          }
         }
    }
    
    
    
    void mouseReleased(){
        myFists.add(new Fist());
    }
    
    //---------Fist Class--------
    
    
    class Fist {
      boolean delete;
      float fistX, fistY, speed, velocityX, velocityY, direction, targetX, targetY;
      float distance, radius, angle, rotateAngle;
    
      Fist() { 
         speed = 1;
         targetX = width/2;
         targetY = height/2;
         velocityX = cos(direction)*speed;
         velocityY = sin(direction)*speed;
         radius = 200;
         angle = degrees(random(0,360));
          fistX = targetX + (radius * cos(angle));
         fistY = targetY + (radius * sin(angle));
         direction = (atan2(targetY-fistY, targetX-fistX));
    
      }
    
      void draw() {
        update();
        display();
      }
      void update() {
    
        velocityX = cos(direction)*speed;
        velocityY = sin(direction)*speed;
    
        fistX += velocityX;
        fistY += velocityY;
    
        rotateAngle = (atan2(targetY-fistY, targetX-fistX));
      }
    
      void display() {
        imageMode(CENTER);
       pushMatrix();
       //move the coordinate system origin to rotation point
       translate(fistX,fistY);
       rotate(rotateAngle);
       rect(fistX,fistY,20,20);
       popMatrix();
      }
    }
    

    This snippet should work. I replaced the fist image with rectangles, and theoretically the rectangles should spawn on a random spot on the radius of a circle, rotate to move towards the center of the screen, and move towards the center of the screen.

  • Answer ✓
     angle = degrees(random(0,360));
     fistX = targetX + (radius * cos(angle));
     fistY = targetY + (radius * sin(angle));
    

    lines 40-42, cos() and sin() are expecting radians.

    i would just use angle = random(0, TWO_PI); instead of that first line.

    degrees() and radians() methods always confuse me. are they converting to or from?

  • ^ that's not your bigger problem though

  • _vk_vk
    Answer ✓

    I just made @PhiLho's and @koogs suggestions, I think it works the way you wanted. There's no check to stop or delete each fist as it reachs the center, but you have a delete var so this is probably the snippet. Also I added a size call.

    look:

    ArrayList <Fist> myFists;
    
    void setup(){
      size(400,400);
    myFists = new ArrayList<Fist>();
    }
    
    void draw(){
       for (int i = myFists.size()-1; i >= 0; i--) {
          Fist fist = myFists.get(i);
          fist.update();
          fist.display();
    
          if (fist.delete) {
            myFists.remove(i);
          }
         }
    }
    
    
    
    void mouseReleased(){
        myFists.add(new Fist());
    }
    
    //---------Fist Class--------
    
    
    class Fist {
      boolean delete;
      float fistX, fistY, speed, velocityX, velocityY, direction, targetX, targetY;
      float distance, radius, angle, rotateAngle;
    
      Fist() { 
         speed = 1;
         targetX = width/2;
         targetY = height/2;
         radius = 200;
         angle = radians(random(0, 360));// radians instead of degrees as koogs
         //could be// angle = random(0, TWO_PI); 
         fistX = targetX + (radius * cos(angle));
         fistY = targetY + (radius * sin(angle));
         direction = (atan2(targetY-fistY, targetX-fistX));
         velocityX = cos(direction)*speed;//now direction has a value
         velocityY = sin(direction)*speed;
    
      }
    
      void draw() {
        update();
        display();
      }
      void update() {
    
        velocityX = cos(direction)*speed;
        velocityY = sin(direction)*speed;
    
        fistX += velocityX;
        fistY += velocityY;
    
        rotateAngle = (atan2(targetY-fistY, targetX-fistX));
      }
    
      void display() {
        imageMode(CENTER);
       pushMatrix();
       //move the coordinate system origin to rotation point
       translate(fistX,fistY);
       rotate(rotateAngle);
       rect(0,0,20,20);// draw at origin as suggested PhiLho
       popMatrix();
      }
    }
    
  • Thanks! The script works perfect now. Thank you all for your time.

Sign In or Register to comment.