Search code examples
expressionafter-effects

After Effect : Rebound on screen border and start in a random direction


I'm trying to reproduce the movement of the DVD sign that we had years ago on TV. When the sign is moving on the screen, touching border, rebounding, etc..

enter image description here

I managed to get something working which was really not that far but with one problem. ALL the objects with this scripts start going in the same direction first, which is to the bottom right. So, depending on their position, after a while, it's working like I wanted, but the start part is really problematic, someone knows how to correct that ?

// Seed random number generator to ensure consistent random values for start position and speed
seedRandom(index, true);

// Start position random 
startX = random(0, thisComp.width);
startY = random(0, thisComp.height);

// Speed random 
speed = random(50, 150); 

// Calculate distance moved since the beginning
distanceMovedX = time * speed + startX ;
distanceMovedY = time * speed + startY ;

// The effective width and height are reduced by the width and height of the layer
effectiveWidth = thisComp.width ;
effectiveHeight = thisComp.height ;

// Compute how many full "trips" across the screen (back and forth is 2 trips) for X and Y
numTripsX = Math.floor(distanceMovedX / effectiveWidth);
numTripsY = Math.floor(distanceMovedY / effectiveHeight);

// Calculate position based on the remainder of the distance after removing full trips for X and Y
positionInCurrentTripX = distanceMovedX % effectiveWidth;
positionInCurrentTripY = distanceMovedY % effectiveHeight;

// If the number of trips is odd, we are moving in the opposite direction; otherwise, we move in the initial direction
newX = (numTripsX % 2 === 0) ? positionInCurrentTripX : effectiveWidth - positionInCurrentTripX;
newY = (numTripsY % 2 === 0) ? positionInCurrentTripY : effectiveHeight - positionInCurrentTripY;

[newX, newY];

Solution

  • You have a beginning of the idea but it should be something more like this :

    // Seed random number generator to ensure consistent random values for start position and speed
    seedRandom(index, true);
    
    // Start position random 
    startX = random(0, thisComp.width);
    startY = random(0, thisComp.height);
    
    // Speed random 
    speedX = random(-150, 150); 
    speedY = random(-150, 150); 
    
    // Calculate the new positions based on time and speed
    newX = time * speedX + startX;
    newY = time * speedX + startY;
    
    // Check boundaries for X
    if (Math.floor(newX/thisComp.width) % 2 == 0) { // even -> to the right
        newX = Math.abs(newX) % thisComp.width
    }
    else { // odd -> to the left 
        newX = thisComp.width - Math.abs(newX) % thisComp.width
    }
    
    // Check boundaries for Y
    if (Math.floor(newY/thisComp.height) % 2 == 0) {
        newY = Math.abs(newY) % thisComp.height
    }
    else { 
        newY = thisComp.height - Math.abs(newY) % thisComp.height
    }
    
    
    [newX, newY];
    

    This way, doesn't matter how many rebounds there are, the images will always stay within the screen boundaries.