|
/* |
|
* study20251026_tetris |
|
* written by cleemy desu wayo / Licensed under CC0 1.0 |
|
* 2025-10-26 |
|
* ---- |
|
* this is just a study in Processing |
|
* |
|
* the following preparations are required: |
|
* save cassidy-james-blaede-UBcXr0DcTAY-unsplash.jpg from https://unsplash.com/photos/UBcXr0DcTAY |
|
* |
|
* ---- |
|
* possibly the updated version is here: |
|
* https://gist.github.com/cleemy-desu-wayo |
|
* |
|
* ---- |
|
* how to play |
|
* LEFT key: move left |
|
* RIGHT key: move right |
|
* UP key: ratate |
|
* DOWN key: move down |
|
* |
|
*/ |
|
|
|
PGraphics pg; |
|
|
|
int drawCnt = 0; |
|
int lastRedraw = -1; |
|
|
|
int leftMargin = 362; |
|
int topMargin = 115; |
|
int blockSize = 20; |
|
int blockMargin = 3; |
|
|
|
int minoRotate; |
|
int minoX; // X position |
|
int minoY; // Y position |
|
int stepInterval = 12; |
|
int lastMinoRotate = -1; |
|
int lastMinoX = -1; |
|
int lastMinoY = -1; |
|
|
|
int matrixSizeX = 14; |
|
int matrixSizeY = 22; |
|
int[][] blockMatrix = new int[matrixSizeX][matrixSizeY]; |
|
|
|
int mino; |
|
int nextMino; |
|
int[][][][] minoBlock = { |
|
// 0: T |
|
{{{0, 0}, {-1, 0}, {0, -1}, {1, 0}}, |
|
{{0, 0}, {0, -1}, {1, 0}, {0, 1}}, |
|
{{0, 0}, {-1, 0}, {0, 1}, {1, 0}}, |
|
{{0, 0}, {-1, 0}, {0, -1}, {0, 1}}}, |
|
// 1: I |
|
{{{0, 0}, {-1, 0}, {1, 0}, {2, 0}}, |
|
{{0, 0}, {0, -1}, {0, 1}, {0, 2}}, |
|
/*{{0, 0}, {-2, 0}, {-1, 0}, {1, 0}}, |
|
{{0, 0}, {0, 1}, {0, -1}, {0, -2}}},*/ |
|
{{0, 0}, {-1, 0}, {1, 0}, {2, 0}}, |
|
{{0, 0}, {0, -1}, {0, 1}, {0, 2}}}, |
|
// 2: O |
|
{{{0, 0}, {1, 0}, {0, -1}, {1, -1}}, |
|
{{0, 0}, {1, 0}, {0, -1}, {1, -1}}, |
|
{{0, 0}, {1, 0}, {0, -1}, {1, -1}}, |
|
{{0, 0}, {1, 0}, {0, -1}, {1, -1}}}, |
|
// 3: S |
|
{{{0, 0}, {-1, 0}, {0, -1}, {1, -1}}, |
|
{{0, 0}, {0, -1}, {1, 0}, {1, 1}}, |
|
{{0, 0}, {-1, 0}, {0, -1}, {1, -1}}, |
|
{{0, 0}, {0, -1}, {1, 0}, {1, 1}}}, |
|
// 4: Z |
|
{{{0, 0}, {-1, -1}, {0, -1}, {1, 0}}, |
|
{{0, 0}, {1, -1}, {1, 0}, {0, 1}}, |
|
{{0, 0}, {-1, -1}, {0, -1}, {1, 0}}, |
|
{{0, 0}, {1, -1}, {1, 0}, {0, 1}}}, |
|
// 5: J |
|
{{{0, 0}, {-1, -1}, {-1, 0}, {1, 0}}, |
|
{{0, 0}, {1, -1}, {0, -1}, {0, 1}}, |
|
{{0, 0}, {-1, 0}, {1, 0}, {1, 1}}, |
|
{{0, 0}, {0, -1}, {0, 1}, {-1, 1}}}, |
|
// 6: L |
|
{{{0, 0}, {-1, 0}, {1, 0}, {1, -1}}, |
|
{{0, 0}, {0, -1}, {0, 1}, {1, 1}}, |
|
{{0, 0}, {-1, 1}, {-1, 0}, {1, 0}}, |
|
{{0, 0}, {-1, -1}, {0, -1}, {0, 1}}} |
|
}; |
|
|
|
void setup() { |
|
size(1280, 720); |
|
PImage bg = loadImage("cassidy-james-blaede-UBcXr0DcTAY-unsplash.jpg"); |
|
pg = createGraphics(1280, 720); |
|
pg.beginDraw(); |
|
pg.image(bg, 0, 0, 1280, 720); |
|
pg.endDraw(); |
|
|
|
noStroke(); |
|
noSmooth(); |
|
frameRate(60); |
|
|
|
//randomSeed(0); |
|
mino = int(random(7)); |
|
nextMino = int(random(7)); |
|
minoX = 6; |
|
minoY = 1; |
|
minoRotate = 0; |
|
|
|
resetBlock(); |
|
} |
|
|
|
void draw() { |
|
drawCnt++; |
|
|
|
if (drawCnt >= lastRedraw + stepInterval) { |
|
clearCurrentMino(); |
|
|
|
if (checkBlock(mino, minoX, minoY + 1, minoRotate) == 1) { |
|
minoY++; |
|
putCurrentMino(); |
|
} else { |
|
putCurrentMino(); |
|
|
|
// check aligned lines |
|
checkAlignedLines(); |
|
|
|
// next mino |
|
mino = nextMino; |
|
nextMino = int(random(7)); |
|
minoX = 6; |
|
minoY = 1; |
|
minoRotate = 0; |
|
if (checkBlock(mino, minoX, minoY, minoRotate) == 0) { |
|
resetBlock(); |
|
putCurrentMino(); |
|
} |
|
} |
|
} |
|
|
|
if (lastMinoRotate != minoRotate || lastMinoX != minoX || lastMinoY != minoY) { |
|
// draw bg |
|
image(pg, 0, 0); |
|
|
|
// draw all blocks of main area |
|
fill(0, 0, 0, 127); |
|
rect(320, 70, 400, 600); |
|
fill(255, 255, 255, 255); |
|
for (int i = 0; i < matrixSizeX; i++) { |
|
for (int j = 0; j < matrixSizeY; j++) { |
|
if (blockMatrix[i][j] == 1) { |
|
square(leftMargin + (blockSize + blockMargin) * i, |
|
topMargin + (blockSize + blockMargin) * j, |
|
blockSize); |
|
} |
|
} |
|
} |
|
|
|
// draw next mino |
|
int nextMinoMarginX; |
|
fill(0, 0, 0, 127); |
|
rect(805, 90, 160, 160); |
|
fill(255, 255, 255, 255); |
|
for (int i = 0; i < 4; i++) { |
|
if (nextMino == 1) { |
|
nextMinoMarginX = 875 - 10; |
|
} else if (nextMino == 2) { |
|
nextMinoMarginX = 875 - 12; |
|
} else { |
|
nextMinoMarginX = 875; |
|
} |
|
square(nextMinoMarginX + (blockSize + blockMargin) * minoBlock[nextMino][0][i][0], |
|
168 + (blockSize + blockMargin) * minoBlock[nextMino][0][i][1], |
|
blockSize); |
|
|
|
} |
|
|
|
lastMinoRotate = minoRotate; |
|
lastMinoY = minoY; |
|
lastMinoX = minoX; |
|
lastRedraw = drawCnt; |
|
} |
|
} |
|
|
|
void resetBlock() { |
|
for (int i = 0; i < matrixSizeX; i++) { |
|
for (int j = 0; j < matrixSizeY; j++) { |
|
if (j == matrixSizeY - 1) { |
|
if (i >= 1 && i < matrixSizeX - 1) { |
|
blockMatrix[i][j] = 1; |
|
} else { |
|
blockMatrix[i][j] = 0; |
|
} |
|
} else { |
|
if (i == 1 || i == matrixSizeX - 2) { |
|
blockMatrix[i][j] = 1; |
|
} else { |
|
blockMatrix[i][j] = 0; |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
void clearCurrentMino() { |
|
int x; |
|
int y; |
|
for (int i = 0; i < 4; i++) { |
|
x = minoX + minoBlock[mino][minoRotate][i][0]; |
|
y = minoY + minoBlock[mino][minoRotate][i][1]; |
|
blockMatrix[x][y] = 0; |
|
} |
|
} |
|
|
|
void putCurrentMino() { |
|
//println("_mino:" + mino); |
|
int x; |
|
int y; |
|
for (int i = 0; i < 4; i++) { |
|
x = minoX + minoBlock[mino][minoRotate][i][0]; |
|
y = minoY + minoBlock[mino][minoRotate][i][1]; |
|
blockMatrix[x][y] = 1; |
|
} |
|
} |
|
|
|
int checkBlock(int mino, int pos, int step, int rotate) { |
|
int result = 1; // ok |
|
int x; |
|
int y; |
|
|
|
for (int i = 0; i < 4; i++) { |
|
x = pos + minoBlock[mino][rotate][i][0]; |
|
y = step + minoBlock[mino][rotate][i][1]; |
|
if (blockMatrix[x][y] == 1) { |
|
result = 0; |
|
} |
|
} |
|
return result; |
|
} |
|
|
|
void checkAlignedLines() { |
|
Boolean isAlignedLine; |
|
for (int i = 0; i < matrixSizeY - 1; i++) { |
|
isAlignedLine = true; |
|
for (int j = 2; j <= matrixSizeX - 2; j++) { |
|
if (blockMatrix[j][i] == 0) { |
|
isAlignedLine = false; |
|
} |
|
} |
|
|
|
if (isAlignedLine) { |
|
println("align y:" + i); |
|
deleteLine(i); |
|
} |
|
} |
|
} |
|
|
|
void deleteLine(int line) { |
|
for (int i = line; i >= 1; i--) { |
|
for (int j = 2; j <= matrixSizeX - 2; j++) { |
|
blockMatrix[j][i] = blockMatrix[j][i - 1]; |
|
} |
|
} |
|
} |
|
|
|
void keyPressed() { |
|
if (keyCode == LEFT) { |
|
clearCurrentMino(); |
|
if (checkBlock(mino, minoX - 1, minoY, minoRotate) == 1) { |
|
minoX--; |
|
} |
|
putCurrentMino(); |
|
} else if (keyCode == RIGHT) { |
|
clearCurrentMino(); |
|
if (checkBlock(mino, minoX + 1, minoY, minoRotate) == 1) { |
|
minoX++; |
|
} |
|
putCurrentMino(); |
|
} else if (keyCode == DOWN) { |
|
clearCurrentMino(); |
|
if (checkBlock(mino, minoX, minoY + 1, minoRotate) == 1) { |
|
minoY++; |
|
} |
|
putCurrentMino(); |
|
} else if (keyCode == UP) { |
|
clearCurrentMino(); |
|
int rotateCandidate = minoRotate + 1; |
|
int minoXCandidate = minoX; |
|
if (rotateCandidate > 3) { rotateCandidate = 0; } |
|
|
|
if (mino == 1 && minoX == 10) { |
|
minoXCandidate = minoX - 1; |
|
} |
|
|
|
if (checkBlock(mino, minoXCandidate, minoY, rotateCandidate) == 1) { |
|
minoRotate = rotateCandidate; |
|
minoX = minoXCandidate; |
|
} |
|
putCurrentMino(); |
|
} |
|
} |