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; int cmx, cmy; void setup(){ //ゲームの初期化 initParam(); background(0); //size( BLOCK_SIZE * field.w+1, BLOCK_SIZE * field.h+7 ); size( 202, 300 ); framerate( 20 ); fill(255); smooth(); cmx = width / 2; cmy = height / 2; } 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(); } } } cmx += ( (block.x+2)*10+50 - cmx ) * 0.2; cmy += ( (block.y+2)*10+70 - cmy ) * 0.2; float xr = ( (float)cmx - (float)width / 2.0f ) / ( (float)width / 2.0f ); float yr = ( (float)cmy - (float)height / 2.0f ) / ( (float)height / 2.0f ); xr *= PI / 2.0f; yr *= PI / 2.0f; translate( width / 2, height / 2 ); rotateX( yr ); rotateY( -xr ); translate( -width / 2, -height / 2 ); //ブロックをフィールドにセット 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 ) ){ //スコアの保存 saveScore( score ); //ゲームの初期化 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] ){ noStroke(); fill( 255 ); rect( x*BLOCK_SIZE+50, y*BLOCK_SIZE+6+50, BLOCK_SIZE, BLOCK_SIZE ); } } } //スコアの描画 number.paint( score, 150, 51 ); stroke( 255 ); noFill(); rect( 49, 49, 102, 208 ); } 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; stroke( 255 ); line( x+ix, y+iy, x+ix, y+iy ); } } } } 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; } } } void saveScore( int score ){ try{ URL dataURL = new URL( "http://***" ); URLConnection connection = dataURL.openConnection(); connection.setUseCaches( false ); connection.setDoOutput( true ); ByteArrayOutputStream byteStream = new ByteArrayOutputStream( 512 ); PrintWriter writer = new PrintWriter( byteStream, true ); String today = year() + "/" + month() + "/" + day() + " " + hour() + ":" + minute(); String data = "score=" + URLEncoder.encode( score + "" ) + "&today=" + URLEncoder.encode( today ); writer.print( data ); writer.flush(); connection.setRequestProperty( "Content-Length", String.valueOf( byteStream.size() ) ); connection.setRequestProperty( "Content-Type", "application/x-www-form-urlencoded" ); byteStream.writeTo( connection.getOutputStream() ); BufferedReader reader = new BufferedReader( new InputStreamReader( connection.getInputStream() ) ); String msg = ""; String line; while( ( line = reader.readLine() ) != null ){ msg += line; } println( msg ); } catch(Exception e ){ e.printStackTrace(); } }