Pivvot like game

edited July 2014 in How To...

Hi

I am tying to make a pivot like game. I have tried with everything bezierVertex(), curveVertex() ,curvepoint() or beizerPoint() but none of them helping me.

Problems:

  1. I am unable to make infinite 2D curve. (smoothly connected )
  2. For small curve I could make the ellipse move using curvePoint or bezierPoint but I am not able to think about the logic to make it work for the infinite 2D curve.

    ArrayList<Float> xmotion = new ArrayList();
    ArrayList<Float> ymotion = new ArrayList();
    void setup() {
      size(400, 300);
      curvegenerate();
    }
    float t=0;
    void draw() {
      background(-1);
      float x = bezierPoint(xmotion.get(0), xmotion.get(1), xmotion.get(2), xmotion.get(3), t);
      float y = bezierPoint(ymotion.get(0), ymotion.get(1), ymotion.get(2), ymotion.get(3), t);
      fill(0);
      ellipse(width/2, height/2, 10, 10);
      pushMatrix();
      translate(width/2-x, height/2-y);
      noFill();
      bezier(xmotion.get(0), ymotion.get(0), xmotion.get(1), ymotion.get(1), xmotion.get(2), ymotion.get(2), xmotion.get(3), ymotion.get(3));
      popMatrix();
      t+=1/100.0;
    }
    
    
    void curvegenerate() {
      for (int i=0; i<4; i++) {
        float x = noise(i)*random(-width/2, width/2);
        float y = noise(i)*random(-800, 800);
        if (i==0)xmotion.add(-width/2.0*2);
        else if (i==3)xmotion.add(width/2.0*2);
        else xmotion.add(noise(i)*random(-width/2, width/2));
        ymotion.add(y);
      }
    }
    
    void mousePressed() {
      xmotion.clear();
      ymotion.clear();
      curvegenerate();
      t=0;
    }
    

Pivot:http://blog.gsmarena.com/pivvot-for-ios-game-review/

Answers

  • Answer ✓

    Good idea to give this link, because you got the name of the game wrong...

    Note that you don't necessarily need an infinite curve, as curves can be created on the fly, and just forgotten when going out of the screen. You just need the capability to connect curves together. With Bézier curves, that's relatively easy, if you align the control points.

  • Sorry about the name :( my bad ! it is Pivvot :P

    PhiLho ! what would you suggest to use a bezier curve or spline for this? Also would you suggest me how deal with the connecting curve ?

  • edited July 2014 Answer ✓

    Hi,

    I have got this far. Still it doesn't look like pivvot but now it is generating infinte curve. May be someone in the forum can fix it for you :)

    If I would have any luck I'll let you know

    ArrayList<PVector>   points = new ArrayList<PVector>();
    float dtheta=0.0;
    int numofPoints=4;
    void setup() {
      size(600, 600);
      curvegenerate();
    }
    
    float t=0;
    void draw() {
      background(-1);
    
      float x = curvePoint(points.get(points.size ()-4).x, points.get(points.size ()-3).x, points.get(points.size ()-2).x, points.get(points.size ()-1).x, t);
      float y = curvePoint(points.get(points.size ()-4).y, points.get(points.size ()-3).y, points.get(points.size ()-2).y, points.get(points.size ()-1).y, t);
    
      float tx = curveTangent(points.get(points.size ()-4).x, points.get(points.size ()-3).x, points.get(points.size ()-2).x, points.get(points.size ()-1).x, t);
      float ty = curveTangent(points.get(points.size ()-4).y, points.get(points.size ()-3).y, points.get(points.size ()-2).y, points.get(points.size ()-1).y, t);
      float a = atan2(ty, tx);
      a -= radians(dtheta);
      if (right)dtheta+=2;
      if (left)dtheta-=2;
      t+=1/100.0;
    
      println(t);
      if (t>1) {
        t=0;
        points.add(new PVector(random(width, 2*width), random(-height, height)));
        if (points.size()>10)
          points.remove(0);
      }
      pushMatrix();
      translate(width/2-x, height/2-y);
      noFill();
      stroke(0);
      beginShape();
      for (int i = 0; i < points.size (); i++) { //0-9
        PVector p = points.get(i);
        curveVertex(p.x, p.y);
        p.x--;
        if (p.x<-width) {
          points.remove(0);
        }
      }
      endShape();
      fill(#00ADFA);
      noStroke();
      ellipse(x, y, 30, 30);
      pushStyle();
      stroke(#FA0334);
      strokeWeight(5);
      line(x, y, cos(a)*40 + x, sin(a)*40 + y);
      popStyle();
      popMatrix();
    }
    
    
    void curvegenerate() {
      for (int i=0; i<numofPoints; i++) {
        if (i==0 )points.add(new PVector(-width/2, random(height)));
        else if (i==(numofPoints-1) )points.add(new PVector(width/2, random(height)));
        else points.add(new PVector(random(-width/2, width/2), random(height)));
      }
    }
    
    void mousePressed() {
      t=0;
      points.add(new PVector(random(width/2), random(height)));
    }
    
    boolean right =false, left = false;
    void keyPressed() {
      if (key==CODED)
      {
        if (keyCode==RIGHT) right = true;
        else if (keyCode==LEFT) left =true;
      }
    }
    
    void keyReleased() {
      if (key==CODED)
      {
        if (keyCode==RIGHT) right = false;
        else if (keyCode==LEFT) left =false;
      }
    }
    
  • Answer ✓

    for bezier curves to be c2 continuous the control points at the join have to be co-linear AND the same length.

    in the following the two control points joining to the middle point are equal and opposite so the curve is always smooth at the join.

    // acd 2014 bezier
    PVector p0, p1, p2;
    PVector ca = new PVector();
    PVector cb = new PVector();
    PVector cc = new PVector();
    PVector cd = new PVector();
    float RAD = 100;
    float a0, a1, a2;
    float d0, d1, d2;
    float V = .02;
    
    void setup() {
      size(640, 480, P2D);
      initPoints();
      smooth();
    }
    
    void initPoints() {
      p0 = new PVector(-200, 0);
      p1 = new PVector(0, 0);
      p2 = new PVector(200, 0);
      a0 = random(TWO_PI);
      a1 = random(TWO_PI);
      a2 = random(TWO_PI);
      d0 = random(-V, V);
      d1 = random(-V, V);
      d2 = random(-V, V);
    }
    
    void draw() {
      background(255);
      translate(width / 2, height / 2);
      a0 += d0;
      a1 += d1;
      a2 += d2;
      // ca rotates around p0
      ca.x = p0.x + RAD * cos(a0);
      ca.y = p0.y + RAD * sin(a0);
      // cb rotates around p1
      cb.x = p1.x + RAD * cos(a1);
      cb.y = p1.y + RAD * sin(a1);
      // cc is same distance and same direction as cb to p1
      cc.x = p1.x + (p1.x - cb.x);
      cc.y = p1.y + (p1.y - cb.y);
      // cd rotates around p2
      cd.x = p2.x + RAD * cos(a2);
      cd.y = p2.y + RAD * sin(a2);
      // red for points
      noStroke();
      fill(255, 0, 0);
      ellipse(p0.x, p0.y, 10, 10);
      ellipse(p1.x, p1.y, 10, 10);
      ellipse(p2.x, p2.y, 10, 10);
      // blue for control points
      noStroke();
      fill(0, 0, 255);
      ellipse(ca.x, ca.y, 5, 5);
      ellipse(cb.x, cb.y, 5, 5);
      ellipse(cc.x, cc.y, 5, 5);
      ellipse(cd.x, cd.y, 5, 5);
      // curves
      stroke(0);
      noFill();
      strokeWeight(1);
      line(p0.x, p0.y, ca.x, ca.y);
      line(ca.x, ca.y, cb.x, cb.y);
      line(cb.x, cb.y, p1.x, p1.y);
      line(p1.x, p1.y, cc.x, cc.y);
      line(cc.x, cc.y, cd.x, cd.y);
      line(cd.x, cd.y, p2.x, p2.y);
      strokeWeight(2);
      bezier(p0.x, p0.y, ca.x, ca.y, cb.x, cb.y, p1.x, p1.y);
      bezier(p1.x, p1.y, cc.x, cc.y, cd.x, cd.y, p2.x, p2.y);
    }
    
    void keyPressed() {
      initPoints();
    }
    
  • edited July 2014

    Thanks everyone ! I would try to use bezier in blyk's code. @Koogs thanks for providing the code for connected bezier :)

    Also when I was playing with the blyk's code it seems something I am missing something. What I was trying to do is to create another curve before t --> 1 so that it wouldn't have to wait for another curve to be generate. The problem occurs when curve generate before t-->1 it jumps to another curve (generated curve) and even sometimes return "array out of the box error" :(

Sign In or Register to comment.