xxxxxxxxxx
189
// Reference : 201204a by takawo
// https://www.openprocessing.org/sketch/1033440
const CELL_SIZE = 10;
const BACKGROUND_COLOR = '#eee';
const CELL_COLOR = 'black';
let gQRModule;
const FLOOR_HEIGHT = 100;
let gBlocks = [];
let gFloor;
let gStone;
function setup() {
createCanvas( 720, 720 );
background( BACKGROUND_COLOR );
rectMode( CENTER );
noStroke();
gQRModule = QRCode.create( generateRandomData() ).modules
matter.init();
frameRate(60);
}
function mousePressed() {
addSquare( mouseX, mouseY, CELL_SIZE );
}
function draw() {
const frameNum = frameCount % 300;
const FRAME_START_FALLING = 60;
// Initialize matter in each 1st frames
if( frameNum === 1 ){
initialize();
}
background( BACKGROUND_COLOR );
fill( CELL_COLOR );
if( frameNum <= FRAME_START_FALLING ){
const size = gQRModule.size;
// Offset for centering
const offsetX = width / 2 - size * CELL_SIZE / 2;
const offsetY = height / 4 - size * CELL_SIZE / 2;
drawStaticQRCode( offsetX, offsetY );
if( frameNum === FRAME_START_FALLING ){
reloadQRBlocks( offsetX, offsetY );
}
}else{
// Draw blocks as Physical model
drawMatterFrames();
}
drawStone();
}
// Initialize matter things
const initialize = () => {
// Reset Stone if it exists
gStone && matter.forget( gStone );
// initialize blocks
for( e of gBlocks){
matter.forget(e);
}
gBlocks = [];
// Set Floor
gFloor = matter.makeBarrier( width / 2, height + FLOOR_HEIGHT / 2,
width, FLOOR_HEIGHT );
// Set Stone
const halfWidth = width / 2;
const halfQRSize = gQRModule.size * CELL_SIZE / 2
gStone = matter.makeBarrier( random( halfWidth - halfQRSize, halfWidth + halfQRSize ),
height - 100, 50, 50 );
}
// Draw Static QR Code
const drawStaticQRCode = ( offsetX, offsetY ) => {
const dataArray = gQRModule.data;
const size = gQRModule.size;
for ( let row = 0; row < size; row++ ) {
for ( let column = 0; column < size; column++ ) {
if( dataArray[ row * size + column ] ){
square( offsetX + column * CELL_SIZE,
offsetY + row * CELL_SIZE, CELL_SIZE );
}
}
}
}
// Draw blocks as Physical model
const drawMatterFrames = () => {
for ( let i = gBlocks.length - 1; i >= 0; i-- ) {
let b = gBlocks[i];
let p = b.body.position;
push();
translate( p.x, p.y, 0 );
rotate( b.body.angle );
square( 0, 0, CELL_SIZE );
pop();
if ( b.isOffCanvas() ) {
matter.forget( b );
gBlocks.splice( i, 1 );
}
}
}
// Draw Stone
const drawStone = () => {
fill('red');
gStone.show();
}
// Reload new QR Blocks
const reloadQRBlocks = ( offsetX, offsetY ) => {
const dataArray = gQRModule.data;
const size = gQRModule.size;
for ( let row = 0; row < size; row++ ) {
for ( let column = 0; column < size; column++ ) {
if( dataArray[ row * size + column ] ){
addSquare( offsetX + column * CELL_SIZE,
offsetY + row * CELL_SIZE, CELL_SIZE );
}
}
}
}
// Push each blocks to matter js.
const addSquare = ( x, y, size ) => {
const b = matter.makeBlock( x, y, size, size );
gBlocks.push( b );
}
// Generate random data
const generateRandomData = () => {
// Memo: There was no alignment patter in the data size below 34.
const size = 35;
let data = '';
for( let i = 0; i < size; i++ ){
data += floor( random( 9 ) );
}
// console.log( data );
return data;
}