/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://studio.sketchpad.cc/sp/pad/view/ro.ipQA72Wf15u/rev.6551
*
* authors:
* Daniel Foster
* Laurie Brown
*
*
*
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
blocks = new Array();
cols = 10;
rows = 6;
margin = 30;
width = 640;
height = 400;
blockWidth = (width - (margin*2))/cols;
blockHeight = (height - (margin*2))/rows;
blockColorCount = 5; // Make sure you count them.
blockColors =
{
color(0xFFFF4444),
color(0xFF33AA33),
color(0xFF6666FF),
color(0xFFEEEE00),
color(0xFFFF9900),
color(0xFFFFFFFF)
};
poppedBlocks = new Array();
popCount = 0;
cursorColor = 0;
holdTime = 0;
holdLength = 500;
score = 0;
string debugText;
isPressing = false;
isHolding = false;
prevSecond = 0;
currSecond = 0;
gameTime = 0;
gameLength = 150;
timeText = "";
isHighScore = false;
highScore = 0;
Start = 0;
Playing = 1;
End = 2;
gameState = Start;
btnW = 150;
btnH = 80;
btnL = (width*0.5) - (btnW*0.5);
btnR = btnL + btnW;
btnT = (height*0.5) - (btnH*0.5);
btnB = btnT + btnH;
Font uiFont;
void setup()
{ // this is run once.
// set the background color
background(130,0,120);
// canvas size (Variable aren't evaluated. Integers only, please.)
size(640, 400);
// smooth edges
smooth();
// limit the number of frames per second
frameRate(30);
for (i = 0; i < rows*cols; i++)
{
blocks[i] = new Block(i);
}
uiFont = loadFont("calibri");
currSecond = second();
loadHighScore();
update();
noCursor();
}
void update()
{
prevSecond = currSecond;
currSecond = second();
if(prevSecond != currSecond)
gameTime++;
timeText = "" + (int((gameLength - gameTime)/60)) + ":";
if(int((gameLength-gameTime)%60) < 10)
timeText = timeText + "0";
timeText = timeText + int((gameLength - gameTime)%60);
if(mouseX>margin && mouseY>margin && !isHolding && mousePressed && millis() - holdTime > holdLength)
{
isHolding = true;
popTest();
}
if(gameTime >= gameLength)
{
gameState = End;
if(score > highScore)
{
isHighScore = true;
saveStrings("highscore.txt", {score});
}
}
}
void draw()
{
if(gameState == Playing)
{
update();
}
background(180,100,180);
for (i = 0; i!= cols*rows; i++)
{
blocks[i].draw();
}
textFont(uiFont ,30);
fill(0);
text("" + score + " / " + highScore, 30, 25);
if(gameState == Playing)
text(timeText , 555, 25);
if (gameState == Start)
{
fill(180,100,180);
strokeWeight(2);
stroke(0);
rect(btnL,btnT,btnW,btnH, 10);
rect(btnL,btnT + btnH + 5,btnW,25, 10);
fill(0);
textFont(uiFont ,56);
text("START",250,215);
textFont(uiFont , 19);
text("Clear High Score",258,263);
}
else if (gameState == End)
{
fill(180,100,180);
strokeWeight(2);
stroke(0);
rect(btnL,btnT,btnW,btnH, 10);
rect(btnL,btnT + btnH + 5,btnW,25, 10);
fill(0);
textFont(uiFont ,56);
text("END!",260,215);
textFont(uiFont , 22);
text("Try Again",280,264);
if(isHighScore)
{
fill(180,100,180);
rect(btnL-20,btnT-45,btnW+40,40, 10);
fill(0);
textFont(uiFont ,26);
text("New High Score!",235,142);
}
}
textFont(uiFont ,18);
text("By Laurie Brown!",520,395);
fill(cursorColor);
triangle(mouseX, mouseY, mouseX + 20, mouseY + 10, mouseX + 10, mouseY + 20);
}
class Block
{
bool isMarked;
int x, y, iter;
int frontColor, backColor;
bool isForwards;
// Animation
bool isAnimating;
bool isClosing;
int animationOffset;
int animationStart;
int animationLength;
Block(int _iter)
{
iter = _iter;
x = int(iter%cols);
y = int(iter/cols);
isMarked = false;
isForwards = true;
isAnimating = false;
animationLength = 200;
newColors();
}
void newColors()
{
frontColor = int(random(blockColorCount));
backColor = int(random(blockColorCount));
while(backColor == frontColor)
backColor = int(random(blockColorCount));
}
int getColor()
{
if(isForwards)
return frontColor;
else
return backColor;
}
void flip()
{
if(!isAnimating)
{
isClosing = true;
isAnimating = true;
animationStart = millis();
}
}
void draw()
{
strokeWeight(2);
stroke(0);
if(isAnimating)
{
int timePassed = millis() - animationStart;
if(isClosing && timePassed >= animationLength * 0.5)
{
isClosing = false;
isForwards= !isForwards;
}
if(timePassed >= animationLength)
{
isAnimating = false;
endFlipAnimation();
fill(blockColors[getColor()]);
rect(margin + (x*blockWidth), margin + (y*blockHeight),blockWidth,blockHeight,10);
return;
}
if(isClosing)
{
offset = blockWidth * ((timePassed / (animationLength * 0.5)));
}
else
{
offset = blockWidth * (1.0 - ((timePassed / (animationLength * 0.5)) - 1.0));
}
fill(blockColors[getColor()]);
rect(margin + (x*blockWidth) + (offset*0.5), margin + (y*blockHeight),blockWidth - offset,blockHeight,10);
}
else
{
fill(blockColors[getColor()]);
rect(margin + (x*blockWidth), margin + (y*blockHeight),blockWidth,blockHeight,10);
}
}
void endFlipAnimation()
{
if(isMarked)
{
if(isForwards)
{
if(gameTime > 120)
{
}
{
backColor = int(random(blockColorCount));
while(backColor == frontColor)
backColor = int(random(blockColorCount));
}
}
else
{
if(gameTime > 120)
{
}
{
frontColor = int(random(blockColorCount));
while(backColor == frontColor)
frontColor = int(random(blockColorCount));
}
}
isMarked = false;
}
}
void pop()
{
flip();
}
}
void mousePressed()
{
isPressing = true;
holdTime = millis();
}
void mouseReleased()
{
isPressing = false;
isHolding = false;
cursorColor = 0;
if(gameState == Playing && mouseX>margin && mouseY>margin && millis() - holdTime < holdLength)
{
x = int((mouseX-margin)/blockWidth);
y = int((mouseY-margin)/blockHeight);
blocks[(y*cols) + x].flip();
}
else if (gameState == Start)
{
if(mouseX < btnR && mouseX > btnL && mouseY < btnB && mouseY > btnT)
{
gameState = Playing;
}
else if(mouseX < btnR && mouseX > btnL && mouseY > btnB + 5 && mouseY < btnB + 30)
{
highScore = 0;
saveStrings("highscore.txt", {0});
}
}
else if (gameState == End)
{
if(mouseX < btnR && mouseX > btnL && mouseY > btnB + 5 && mouseY < btnB + 30)
{
reset();
}
}
}
void popTest()
{
cursorColor = 255;
x = int((mouseX-margin)/blockWidth);
y = int((mouseY-margin)/blockHeight);
popCount = 0;
poppedBlocks = new Array();
canPop(blocks[(y*cols) + x]);
for(i = 0; i < poppedBlocks.length; i++)
{
if(popCount >= 4)
{
score += popCount * popCount * 5;
poppedBlocks[i].pop();
}
else
poppedBlocks[i].isMarked = false;
}
}
bool canPop(Block block)
{
block.isMarked = true;
poppedBlocks[popCount] = block
popCount++;
if(block.x-1 >= 0 && !blocks[block.iter-1].isMarked && block.getColor() == blocks[block.iter-1].getColor())
{
canPop(blocks[block.iter-1]);
}
if(block.x+1 < cols && !blocks[block.iter+1].isMarked && block.getColor() == blocks[block.iter+1].getColor())
{
canPop(blocks[block.iter+1]);
}
if(block.y-1 >= 0 && !blocks[block.iter-cols].isMarked && block.getColor() == blocks[block.iter-cols].getColor())
{
canPop(blocks[block.iter-cols]);
}
if(block.y+1 < rows && !blocks[block.iter+cols].isMarked && block.getColor() == blocks[block.iter+cols].getColor())
{
canPop(blocks[block.iter+cols]);
}
}
void reset()
{
gameState = Start;
prevSecond = 0;
currSecond = 0;
gameTime = 0;
if(isHighScore)
highScore = score;
score = 0;
isHighScore = false;
for (i = 0; i < rows*cols; i++)
{
blocks[i].newColors();
}
}
void loadHighScore()
{
File f = localStorage["highscore.txt"];
if (f != null)
{
list = loadStrings("highscore.txt");
highScore = list[0];
}
}