Willkommen auf unserem Seminar-Blog

Immer auf dem aktuellen Stand bleiben

Dieser Seminar-Blog befindet sich noch im Aufbau und wird in den kommenden Tagen entsprechend verfeinert.

Member Login

Lost your password?

Registration is closed

Sorry, you are not allowed to register by yourself on this site!

You must either be invited by one of our team member or request an invitation by email at viad.info {at} zhdk {dot} ch.

Vectory!

24. September 2013

Wie bereits im Beitrag "Lessons+" angekündigt, wurde auch in den Lektionen die Klasse PVector behandelt. Die Aufgabe dazu war der PingPongBall auf einer Linie hin und her zu animieren. Das ganze sieht so aus: Animation Live Zum Code. Wahrscheinlich ist die Sache nicht allzu elegant gelöst, aber es funktioniert. Als Erstes habe ich einen clickcount eingebaut, der mir schaut, ob ich das erste oder das zweite Mal geklickt habe. Je nachdem wird die start oder die endPosition gesetzt. Darauf wird das drawFlag auf true gesetzt und die Linie mitsamt Kugel werden gezeichnet. Dabei verwende ich ein Boolean 'reverse', welches mir sagt ob der Ball in die eine oder die andere Richtung schwebt. Anfänglich ist das auf false gesetzt und die curTime berechnet sich aus Additionen von animSpeed. Falls die animTime erreicht ist, wird die Richtung umgestellt; sprich reverse wird auf true gesetzt. Ab diesem Punkt berechnet sich die curTime aus animTime - animSpeed*verstrichene Frames. So wird hier im Beispiel von 2000 auf 0 abgezählt. So geht der Ball rückwärts. Sobald er bei 0 angelangt ist, wird reverse wieder auf false gesetzt und die Kugel kann wieder wie anfänglich in die Ursprungsrichtung schweben. Auch hier, gäbe es vielleicht eine hübschere Variante, das ist jedoch grad das einzige, was mir einfällt und auch umzusetzen war. Der Code
PVector     startPos = new PVector();
PVector     endPos = new PVector();
int         curTime = 0;
int         animSpeed = 20;
int         animTime = 2000;
boolean     drawFlag=false;
boolean     reverse = false;
int         clickcount = 0;


void setup()
{
  size(640, 480);
  smooth();
}

void draw()
{
  background(51);

  if (!reverse) {
    // calc. the anim time
    curTime += animSpeed;  //in diesem Beispiel; 0 + 20; in 20er Schritten dazu
    println("NORMAL " + curTime);
    if (curTime >= animTime) {  //wenn 2000, umkehren
      reverse = true; //umkehren
    }
  } 
  else if (reverse) {
    curTime -= animSpeed;
    println("REVERSE " + curTime);
    if (curTime <= 0) {
      reverse = false;
    }
  }


  // calc. the current time in the animation
  float normTime = curTime * 1.0 / animTime;

  if (drawFlag)
  {
    stroke(255);
    line(startPos.x, startPos.y, 
    endPos.x, endPos.y);

    // calculate the position of the circle on the line
    PVector dir = PVector.sub(endPos, startPos);

    PVector pos = PVector.add( startPos, PVector.mult(dir, normTime));
    ellipse(pos.x, pos.y, 20, 20);
  }
}

void mousePressed()
{
  if (clickcount == 0) {
    curTime = 0;
    startPos.set(mouseX, mouseY, 0);
    endPos = startPos.get();
    clickcount = 1; //zähler wieviele clicks
  } 
  else if (clickcount == 1) {
    drawFlag = true;
    endPos.set(mouseX, mouseY, 0);
    println("draw, dammit!");
    clickcount = 0; //
  }
}

--------------- Ein Blick nach links zu Jon zeigt mir eine wahrlich einfachere und schönere Variante was das hin- und her betrifft: Einfach den animSpeed ändern. -> animSpeed = -animSpeed. Dann noch der Check, falls curTime = 0; wird wieder animSpeed = -animSpeed gesetzt – also wieder umgekehrt. Ebenfalls habe ich noch einen kleinen SChönheitsfehler ausgemerzt: Nun wird nicht beim ersten Click die curTime auf 0 zurückgesetzt (wenn der zweite Click nämlich lange danach fällt, startet der Ball in der Mitte) sondern erst beim zweiten Click. Der neue Code:
PVector     startPos = new PVector();
PVector     endPos = new PVector();
int         curTime = 0;
int         animSpeed = 20;
int         animTime = 2000;
boolean     drawFlag=false;
int         clickcount = 0;


void setup()
{
  size(640, 480);
  smooth();
}

void draw()
{
  background(51);

  // calc. the anim time
  curTime += animSpeed;
  if(curTime >= animTime){
     animSpeed = -animSpeed;
  }
  if(curTime <= 0 ){
    animSpeed = -animSpeed;
  }
 
  // calc. the current time in the animation
  float normTime = curTime * 1.0 / animTime;


  if (drawFlag)
  {
    stroke(255);
    line(startPos.x, startPos.y, 
    endPos.x, endPos.y);

    // calculate the position of the circle on the line
    PVector dir = PVector.sub(endPos, startPos);

    PVector pos = PVector.add( startPos, PVector.mult(dir, normTime));
    ellipse(pos.x, pos.y, 20, 20);
  }
}

void mousePressed()
{
  if (clickcount == 0) {
    startPos.set(mouseX, mouseY, 0);
    endPos = startPos.get();
    clickcount = 1; //zähler wieviele clicks
  } 
  else if (clickcount == 1) {
    drawFlag = true;
    curTime = 0;
    endPos.set(mouseX, mouseY, 0);
    println("draw, dammit!");
    clickcount = 0; //
  }
}