I take references from this animation/rendering competition and made this robot pushing a sphere in an alien planet:
I have trees generation in the background
boulders in front
and hills in the back
/*
* Andrew J Wang
* ajw2@andrew.cmu.edu
* Section A
*
* This Program is walking
*/
//sets of links
//location of feets of the walking person
var pointXG = 0;
var pointYG = 0;
//steps (frame) locations of the feets
var stepsX = [0,1,2,3,4,5,6,7,8,9,10,10,10,10,10,10,9,8,7,6,5,4,3,2,1,0];
var stepsY = [0,0.5,1,1.5,2,2.5,3,3.5,4,4.5,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0];
//counters for multiple frames (feet + mountains)
var counter = 0;
//location of the person on the drawing
var locationX = 120;
var locationY = 200;
//arrays for trees for clusters of boulders
var trees = [];
var clusters = [];
//set a array for land heights (FROM PREVIOUS ASSIGNMENT)
var landHeight = [];
var landHeight2 = [];
//create noice parameter and steps
var noiseParam = 0;
var noiseParam2 = 0;
var noiseStep = 0.005;
var noiseStep2 = 0.01;
function setup() {
createCanvas(480,300);
// create an initial collection of trees
for (var i = 0; i < 5; i++){
var rx = random(width);
trees[i] = makeTrees(rx);
}
// create an initial collection of boulders
for (var i = 0; i < 10; i++)
{
var rx2 = random(width);
clusters[i] = makeClusters(rx2);
}
//hill #1
for (var k=0; k<=480; k++)
{
//get noise through noise param
var n = noise(noiseParam);
//remapping based on height
var value = map(n,0,1,0,height/4)+130;
//add to array
landHeight.push(value);
//plus steps
noiseParam += noiseStep;
}
//hill #2
for (var k=0; k<=480; k++)
{
//get noise through noise param
var n2 = noise(noiseParam2);
//remapping based on height
var value2 = map(n2,0,1,0,height/3)+80;
//add to array
landHeight2.push(value2);
//plus steps
noiseParam2 += noiseStep2;
}
}
function draw() {
background(100);
//MOON
push();
noStroke();
fill(255,255,220);
ellipse(380,0,250,250);
pop();
//draw first sets of hill
push();
noStroke();
fill(240);
beginShape();
//fist vertex
vertex(0,(locationY+70+60)*0.8-80);
//for loop to grab all the vertex
for (var k=0; k<=480; k++)
{
vertex(k,landHeight2[k]);
}
//last vertex
vertex(width,(locationY+70+60)*0.8-80);
endShape(CLOSE);
//adding another point by shifting
var n2=noise(noiseParam2);
var value2 = map(n2,0,1,0,height/3)+80;
noiseParam2 += 0.01/20;
//slowing the speed of refreshing by using a counter
if (counter%40==0)
{
landHeight2.shift();
landHeight2.push(value2);
}
pop();
//draw second sets of hill
push();
noStroke();
fill(220);
beginShape();
//fist vertex
vertex(0,(locationY+70+60)*0.8-80);
//for loop to grab all the vertex
for (var k=0; k<=480; k++)
{
vertex(k,landHeight[k]);
}
//last vertex
vertex(width,(locationY+70+60)*0.8-80);
endShape(CLOSE);
//adding another point by shifting
var n=noise(noiseParam);
var value = map(n,0,1,0,height/4)+130;
noiseParam += 0.005/5;
//slowing the speed of refreshing by using a counter
if (counter%10==0)
{
landHeight.shift();
landHeight.push(value);
}
pop();
//ground plane
push();
noStroke();
fill(200);
rect(0,(locationY+70+60)*0.8-80,width, height-((locationY+70+60)*0.8-80));
pop();
//set trees and clusters by refreshing the removed objects and clusters
updateDisplay();
removeTrees();
addTrees();
removeClusters();
addClusters();
//walking person
strokeWeight(3);
push();
//scaling it
scale(0.6);
translate(0,150);
walking(locationX,locationY);
walking2(locationX,locationY);
body(locationX,locationY);
//butt
push();
strokeWeight(2);
ellipse(locationX,locationY,15,15);
pop();
pop();
//display clusters in the end
updateDisplay2();
}
//refreashing trees and display them
function updateDisplay(){
for (var i = 0; i < trees.length; i++){
trees[i].move();
trees[i].display();
}
}
//refreshing boulders and display them
function updateDisplay2(){
for (var i = 0; i < clusters.length; i++){
clusters[i].move();
clusters[i].display();
}
}
//removing trees if it is too far away from the screen
function removeTrees(){
var treesToKeep = [];
for (var i = 0; i < trees.length; i++){
if (trees[i].x + trees[i].breadth > 0) {
treesToKeep.push(trees[i]);
}
}
}
//removing boulders if it is too far away from the screen
function removeClusters(){
var clustersToKeep = [];
for (var i = 0; i < clusters.length; i++){
if (clusters[i].x + clusters[i].breadth > 0) {
clustersToKeep.push(clusters[i]);
}
}
}
//add trees 100 units away from border
function addTrees() {
var Likelihood = 0.01;
if (random(0,1) < Likelihood) {
trees.push(makeTrees(width+100));
}
}
//add boulders 500 units away from border
function addClusters() {
var Likelihood = 0.01;
if (random(0,1) < Likelihood) {
clusters.push(makeClusters(width+500));
}
}
//set trees values and function
function makeTrees(birthLocationX) {
var tree = {x: birthLocationX,
breadth: 100,
speed: -0.4,
y: 160+round(random(20)),
treeHeight: round(random(40,50)),
size: round(random(30,50)),
move: objectMove,
display: treeDisplay}
return tree;
}
//set boulders values and functions
function makeClusters(birthLocationX) {
var tree = {x: birthLocationX,
breadth: 100,
speed: -2.0,
treeHeight: round(random(40,50)),
size: round(random(200,350)),
move: object2Move,
display: clusterDisplay}
return tree;
}
//move objects
function objectMove() {
this.x += this.speed;
}
function object2Move() {
this.x += this.speed;
}
//draw trees
function treeDisplay() {
line(this.x, this.y , this.x, this.y+this.treeHeight);
push();
translate(this.x,this.y);
rectMode(CENTER);
noFill();
strokeWeight(1);
push();
rotate(-counter/180*Math.PI);
rect(0,0,this.size,this.size);
pop();
push();
rotate(counter/180*Math.PI);
rect(0,0,this.size-10,this.size-10);
pop();
pop();
}
//draw bolders
function clusterDisplay() {
push();
fill(0);
ellipse(this.x,height+30,this.size,this.size/2);
strokeWeight(1.5);
noFill();
ellipse(this.x,height+30,this.size+20,this.size/2+10);
pop();
}
//leg #1
function walking(xL,yL)
{
//counter/10 get frame number
var counterK = Math.floor(counter/10)%(stepsX.length);
//Feet locations
pointXG = xL-70+stepsX[counterK]*6;
pointYG = yL+70-stepsY[counterK]*4;
//Pathegorean theorm to get the knee and legs
var dis = Math.sqrt((xL-pointXG)*(xL-pointXG)+(yL-pointYG)*(yL-pointYG));
var num = (10000)-(dis*dis);
var sid = sqrt(num);
var midX = xL-(xL-pointXG)/2;
var midY = yL-(yL-pointYG)/2;
var tan = atan2(pointXG-xL,pointYG-yL);
ellipse ((pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2, 5,5);
line(xL,yL,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
line(pointXG,pointYG,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
//feet bending
if (stepsY[counterK]==0)
{
line(pointXG,pointYG,pointXG+20,pointYG);
}
else
{
var tanF = atan2(Math.sqrt(400-stepsY[counterK]*2),stepsY[counterK]*4);
line(pointXG,pointYG,pointXG+20*sin(tanF),pointYG+20*cos(tanF));
}
counter++;
}
//repeat for the second leg
function walking2(xL,yL)
{
var counterK = (Math.floor(counter/10)+stepsX.length/2)%(stepsX.length);
pointXG = xL-70+stepsX[counterK]*6;
pointYG = yL+70-stepsY[counterK]*4;
var dis = Math.sqrt((xL-pointXG)*(xL-pointXG)+(yL-pointYG)*(yL-pointYG));
var num = (10000)-(dis*dis);
var sid = sqrt(num);
var midX = xL-(xL-pointXG)/2;
var midY = yL-(yL-pointYG)/2;
var tan = atan2(pointXG-xL,pointYG-yL);
ellipse ((pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2, 5,5);
line(xL,yL,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
line(pointXG,pointYG,(pointXG-xL)/2+xL+cos(tan)*sid/2, (pointYG-yL)/2+yL-sin(tan)*sid/2);
if (stepsY[counterK]==0)
{
line(pointXG,pointYG,pointXG+20,pointYG);
}
else
{
var tanF = atan2(Math.sqrt(400-stepsY[counterK]*2),stepsY[counterK]*4);
line(pointXG,pointYG,pointXG+20*sin(tanF),pointYG+20*cos(tanF));
}
counter++;
}
//body parts and other stuff
function body(xL,yL)
{
var counterK = (Math.floor(counter/10)+stepsX.length/2)%(stepsX.length);
var counterK2 = (Math.floor(counter/10)+10)%(stepsX.length);
var counterK3 = (Math.floor(counter/10)+25)%(stepsX.length);
push();
strokeWeight(2);
fill("grey")
//shoulder 1
ellipse(xL+35+stepsY[counterK2],yL-45-stepsX[counterK2],30,30);
//hand
ellipse(xL+35+60,yL-45-stepsX[counterK]+10,10,10);
pop();
//arms
line(xL+35+stepsY[counterK],yL-45-stepsX[counterK],xL+35+30,yL-45-stepsX[counterK]+20);
line(xL+35+30,yL-45-stepsX[counterK]+20,xL+35+60,yL-45-stepsX[counterK]+10);
//body
line(xL,yL,xL+35+stepsY[counterK],yL-45-stepsX[counterK]);
push();
fill("black");
ellipse(xL+35+30,yL-45-stepsX[counterK]+20,5,5);
pop();
//Round thingy
push();
noFill();
strokeWeight(2);
ellipse(xL+35+175,yL-45,230,230);
fill(255);
ellipse(xL+35+175,yL-45,220,220);
stroke(255);
pop();
//shoulder 2
push();
noStroke();
ellipse(xL+35+stepsY[counterK2],yL-45-stepsX[counterK2],15,15);
pop();
//head
push();
strokeWeight(1);
noFill();
translate(xL+55+stepsY[counterK3],yL-85-stepsX[counterK3]);
rectMode(CENTER);
rotate(-counter/180*Math.PI);
rect(0,0,40,40);
rect(0,0,30,30);
pop();
push();
strokeWeight(1);
noFill();
translate(xL+65+stepsY[counterK2]*2,yL-95-stepsX[counterK2]);
rectMode(CENTER);
rotate(counter/180*Math.PI);
rect(0,0,25,25);
rect(0,0,30,30);
pop();
push();
strokeWeight(1);
noFill();
translate(xL+45+stepsY[counterK]*2,yL-75-stepsX[counterK]);
rectMode(CENTER);
rotate(counter/180*Math.PI);
rect(0,0,25,25);
rect(0,0,15,15);
pop();
}