Creative Communities of the World Forums

The peer to peer support community for media production professionals.

Forums Adobe After Effects Expressions PONG expression

  • PONG expression

  • Jalal Jemison

    September 21, 2005 at 12:09 am

    I got this script from further down the forum.
    I am trying to make a script that is like pong. Where the ball bounces between the four sides of a box, forever. I can add the paddles after, to make it look like someone is playing the game.

    I got this expression off creativecow.net but it doesn’t bounce between the sides

    box=[10,10,100,200]; // box you want to stay in [x1,y1,x2,y2]
    motion=[312,123]; // motion-vector in pixels per sond [x,y]
    startpos=[160,120]; // startposition

    // calculations:
    w=box[2]-box[0]; h=box[3]-box[1]; corner=[box[0],box[1]];
    delta=motion*time; pos=startpos+delta-corner;
    xx=pos[0]%(w*2); yy=pos[1]%(h*2);

    corner+[xx,yy]

    Anyone got a script that would bounce an between the four sides of the screen forever?

    Thanks

  • Dan Ebberts

    September 21, 2005 at 2:31 am

    Try this one:

    left = 0;
    top = 0;
    right = thisComp.width;
    bottom = thisComp.height;

    minSpeed = 200; //pixels per second
    maxSpeed = 500;

    minX = left + 20;
    maxX = right – 20;
    minY = top + 20;
    maxY = bottom – 20;

    minR = 5;
    maxR = 85;

    seedRandom(index,true);

    // calc start position

    pos = random([minX,minY],[maxX,maxY])
    quadrent = Math.floor(random(4))*90;
    angle = random(minR,maxR) + quadrent;
    spd = random(minSpeed,maxSpeed);

    // initialize time count;

    t = 0;

    while(t <= time){ rads = degreesToRadians(angle); xVel = spd*Math.cos(rads); yVel = spd*Math.sin(rads); // see if going up or down if (yVel < 0) yLim = top else yLim = bottom; // see if going right or left if (xVel < 0) xLim = left else xLim = right; timeX = (xLim - pos[0])/xVel; timeY = (yLim - pos[1])/yVel; if (timeX < timeY){ //hit left or right wall if (t + timeX >= time){
    deltaT = time – t;
    pos += [xVel,yVel]*deltaT;
    break;
    }else{
    pos = [xLim,pos[1] + yVel*timeX];
    angle = 180 – angle;
    t += timeX;
    }
    }else{ //hit upper or lower wall
    if (t + timeY >= time){
    deltaT = time – t;
    pos += [xVel,yVel]*deltaT;
    break;
    }else{
    pos = [pos[0] + xVel*timeY,yLim];
    angle = 360 – angle;
    t += timeY;
    }
    }
    }
    pos

    Dan

  • Jaime Vazquez

    February 25, 2012 at 2:08 am

    That is an excellent expression Dan. Glad these posts stay up 7 years later. I am trying the same animation but for a screensaver. I would like to know if there is a way to change the object with each bounce. for example if I am bouncing a word, to have it change on every bounce.
    Maybe get text from an array?

  • Dan Ebberts

    February 25, 2012 at 3:22 pm

    The problem is that this expression, which moves the layer, wouldn’t have any way to cause the text to change when it hits a wall. A text expression would have to do the same calculation, but it can’t generate the same random sequence, because the same seed produces different results for each property. You could do it by generating the random numbers in a Point Control and three sliders, then the position and text versions of the expression could do the same calculation.

    The expression would need to be modified to get the values of variables pos, quadrent, angle, and spd from the controls. The text version of the expression would need to bump a counter each time the layer hits a wall and use that counter as the seed to seedRandom() to generate a random index into your array of words. Pretty straight forward. If you give it a try and run into problems, come on back.

    Dan

  • Jacob Roth

    October 31, 2018 at 1:34 pm

    Hi Dan,

    This expression is great, but is there any way for the layer to bounce at its layer edges and not the anchor point?

  • Kalleheikki Kannisto

    October 31, 2018 at 3:18 pm

    Change the beginning section to this

    content = thisLayer.sourceRectAtTime();
    left = content.width/2;
    top = content.height/2;
    right = thisComp.width-content.width/2;
    bottom = thisComp.height-content.height/2;

    Note: this expects that the anchor point is in the center of the layer.

    Kalleheikki Kannisto
    Senior Graphic Designer

  • Jacob Roth

    October 31, 2018 at 3:25 pm

    Thanks for the response.

    Subbing your suggestions gives me an error at line 65, which is…

    t += timeY;

  • Jacob Roth

    October 31, 2018 at 3:28 pm

    Sorry, that’s not right. The error is at line 32, and it’s a timeout waiting for the engine.

    rads=degreesToRadians(angle);

  • Dan Ebberts

    October 31, 2018 at 4:36 pm

    If you’re using the latest version of AE, you’ll need to update the lines that define yLim and xLim:

    yLim = (yVel < 0) ? top : bottom;

    xLim = (xVel < 0) ? left : right;

    Dan

  • Jacob Roth

    October 31, 2018 at 5:46 pm

    Now I can’t seem to define xLim. Error at line 46, xLim is missing or does not exist.

    content = thisLayer.sourceRectAtTime();
    left = content.width/2;
    top = content.height/2;
    right = thisComp.width-content.width/2;
    bottom = thisComp.height-content.height/2;

    minSpeed = 100; //pixels per second
    maxSpeed = 100;

    minX = left + 20;
    maxX = right - 20;
    minY = top + 20;
    maxY = bottom - 20;

    minR = 5;
    maxR = 85;

    seedRandom(index,true);

    // calc start position

    pos = random([minX,minY],[maxX,maxY])
    quadrent = Math.floor(random(4))*90;
    angle = random(minR,maxR) + quadrent;
    spd = random(minSpeed,maxSpeed);

    // initialize time count;

    t = 0;

    while(t &lt;= time){
    rads = degreesToRadians(angle);
    xVel = spd*Math.cos(rads);
    yVel = spd*Math.sin(rads);

    // see if going up or down

    if (yVel &lt; 0) yLim = (yVel &lt; 0) ? top : bottom;
    // see if going right or left

    if (xVel &lt; 0) xLim = (xVel &lt; 0) ? left : right;

    timeX = (xLim - pos[0])/xVel;
    timeY = (yLim - pos[1])/yVel;

    if (timeX &lt; timeY){ //hit left or right wall
    if (t + timeX >= time){
    deltaT = time - t;
    pos += [xVel,yVel]*deltaT;
    break;
    }else{
    pos = [xLim,pos[1] + yVel*timeX];
    angle = 180 - angle;
    t += timeX;
    }
    }else{ //hit upper or lower wall
    if (t + timeY >= time){
    deltaT = time - t;
    pos += [xVel,yVel]*deltaT;
    break;
    }else{
    pos = [pos[0] + xVel*timeY,yLim];
    angle = 360 - angle;
    t += timeY;
    }
    }
    }
    pos

Viewing 1 - 10 of 13 posts

Log in to reply.

We use anonymous cookies to give you the best experience we can.
Our Privacy policy | GDPR Policy