//************************
// SETUP Class Bullet
//************************
class bullet{
boolean bulletActive; // holds whether the bullet is active
float bulletXpos; // holds bullet's current X position
float bulletYpos; // holds bullet's current Y position
float bulletXspeed; // holds bullet's X speed
float bulletYspeed; // holds bullet's Y speed
float bulletXsize;
float bulletYsize;
bullet(float tempXbullet, float tempYbullet) {
bulletActive = true;
bulletXpos = tempXbullet;
bulletYpos = tempYbullet;
bulletXspeed = 0;
bulletYspeed = 7;
bulletXsize = 3;
bulletYsize = 10;
}
void moveBullet() {
if (bulletYpos > -10 && bulletActive) {
bulletYpos = bulletYpos - 14;
} else {
bulletActive = false;
}
}
void displayBullet() {
// if (bulletActive) {
color(0);
fill(0);
noStroke();
rect (bulletXpos, bulletYpos, bulletXsize, bulletYsize);
ellipseMode(CORNER);
ellipse(bulletXpos, bulletYpos-4, bulletXsize, 4);
// }
}
void bulletDisappear(boolean disappearStatus) {
if (disappearStatus) {
bulletActive = false;
bulletXpos = width*2;
bulletYpos = height*2;
} else {
bulletActive = true;
}
}
boolean bulletStatus() {
return bulletActive;
}
int getBulletXpos () {
return int(bulletXpos);
}
int getBulletYpos () {
return int(bulletYpos);
}
int getBulletXposLong () {
return int(bulletXsize);
}
int getBulletYposLong () {
return int(bulletYsize);
}
}
//************************
// SETUP Class Fangs
//************************
class fangs{
// declaration of variables for fangs class
boolean gameOver; // holds whether game is active or over
boolean playerWin; // holds whether the player has won or lost
boolean batAlive; // holds life state of bat - whether alive or dead
color batColor; // holds bat color, which is provided as an argument in the fangs object
float pupilx, pupily; // holds the position of the bat pupils
float yspeed, xspeed; // holds the speed of the x and y coordinates
float fangSize; // holds relative size of fang as a percentage of full size (x 180, y 130)
float origFangYSize, origFangXSize; // holds size of the original bat drawing
float origFangXradius, origFangYradius; // holds the radius size of the original
float batRotation; // holds current rotation of the bat
float newRotation; // holds new rotation value
float oldRotation; // holds old rotation value (pre-sleeping mode)
float batPosX, batPosY; // holds location of bat at all times
float sleepX,sleepY; // holds location of bat before sleepMode
boolean sleepMode; // holds status information about whether bat is in sleep mode
boolean wakeSet; // holds information about awake (e.g. launching) the bats after sleep mode
float eyeStatus, eyeClosed, eyeOpen; // holds the thickness of eyebrow and status of eye (whether closed or openned)
float createTime; // holds the time in millis() at which the bat was created
float moveTime; // holds the last time that bat's flight range was expanded
int maxXLoc, maxYLoc; // holds the farthest that the bat can fly at any given moment
float descentTimeInterval; // holds the amount of time that bats stay within each flight space
int descentYInterval; // holds how far the bat goes down with each interval that passes
fangs(color tempC, float tempx, float tempy) { //construction of fangs data type (this is essentially the setup section of the object)
gameOver = false;
playerWin = false;
batAlive = true;
batColor = tempC;
xspeed = random(-8, 8); // generate x speed
yspeed = random(-8, -2); // generate y speed
fangSize = 0; // holds the relative size of the bat (original x 180, x 130)
origFangYSize = 130;
origFangXSize = 180;
origFangXradius = origFangXSize/2;
origFangYradius = origFangYSize/2;
batRotation = radians(0); // sets rotation degrees to 0 so that bats will start upright
newRotation = radians(0); // initializes newRotation to 0 degrees
oldRotation = radians(0); // initializes oldRotation to 0 degrees
batPosX = tempx; // initializing x coordinates of the bat
batPosY = tempy; // initializing y coordinates of the bat
sleepX = tempx; // initializes sleepX coordinate to current x location
sleepY = tempy; // initializes sleepY coordinate to current y location
sleepMode = false;
wakeSet = false;
eyeClosed = 20;
eyeOpen = 7;
eyeStatus = eyeOpen;
createTime = millis();
moveTime = createTime;
descentTimeInterval = 10000;
descentYInterval = height/10;
maxXLoc = width;
maxYLoc = height/2;
}
void sizeSet (float tempSize) { // function that enables the setting of the size of the bat
fangSize = map(tempSize, 0, 200, 0, 2);
}
float sizeReturn () { // function that enables the setting of the size of the bat
return fangSize;
}
// function that randomly generates a size for the bat
void sizeRandom () {
fangSize = map(random (0,15), 0, 15, 0.6, 1.25); // holds the relative size of the bat (original x 180, x 130)
}
void mouseFollow(float xdraw, float ydraw) { // function that enables the bat to follow the mouse
// set position variables (use fangSize to move center of fangs
batPosX = xdraw;
batPosY = ydraw;
// batColor= drawc;
}
void randomMove() { // function that enables the bat to randomly move
// LOGIC that determines when bat has reached edge of window
// also checks to confirm that original direction, based on speed, aligns with expectations before changing direction
if (batAlive) {
xspeed = speedXadj(xspeed, batPosX);
yspeed = speedYadj(yspeed, batPosY);
batPosX = batPosX + xspeed;
batPosY = batPosY + yspeed;
} else {
batPosX = width*2;
batPosY = height*2;
}
}
// function that enables setting the limit of the flight range for each bat
void setMaxFlightRange(int tempXRange, int tempYRange) {
maxXLoc = tempXRange;
maxYLoc = tempYRange;
}
// function that enables setting the limit of the flight range for each bat
void gameInitMaxFlightRange() {
setMaxFlightRange(width, descentYInterval);
}
// function that expands the flight range of the bat based on current time so that they move down the screen as time goes by
void expandMaxFlightRange() {
if ((millis() - moveTime > descentTimeInterval) && (maxYLoc < height)) {
maxYLoc = maxYLoc + descentYInterval;
setMaxFlightRange(maxXLoc, maxYLoc);
moveTime = millis();
}
}
// function that checks if the bat has been killed by verifying if it has been hit by a bullet
void killBatCheck (int tempXLoc, int tempYLoc, int tempXwidth, int tempYheight) {
boolean batKillStatus = batIntersect (tempXLoc, tempYLoc, tempXwidth, tempYheight); // call intersect function to see if object intersected bat
if (batKillStatus) { // if object did intersect the bat then
batAlive = false; // record that bat is no longer alive in the batAlive variable
print("coordinates for intersection ");
println(tempXLoc);
println(tempYLoc);
println(tempXwidth);
println(tempYheight);
}
}
boolean batLife() {
return batAlive;
}
void batWinCheck () {
if (batPosY > height-(origFangXradius*fangSize)) {
playerWin = false;
gameOver = true;
}
}
// function that determines whether an object has intersected with the bat
boolean batIntersect(int tempXLoc, int tempYLoc, int tempXwidth, int tempYheight) {
int intersectX = tempXLoc;
int intersectY = tempYLoc;
int intersectXLong = tempXwidth+tempXLoc;
int intersectYLong = tempYheight+tempYLoc;
// check if object is in the x range of the bat
if (tempXLoc > 0 && tempYLoc > 0) {
if (((intersectX > (batPosX - (origFangXradius*fangSize))) && (intersectX < (batPosX + (origFangXradius*fangSize)))) ||
((intersectXLong > (batPosX - (origFangXradius*fangSize))) && (intersectXLong < (batPosX + (origFangXradius*fangSize))))) {
// check if object is in the y range of the bat
if (((intersectY > (batPosY - (origFangYradius*fangSize))) && (intersectY < (batPosY + (origFangYradius*fangSize)))) ||
((intersectYLong > (batPosY - (origFangYradius*fangSize))) && (intersectYLong < (batPosY + (origFangYradius*fangSize))))) {
return true;
} else {
return false;
}} else {
return false;
}
} else {
return false;
}
}
// function that checks the speed and location of the bat to ensure that the does not go off screen horizontally
float speedXadj(float moveXspeed, float curXlocation) {
float tempXspeed = moveXspeed;
float tempXLoc = curXlocation;
if (tempXLoc > maxXLoc - origFangXradius*fangSize && tempXspeed > 0 || tempXLoc < origFangXradius*fangSize && tempXspeed < 0) {
tempXspeed = tempXspeed * -1;
}
return tempXspeed; // returns adjusted X speed
}
// function that checks the speed and location of the bat to ensure that the does not go off screen vertically
float speedYadj(float moveYspeed, float curYlocation) {
float tempYSpeed = moveYspeed;
float tempYLoc = curYlocation;
if (((tempYLoc > (maxYLoc - (origFangYradius*fangSize))) && (tempYSpeed > 0)) || ((tempYLoc < (origFangYradius*fangSize)) && (tempYSpeed < 0))) {
tempYSpeed = tempYSpeed * -1;
}
return tempYSpeed; // returns adjusted Y speed
}
void setSleepLocation() { // save location of bat for return after sleep mode
oldRotation = batRotation;
sleepX = batPosX;
sleepY = batPosY;
}
void sleepMove() { // function that moves the bats to the top of the screen.
wakeSet = false; // set the wake status to false
if (batPosY > 55*fangSize) { // if the bat is higher than sleeping posision
batPosY = batPosY -8; // move the bat up towards -3
batPosX = batPosX + xspeed/2;
}
// if the bat is close to the top of the page (batPosY), his rotation is not upside down (batRotation), and his status is not a sleep (sleepMode)
if (batPosY < origFangXSize*fangSize) {
if(sleepMode == false) {
if (degrees(batRotation) > 190 ) {
newRotation = radians(-8); // rotate the bat 5 degress at a time till he reaches sleeping position
}
else if (degrees(batRotation) < 170) {
newRotation = radians(14); // rotate the bat 5 degress at a time till he reaches sleeping position
}
else {
batRotation = radians(180); // set bat rotation to 180 degrees (upside down)
sleepMode = true; // set bat status to sleep
eyeStatus = eyeClosed;
}
}
if (eyeStatus < eyeClosed) { // check if eyes are opened
eyeStatus++; // open eyes
}
}
}
void wakeMove() { // function that makes bats wake up from sleeping
sleepMode = false; // set sleepMode to false
if (eyeStatus > eyeOpen) { // check if eyes are opened
eyeStatus--; // open eyes
}
// check if bat has already returned to his previous location from an x perspective
if (batPosY < sleepY) {
batPosY = batPosY + abs(yspeed*2);
}
// check if bat has already rotate to be right side up
if (degrees(batRotation) <= 5) {
wakeSet = true; // set bat awake status to true
batRotation = radians (0);
}
else {
newRotation = radians(-8); // rotate the bat 5 degress at a time till he reaches sleeping position
}
}
boolean wakeStatus() { // return status of the bat
return wakeSet;
}
void randomDir() { // function that changes the direction of the bat to a random new direction
xspeed = random(-6,6);
yspeed = random(-6,6);
}
void rotateBat(boolean rotateDir) { // function that rotates the bats
boolean rotateTest = rotateDir;
if (rotateTest == true) {
newRotation = radians(xspeed*3);
// println(newRotation);
}
else if (rotateTest == false){
newRotation = radians(xspeed*3*-1);
// println(newRotation);
}
}
// function that displays the bat in the location set by one of the movement functions
void display() {
if (batAlive) {
pushMatrix(); // save coordinates to the matrix stack
translate(batPosX, batPosY); // move the origin of the screen to the location where the bat will be drawn
setBatRotation();
rotate(batRotation);
drawWings();
drawHead();
drawEyes();
drawPupils();
drawEyebrows();
drawFangs();
drawLegs();
popMatrix();
}
} // close display () function
// function with logic to check if bat should be rotated (if newRotation variable is not equal 0)
void setBatRotation() {
if (degrees(newRotation) != 0){
batRotation = batRotation + newRotation;
newRotation = radians(0);
}
}
void drawWings() {
noStroke();
fill(batColor);
triangle (-55*fangSize, -65*fangSize, -25*fangSize, -25*fangSize, -95*fangSize, 45*fangSize);
triangle (-55*fangSize, -25*fangSize, -25*fangSize, -25*fangSize, -75*fangSize, 55*fangSize);
triangle (-65*fangSize, -25*fangSize, 5*fangSize, -25*fangSize, -35*fangSize, 55*fangSize);
triangle (-30*fangSize, -25*fangSize, 30*fangSize, -25*fangSize, 0, 65*fangSize);
triangle (55*fangSize, -65*fangSize, 25*fangSize, -25*fangSize, 95*fangSize, 45*fangSize);
triangle (55*fangSize, -25*fangSize, 25*fangSize, -25*fangSize, 75*fangSize, 55*fangSize);
triangle (65*fangSize, -25*fangSize, -5*fangSize, -25*fangSize, 35*fangSize, 55*fangSize);
}
void drawHead() {
fill(batColor); // draw the ears
triangle (-20*fangSize, -65*fangSize, -30*fangSize, -25*fangSize, -10*fangSize, -25*fangSize);
triangle (20*fangSize, -65*fangSize, 30*fangSize, -25*fangSize, 10*fangSize, -25*fangSize);
fill(batColor); // draw head
ellipseMode (CENTER);
ellipse (0,-28*fangSize, 60*fangSize, 45*fangSize);
}
void drawEyes() {
fill (235);
ellipseMode (CORNER);
ellipse (-25*fangSize, -35*fangSize, 23*fangSize, 19*fangSize); // left eye placement x: 65 - 88, y: 30 - 49
ellipse (2*fangSize, -35*fangSize, 23*fangSize, 19*fangSize); // right eye placement x: 92 - 115, y: 30 - 49
}
void drawPupils() {
pupilLogic(); // determine pupil location
ellipseMode (CENTER); // change circle mode for pupil drawing
fill (0);
ellipse (pupilx, pupily, 5*fangSize, 5*fangSize);
ellipse (pupilx + 28*fangSize, pupily, 5*fangSize, 5*fangSize); // add 28 to adjust placement of second eye
}
void drawEyebrows() {
fill(batColor);
rectMode (CORNER);
rect (-27*fangSize,-36*fangSize,53*fangSize,eyeStatus*fangSize);
}
// function that contains logic to calculate pupil location based on location of bat
void pupilLogic() {
pupilx = -20*fangSize + map(width-batPosX, 0, width, 0, 12*fangSize);
pupily = -26*fangSize + map(height-batPosY, 0, height, 0, 6*fangSize);
}
// draw fangs
void drawFangs() {
noStroke();
fill (235);
triangle (-14*fangSize, -5*fangSize, -5*fangSize, -5*fangSize, -11*fangSize, 3*fangSize);
triangle (-5*fangSize, -5*fangSize, 0, -5*fangSize, -3*fangSize, -2*fangSize);
triangle (0, -5*fangSize, 5*fangSize, -5*fangSize, 3*fangSize, -2*fangSize);
triangle (6*fangSize, -5*fangSize, 15*fangSize, -5*fangSize, 11*fangSize, 8*fangSize);
}
void drawLegs() {
stroke(batColor);
strokeWeight (1);
line (-60*fangSize, -70*fangSize, -55*fangSize, -65*fangSize);
line (-55*fangSize, -70*fangSize, -55*fangSize, -65*fangSize);
line (-50*fangSize, -70*fangSize, -55*fangSize, -65*fangSize);
line (60*fangSize, -70*fangSize, 55*fangSize, -65*fangSize);
line (55*fangSize, -70*fangSize, 55*fangSize, -65*fangSize);
line (50*fangSize, -70*fangSize, 55*fangSize, -65*fangSize);
}
} // close fangs class
class fangsShooter extends fangs {
int shooterSpeed;
fangsShooter(color tempC, float tempx, float tempy) {
super(tempC, tempx, tempy);
shooterSpeed = 10;
}
float checkXloc () {
return batPosX;
}
float checkYloc () {
return batPosY;
}
void moveRight () {
if (batPosX < (width - (origFangXradius*fangSize))) {
batPosX = batPosX + shooterSpeed;
}
}
void moveLeft () {
if (batPosX > (origFangXradius*fangSize)) {
batPosX = batPosX + (shooterSpeed * -1);
}
}
}
class gameTimer {
float gameStart;
boolean gameOver;
float lastPhaseStart;
float batInterval;
float phaseTime;
int phaseCounter;
int totalPhases;
float gameTimeOver;
gameTimer () {
gameStart = millis();
gameOver = true;
lastPhaseStart = gameStart;
batInterval = 2000;
phaseTime = 60000;
phaseCounter = 1;
totalPhases = 4;
gameTimeOver = phaseTime * 4;
}
float setGamePhase() {
if (millis() - lastPhaseStart > phaseTime) {
if (phaseCounter <= 4) {
batInterval = batInterval/2;
phaseCounter++;
} else {
gameOver = true;
}
}
return batInterval;
}
boolean checkGameStatus() {
if (gameOver) {
return true;
} else {
return false;
}
}
}
// Meet Fangs
// Developed in September, 2009
// Developed by Julio Terra
fangs [] myFangs = new fangs [200]; // declaring array of bats
bullet [] myBullets = new bullet [1]; // declaring array of bullets
gameTimer myTimer;
fangsShooter myShooter;
color shooterColor; // color for first
int startx; // x coordinate start position for each bat
int starty; // y coordinate start position for each bat
color backColor = color(175,175,175); // set the background color
int sleepMode; // declare and sleepMode
int batStartYPos; // starting position in Y coordinate for all bats
int batCounter; // counter that holds the number of bats that already exist
int bulletCounter; // counter that holds the number of bullets shot-off so far
float lastBullet; // holds time last bullet was shot
float lastBat; // holds time last bat was created
//***********
// Application SETUP
//***********
void setup() {
// setting the size of the window and smoothness
size (800, 600); // bat movement will adjust to screen size
smooth();
// initiating additional variables
startx = width/2; // initiate x coordinate
starty = height - 40; // initiated y coordinate
shooterColor = #000000;
constrain(sleepMode, 0,2);
batStartYPos = -120;
batCounter = 2;
lastBullet = millis();
lastBat = millis();
myShooter = new fangsShooter(shooterColor,startx,starty); // initiates the first bat, which follows the coordinate
myShooter.sizeSet(35);
myTimer = new gameTimer();
for (int fangCount = 0; fangCount < batCounter; fangCount++) {
color newColor = color(random(5,254), random(5,254), random(5,254)); // set random color for the new bat
myFangs[fangCount] = new fangs(newColor,random(90,width-90),batStartYPos); // initiates the first bat, which follows the coordinate
myFangs[fangCount].sizeSet(random(30, 50));
}
myBullets[0] = new bullet(width*2, height*2);
}
//************************
// DRAW Function
//************************
void draw() {
background (backColor); // setting background color
// loop to draw each bullet from the array of bullets
for (int bulletDrawLoop = 1; bulletDrawLoop < myBullets.length; bulletDrawLoop++) {
myBullets[bulletDrawLoop].moveBullet(); // display the bullet on the screen
myBullets[bulletDrawLoop].displayBullet(); // display the bullet on the screen
} // end loop for drawing bats
// loop to draw each bat from the array of bats
for (int batDrawLoop = 0; batDrawLoop < batCounter; batDrawLoop++) {
if (myFangs[batDrawLoop].batLife() == true) {
// check to see if any bullets have intersect bats
for (int bulletCheck = 0; bulletCheck < myBullets.length; bulletCheck++) {
myFangs[batDrawLoop].killBatCheck(myBullets[bulletCheck].getBulletXpos(),myBullets[bulletCheck].getBulletYpos(),myBullets[bulletCheck].getBulletXposLong(), myBullets[bulletCheck].getBulletYposLong());
if (myFangs[batDrawLoop].batLife() == false) {
myBullets[bulletCheck].bulletDisappear(true);
}
}
myFangs[batDrawLoop].expandMaxFlightRange();
myFangs[batDrawLoop].batWinCheck();
myFangs[batDrawLoop].randomMove(); // move the coordinates of all randomly moving bats using the randomMove function of the bat object
myFangs[batDrawLoop].display(); // draw bat on screen by calling the display function from the fangs object
}
} // end loop for drawing bats
//
if (millis() - lastBat > myTimer.setGamePhase() && batCounter <200) {
color newColor = color(random(5,254), random(5,254), random(5,254)); // set random color for the new bat
myFangs[batCounter] = new fangs(newColor,random(90,width-90),batStartYPos); // initiates the first bat, which follows the coordinate
myFangs[batCounter].sizeSet(random(30, 50));
batCounter++;
lastBat = millis();
}
myShooter.display(); // displays shooter bat
} // end draw function
//************************
// Response to MOUSEPRESS
//************************
void mousePressed() {
if (millis() - lastBullet > 200) {
bullet newBullet = new bullet(myShooter.checkXloc(), myShooter.checkYloc()); // create new fangs variable
myBullets = (bullet[]) append (myBullets, newBullet); // append fangs variable to end of myFangs array
lastBullet = millis();
}
}
//************************
// Response to KEYPRESSED
//************************
// randomly change directions of all bats when a key is pressed
void keyPressed() {
if (key == CODED) {
if (keyCode == LEFT) {
myShooter.moveLeft(); // move shooter bat to the left
}
}
if (keyCode == RIGHT) {
myShooter.moveRight(); // move shooter bat to the right
}
}
Here is the first draft of my attempt to turn my fangs animation into a simple space invaders type game.