Your browser does not support the canvas tag.

previous        Show / Hide Source        Download        next
/// UFO ABDUCTION ///

// Created by: Eyan Howlader


// Abduct all the cows as you fly your UFO through a farm!
// WASD to move the UFO
// If you fly your UFO too close to the ground, your game will be over
// Click and hold a mouse button to begin your abduction process
// Your Abduction Beam only activates when you're a certain height directly above a cow
// You must completely abduct the cow into your ship in order for the next to appear
// If you let go of the mouse button midway through abducting a cow, the cow will start falling down!

// Cylon lander's visuals inspired the visuals in this game


// global variables

// position of ufo
int ufoX;
int ufoY;

// ufo directional movement
float up = 0;
float down = 0;
float left = 0;
float right = 0;

// ufo directional speed
float speed = 4;

// initial randomized position of cow
int cowBodyX = int(random(100, 300));
int cowBodyY = 310;


void setup() {

  // set window size
  size(400, 400);
  // set anti-aliasing
  smooth();
  // set 60fps
  frameRate(60);
  // remove all outlines
  noStroke();

  // call game over message display
  gameOver();

  // initial ufo position
  ufoX = width/2;
  ufoY = 40;
}

void draw() {

  // set shape drawing modes
  rectMode(CORNERS);
  // black night background
  background(0);

  // call background stars
  drawStars();
  // call background barn tower
  drawBarnTower();
  // call background barn
  drawBarn();
  // call cow
  drawCow();
  // call ufo
  drawUFO();
  // call looped background fence
  drawFence();

  // apply shape drawing mode for remaining lines of code until one section
  rectMode(CORNERS);

  // call game over function
  updateUFO();

  // method referenced from: example 5-4 of "Learning Processing"
  // draw cow being abducted at an increasing vertical value as a mouse button is pressed
  if (mousePressed && ufoX+40 >= cowBodyX+5 && ufoX - 35 <= cowBodyX+5 && ufoY >= 100) {
    abductionBeam();
    cowBodyY = cowBodyY - 1;
  } 
  // draw cow falling downwards if mouse button is released
  else {
    cowBodyY = cowBodyY + 1;
  }
  // spawn a cow at a randomized location changing only in x-valu along the ground after a complete abduction is complete
  if (mousePressed && cowBodyY == ufoY+17) {
    cowRespawn();
  }

  // ufo movement
  ufoX += (right - left) * speed;
  ufoY += (down - up) * speed;
}

// draw white stars in the background parallaxed
void drawStars() {

  fill(255);
  ellipse(10+mouseX/35, 10+mouseY/35, 1, 1);
  ellipse(200+mouseX/35, 20+mouseY/35, 1, 1);
  ellipse(40+mouseX/35, 240+mouseY/35, 1, 1);
  ellipse(75+mouseX/35, 275+mouseY/35, 1, 1);
  ellipse(95+mouseX/35, 195+mouseY/35, 1, 1);
  ellipse(60+mouseX/35, 160+mouseY/35, 1, 1);
  ellipse(250+mouseX/35, 25+mouseY/35, 1, 1);
  ellipse(175+mouseX/35, 75+mouseY/35, 1, 1);
  ellipse(320+mouseX/35, 30+mouseY/35, 1, 1);
  ellipse(340+mouseX/35, 170+mouseY/35, 1, 1);
  ellipse(20+mouseX/35, 106+mouseY/35, 1, 1);
  ellipse(310+mouseX/35, 130+mouseY/35, 1, 1);
  ellipse(60+mouseX/35, 60+mouseY/35, 1, 1);
  ellipse(220+mouseX/35, 200+mouseY/35, 1, 1);
  ellipse(300+mouseX/35, 210+mouseY/35, 1, 1);
  ellipse(131+mouseX/35, 128+mouseY/35, 1, 1);
  ellipse(242+mouseX/35, 110+mouseY/35, 1, 1);
  ellipse(158+mouseX/35, 244+mouseY/35, 1, 1);
  ellipse(253+mouseX/35, 281+mouseY/35, 1, 1);
  ellipse(364+mouseX/35, 270+mouseY/35, 1, 1);
}

// draw game over text 
void gameOver() {

  fill (0);
  rect(0, 0, width, height);
  fill(255, 0, 0);
  // print text "Game Over" at the center of the screen
  textSize(60);
  text("Game Over!", 20, 200);
  textSize(20);
  text("Click refresh to restart.", 80, 250);
}

// draw barn tower parallaxed
void drawBarnTower() {

  fill(102, 7, 7);
  rect(20+mouseX/80, 100+mouseY/80, 60+mouseX/80, 320+mouseY/80);
  fill(195, 195, 195);
  arc(40+mouseX/80, 100+mouseY/80, 40, 40, PI, TWO_PI);
}

// draw barn parallaxed
void drawBarn() {

  // draw ground
  fill(12, 85, 20);
  rect(0, 320+mouseY/100, 400, 400+mouseY/100);

  // draw base
  fill(122, 7, 7);
  rect(40+mouseX/100, 240+mouseY/100, 120+mouseX/100, 320+mouseY/100);
  triangle(80+mouseX/100, 200+mouseY/100, 57+mouseX/100, 220+mouseY/100, 103+mouseX/100, 220+mouseY/100);
  quad(57+mouseX/100, 220+mouseY/100, 103+mouseX/100, 220+mouseY/100, 120+mouseX/100, 240+mouseY/100, 40+mouseX/100, 240+mouseY/100);

  // draw door frame
  fill(255);
  rect(61+mouseX/100, 279+mouseY/100, 101+mouseX/100, 320+mouseY/100);

  // draw door base
  fill(97, 9, 9);
  triangle(63+mouseX/100, 280+mouseY/100, 71+mouseX/100, 300+mouseY/100, 80+mouseX/100, 280+mouseY/100);
  triangle(62+mouseX/100, 280+mouseY/100, 62+mouseX/100, 320+mouseY/100, 70+mouseX/100, 300+mouseY/100);
  triangle(72+mouseX/100, 300+mouseY/100, 81+mouseX/100, 280+mouseY/100, 81+mouseX/100, 320+mouseY/100);
  triangle(71+mouseX/100, 300+mouseY/100, 80+mouseX/100, 320+mouseY/100, 63+mouseX/100, 320+mouseY/100);
  triangle(82+mouseX/100, 280+mouseY/100, 99+mouseX/100, 280+mouseY/100, 90+mouseX/100, 300+mouseY/100);
  triangle(82+mouseX/100, 281+mouseY/100, 82+mouseX/100, 320+mouseY/100, 89+mouseX/100, 300+mouseY/100);
  triangle(82+mouseX/100, 320+mouseY/100, 90+mouseX/100, 301+mouseY/100, 99+mouseX/100, 320+mouseY/100);
  triangle(100+mouseX/100, 280+mouseY/100, 91+mouseX/100, 300+mouseY/100, 100+mouseX/100, 320+mouseY/100);

  // draw window
  fill(255);
  rect(70+mouseX/100, 220+mouseY/100, 90+mouseX/100, 250+mouseY/100);
  fill(0);
  rect(71+mouseX/100, 221+mouseY/100, 89+mouseX/100, 249+mouseY/100);

  // draw roof
  fill(195, 195, 195);
  rect(30+mouseX/100, 240+mouseY/100, 40+mouseX/100, 250+mouseY/100);
  rect(120+mouseX/100, 240+mouseY/100, 130+mouseX/100, 250+mouseY/100);
  quad(30+mouseX/100, 240+mouseY/100, 40+mouseX/100, 240+mouseY/100, 57+mouseX/100, 220+mouseY/100, 51+mouseX/100, 210+mouseY/100);
  quad(130+mouseX/100, 240+mouseY/100, 120+mouseX/100, 240+mouseY/100, 103+mouseX/100, 220+mouseY/100, 108+mouseX/100, 210+mouseY/100);
  quad(57+mouseX/100, 220+mouseY/100, 49+mouseX/100, 212+mouseY/100, 80+mouseX/100, 190+mouseY/100, 80+mouseX/100, 200+mouseY/100);
  quad(80+mouseX/100, 200+mouseY/100, 80+mouseX/100, 190+mouseY/100, 110+mouseX/100, 212+mouseY/100, 103+mouseX/100, 220+mouseY/100);
}

// make game over message appear if ufo touches the ground
void updateUFO() {

  if (ufoY > 295) {
    gameOver();
    speed = 0;
  }
}

// draw ufo (player)
void drawUFO() {

  // glass dome
  fill(0, 255, 255, 150);
  ellipse(ufoX, ufoY, 40, 40);

  // metal body
  fill(64, 246, 119);
  arc(ufoX, ufoY+15, 100, 30, PI, TWO_PI);
  arc(ufoX, ufoY+14, 100, 30, 0, PI);

  // lights
  fill(255, 154, 0);
  ellipse(ufoX, ufoY+12, 12, 12);
  ellipse(ufoX+20, ufoY+12, 5, 10);
  ellipse(ufoX+35, ufoY+12, 3, 7);
  ellipse(ufoX-20, ufoY+12, 5, 10);
  ellipse(ufoX-35, ufoY+12, 3, 7);
  fill(255, 255, 0);
  ellipse(ufoX, ufoY+12, 10, 10);
  ellipse(ufoX+20, ufoY+12, 4, 9);
  ellipse(ufoX+35, ufoY+12, 2, 6);
  ellipse(ufoX-20, ufoY+12, 4, 9);
  ellipse(ufoX-35, ufoY+12, 2, 6);

  // set screen boundaries of ufo
  if (ufoX < 50) {
    ufoX = 50;
  }
  if (ufoX > 350) {
    ufoX = 350;
  }
  if (ufoY < 20) {
    ufoY = 20;
  }
}

// draw abduction beam
void abductionBeam() {

  fill(214, 253, 122, 200);
  quad(ufoX-10, ufoY+28, ufoX+10, ufoY+28, ufoX+40, ufoY+200, ufoX-35, ufoY+200);
}

// draw cow
void drawCow() {

  // body
  fill(235, 235, 235);
  rect(cowBodyX+5+mouseX/100, cowBodyY-28+mouseY/100, cowBodyX+40+mouseX/100, cowBodyY+mouseY/100, 5);

  // legs
  triangle(cowBodyX+8+mouseX/100, cowBodyY+mouseY/100, cowBodyX+18+mouseX/100, cowBodyY+mouseY/100, cowBodyX+13+mouseX/100, cowBodyY+9+mouseY/100);
  triangle(cowBodyX+25+mouseX/100, cowBodyY+mouseY/100, cowBodyX+35+mouseX/100, cowBodyY+mouseY/100, cowBodyX+30+mouseX/100, cowBodyY+9+mouseY/100);

  // head
  rect(cowBodyX-5+mouseX/100, cowBodyY-30+mouseY/100, cowBodyX+12+mouseX/100, cowBodyY-10+mouseY/100, 5);

  // tail
  triangle(cowBodyX+40+mouseX/100, cowBodyY-10+mouseY/100, cowBodyX+40+mouseX/100, cowBodyY-5+mouseY/100, cowBodyX+45+mouseX/100, cowBodyY-5+mouseY/100);

  // mouth
  fill(255, 165, 223);
  rect(cowBodyX-8+mouseX/100, cowBodyY-20+mouseY/100, cowBodyX+9+mouseX/100, cowBodyY-8+mouseY/100, 5);

  // nostrils
  fill(0);
  ellipse(cowBodyX-5+mouseX/100, cowBodyY-15+mouseY/100, 2, 2);
  ellipse(cowBodyX+mouseX/100, cowBodyY-15+mouseY/100, 2, 2);

  // horns
  fill(161, 116, 27);
  triangle(cowBodyX-5+mouseX/100, cowBodyY-28+mouseY/100, cowBodyX+mouseX/100, cowBodyY-30+mouseY/100, cowBodyX-10+mouseX/100, cowBodyY-35+mouseY/100);
  triangle(cowBodyX+3+mouseX/100, cowBodyY-30+mouseY/100, cowBodyX+10+mouseX/100, cowBodyY-28+mouseY/100, cowBodyX+18+mouseX/100, cowBodyY-35+mouseY/100);

  // eyes
  fill(0);
  ellipse(cowBodyX-2+mouseX/100, cowBodyY-25+mouseY/100, 2, 3);
  ellipse(cowBodyX+2+mouseX/100, cowBodyY-25+mouseY/100, 2, 3);

  // add a constraint on how high to cow goes before completing the abduction process
  cowBodyY = constrain(cowBodyY, ufoY+12, 312);
}

// initiate cow's randomized location respawn across the x-axis while remaining constant to the y-value of the ground
void cowRespawn() {

  cowBodyX = int(random(0, 400));
  cowBodyY = 312;
}

// draw looping fence
void drawFence() {

  fill(255);
  float fencePos = 250;
  rectMode(CORNER);

  while (fencePos <= width) {
    rect(fencePos+mouseX/100, 295+mouseY/100, 5, 25);
    rect(fencePos+5+mouseX/100, 300+mouseY/100, 25, 3);
    rect(fencePos+5+mouseX/100, 305+mouseY/100, 25, 3);
    rect(fencePos+5+mouseX/100, 310+mouseY/100, 25, 3);
    rect(fencePos+5+mouseX/100, 315+mouseY/100, 25, 3);

    // fence spacing
    fencePos += 30;
  }
}

// referenced http://www-acad.sheridanc.on.ca/PROG14998/2016/interactive-toy/josh_schwarm_interactive_toy/index.html for movement controls reference
// keyboard controls for ufo movement
void keyPressed() {

  // moves ufo up
  if (key == 'w') {
    up=1;
    // moves ufo left
  } else if (key == 'a') {
    left=1;
    // moves ufo down
  } else if (key == 's') {
    down=1;
    // moves ufo right
  } else if (key == 'd') {
    right=1;
  }
}

// keyboard outcomes when keys are released
void keyReleased() {

  // ufo remains stationary if any of the movement keys are released
  if (key == 'w') {
    up=0;
  } else if (key == 'a') {
    left=0;
  } else if (key == 's') {
    down=0;
  } else if (key == 'd') {
    right=0;
  }
}