/*
The Hungry Dinosaur
By: Jaylin Grierson
Date: October 5th, 2018
Description: Use the mouse to click the start button to begin.
Control the dinosaur to eat the cake! Eat as much cake as you can.
Eat cake by moving the dinosaur's mouth over the slices.
The more cake the dinosaur eats the fuller he will get.
Press W to move up, A to move left and D to move right.
Adjust the time of day by sliding the mouse left and right.
After the cake is eaten a new slice will randomly appear elsewhere with a new colour.
*/
//===============================================================================
//Initial setup
//===============================================================================
//Declaring all variables used in the program
//Dinosaur's x and y locations
float dinoLocX;
float dinoLocY;
//Cake's x and y locations
float cakeLocX;
float cakeLocY;
//Cake's icing colour
float cakeColour;
float cakeColour2;
float cakeColour3;
//Cake eaten counter
int cakes;
//Grass's x location
float grassX;
//Tree's x location
float treeLocX;
//Top of tree movement (swaying)
float treeMove;
//Coefficient of gravity
float gravity = 0.1;
//Speed of the dinosaur on x and y axis
float dinoSpeedX;
float dinoSpeedY;
//Keeps track of if the cake is eaten and if a new one needs to be spawned
boolean cakeEaten = false;
//Dinosaur's movement
boolean goLeft = false;
boolean goRight = false;
boolean goUp = false;
//When this is true the interaction begins and the start screen dissapears
boolean programStarted = false;
//===============================================================================
//Program setup
void setup() {
//400 square pixel canvas with frame rate of 60 FPS
size(400, 400);
frameRate(60);
//Setting the ellipse and rectangle modes
ellipseMode(CENTER);
rectMode(CORNERS);
//Setting the cake eaten counter to 0
cakes = 0;
//Setting initial random location of the cake
cakeLocX = random(50, 310);
cakeLocY = random(50, 310);
//Setting initial random colour of the cake
cakeColour = random(255);
cakeColour2 = random(255);
cakeColour3 = random(255);
//Setting the initial location of the dinosaur
dinoLocX = 100;
dinoLocY = 300;
//Setting the initial speed of the dinosaur
dinoSpeedX = 0;
dinoSpeedY = 0;
//Outputting how many cakes have been eaten
println("Cakes Eaten:");
print(cakes);
}
//===============================================================================
//Draw
//===============================================================================
//Active program
void draw() {
//If the start button has not been pressed the start screen is displayed
if (programStarted == false) {
startupScreen();
}
//If the start button has been pressed the program begins
else if (programStarted == true) {
//Since the program has just begun the cake has not been eaten
cakeEaten = false;
//Setting the stroke weight to 1
strokeWeight(1);
//===============================================================================
//Draw background
drawBackground();
//Dinosaur and cake
//Dinosaur movement
dinoMovement();
//Interaction between dinosaur and cake
interaction();
//Update cake location
updateCakeLoc();
//Draw cake
drawCake();
//Draw dinosaur
drawDino();
}
}
//===============================================================================
//Key and mouse commands
//===============================================================================
void mousePressed() {
//If the mouse is pressed over the start button then the program will begin
if ((mouseX > 150) && (mouseX < 250) && (mouseY > 180) && (mouseY < 220)) {
programStarted = true;
}
}
void keyPressed() {
//Directional keys control the dinosaur's movement
if (key == 'w') {
goUp = true;
}
if (key == 'a') {
goLeft = true;
}
if (key == 'd') {
goRight = true;
}
}
void keyReleased() {
//When a key is released the dinosaur stops accelerating in that direction
if (key == 'w') {
goUp = false;
}
if (key == 'a') {
goLeft = false;
}
if (key == 'd') {
goRight = false;
}
}
//===============================================================================
//Functions
//===============================================================================
//Startup Screen
void startupScreen() {
//Background
fill(175, 255, 175);
rect(0, 0, 400, 400);
//Black stroke
stroke (0);
//Palm Trees
//Trunk
//Brown fill
fill (148, 107, 71);
//Trunk 1
quad(90, 310, 110, 310, 105, 120, 95, 120);
//Trunk 2
quad(290, 310, 310, 310, 305, 120, 295, 120);
//Leaves
//Green fill
fill (0, 255, 100);
//Leaf 1, Tree 1
triangle(100, 120, 150, 90, 200, 120);
//Leaf 2, Tree 1
triangle(100, 120, 50, 90, 0, 120);
//Leaf 3, Tree 1
triangle(100, 120, 150, 100, 190, 140);
//Leaf 4, Tree 1
triangle(100, 120, 50, 100, 10, 140);
//Leaf 1, Tree 2
triangle(300, 120, 350, 90, 400, 120);
//Leaf 2, Tree 2
triangle(300, 120, 250, 90, 200, 120);
//Leaf 3, Tree 2
triangle(300, 120, 350, 100, 390, 140);
//Leaf 4, Tree 2
triangle(300, 120, 250, 100, 210, 140);
//Leaf 3
//Coconuts
//Dark brown fill
fill (128, 87, 51);
//Coconut 1, Tree 1
ellipse(95, 120, 15, 15);
//Coconut 2, Tree 1
ellipse(100 + 5, 120, 15, 15);
//Coconut 3, Tree 1
ellipse(100, 110, 15, 15);
//Coconut 1, Tree 2
ellipse(290 + 5, 120, 15, 15);
//Coconut 2, Tree 2
ellipse(290 + 15, 120, 15, 15);
//Coconut 3, Tree 2
ellipse(290 + 10, 110, 15, 15);
//Start button
//dark red fill
fill(200, 0, 0);
rect(150, 180, 250, 220);
//"Start" letters on button
//Thicker stroke weight
strokeWeight(2);
//S
line(160, 190, 170, 190);
line(160, 190, 160, 200);
line(160, 200, 170, 200);
line(170, 200, 170, 210);
line(170, 210, 160, 210);
//T
line(175, 190, 185, 190);
line(180, 190, 180, 210);
//A
line(190, 210, 195, 190);
line(195, 190, 200, 210);
line(192, 205, 198, 205);
//R
line(210, 210, 210, 190);
line(210, 190, 220, 190);
line(220, 190, 220, 200);
line(220, 200, 210, 200);
line(210, 200, 220, 210);
//T
line(230, 190, 240, 190);
line(235, 190, 235, 210);
}
//===============================================================================
//Drawing the background of the main program
void drawBackground() {
//Draw background
//Background transitions from black to blue (night to day) with the mouse's x movement
background(0 + mouseX/3, 0 + mouseX/2, mouseX);
//Moon
//Black stroke
stroke(0);
//White fill
fill(255);
ellipse(100, mouseX + 25, 50, 50);
//Sun
//Yellow fill
fill(255, 255, 0);
ellipse(300, 400-mouseX + 25, 50, 50);
//Grass
rectMode(CORNERS);
//Green fill
fill(0, 255, 125);
rect(0, 260, 400, 400);
//Long grass
longGrass();
//Draw trees
drawTrees();
drawTrees2();
}
//===============================================================================
//Function that draws long grass
void longGrass() {
//Setting grass x location to 0
grassX = 0;
//setting fill colour to dark green
fill(0, 150, 0);
//While the grass is on the screen draw grass every 15 pixels
while (grassX < width) {
triangle(grassX, 260, grassX + 10, 220, grassX + 20, 260);
//After grass is drawn, the x location increases to draw new grass
grassX += 15;
}
}
//===============================================================================
//Function that draws the trees
void drawTrees() {
//Setting tree's x location to 50
treeLocX = 50;
//Setting tree's movement
treeMove = 5*sin(frameCount*0.1);
//While the trees are on the screen, draw trees every 100 pixels
while (treeLocX < width) {
//Brown fill
fill (148, 107, 71);
//Trunk
quad(treeLocX, 270, treeLocX + 20, 270, treeLocX + 15 + treeMove, 80, treeLocX + 5 + treeMove, 80);
//Leaves
//Green fill
fill (0, 255, 100);
//Leaf 1
triangle(treeLocX + 10 + treeMove, 80, treeLocX + 60 + treeMove, 50, treeLocX + 110 + treeMove, 80);
//Leaf 2
triangle(treeLocX + 10 + treeMove, 80, treeLocX -40 + treeMove, 50, treeLocX -90 + treeMove, 80);
//Leaf 3
triangle(treeLocX + 10 + treeMove, 80, treeLocX + 60 + treeMove, 60, treeLocX + 100 + treeMove, 100);
//Leaf 4
triangle(treeLocX + 10 + treeMove, 80, treeLocX -40 + treeMove, 60, treeLocX -80 + treeMove, 100);
//Coconuts
//Dark brown fill
fill (128, 87, 51);
//Coconut 1
ellipse(treeLocX + 5 + treeMove, 80, 15, 15);
//Coconut 2
ellipse(treeLocX + 15 + treeMove, 80, 15, 15);
//Coconut 3
ellipse(treeLocX + 10 + treeMove, 70, 15, 15);
//After a tree is drawn 200 units is added to the location so a new tree can be drawn
treeLocX += 200;
}
}
//===============================================================================
//Function that draws the second row of trees
void drawTrees2() {
//Setting tree's x location to 150
treeLocX = 150;
//Setting tree's movement
treeMove = 5*sin(frameCount*0.1);
//While the trees are on the screen, draw trees every 100 pixels
while (treeLocX < width) {
//Brown fill
fill (148, 107, 71);
//Trunk
quad(treeLocX, 310, treeLocX + 20, 310, treeLocX + 15 + treeMove, 120, treeLocX + 5 + treeMove, 120);
//Leaves
//Green fill
fill (0, 255, 100);
//Leaf 1
triangle(treeLocX + 10 + treeMove, 120, treeLocX + 60 + treeMove, 90, treeLocX + 110 + treeMove, 120);
//Leaf 2
triangle(treeLocX + 10 + treeMove, 120, treeLocX -40 + treeMove, 90, treeLocX -90 + treeMove, 120);
//Leaf 3
triangle(treeLocX + 10 + treeMove, 120, treeLocX + 60 + treeMove, 100, treeLocX + 100 + treeMove, 140);
//Leaf 4
triangle(treeLocX + 10 + treeMove, 120, treeLocX -40 + treeMove, 100, treeLocX -80 + treeMove, 140);
//Coconuts
//Dark brown fill
fill (128, 87, 51);
//Coconut 1
ellipse(treeLocX + 5 + treeMove, 120, 15, 15);
//Coconut 2
ellipse(treeLocX + 15 + treeMove, 120, 15, 15);
//Coconut 3
ellipse(treeLocX + 10 + treeMove, 110, 15, 15);
//After a tree is drawn 200 units is added to the location so a new tree can be drawn
treeLocX += 200;
}
}
//===============================================================================
void dinoMovement() {
//Location of dinosaur = location of dinosaur + speed of dinosaur
dinoLocX = dinoLocX + dinoSpeedX;
dinoLocY = dinoLocY + dinoSpeedY;
//Speed of dinosaur = speed of dinosau + gravity
dinoSpeedY = dinoSpeedY + gravity;
//Regulating dinosaur's Y axis speed so it doesn't get stuck on the top or bottom of the screen
if (dinoSpeedY > 3) {
dinoSpeedY = 3;
}
if (dinoSpeedY < -3) {
dinoSpeedY = -3;
}
//Constraining the dinosaur to the limits of the screen
if (dinoLocX < 30) {
dinoLocX = 30;
}
if (dinoLocX > width - 30) {
dinoLocX = width - 30;
}
if (dinoLocY < 70) {
dinoLocY = 70;
}
if (dinoLocY > height - 40) {
dinoLocY = height - 40;
}
//When a a key is pressed the dinosaur moves in the corresponding direction
if (goLeft == true) {
dinoSpeedX = dinoSpeedX - 0.1;
}
if (goRight == true) {
dinoSpeedX = dinoSpeedX + 0.1;
}
if (goUp == true) {
dinoSpeedY = dinoSpeedY - 0.5;
}
//If the dinosaur's speed is not zero, the dinsoaur slows down to a stop
if (dinoSpeedX > 0) {
dinoSpeedX = dinoSpeedX - 0.05;
}
if (dinoSpeedX < 0) {
dinoSpeedX = dinoSpeedX + 0.05;
}
if (dinoSpeedY < 0) {
dinoSpeedY = dinoSpeedY + 0.05;
}
//Dampening "ice physics" on the ground so the momentum buildup is less than that in the air
if (dinoLocY == 360){
if((goLeft == false) && (dinoSpeedX < 0)){
dinoSpeedX = dinoSpeedX + 0.1;
}
else if ((goRight == false) && (dinoSpeedX > 0)){
dinoSpeedX = dinoSpeedX - 0.1;
}
}
}
//===============================================================================
//Interaction
void interaction() {
//If the dinosaur's mouth is less than 15 pixels away from the cake then the cake is "eaten"
if (dist(dinoLocX + 10, dinoLocY - 40, cakeLocX, cakeLocY) < 15) {
cakeEaten = true;
//The cake counter increases
cakes += 1;
//Program prints blank line and then the message saying how many cakes have been eaten
println();
println("Cakes Eaten:");
print(cakes);
}
}
//===============================================================================
//Function that updates the location of the cake
void updateCakeLoc() {
//If the cake is eaten set a new random cake location and colour
if (cakeEaten == true) {
cakeLocX = random (50, 310);
cakeLocY = random (50, 310);
cakeColour = random(255);
cakeColour2 = random(255);
cakeColour3 = random(255);
}
}
//===============================================================================
//Function that draws the slices of cake
void drawCake() {
//Setting rectangle mode
rectMode(CENTER);
//Side
//Beige fill
fill(228, 220, 190);
rect(cakeLocX, cakeLocY - 10, 30, 5);
rect(cakeLocX, cakeLocY, 30, 10);
//Icing
//Random fill
fill(cakeColour, cakeColour2, cakeColour3);
rect(cakeLocX, cakeLocY - 5, 30, 5);
//Top
//White fill
fill(255);
triangle(cakeLocX + 15, cakeLocY - 13, cakeLocX - 15, cakeLocY - 13, cakeLocX + 10, cakeLocY - 23);
//Stawberry
//Red fill
fill(255, 0, 0);
ellipse(cakeLocX + 5, cakeLocY - 17, 5, 5);
}
//===============================================================================
//Function that draws the dinosaur
void drawDino() {
//Drawing the dinosaur facing left if the "a" key is being pressed
if (goLeft == true) {
rectMode(CORNERS);
//Back wing
//Medium-dark purple fill
fill(180, 0, 235);
//If the dinosaur is not moving up, the wing is up
if (goUp == false) {
triangle(dinoLocX, dinoLocY - 20, dinoLocX + 15, dinoLocY - 40, dinoLocX + 30, dinoLocY - 10);
}
//If the dinosaur is moving up, the wing moves down to give a flying animation
if (goUp == true) {
triangle(dinoLocX, dinoLocY - 20, dinoLocX + 15, dinoLocY - 30, dinoLocX + 30, dinoLocY);
}
//Head
//No stroke on the head
noStroke();
//Dark purple fill
fill(100, 0, 155);
rect(dinoLocX + 10, dinoLocY - 30, dinoLocX - 20, dinoLocY - 40);
rect(dinoLocX + 10, dinoLocY, dinoLocX, dinoLocY - 70);
rect(dinoLocX + 10, dinoLocY - 50, dinoLocX - 30, dinoLocY - 70);
//Red fill
fill(255, 0, 0);
//Eye
triangle(dinoLocX, dinoLocY - 60, dinoLocX, dinoLocY - 70, dinoLocX - 10, dinoLocY - 60);
//White fill
fill(255);
//Teeth
triangle(dinoLocX - 10, dinoLocY - 50, dinoLocX - 20, dinoLocY - 50, dinoLocX - 15, dinoLocY - 45);
triangle(dinoLocX - 20, dinoLocY - 50, dinoLocX - 30, dinoLocY - 50, dinoLocX - 25, dinoLocY - 45);
triangle(dinoLocX, dinoLocY - 50, dinoLocX - 10, dinoLocY - 50, dinoLocX - 5, dinoLocY - 45);
triangle(dinoLocX, dinoLocY - 40, dinoLocX, dinoLocY - 45, dinoLocX - 5, dinoLocY - 40);
triangle(dinoLocX - 5, dinoLocY - 40, dinoLocX - 15, dinoLocY - 40, dinoLocX - 10, dinoLocY - 45);
triangle(dinoLocX - 15, dinoLocY - 40, dinoLocX - 20, dinoLocY - 40, dinoLocX - 20, dinoLocY - 45);
//Spikes
//Very dark purple fill
fill(50, 0, 105);
triangle(dinoLocX + cakes/2, dinoLocY - 30, dinoLocX + 15 + cakes/2, dinoLocY - 30, dinoLocX + 15 + cakes/2, dinoLocY - 10);
triangle(dinoLocX + cakes/2, dinoLocY - 20, dinoLocX + 25 + cakes/2, dinoLocY - 20, dinoLocX + 20 + cakes/2, dinoLocY);
triangle(dinoLocX + 10 + cakes/2, dinoLocY - 5, dinoLocX + 30 + cakes/2, dinoLocY, dinoLocX + 15 + cakes/2, dinoLocY + 10);
//Hind leg
//Dark purple fill
fill(100, 0, 155);
rect(dinoLocX, dinoLocY + 20, dinoLocX - 10, dinoLocY + 40);
//White fill
fill(255);
//Toe
triangle(dinoLocX -10, dinoLocY + 40, dinoLocX - 15, dinoLocY + 40, dinoLocX - 10, dinoLocY + 35);
//Tail
//Medium purple fill
fill(150, 0, 205);
triangle(dinoLocX, dinoLocY - 10, dinoLocX + 40, dinoLocY + 40, dinoLocX, dinoLocY + 30);
//Body
//Light purple fill
fill(200, 50, 255);
ellipse(dinoLocX, dinoLocY, 40 + cakes, 60);
//Arm
//Dark purple fill
fill(100, 0, 155);
triangle(dinoLocX, dinoLocY - 10, dinoLocX + 10, dinoLocY - 10, dinoLocX, dinoLocY + 10);
//white fill
fill(255);
triangle(dinoLocX, dinoLocY +10, dinoLocX, dinoLocY + 5, dinoLocX + 2.5, dinoLocY + 5);
//Front leg
//Dark purple fill
fill(100, 0, 155);
rect(dinoLocX + 2.5, dinoLocY + 20, dinoLocX + 12.5, dinoLocY + 40);
//white fill
fill(255);
//Toe
triangle(dinoLocX + 2.5, dinoLocY + 40, dinoLocX - 5, dinoLocY + 40, dinoLocX + 2.5, dinoLocY + 35);
//Front wing
//Adding outline for wing
stroke(0);
//Dark Purple fill
fill(130, 0, 185);
//If the dinosaur is not moving up, the wing is up
if (goUp == false) {
triangle(dinoLocX + 10, dinoLocY - 20, dinoLocX + 40, dinoLocY - 40, dinoLocX + 70, dinoLocY - 10);
}
//If the dinosaur is moving up, the wing is down
if (goUp == true) {
triangle(dinoLocX + 10, dinoLocY - 20, dinoLocX + 40, dinoLocY - 30, dinoLocX + 70, dinoLocY);
}
}
//If the dinosaur is not moving left it faces right
else {
rectMode(CORNERS);
//Back wing
fill(180, 0, 235);
//If the dinosaur is not moving up, the wing is up
if (goUp == false) {
triangle(dinoLocX, dinoLocY - 20, dinoLocX - 15, dinoLocY - 40, dinoLocX - 30, dinoLocY - 10);
}
//If the dinosaur is moving up, the wing is down
if (goUp == true) {
triangle(dinoLocX, dinoLocY - 20, dinoLocX - 15, dinoLocY - 30, dinoLocX - 30, dinoLocY);
}
//Head
//No stroke
noStroke();
//Head
//Dark purple fill
fill(100, 0, 155);
rect(dinoLocX - 10, dinoLocY - 30, dinoLocX + 20, dinoLocY - 40);
rect(dinoLocX - 10, dinoLocY, dinoLocX, dinoLocY - 70);
rect(dinoLocX - 10, dinoLocY - 50, dinoLocX + 30, dinoLocY - 70);
//Red fill
fill(255, 0, 0);
//Eye
triangle(dinoLocX, dinoLocY - 60, dinoLocX, dinoLocY - 70, dinoLocX + 10, dinoLocY - 60);
//White fill
fill(255);
//Teeth
triangle(dinoLocX + 10, dinoLocY - 50, dinoLocX + 20, dinoLocY - 50, dinoLocX + 15, dinoLocY - 45);
triangle(dinoLocX + 20, dinoLocY - 50, dinoLocX + 30, dinoLocY - 50, dinoLocX + 25, dinoLocY - 45);
triangle(dinoLocX, dinoLocY - 50, dinoLocX + 10, dinoLocY - 50, dinoLocX + 5, dinoLocY - 45);
triangle(dinoLocX, dinoLocY - 40, dinoLocX, dinoLocY - 45, dinoLocX + 5, dinoLocY - 40);
triangle(dinoLocX + 5, dinoLocY - 40, dinoLocX + 15, dinoLocY - 40, dinoLocX + 10, dinoLocY - 45);
triangle(dinoLocX + 15, dinoLocY - 40, dinoLocX + 20, dinoLocY - 40, dinoLocX + 20, dinoLocY - 45);
//Spikes
//Very dark purple fill
fill(50, 0, 105);
triangle(dinoLocX -cakes/2, dinoLocY - 30, dinoLocX - 15 - cakes/2, dinoLocY - 30, dinoLocX - 15 - cakes/2, dinoLocY - 10);
triangle(dinoLocX -cakes/2, dinoLocY - 20, dinoLocX - 25 - cakes/2, dinoLocY - 20, dinoLocX - 20 - cakes/2, dinoLocY);
triangle(dinoLocX - 10 -cakes/2, dinoLocY - 5, dinoLocX - 30 - cakes/2, dinoLocY, dinoLocX - 15 - cakes/2, dinoLocY + 10);
//Hind leg
//Dark purple fill
fill(100, 0, 155);
rect(dinoLocX, dinoLocY + 20, dinoLocX + 10, dinoLocY + 40);
//while fill
fill(255);
//Toe
triangle(dinoLocX +10, dinoLocY + 40, dinoLocX + 15, dinoLocY + 40, dinoLocX + 10, dinoLocY + 35);
//Tail
//Medium purple fill
fill(150, 0, 205);
triangle(dinoLocX, dinoLocY - 10, dinoLocX - 40, dinoLocY + 40, dinoLocX, dinoLocY + 30);
//Body
//Light purple fill
fill(200, 50, 255);
ellipse(dinoLocX, dinoLocY, 40 + cakes, 60);
//Arm
//Dark purple fill
fill(100, 0, 155);
triangle(dinoLocX, dinoLocY - 10, dinoLocX - 10, dinoLocY - 10, dinoLocX, dinoLocY + 10);
//White fill
fill(255);
triangle(dinoLocX, dinoLocY +10, dinoLocX, dinoLocY + 5, dinoLocX - 2.5, dinoLocY + 5);
//Front leg
//Dark purple fill
fill(100, 0, 155);
rect(dinoLocX - 2.5, dinoLocY + 20, dinoLocX - 12.5, dinoLocY + 40);
//White fill
fill(255);
//Toe
triangle(dinoLocX - 2.5, dinoLocY + 40, dinoLocX + 5, dinoLocY + 40, dinoLocX - 2.5, dinoLocY + 35);
//Wings
//Black stroke
stroke(0);
//Medium-light purple fill
fill(130, 0, 185);
//If the dinosaur is not moving up the wing is up
if (goUp == false) {
triangle(dinoLocX - 10, dinoLocY - 20, dinoLocX - 40, dinoLocY - 40, dinoLocX - 70, dinoLocY - 10);
}
//If the dinosaur is moving up the wing is down
if (goUp == true) {
triangle(dinoLocX - 10, dinoLocY - 20, dinoLocX - 40, dinoLocY - 30, dinoLocX - 70, dinoLocY);
}
}
}