Gra 'kółko i krzyżyk’ (tic tac toe) napisana w języku Processing (wersja używa funkcji z Javy do pobierania czasu). Dla 2 graczy, limit czasu 5 sekund, kółka/krzyżyki gracza który powinien się ruszyć zmieniają kolor z zielonego do czerwonego (przez żółty) i 'zanikają’ (zwiększa się przeźroczystość).
Plik gra.pde:
Field[][] fields;
// time to move for players in miliseconds
long timeToMove = 5000;
/* current/winner:
0 = none
1 = player one
2 = player two
*/
int currentPlayer = 0;
int gameWinner = 0;
/* game states:
0 = game not started
1 = game running
2 = game finished
*/
int gameState = 0;
// time of last time counter reset
long timeCounterStart = 0;
long getTime()
{
// Java's function
return System.currentTimeMillis() - timeCounterStart;
}
void resetTime()
{
// Java's function
timeCounterStart = System.currentTimeMillis();
}
// PROCESSING's function called at start of program
void setup()
{
// window size
size(600, 630);
// draw anti-aliased lines/texts/shapes
smooth();
// initialize fields array
fields = new Field[3][3];
for(int i1 = 0; i1 < 3; i1++)
{
for(int i2 = 0; i2 < 3; i2++)
{
// create Fields with their 3 and position (position with 30 px offset from top)
fields[i1][i2] = new Field(width / 3 * i1, 30 + 600 / 3 * i2, width / 3, 600 / 3);
}
}
}
// PROCESSING's function called every 'frame draw'
void draw()
{
// set background color to rgb(0,0,0) [black]
background(0);
// game not started
if(gameState == 0)
{
// set 'fill' [for text/shapes] color to rgb(255,255,255) [white]
fill(255);
// set text size to 20 px
textSize(20);
// draw text
text("Press ANY KEY to Start", width / 2 - width / 4, height / 2);
}
// game is running
else if(gameState == 1)
{
// check time left for move (switch player?)
if(checkTimeForMove()) // true = time elapsed
{
switchPlayer();
}
// set 'fill' [for text/shapes] color to rgb(255,255,255) [white]
fill(255);
textSize(15);
text("Player " + getPlayerName(currentPlayer) + " move", 150, 20);
// draw time left for move
setDrawColorByTimeLeft();
textSize(20);
double timeLeft = ((double)timeToMove - (double)getTime()) / 1000.0;
text("" + timeLeft, 20, 20);
// call draw function for each Field
for(int i1 = 0; i1 < 3; i1++)
{
for(int i2 = 0; i2 < 3; i2++)
{
fields[i1][i2].draw();
}
}
}
// someone won game
else
{
// set 'fill' [for text/shapes] color to rgb(255,255,255) [white]
fill(255);
// set text size to 20 px
textSize(20);
// draw text
if(gameWinner > 0)
{
text("Player " + getPlayerName(gameWinner) + " won game!", width / 2 - width / 4, height / 2);
}
else
{
text("Game draw!", width / 2 - width / 4, height / 2);
}
text("Press ANY KEY", width / 2 - width / 4, (height / 2) + 30);
}
}
//mouse & key functions
void mousePressed()
{
if(gameState == 1)
{
for(int i1 = 0; i1 < 3; i1++)
{
for(int i2 = 0; i2 < 3; i2++)
{
fields[i1][i2].click(mouseX, mouseY);
}
}
}
else
{
keyPressed();
}
}
void keyPressed()
{
if(gameState == 0)
{
gameState = 1;
switchPlayer();
}
else if(gameState == 2)
{
gameState = 0;
}
}
String getPlayerName(int id)
{
if(id == 1)
{
return "ONE";
}
else
{
return "TWO";
}
}
void setDrawColorByTimeLeft()
{
double alpha = (double) (timeToMove-getTime()) / (double) timeToMove;
int g = 255;
int r = 0;
if(alpha > 0.5)
{
r = (int) ((1 - alpha) * 510);
}
else
{
r = 255;
g -= (0.5 - alpha) * 510;
}
int alphaValue = (int) (alpha * 155.0) + 100;
fill(r, g, 0, alphaValue);
stroke(r, g, 0, alphaValue);
}
void switchPlayer()
{
resetTime();
if(currentPlayer == 2)
{
currentPlayer = 1;
}
else
{
currentPlayer = 2;
}
}
boolean checkTimeForMove()
{
return timeToMove < getTime();
}
int getWinner()
{
// lines
for(int i = 0; i < 3; i++)
{
if(fields[i][0].getOwner() != 0 && fields[i][0].getOwner() == fields[i][1].getOwner() && fields[i][1].getOwner() == fields[i][2].getOwner())
{
return fields[i][0].getOwner();
}
if(fields[0][i].getOwner() != 0 && fields[0][i].getOwner() == fields[1][i].getOwner() && fields[1][i].getOwner() == fields[2][i].getOwner())
{
return fields[0][i].getOwner();
}
}
// diagonal 1
if(fields[0][0].getOwner() != 0 && fields[0][0].getOwner() == fields[1][1].getOwner() && fields[1][1].getOwner() == fields[2][2].getOwner())
{
return fields[0][0].getOwner();
}
// diagonal 2
if(fields[0][2].getOwner() != 0 && fields[0][2].getOwner() == fields[1][1].getOwner() && fields[1][1].getOwner() == fields[2][0].getOwner())
{
return fields[0][2].getOwner();
}
return 0;
}
// Field:
//
//
class Field
{
int x;
int y;
int w;
int h;
int fieldOwner = 0;
Field(int posX, int posY, int fieldWidth, int fieldHeight)
{
x = posX;
y = posY;
w = fieldWidth;
h = fieldHeight;
}
void clear()
{
fieldOwner = 0;
}
int getOwner()
{
return fieldOwner;
}
void click(int mx, int my)
{
if(fieldOwner > 0)
{
return;
}
if(mx > x && mx < x+w && my > y && my < y+h)
{
fieldOwner = currentPlayer;
gameWinner = getWinner();
if(gameWinner == 0)
{
for(int i1 = 0; i1 < 3; i1++)
{
for(int i2 = 0; i2 < 3; i2++)
{
if(fields[i1][i2].getOwner() == 0)
{
// not all fields are full
switchPlayer();
return;
}
}
}
}
for(int i1 = 0; i1 < 3; i1++)
{
for(int i2 = 0; i2 < 3; i2++)
{
fields[i1][i2].clear();
}
}
gameState = 2;
}
}
void draw()
{
noFill();
stroke(255);
strokeWeight(3);
rect(x, y, w, h);
stroke(150,0,150, 160);
if(fieldOwner == currentPlayer)
{
strokeWeight(6);
setDrawColorByTimeLeft();
}
noFill();
if(fieldOwner == 1)
{
ellipseMode(CORNER);
ellipse(x, y, w, h);
}
else if(fieldOwner == 2)
{
line(x, y, x+w, y+h);
line(x+w, y, x, y+h);
}
}
}
Oczywiście każdy pisze sam, zero ściągania 🙂