Field field; Block block; Block lastBlock; final int BLOCK_SIZE = 10; Number number; int score; int deltaScore; final int MAX_SCORE = 999999999; int speed; final int MAX_SPEED = 1; int counter; boolean keyReleaseFlag; void setup(){ //ゲームの初期化 initParam(); background(0); //size( BLOCK_SIZE * field.w+1, BLOCK_SIZE * field.h+7 ); size( 101, 207 ); framerate( 20 ); fill(255); } void initParam(){ field = new Field( 10, 20 ); block = new Block(); lastBlock = new Block(); lastBlock.copy( block ); number = new Number(); score = 0; deltaScore = 1; speed = 10; counter = 0; keyReleaseFlag = false; } void loop(){ //Key判定 if( keyPressed ){ if( key == LEFT ){ if( field.canSetBlock( block, block.x-1, block.y ) ){ block.x--; } } else if( key == RIGHT ){ if( field.canSetBlock( block, block.x+1, block.y ) ){ block.x++; } } else if( key == DOWN ){ if( field.canSetBlock( block, block.x, block.y+1 ) ){ block.y++; } } else if( key == UP && !keyReleaseFlag ){ keyReleaseFlag = true; Block tempBlock = new Block(); tempBlock.copy( block ); tempBlock.turnLeft(); if( field.canSetBlock( tempBlock, tempBlock.x, tempBlock.y ) ){ block.turnLeft(); } } } //ブロックをフィールドにセット field.resetBlock( lastBlock, lastBlock.x, lastBlock.y ); field.setBlock( block, block.x, block.y ); lastBlock.copy( block ); //スピードに応じて定期的に強制ダウン if( counter > speed ){ if( field.canSetBlock( block, block.x, block.y+1 ) ){ block.y++; } else{ block = new Block(); lastBlock.copy( block ); field.collapse(); //ゲームオーバーの判定 if( !field.isContinue( block, block.x, block.y ) ){ //ゲームの初期化 initParam(); return; } } counter = 0; } counter++; //ブロックをフィールドにセット field.resetBlock( lastBlock, lastBlock.x, lastBlock.y ); field.setBlock( block, block.x, block.y ); lastBlock.copy( block ); //フィールドの描画 background(0); for( int y = 0; y < field.h; y++ ){ for( int x = 0; x < field.w; x++ ){ if( field.table[x][y] ){ rect( x*BLOCK_SIZE, y*BLOCK_SIZE+6, BLOCK_SIZE, BLOCK_SIZE ); } } } //スコアの描画 number.paint( score, 100, 1 ); } void keyReleased(){ keyReleaseFlag = false; } class Field{ boolean[][] table; int w, h; Field( int w, int h ){ this.w = w; this.h = h; table = new boolean[this.w][this.h]; for( int iy = 0; iy < this.h; iy++ ){ for( int ix = 0; ix < this.w; ix++ ){ table[ix][iy] = false; } } } void setBlock( Block b, int bx, int by ){ for( int y = 0; y < 3; y++ ){ for( int x = 0; x < 3; x++ ){ if( b.table[y*3+x] ){ this.table[bx+x][by+y] = true; } } } } void resetBlock( Block b, int bx, int by ){ for( int y = 0; y < 3; y++ ){ for( int x = 0; x < 3; x++ ){ if( b.table[y*3+x] ){ this.table[bx+x][by+y] = false; } } } } boolean canSetBlock( Block b, int bx, int by ){ this.resetBlock( lastBlock, lastBlock.x, lastBlock.y ); for( int y = 0; y < 3; y++ ){ for( int x = 0; x < 3; x++ ){ if( b.table[y*3+x] ){ if( bx+x < 0 || bx+x > 9 || by+y < 0 || by+y > 19 ){ this.setBlock( lastBlock, lastBlock.x, lastBlock.y ); return false; } if( this.table[bx+x][by+y] ){ this.setBlock( lastBlock, lastBlock.x, lastBlock.y ); return false; } } } } this.setBlock( lastBlock, lastBlock.x, lastBlock.y ); return true; } boolean isContinue( Block b, int bx, int by ){ for( int y = 0; y < 3; y++ ){ for( int x = 0; x < 3; x++ ){ if( b.table[y*3+x] ){ if( this.table[bx+x][by+y] ) return false; } } } return true; } void collapse(){ for( int y = 0; y < this.h; y++ ){ boolean isCollapse = true; for( int x = 0; x < this.w; x++ ){ if( !this.table[x][y] ){ isCollapse = false; } } if( isCollapse ){ //スコアアップ score += deltaScore; if( score > MAX_SCORE ) score = MAX_SCORE; if( score == 10 || score == 30 || score == 70 || score == 150 || score == 320 || score == 640 || score == 1280 || score == 2560 || score == 5120 ){ deltaScore *= 2; speed--; if( speed < MAX_SPEED ) speed = MAX_SPEED; } //崩す for( int x = 0; x < this.w; x++ ){ this.table[x][y] = false; } for( int iy = y; iy > 0; iy-- ){ for( int x = 0; x < this.w; x++ ){ this.table[x][iy] = this.table[x][iy-1]; } } } } } } static final boolean[][] PATTERN = { { false, true, true, true, true, false, false, false, false }, { true, true, false, false, true, true, false, false, false }, { true, false, false, true, true, true, false, false, false }, { false, false, true, true, true, true, false, false, false }, { false, true, false, true, true, true, false, false, false }, { false, false, false, true, true, true, false, false, false } }; class Block{ boolean[] table; int x, y; Block(){ this.x = 3; this.y = 0; this.table = new boolean[9]; int p = (int)floor( random( 6 ) ); for( int y = 0; y < 3; y++ ){ for( int x = 0; x < 3; x++ ){ table[y*3+x] = PATTERN[p][y*3+x]; } } } void copy( Block b ){ this.x = b.x; this.y = b.y; for( int i = 0; i < this.table.length; i++ ){ this.table[i] = b.table[i]; } } void turnLeft(){ boolean[] tempTable= new boolean[this.table.length]; for( int i = 0; i < this.table.length; i++ ){ tempTable[i] = this.table[i]; } this.table[0] = tempTable[2]; this.table[1] = tempTable[5]; this.table[2] = tempTable[8]; this.table[3] = tempTable[1]; this.table[5] = tempTable[7]; this.table[6] = tempTable[0]; this.table[7] = tempTable[3]; this.table[8] = tempTable[6]; } } static final boolean[][] NUMBER = { { true, true, true, true, false, true, true, false, true, true, false, true, true, true, true, }, { false, true, false, true, true, false, false, true, false, false, true, false, false, true, false }, { true, true, true, false, false, true, false, true, false, true, false, false, true, true, true }, { true, true, true, false, false, true, true, true, true, false, false, true, true, true, true }, { true, false, true, true, false, true, true, true, true, false, false, true, false, false, true }, { true, true, true, true, false, false, true, true, true, false, false, true, true, true, true }, { true, true, true, true, false, false, true, true, true, true, false, true, true, true, true }, { true, true, true, true, false, true, false, false, true, false, false, true, false, false, true }, { true, true, true, true, false, true, true, true, true, true, false, true, true, true, true }, { true, true, true, true, false, true, true, true, true, false, false, true, false, false, true } }; class Number{ void paintNum( int num, int x, int y ){ for( int iy = 0; iy < 5; iy++ ){ for( int ix = 0; ix < 3; ix++ ){ if( NUMBER[num][iy*3+ix] ){ int pos = (y+iy)*width+(x+ix); pixels[pos] = 0xffffff; } } } } void paint( int num, int x, int y ){ String strNum = num + ""; int nextx = x-3; for( int i = 0; i < strNum.length(); i++ ){ String sn = strNum.substring( (strNum.length()-1)-i, strNum.length()-i ); int n = Integer.parseInt( sn ); paintNum( n, nextx, y ); nextx -= 4; } } }