Add Processing Sketchs
Add Processing Sketchs and Processing tutorial
This commit is contained in:
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user