Add Processing Sketchs

Add Processing Sketchs and Processing tutorial
This commit is contained in:
Suhaylzhao
2016-09-09 23:25:32 +08:00
parent f9ac09f78a
commit e257cf299b
80 changed files with 5383 additions and 0 deletions
@@ -0,0 +1,136 @@
/******************************************************************************* //<>//
* Sketch App_01_1_1_Oscilloscope
* Author Freenove (http://www.freenove.com)
* Date 2016/08/26
******************************************************************************
* Brief
* This sketch is used to make an oscilloscope
*************************************p*****************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
******************************************************************************
*/
import processing.io.*;
PCF8591 pcf = new PCF8591(0x48);
int[] analogs; // Analog data send from serial device
int analogsCount; // Length of analogs[] array
int voltage = 0; // Voltage
int hMult = 1; // Horizontal zoom ratio, relative to 1 second
boolean pause = false; // Storage is suspended display
void setup()
{
size(530, 290);
background(102);
textAlign(CENTER, CENTER);
textSize(64);
text("Starting...", width / 2, (height - 40) / 2);
textSize(16);
text("www.freenove.com", width / 2, height - 20);
textAlign(LEFT, CENTER);
analogsCount = width / 2;
analogs = new int[analogsCount];
for (int i = 0; i < analogsCount; i++)
analogs[i] = -1;
}
void draw()
{
int analog = pcf.analogRead(0); //serialDevice.requestAnalog();
if (analog != -1)
{
// GUI
background(102);
textSize(12);
text("↑: Zoom up", 120, 6);
text("↓: Zoom down", 120, 20);
text("Enter: Visit Freenove website", 220, 6);
text("Space: Pause", 220, 20);
textSize(16);
// Voltage scale text
for (int i = 5; i >= 0; i--)
{
text(i, 5, 280 - i * 50 - 2);
if (i == 5)
text("V", 15, 280 - i * 50 - 2);
}
// Horizontal line
stroke(64, 64, 64);
for (int i = 0; i < 6; i++)
line(30, 30 + i * 50, width, 30 + i * 50);
// Vertical line time text
text(1000 / hMult + "ms", 40, 15 - 2);
// Vertical line
for (int i = 0; i < (width - 30) / 50 + 1; i++)
line(30 + i * 50, 30, 30 + i * 50, height - 10);
if (!pause)
{
// Prepare wave data
for (int i = 0; i < analogsCount - 1; i++)
analogs[i] = analogs[i + 1];
analogs[analogsCount - 1] = height - 10 - analog * (height - 10 - 30) / 255;
// Voltage text
voltage = analog * 500 / 255;
}
String sVoltage = voltage / 100 + "." + voltage / 10 % 10 + voltage % 10;
text(sVoltage + "V", width - 48, 15 - 2);
// Wave line
stroke(0, 255, 0);
for (int i = width; i > 30; i -= hMult * width / analogsCount)
{
int a = i / hMult + width * (hMult - 1) / hMult;
a = a * analogsCount / width - 1;
if (analogs[a] >= 0 && analogs[a - 1] >= 0)
line(i, analogs[a], i - hMult * width / analogsCount, analogs[a - 1]);
}
}
}
void keyPressed()
{
if (key == CODED)
{
if (keyCode == UP)
{
if (hMult == 1)
hMult = 2;
else if (hMult == 2)
hMult = 5;
else if (hMult == 5)
hMult = 10;
}
else if (keyCode == DOWN)
{
if (hMult == 10)
hMult = 5;
else if (hMult == 5)
hMult = 2;
else if (hMult == 2)
hMult = 1;
}
}
else
{
if (key == ' ')
{
pause = !pause;
if (!pause)
{
for (int i = 0; i < analogsCount; i++)
analogs[i] = -1;
}
}
else if (key == '\n' || key == '\r')
{
link("http://www.freenove.com");
}
}
}
@@ -0,0 +1,47 @@
/*****************************************************
* Filename : PCF8591
* Description : class PCF8591,DAC and ADC
* auther : www.freenove.com
* modification: 2016/08/20
*****************************************************/
class PCF8591 {
private int address;
private I2C i2c;
//constructor,Parameters for the PCF8591 I2C address
public PCF8591(int addr) {
address = addr;
i2c = new I2C(I2C.list()[0]);
}
//Read the ADC value of one channel
public int analogRead(int chn) {
int result = 0;
i2c.beginTransmission(address);
constrain(chn, 0, 3);
i2c.write(0x40 | chn);
try {
byte[] in = i2c.read(1);
result = in[0]&0xff;
}
catch(Exception e) {
println(e);
}
i2c.endTransmission();
return result;
}
//Read the ADC value of all channels
public byte[] analogRead() {
i2c.beginTransmission(address);
i2c.write(0x44);
i2c.endTransmission();
byte[] in = i2c.read(4);
return in;
}
//Write the DACvalue
public void analogWrite(int data) {
i2c.beginTransmission(address);
i2c.write(0x40);
i2c.write(data);
i2c.endTransmission();
}
}
@@ -0,0 +1,64 @@
/******************************************************************************* //<>//
* Sketch App_02_1_1_Ellipse
* Author Freenove (http://www.freenove.com)
* Date 2016/08/26
******************************************************************************
* Brief
* This sketch is used to control a 2D ellipse
******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
******************************************************************************
*/
import processing.io.*;
PCF8591 pcf = new PCF8591(0x48);
void setup()
{
size(360, 360);
background(102);
textAlign(CENTER, CENTER);
textSize(64);
text("Starting...", width / 2, (height - 40) / 2);
textSize(16);
text("www.freenove.com", width / 2, height - 20);
}
void draw()
{
int[] analogs = new int[2];
analogs[0] = pcf.analogRead(0);
analogs[1] = pcf.analogRead(1);
if (analogs != null)
{
background(102);
drawEllipse(analogs[0], analogs[1]);
}
}
void drawEllipse(int x, int y)
{
int maxDiameter = 280;
fill(255, 255, 255);
textAlign(CENTER, CENTER);
textSize(16);
text("Press Enter to visit www.freenove.com", width / 2, height - 20);
text("X: " + x, width / 2 - 30, 20);
text("Y: " + y, width / 2 + 30, 20);
x = x * maxDiameter / 255;
y = y * maxDiameter / 255;
fill(227, 118, 12);
ellipse(width / 2, height / 2, x, y);
}
void keyPressed()
{
if (key == '\n' || key == '\r')
{
link("http://www.freenove.com");
}
}
@@ -0,0 +1,47 @@
/*****************************************************
* Filename : PCF8591
* Description : class PCF8591,DAC and ADC
* auther : www.freenove.com
* modification: 2016/08/20
*****************************************************/
class PCF8591 {
private int address;
private I2C i2c;
//constructor,Parameters for the PCF8591 I2C address
public PCF8591(int addr) {
address = addr;
i2c = new I2C(I2C.list()[0]);
}
//Read the ADC value of one channel
public int analogRead(int chn) {
int result = 0;
i2c.beginTransmission(address);
constrain(chn, 0, 3);
i2c.write(0x40 | chn);
try {
byte[] in = i2c.read(1);
result = in[0]&0xff;
}
catch(Exception e) {
println(e);
}
i2c.endTransmission();
return result;
}
//Read the ADC value of all channels
public byte[] analogRead() {
i2c.beginTransmission(address);
i2c.write(0x44);
i2c.endTransmission();
byte[] in = i2c.read(4);
return in;
}
//Write the DACvalue
public void analogWrite(int data) {
i2c.beginTransmission(address);
i2c.write(0x40);
i2c.write(data);
i2c.endTransmission();
}
}
@@ -0,0 +1,172 @@
/*
******************************************************************************
* Sketch App_03_1_1_Pong_Game
* Author Freenove (http://www.freenove.com)
* Date 2016/08/26
******************************************************************************
* Brief
* This sketch is used to play pong game
******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
******************************************************************************
*/
import processing.io.*;
PCF8591 pcf = new PCF8591(0x48);
int winScore = 3;
float acceleration = 0.5;
float deviate = 1;
/* Private variables ---------------------------------------------------------*/
Ball ball;
Paddle lPaddle, rPaddle;
int gameState = GameState.WELCOME;
int lScore, rScore;
void setup() {
size(640, 360);
background(102);
textAlign(CENTER, CENTER);
textSize(64);
text("Starting...", width / 2, (height - 40) / 2);
textSize(16);
text("www.freenove.com", width / 2, height - 20);
ball = new Ball(10);
lPaddle = new Paddle(new Size(12, 80), 12);
rPaddle = new Paddle(new Size(12, 80), width - 12);
}
void draw() {
int[] analogs = new int[2];
analogs[0] = pcf.analogRead(0);
analogs[1] = pcf.analogRead(1);
if (analogs != null)
{
lPaddle.position.y = analogs[0] * height /255;
rPaddle.position.y = analogs[1] * height /255;
}
background(102);
if (gameState == GameState.WELCOME)
{
showGUI();
lPaddle.display();
rPaddle.display();
showInfo("Pong Game");
}
else if (gameState == GameState.PLAYING)
{
ball.updata();
calculateGame();
showGUI();
ball.display();
lPaddle.display();
rPaddle.display();
}
else if (gameState == GameState.PLAYER1WIN)
{
showGUI();
lPaddle.display();
rPaddle.display();
showInfo("Player 1 win!");
}
else if (gameState == GameState.PLAYER2WIN)
{
showGUI();
lPaddle.display();
rPaddle.display();
showInfo("Player 2 win!");
}
}
void showInfo(String info)
{
rectMode(CENTER);
stroke(0, 0, 0);
fill(0, 0, 0, 50);
rect(width / 2, height / 2, width / 2, height / 3);
fill(255, 255, 255);
textSize(24);
textAlign(CENTER, CENTER);
text(info, width / 2, height / 2 - 24);
text("Press Space to start", width / 2, height / 2 + 24);
}
void calculateGame()
{
if (ball.position.x - ball.radius < lPaddle.position.x + lPaddle.size.width / 2)
{
if (ball.position.y < lPaddle.position.y - lPaddle.size.height / 2 - ball.radius||
ball.position.y > lPaddle.position.y + lPaddle.size.height / 2 + ball.radius)
{
rScore++;
ball.reset();
}
else
{
ball.speed.getSpeed();
ball.speed.speed += acceleration;
ball.speed.getXYSpeed((ball.position.y - lPaddle.position.y) / (lPaddle.size.height / 2) * deviate);
}
}
if (ball.position.x + ball.radius > rPaddle.position.x - rPaddle.size.width / 2)
{
if (ball.position.y < rPaddle.position.y - rPaddle.size.height / 2 - ball.radius||
ball.position.y > rPaddle.position.y + rPaddle.size.height / 2 + ball.radius)
{
lScore++;
ball.reset();
}
else
{
ball.speed.getSpeed();
ball.speed.speed += acceleration;
ball.speed.getXYSpeed((ball.position.y - rPaddle.position.y) / (rPaddle.size.height / 2) * deviate);
ball.speed.x = - ball.speed.x;
}
}
if (lScore == winScore)
gameState = GameState.PLAYER1WIN;
if (rScore == winScore)
gameState = GameState.PLAYER2WIN;
}
void showGUI()
{
fill(255, 255, 255);
textSize(16);
textAlign(CENTER, CENTER);
text("Press Enter to visit www.freenove.com", width / 4, height - 20);
text("Press Space to restart game", width * 3 / 4, height - 20);
text("Player 1: " + lScore, width / 4, 20);
text("Player 2: " + rScore, width * 3 / 4, 20);
rectMode(CENTER);
noStroke();
fill(144, 144, 144);
rect(width / 2, height / 2, 4, height);
}
void keyPressed() {
if (key == '\n' || key == '\r')
{
link("http://www.freenove.com");
}
else if (key == ' ')
{
lScore = 0;
rScore = 0;
ball.reset();
gameState = GameState.PLAYING;
}
}
@@ -0,0 +1,57 @@
/*
*******************************************************************************
* Class Ball
* Author Ethan Pan @ Freenove (http://www.freenove.com)
* Date 2016/7/22
*******************************************************************************
* Brief
* This class is for pong game.
*******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
*******************************************************************************
*/
/*
* Brief This class is for ball
*****************************************************************************/
class Ball {
Point position = new Point();
Speed speed = new Speed();
int radius;
float initialSpeed = 1;
Ball(int Radius)
{
radius = Radius;
reset();
}
void updata()
{
position.x += speed.x;
position.y += speed.y;
if (position.y < radius || position.y > height - radius)
speed.y = -speed.y;
}
void reset()
{
position.x = width / 2;
position.y = height / 2;
speed.x = (random(-1, 1) > 0 ? 1 : -1) * initialSpeed;
speed.y = 0;
}
void display()
{
ellipseMode(CENTER);
noStroke();
fill(255, 255, 255);
ellipse(position.x, position.y, 2 * radius, 2 * radius);
}
}
@@ -0,0 +1,94 @@
/*
*******************************************************************************
* Class BasicClass
* Author Ethan Pan @ Freenove (http://www.freenove.com)
* Date 2016/8/6
*******************************************************************************
* Brief
* These basic classes are for pong game.
*******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
*******************************************************************************
*/
/*
* Brief This class is used to save a point
*****************************************************************************/
class Point
{
float x = 0;
float y = 0;
Point() {
}
Point(float X, float Y)
{
x = X;
y = Y;
}
}
/*
* Brief This class is used to save a size
*****************************************************************************/
class Size
{
int width = 0;
int height = 0;
Size() {
}
Size(int Width, int Height)
{
width = Width;
height = Height;
}
}
/*
* Brief This class is used to save a 2D speed
*****************************************************************************/
class Speed
{
float x = 0;
float y = 0;
float speed;
void getSpeed()
{
speed = sqrt(sq(x) + sq(y));
}
void getXYSpeed(float degree)
{
x = speed * cos(degree);
y = speed * sin(degree);
}
Speed() {
}
Speed(float X, float Y)
{
x = X;
y = Y;
}
}
/*
* Brief This enum is used to save a gameState
*****************************************************************************/
class GameState
{
final static int WELCOME = 0;
final static int PLAYING = 1;
final static int PLAYER1WIN = 2;
final static int PLAYER2WIN = 3;
}
@@ -0,0 +1,47 @@
/*****************************************************
* Filename : PCF8591
* Description : class PCF8591,DAC and ADC
* auther : www.freenove.com
* modification: 2016/08/20
*****************************************************/
class PCF8591 {
private int address;
private I2C i2c;
//constructor,Parameters for the PCF8591 I2C address
public PCF8591(int addr) {
address = addr;
i2c = new I2C(I2C.list()[0]);
}
//Read the ADC value of one channel
public int analogRead(int chn) {
int result = 0;
i2c.beginTransmission(address);
constrain(chn, 0, 3);
i2c.write(0x40 | chn);
try {
byte[] in = i2c.read(1);
result = in[0]&0xff;
}
catch(Exception e) {
println(e);
}
i2c.endTransmission();
return result;
}
//Read the ADC value of all channels
public byte[] analogRead() {
i2c.beginTransmission(address);
i2c.write(0x44);
i2c.endTransmission();
byte[] in = i2c.read(4);
return in;
}
//Write the DACvalue
public void analogWrite(int data) {
i2c.beginTransmission(address);
i2c.write(0x40);
i2c.write(data);
i2c.endTransmission();
}
}
@@ -0,0 +1,44 @@
/*
*******************************************************************************
* Class Paddle
* Author Ethan Pan @ Freenove (http://www.freenove.com)
* Date 2016/7/22
*******************************************************************************
* Brief
* This class is for pong game.
*******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
*******************************************************************************
*/
/*
* Brief This class is for paddle
*****************************************************************************/
class Paddle {
Point position = new Point();
Size size;
Paddle(Size paddleSize, int xPosition)
{
size = paddleSize;
position.x = xPosition;
position.y = height / 2;
}
void moveTo(int yPosition)
{
position.y = yPosition;
}
void display()
{
rectMode(CENTER);
noStroke();
fill(255, 255, 255);
rect(position.x, position.y, size.width, size.height);
}
}
@@ -0,0 +1,164 @@
/*
******************************************************************************
* Sketch App_04_1_1_Snake_Game
* Author Freenove (http://www.freenove.com)
* Date 2016/08/27
******************************************************************************
* Brief
* This sketch is used to play snake game
******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
******************************************************************************
*/
import processing.io.*;
int threshold = 400;
KeyPad keyUp = new KeyPad(23);
KeyPad keyDown = new KeyPad(17);
KeyPad keyLeft = new KeyPad(22);
KeyPad keyRight = new KeyPad(18);
Snake snake;
Food food;
void setup() {
print("Starting ... \n");
size(640, 360);
background(102);
textAlign(CENTER, CENTER);
textSize(64);
text("Starting...", width / 2, (height - 40) / 2);
textSize(16);
text("www.freenove.com", width / 2, height - 20);
food = new Food(new GridMap(new Size(width, height), 20, 2));
snake = new Snake(new GridMap(new Size(width, height), 20, 2));
thread("keypadDetect");
}
void draw() {
background(102);
if (snake.gameState == GameState.WELCOME)
{
rectMode(CENTER);
stroke(0, 0, 0);
fill(0, 0, 0, 50);
rect(width / 2, height / 2, width / 2, height / 3);
fill(255, 255, 255);
textSize(24);
textAlign(CENTER, CENTER);
text("Snake Game", width / 2, height / 2 - 24);
text("Press Space to start", width / 2, height / 2 + 24);
} else if (snake.gameState == GameState.PLAYING)
{
if (snake.body[0].x == food.position.x && snake.body[0].y == food.position.y)
{
snake.grow();
food.generate(snake.body, snake.length);
snake.speedUp();
}
snake.step();
showGame();
} else if (snake.gameState == GameState.LOSE)
{
showGame();
rectMode(CENTER);
stroke(0, 0, 0);
fill(0, 0, 0, 50);
rect(width / 2, height / 2, width / 2, height / 3);
fill(255, 255, 255);
textSize(24);
textAlign(CENTER, CENTER);
text("You lose!", width / 2, height / 2 - 24);
text("Press Space to start", width / 2, height / 2 + 24);
}
}
void showGame()
{
snake.display();
food.display();
fill(255, 255, 255);
textSize(16);
textAlign(LEFT, CENTER);
text("Press Enter to visit www.freenove.com", 20, height - 20);
textAlign(RIGHT, CENTER);
text("Press Space to restart game", width - 20, height - 20);
textAlign(LEFT, CENTER);
text("Score: " + (snake.length - 3), 20, 20);
textAlign(RIGHT, CENTER);
text("Speed: " + ((snake.initSpeed - snake.speed) / 5 + 1), width - 20, 20);
}
void keyPressed() {
if ((key == CODED) || (keyValue != -1))
{
if ((keyCode == UP) ||((keyValue == keyUp.pin)))
{
if (snake.direction != Direction.DOWN)
snake.nextDirection = Direction.UP;
} else if ((keyCode == DOWN)||((keyValue == keyDown.pin))) {
if (snake.direction != Direction.UP)
snake.nextDirection = Direction.DOWN;
} else if ((keyCode == LEFT)||((keyValue == keyLeft.pin))) {
if (snake.direction != Direction.RIGHT)
snake.nextDirection = Direction.LEFT;
} else if ((keyCode == RIGHT)||((keyValue == keyRight.pin))) {
if (snake.direction != Direction.LEFT)
snake.nextDirection = Direction.RIGHT;
}
//keyValue = -1;
println(keyValue);
} else
{
if (key == '\n' || key == '\r')
{
link("http://www.freenove.com");
} else if (key == ' ')
{
snake.reset();
food.generate(snake.body, snake.length);
snake.gameState = GameState.PLAYING;
}
}
}
void keypadDetect() {
while (true) {
keyUp.keyScan();
keyDown.keyScan();
keyLeft.keyScan();
keyRight.keyScan();
transAction();
try {
Thread.sleep(10);
}
catch(Exception e) {
}
}
}
void transAction() {
if ((keyValue != -1))
{
if (keyValue == keyUp.pin)
{
if (snake.direction != Direction.DOWN)
snake.nextDirection = Direction.UP;
} else if (((keyValue == keyDown.pin))) {
if (snake.direction != Direction.UP)
snake.nextDirection = Direction.DOWN;
} else if (((keyValue == keyLeft.pin))) {
if (snake.direction != Direction.RIGHT)
snake.nextDirection = Direction.LEFT;
} else if (((keyValue == keyRight.pin))) {
if (snake.direction != Direction.LEFT)
snake.nextDirection = Direction.RIGHT;
}
keyValue = -1;
}
}
@@ -0,0 +1,120 @@
/*
*******************************************************************************
* Class BasicClass
* Author Ethan Pan @ Freenove (http://www.freenove.com)
* Date 2016/8/6
*******************************************************************************
* Brief
* These basic classes are for snake game.
*******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
*******************************************************************************
*/
/*
* Brief This class is used to save a point
*****************************************************************************/
class Point
{
int x = 0;
int y = 0;
Point() {
}
Point(int X, int Y)
{
x = X;
y = Y;
}
}
/*
* Brief This class is used to save a size
*****************************************************************************/
class Size
{
int width = 0;
int height = 0;
Size() {
}
Size(int Width, int Height)
{
width = Width;
height = Height;
}
}
/*
* Brief This enum is used to save a direction
*****************************************************************************/
class Direction
{
final static int UP = 0;
final static int DOWN = 1;
final static int LEFT = 2;
final static int RIGHT = 3;
}
/*
* Brief This enum is used to save a gameState
*****************************************************************************/
class GameState
{
final static int WELCOME = 0;
final static int PLAYING = 1;
final static int WIN = 2;
final static int LOSE = 3;
}
/*
* Brief This enum is used to save a grid map
*****************************************************************************/
class GridMap
{
Size mapSize;
Size gripSize;
int gridLength;
int blockGap;
int blockLength;
GridMap() {
}
GridMap(Size MapSize, int GridLength, int BlockGap)
{
mapSize = MapSize;
gridLength = GridLength;
gripSize = new Size(mapSize.width / gridLength, mapSize.height / gridLength);
blockGap = BlockGap;
blockLength = gridLength - blockGap;
}
Point getGripPoint(Point mapPoint)
{
Point point = new Point();
point.x = mapPoint.x / gridLength;
point.y = mapPoint.y / gridLength;
return point;
}
Point getMapPoint(Point gripPoint)
{
Point point = new Point();
point.x = gripPoint.x * gridLength + gridLength / 2;
point.y = gripPoint.y * gridLength + gridLength / 2;
return point;
}
void adjustMapPoint(Point mapPoint)
{
mapPoint.x = mapPoint.x / gridLength * gridLength + gridLength / 2;
mapPoint.y = mapPoint.y / gridLength * gridLength + gridLength / 2;
}
}
@@ -0,0 +1,61 @@
/*
*******************************************************************************
* Class Food
* Author Ethan Pan @ Freenove (http://www.freenove.com)
* Date 2016/7/20
*******************************************************************************
* Brief
* This class is for snake game.
*******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
*******************************************************************************
*/
/*
* Brief This class is for food
*****************************************************************************/
class Food {
Point position;
GridMap map;
Food(GridMap gridMap)
{
map = gridMap;
}
void generate(Point[] exclude, int length)
{
Point point = new Point();
boolean isGenerating = true;
while (isGenerating)
{
point.x = (int)random(0, map.gripSize.width - 1);
point.y = (int)random(0, map.gripSize.height - 1);
isGenerating = false;
if (exclude != null)
{
for (int i = 0; i < length; i++)
{
if (point.x == exclude[i].x && point.y == exclude[i].y)
isGenerating = true;
}
}
}
position = point;
}
void display()
{
rectMode(CENTER);
noStroke();
fill(0, 255, 0);
Point mapPosition = map.getMapPoint(position);
rect(mapPosition.x, mapPosition.y, map.blockLength, map.blockLength);
}
}
@@ -0,0 +1,90 @@
/*
******************************************************************************
* class Keypad
* Author Freenove (http://www.freenove.com)
* Date 2016/08/27
******************************************************************************
* Brief
* This class is used to get a single button key value (GPIO numbering)
******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
******************************************************************************
*/
int keyValue = -1;
class KeyPad
{
final int IDLE = 0,
PRESSED = 1,
HOLD = 2,
RELEASED = 3;
int btnState = IDLE;
long holdTimer = 0;
final int holdTime = 500;
boolean changeState = false;
int lastButtonIOState = GPIO.HIGH;
int buttonIOState=GPIO.HIGH;
int nowButtonState;
boolean buttonChanged = false;
int lastChangeTime;
int decounceTime = 50;
int pin;
public KeyPad(int Pin) {
pin = Pin;
GPIO.pinMode(pin, GPIO.INPUT);
}
void keyScan() {
nowButtonState =GPIO.digitalRead(pin);
if (nowButtonState != lastButtonIOState) {
lastChangeTime = millis();
}
if (millis() - lastChangeTime > decounceTime) {
if (buttonIOState != nowButtonState) {
buttonIOState = nowButtonState;
changeState = true;
if (buttonIOState == GPIO.LOW) {
//btnState = PRESSED;
//keyValue = pin;
//println("Key is Pressed !! ");
} else if (buttonIOState == GPIO.HIGH) {
//println("Key is Released !! ");
}
}
}
switch(btnState) {
case IDLE:
if (changeState) {
changeState = false;
btnState = PRESSED;
holdTimer = millis();
keyValue = pin;
}
break;
case PRESSED:
if (millis() - holdTimer > holdTime) {
btnState = HOLD;
keyValue = pin;
}else if(changeState){
changeState = false;
btnState = RELEASED;
}
break;
case HOLD:
keyValue = pin;
if (changeState) {
changeState = false;
btnState = RELEASED;
}
break;
case RELEASED:
keyValue = -1;
btnState = IDLE;
break;
}
lastButtonIOState = nowButtonState;
}
}
@@ -0,0 +1,115 @@
/*
*******************************************************************************
* Class Snake
* Author Ethan Pan @ Freenove (http://www.freenove.com)
* Date 2016/8/6
*******************************************************************************
* Brief
* This class is for snake game.
*******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
*******************************************************************************
*/
/*
* Brief This class is for snake
*****************************************************************************/
class Snake {
GridMap map;
int length;
final int initSpeed = 150;
int speed;
int stepCounter;
int direction;
int nextDirection;
Point[] body;
int gameState = GameState.WELCOME;
Snake(GridMap gridMap)
{
map = gridMap;
body = new Point[map.gripSize.height * map.gripSize.width];
reset();
}
void reset()
{
length = 3;
speed = initSpeed ;
direction = Direction.UP;
nextDirection = Direction.UP;
body[0] = new Point(map.gripSize.width / 2, map.gripSize.height / 2);
body[1] = new Point(body[0].x, body[0].y + 1);
body[2] = new Point(body[0].x, body[0].y + 2);
}
void display()
{
rectMode(CENTER);
noStroke();
fill(227, 118, 12);
for (int i = 0; i < length; i++)
{
Point mapPosition = map.getMapPoint(body[i]);
rect(mapPosition.x, mapPosition.y, map.blockLength, map.blockLength);
}
}
void speedUp()
{
if (speed > 0)
speed--;
}
void grow()
{
length++;
}
void step()
{
if (stepCounter++ % (speed / 5) != 0)
return;
for (int i = length; i > 0; i--)
body[i] = body[i - 1];
direction = nextDirection;
if (direction == Direction.UP)
{
body[0] = new Point(body[1].x, body[1].y - 1);
if (body[0].y < 0)
gameState = GameState.LOSE;
}
else if (direction == Direction.DOWN)
{
body[0] = new Point(body[1].x, body[1].y + 1);
if (body[0].y > map.gripSize.height - 1)
gameState = GameState.LOSE;
}
else if (direction == Direction.LEFT)
{
body[0] = new Point(body[1].x - 1, body[1].y);
if (body[0].x < 0)
gameState = GameState.LOSE;
}
else if (direction == Direction.RIGHT)
{
body[0] = new Point(body[1].x + 1, body[1].y);
if (body[0].x > map.gripSize.width - 1)
gameState = GameState.LOSE;
}
for (int i = 1; i < length; i++)
{
if (body[0].x == body[i].x && body[0].y == body[i].y)
gameState = GameState.LOSE;
}
}
}
@@ -0,0 +1,156 @@
/*
******************************************************************************
* Sketch App_05_1_1_Tetris
* Author Freenove (http://www.freenove.com)
* Date 2016/08/27
******************************************************************************
* Brief
* This sketch is used to play Tetris game
******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
******************************************************************************
*/
import processing.io.*;
static final int w = 10; // 4
static final int h = 25; // 60
static final int framesInSecond = 30;
static float gameInitSpeed = 10;
static float gameSpeed = 10;
static final int BlockScale = 15;
static final int sizeWidth = w*BlockScale+100;
static final int sizeHeight = h*BlockScale;
KeyPad keyUp = new KeyPad(23);
KeyPad keyDown = new KeyPad(17);
KeyPad keyLeft = new KeyPad(22);
KeyPad keyRight = new KeyPad(18);
boolean isPaused = false;
boolean keyAllow = true;
float updatingThreshold = 0;
Game game;
float recalculateUpdatingThreshold(float threshold) {
return threshold + 1;
}
void settings() {
size(sizeWidth, sizeHeight);
}
void setup() {
game = new Game(w, h);
generateRandomBlock(game);
frameRate(framesInSecond);
thread("keypadDetect");
}
void draw() {
background(102);
Game newGame = game;
updatingThreshold = recalculateUpdatingThreshold(updatingThreshold);
if (updatingThreshold > gameSpeed) {
if (isGameOver(newGame)) {
} else if (isPaused) {
} else {
newGame = updateGameState(game);
}
updatingThreshold = 0;
}
drawGameState(newGame);
if (!isGameOver(newGame)&& (isPaused)) { //pause
textSize(40);
fill(0);
text("Pause", BlockScale*2, 150);
keyAllow = false;
} else if (isGameOver(newGame)&& (isPaused)) { //restart game
game = new Game(w, h);
generateRandomBlock(game);
isPaused = false;
keyAllow = false;
} else if (isGameOver(newGame)) { //game over
textSize(40);
fill(0);
text("Game \nOver", BlockScale*2, 150);
keyAllow = false;
} else { //playing
keyAllow = true;
}
//level,score information
pushMatrix();
translate(w*BlockScale, 0);
fill(255);
textSize(20);
text("Level\n"+game.level, 10, BlockScale*7);
text("Scores\n"+game.score, 10, BlockScale*11);
textSize(12);
text("Freenove.com", 10, sizeHeight-30);
drawNextBlock(game.nextBlock, BlockScale*2, BlockScale*1);
popMatrix();
}
void keyPressed() {
if (key == CODED) {
if (keyAllow) {
switch (keyCode) {
case LEFT:
moveBlock(game, MoveLeft);
break;
case RIGHT:
moveBlock(game, MoveRight);
break;
case DOWN:
makeBlockFall(game);
break;
case UP:
rotateBlock(game);
break;
}
}
} else if (key == ' ') { // SPACE
isPaused =! isPaused;
}
}
void keypadDetect() {
while (true) {
keyUp.keyScan();
keyDown.keyScan();
keyLeft.keyScan();
keyRight.keyScan();
transAction();
try {
Thread.sleep(10);
}
catch(Exception e) {
}
}
}
void transAction() {
if ((keyValue != -1))
{
if (keyAllow) {
if (keyValue == keyLeft.pin) {
moveBlock(game, MoveLeft);
} else if (keyValue == keyRight.pin) {
moveBlock(game, MoveRight);
} else if (keyValue == keyDown.pin) {
makeBlockFall(game);
} else if (keyValue == keyUp.pin) {
rotateBlock(game);
}
}
try {
Thread.sleep(50);
}
catch(Exception e) {
}
keyValue = -1;
}
}
@@ -0,0 +1,90 @@
/*
******************************************************************************
* class Keypad
* Author Freenove (http://www.freenove.com)
* Date 2016/08/27
******************************************************************************
* Brief
* This class is used to get a single button key value (GPIO numbering)
******************************************************************************
* Copyright
* Copyright © Freenove (http://www.freenove.com)
* License
* Creative Commons Attribution ShareAlike 3.0
* (http://creativecommons.org/licenses/by-sa/3.0/legalcode)
******************************************************************************
*/
int keyValue = -1;
class KeyPad
{
final int IDLE = 0,
PRESSED = 1,
HOLD = 2,
RELEASED = 3;
int btnState = IDLE;
long holdTimer = 0;
final int holdTime = 500;
boolean changeState = false;
int lastButtonIOState = GPIO.HIGH;
int buttonIOState=GPIO.HIGH;
int nowButtonState;
boolean buttonChanged = false;
int lastChangeTime;
int decounceTime = 50;
int pin;
public KeyPad(int Pin) {
pin = Pin;
GPIO.pinMode(pin, GPIO.INPUT);
}
void keyScan() {
nowButtonState =GPIO.digitalRead(pin);
if (nowButtonState != lastButtonIOState) {
lastChangeTime = millis();
}
if (millis() - lastChangeTime > decounceTime) {
if (buttonIOState != nowButtonState) {
buttonIOState = nowButtonState;
changeState = true;
if (buttonIOState == GPIO.LOW) {
//btnState = PRESSED;
//keyValue = pin;
//println("Key is Pressed !! ");
} else if (buttonIOState == GPIO.HIGH) {
//println("Key is Released !! ");
}
}
}
switch(btnState) {
case IDLE:
if (changeState) {
changeState = false;
btnState = PRESSED;
holdTimer = millis();
keyValue = pin;
}
break;
case PRESSED:
if (millis() - holdTimer > holdTime) {
btnState = HOLD;
keyValue = pin;
}else if(changeState){
changeState = false;
btnState = RELEASED;
}
break;
case HOLD:
keyValue = pin;
if (changeState) {
changeState = false;
btnState = RELEASED;
}
break;
case RELEASED:
keyValue = -1;
btnState = IDLE;
break;
}
lastButtonIOState = nowButtonState;
}
}
@@ -0,0 +1,42 @@
// Classic Tetris only blocks
static final int BlockPartsCount = 4;
static final int BlocksCount = 7;
static final int DirectionsCount = 4;
static final int I = 0;
static final int O = 1;
static final int T = 2;
static final int S = 3;
static final int Z = 4;
static final int J = 5;
static final int L = 6;
static final int North = 0;
static final int East = 1;
static final int South = 2;
static final int West = 3;
class BlockPart {
int xPos;
int yPos;
BlockPart(int blockXPos, int blockYPos) {
xPos = blockXPos;
yPos = blockYPos;
}
};
class Block {
int type;
int xPos;
int yPos;
int direction;
BlockPart[] parts;
Block (int blockType, int blockXPos, int blockYPos, int blockDirection) {
type = blockType;
xPos = blockXPos;
yPos = blockYPos;
direction = blockDirection;
}
};
@@ -0,0 +1,159 @@
BlockPart[] getIBlockParts(int direction) {
BlockPart[] parts = new BlockPart[BlockPartsCount];
if ((direction == East) || (direction == West)) {
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(1,0);
parts[2] = new BlockPart(2,0);
parts[3] = new BlockPart(3,0);
} else {
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(0,1);
parts[2] = new BlockPart(0,2);
parts[3] = new BlockPart(0,3);
}
return parts;
}
BlockPart[] getOBlockParts() {
BlockPart[] parts = new BlockPart[BlockPartsCount];
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(1,0);
parts[2] = new BlockPart(0,1);
parts[3] = new BlockPart(1,1);
return parts;
}
BlockPart[] getTBlockParts(int direction) {
BlockPart[] parts = new BlockPart[BlockPartsCount];
switch (direction) {
case East:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(1,0);
parts[2] = new BlockPart(2,0);
parts[3] = new BlockPart(1,1);
break;
case South:
parts[0] = new BlockPart(1,0);
parts[1] = new BlockPart(0,1);
parts[2] = new BlockPart(1,1);
parts[3] = new BlockPart(1,2);
break;
case West:
parts[0] = new BlockPart(1,0);
parts[1] = new BlockPart(0,1);
parts[2] = new BlockPart(1,1);
parts[3] = new BlockPart(2,1);
break;
case North:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(0,1);
parts[2] = new BlockPart(1,1);
parts[3] = new BlockPart(0,2);
break;
}
return parts;
}
BlockPart[] getSBlockParts(int direction) {
BlockPart[] parts = new BlockPart[BlockPartsCount];
switch (direction) {
case East:
case West:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(0,1);
parts[2] = new BlockPart(1,1);
parts[3] = new BlockPart(1,2);
break;
case South:
case North:
parts[0] = new BlockPart(0,1);
parts[1] = new BlockPart(1,0);
parts[2] = new BlockPart(1,1);
parts[3] = new BlockPart(2,0);
break;
}
return parts;
}
BlockPart[] getZBlockParts(int direction) {
BlockPart[] parts = new BlockPart[BlockPartsCount];
switch (direction) {
case East:
case West:
parts[0] = new BlockPart(1,0);
parts[1] = new BlockPart(0,1);
parts[2] = new BlockPart(1,1);
parts[3] = new BlockPart(0,2);
break;
case South:
case North:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(1,0);
parts[2] = new BlockPart(1,1);
parts[3] = new BlockPart(2,1);
break;
}
return parts;
}
BlockPart[] getJBlockParts(int direction) {
BlockPart[] parts = new BlockPart[BlockPartsCount];
switch (direction) {
case East:
parts[0] = new BlockPart(1,0);
parts[1] = new BlockPart(1,1);
parts[2] = new BlockPart(0,2);
parts[3] = new BlockPart(1,2);
break;
case South:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(0,1);
parts[2] = new BlockPart(1,1);
parts[3] = new BlockPart(2,1);
break;
case West:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(1,0);
parts[2] = new BlockPart(0,1);
parts[3] = new BlockPart(0,2);
break;
case North:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(1,0);
parts[2] = new BlockPart(2,0);
parts[3] = new BlockPart(2,1);
break;
}
return parts;
}
BlockPart[] getLBlockParts(int direction) {
BlockPart[] parts = new BlockPart[BlockPartsCount];
switch (direction) {
case East:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(0,1);
parts[2] = new BlockPart(0,2);
parts[3] = new BlockPart(1,2);
break;
case South:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(0,1);
parts[2] = new BlockPart(1,0);
parts[3] = new BlockPart(2,0);
break;
case West:
parts[0] = new BlockPart(0,0);
parts[1] = new BlockPart(1,0);
parts[2] = new BlockPart(1,1);
parts[3] = new BlockPart(1,2);
break;
case North:
parts[0] = new BlockPart(0,1);
parts[1] = new BlockPart(1,1);
parts[2] = new BlockPart(2,0);
parts[3] = new BlockPart(2,1);
break;
}
return parts;
}
@@ -0,0 +1,64 @@
BlockPart[] getBlockParts(Block block) {
switch(block.type) {
case I: return getIBlockParts(block.direction);
case O: return getOBlockParts();
case T: return getTBlockParts(block.direction);
case S: return getSBlockParts(block.direction);
case Z: return getZBlockParts(block.direction);
case J: return getJBlockParts(block.direction);
case L: return getLBlockParts(block.direction);
}
return getIBlockParts(block.direction);
}
void makeBlockFall(Block block) {
block.yPos += 1;
for (int i = 0; i < BlockPartsCount; i++) {
block.parts[i].yPos += 1;
}
}
// We assume, only unsigned int is possible in block parts[i].xPos.
void arrangeNewBlock(Block block, int wellWidth) {
int leftXShift = 0;
int maxYShift = 0;
for (int i = 0; i < BlockPartsCount; i++) {
maxYShift = max (block.parts[i].yPos, maxYShift);
block.parts[i].xPos = block.parts[i].xPos + block.xPos;
block.parts[i].yPos = block.parts[i].yPos + block.yPos;
if (block.parts[i].xPos >= wellWidth)
leftXShift = max(leftXShift, block.parts[i].xPos + 1 - wellWidth);
}
for (int i = 0; i < BlockPartsCount; i++) {
block.parts[i].xPos = block.parts[i].xPos - leftXShift;
block.parts[i].yPos = block.parts[i].yPos - (1 + maxYShift);
}
}
Block createBlock(int type, int direction, int xPos, int yPos, int wellWidth) {
Block block = new Block(type, xPos, yPos, direction);
block.parts = getBlockParts(block);
arrangeNewBlock(block, wellWidth);
return block;
}
void moveBlockHorizontal(Block block, int distance) {
for (int i = 0; i < BlockPartsCount; i++) {
block.parts[i].xPos = block.parts[i].xPos + distance;
}
block.xPos += distance;
}
int rotateDirection(int prevDirection) {
if (prevDirection < DirectionsCount - 1)
return prevDirection + 1;
return 0;
}
@@ -0,0 +1,23 @@
class Game {
int wellWidth;
int wellHeight;
int score;
int level;
boolean[][] blocks;
Block fallingBlock;
Block nextBlock;
boolean erasingNeeded;
Game (int w, int h) {
wellWidth = w;
wellHeight = h;
fallingBlock = null;
erasingNeeded = false;
blocks = new boolean[w][h];
for (int x = 0; x < w; x++)
for (int y = 0; y < h; y++)
blocks[x][y] = false;
}
};
@@ -0,0 +1,160 @@
static final int MoveLeft = -1;
static final int MoveRight = 1;
boolean isBlockStuck(Game game)
{
Block block = game.fallingBlock;
if (block == null)
return false;
boolean[][] blocks = game.blocks;
BlockPart[] parts = block.parts;
boolean stuck = false;
for (int i = 0; (i < BlockPartsCount) && (!stuck); i++) {
if (parts[i].xPos >= 0 && parts[i].yPos >= 0)
stuck = stuck
|| parts[i].yPos + 1 >= game.wellHeight
|| blocks[parts[i].xPos][parts[i].yPos + 1];
}
return stuck;
}
void fixateBlock(Game game) {
Block block = game.fallingBlock;
if (block == null)
return;
BlockPart[] parts = block.parts;
for (int i = 0; i < BlockPartsCount; i++) {
if (parts[i].yPos >= 0)
game.blocks[parts[i].xPos][parts[i].yPos] = true;
}
game.fallingBlock = null;
}
void eraseFilledLines(Game game) {
int eraseRows=0;
for (int y = game.wellHeight - 1; y >= 0; ) {
boolean erasable = true;
for (int x = 0; x < game.wellWidth; x++)
erasable = erasable && game.blocks[x][y];
if (erasable) {
eraseRows +=1;
// Move blocks down
for (int y2 = y - 1; y2 >= 0; y2--)
for (int x = 0; x < game.wellWidth; x++)
game.blocks[x][y2 + 1] = game.blocks[x][y2];
// Top level needs to be cleared.
for (int x = 0; x < game.wellWidth; x++)
game.blocks[x][0] = false;
} else {
y--;
}
}
if (eraseRows != 0) {
game.score+=10*(eraseRows*2-1);
eraseRows=0;
game.level = game.score / 200;
if (game.level <0) {
game.level = 0;
} else if (game.level > 9) {
game.level = 9;
}
gameSpeed = (gameInitSpeed-game.level);
}
game.erasingNeeded = false;
}
void enableErasing(Game game) {
game.erasingNeeded = true;
}
Block randomBlock() {
int blockType = int(random(0, BlocksCount));
int blockDirection = int(random(0, DirectionsCount));
Block block = new Block(blockType, 0, 0, blockDirection);
block.parts = getBlockParts(block);
return block;
}
void generateRandomBlock(Game game) {
int blockType = int(random(0, BlocksCount));
int blockDirection = int(random(0, DirectionsCount));
//int xPos = int(random(0, game.wellWidth));
int xPos = game.wellWidth/2-1;
//game.fallingBlock = createBlock(blockType, blockDirection, xPos, -1, game.wellWidth);
if (game.nextBlock == null) {
game.fallingBlock = createBlock(blockType, blockDirection, xPos, -1, game.wellWidth);
game.nextBlock = randomBlock();
} else {
game.fallingBlock = game.nextBlock;
game.fallingBlock.xPos = game.wellWidth/2-1;
arrangeNewBlock(game.fallingBlock, game.wellWidth);
game.nextBlock = randomBlock();
}
}
boolean isBlockMovingPossible(Game game, int moveDirection) {
Block block = game.fallingBlock;
if (block == null)
return false;
boolean possible = true;
for (int i = 0; i < BlockPartsCount; i++) {
int desiredXPos = block.parts[i].xPos + moveDirection;
int desiredYPos = block.parts[i].yPos;
possible = possible
&& (moveDirection == MoveLeft ? desiredXPos >= 0 : desiredXPos < game.wellWidth);
if ((desiredYPos >= 0) && (desiredYPos < game.wellHeight))
possible = possible && !(game.blocks[desiredXPos][desiredYPos]);
}
return possible;
}
void moveBlock(Game game, int moveDirection) {
if (isBlockMovingPossible(game, moveDirection))
moveBlockHorizontal(game.fallingBlock, moveDirection);
}
void makeBlockFall(Game game) {
if (isBlockStuck(game)) {
fixateBlock(game);
enableErasing(game);
generateRandomBlock(game);
} else {
makeBlockFall(game.fallingBlock);
}
}
void rotateBlock(Game game) {
Block block = game.fallingBlock;
Block rotated = createBlock(block.type, rotateDirection(block.direction), block.xPos, block.yPos, game.wellWidth);
game.fallingBlock = rotated;
}
Game updateGameState(Game game) {
Game currentGame = game;
if (currentGame.erasingNeeded) {
eraseFilledLines(currentGame);
} else if (currentGame.fallingBlock != null) {
makeBlockFall(currentGame);
}
return currentGame;
}
boolean isGameOver(Game game) {
for (int i = 0; i < game.wellWidth; i++)
if (game.blocks[i][0])
return true;
return false;
}
@@ -0,0 +1,56 @@
void drawWellGrid(int w, int h)
{
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
stroke(0xFFBBBB00);
fill(0xFF00FF00);
rect(x*BlockScale, y*BlockScale, BlockScale, BlockScale);
}
}
}
void drawBlocks(int w, int h, boolean[][] blocks) {
for (int x = 0; x < w; x++) {
for (int y = 0; y < h; y++) {
if (blocks[x][y]) {
//fill(0xFF000000 | (int)random(0xFFFFFF)); // For fun.
fill(0xFF0000FF);
rect(x*BlockScale, y*BlockScale, BlockScale, BlockScale);
}
}
}
}
void drawFallingBlock(Block block)
{
if (block == null)
return;
BlockPart[] parts = block.parts;
stroke(0x00BB0000);
fill(0xFFFF0000);
for (int i = 0; i < BlockPartsCount; i++)
rect(parts[i].xPos*BlockScale, parts[i].yPos*BlockScale, BlockScale, BlockScale);
}
void drawNextBlock(Block block,int x,int y) {
if (block == null)
return;
BlockPart[] parts = block.parts;
stroke(255,0,0);
fill(255,255,0);
for (int i = 0; i < BlockPartsCount; i++)
rect(parts[i].xPos*BlockScale+x, parts[i].yPos*BlockScale+y, BlockScale, BlockScale);
}
void drawGameState(Game game)
{
drawWellGrid(game.wellWidth, game.wellHeight);
drawBlocks(game.wellWidth, game.wellHeight, game.blocks);
drawFallingBlock(game.fallingBlock);
}