MessageBox+Tetris

by hacker_johiroshi
♥0 | Line 506 | Modified 2010-05-23 17:20:48 | MIT License
play

ActionScript3 source code

/**
 * Copyright hacker_johiroshi ( http://wonderfl.net/user/hacker_johiroshi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/aqg4
 */

package {
  	import flash.display.Sprite;
   	import flash.text.TextField;
   	import flash.text.TextFormat;
	import flash.display.SimpleButton;
	import flash.events.MouseEvent;
	import flash.display.Graphics;
	
	public class MessageBox extends Sprite {
        
	private var tf:TextField = new TextField();
	private var tfm:TextFormat = new TextFormat;
	private var count:int = 0;
        
        	public function MessageBox() {

			//テキストの設定
			var TextDetail = new TextDetail(tf);

			addChild(TextDetail);

			//テキストボックスの生成
			var createTextField = new createTextField(tf, 20, 20, 425, 300);
			addChild(createTextField);

			//テキストのデフォルト値を設定
			//tf.defaultTextFormat = new TextFormat("", 20, 0x0, true);

			//TextFormatの生成
			tfm.color = 0x000000;
			tfm.size = 20;
			tfm.italic = true;
			tf.appendText("\nIntroduction2");
			tf.setTextFormat(tfm);
			addChild(tf);

			//Bottonの生成
			var up:Next = new Next(0x0);
			var over:Next = new Next(0xFF4500);
			var button:SimpleButton = new SimpleButton(up, over, over, over);
			button.x = 350;
			button.y = 350;
			button.addEventListener(MouseEvent.CLICK, onMouseClick);
			addChild(button);  
			}

		//マウスプッシュに依る先送り。Message0.
		private function onMouseClick(event:MouseEvent):void
		{
			if(count==5)
			{
				RMBox();
				//removeChild(MessageBox.button);
				Next.RNext();
			}

			var ms0:Array = ["学生も最後か。", "思えば短かったかもしれない。", "学生らしいのは高校生までか。", "これからは半社会人として生きていかなければならないと思うと気が重い。\n\nどうしよう。", "始まる…", "確認array5", "array6"];

			tf.text = "\n僕:" + (ms0[count++]);
			tf.setTextFormat(tfm);
		}

		private function RMBox():void
		{
			removeChild(tf);
			tf = null;
			tfm = null;
		}
	}
}

import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.display.Graphics;
 
class Next extends Sprite
{
	public function Next(color:int)
	{
		//”Next”枠の生成
		graphics.lineStyle(2.0, color);
		graphics.beginFill(0xFFFFFF);
		graphics.drawRect(0, 0, 100, 50);
		graphics.endFill();
 
		//"Next"のフォーマットの指定
		var tf1:TextField = new TextField();

		tf1.defaultTextFormat = new TextFormat("_typeWriter", 20, color, true);
		tf1.text = "Next";
		tf1.autoSize = "left";
        	tf1.width = 400;
        	tf1.height = 400;
		tf1.x =  (this.width  - tf1.width)  / 2;
		tf1.y = (this.height - tf1.height) / 2;
		tf1.selectable = false;
		addChild(tf1);
	}

	public static function RNext():void
	{
		var canvas:Sprite = new Sprite();
		var g:Graphics = canvas.graphics;
		g.clear();
	}
}

import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;

class TextDetail extends Sprite
{
	private var tf:TextField = new TextField();

	//テキストの詳細を記入
	public function TextDetail(tf:TextField)
	{
		//TextBoxの生成
		//var tf:TextField = new TextField();
		tf.text = "Introduction1";
		tf.x = 30;
		tf.y = 30;
		tf.width = 390;
		tf.height = 270;
		tf.multiline = true;		//複数行
		tf.wordWrap = true;		//テキストの折り返し
		//tf.autoSize = "left";
		//addChild(tf);
	}
}

import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;

class createTextField extends Sprite
{
	public function createTextField(result:TextField, x:Number, y:Number, width:Number, height:Number)
	{
		result.x = x;
		result.y = y;
		result.width = width;
		result.height = height;
		result.border = true;
		result.background = true;
		addChild(result);

	}
}

import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.geom.Matrix;
import flash.utils.ByteArray;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.ui.Keyboard;
import frocessing.color.ColorHSV;
import mx.controls.Alert;
import flash.media.*;
import flash.net.*;
	
[SWF(width="465", height="465", frameRate="30", backgroundColor="0x393939")]
class Tetris extends Sprite
{
	private var block:Array;
	private var field:Array;
	private var px:int = 4;
	private var py:int = 0;
	private var frameCount:int = 0;
	private var blockType:int;
	private var nextBlock:int;
	private var nextDrawBlock:Array;
	private var lines:int = 0;
	private var blocks:int = 0;
	private var linesText:TextField;
	private var blocksText:TextField;
	private var gameoverText:TextField;
	private var h:int = 11;
	private var s:Number = 0.5;
	private var v:Number = 0.3;
	private var stop:Boolean = false;
	private var gameover:Boolean = false;
	private var seq:Array = new Array(3,4);
	private var bgm:Boolean;
	private var effects:Array;
	private var snd:Sound;
	private var channel:SoundChannel;
	private var fieldStack:Array;
	private var linesStack:Array;
	private var blocksStack:Array;
				
	public function Tetris()
	{
		Wonderfl.capture_delay(25);
		nextBlock = seq[0];
		createTextField(null, "Next:", 270, 35, 20);
		createTextField(null, "Move", 270, 200, 20);
		createTextField(null, "[A, S, D], [←, ↓, →]", 270, 220, 13);
		createTextField(null, "Rotate", 270, 250, 20);
		createTextField(null, "W, ↑, Enter, Space", 270, 270, 13);
		createTextField(null, "黒いラインを越えたらGame Over", 270, 350, 13);
		createTextField(null, "RでRestart,Pでモード切り替え", 270, 370, 13);
		createTextField(null, "一回、画面をクリックしないと", 270, 400, 13);
		createTextField(null, "キーが反応しないかもしれません", 270, 420, 13);
			
		linesText = createTextField(null, "lines: 0", 270, 120, 20);
		blocksText = createTextField(null, "blocks: 0", 270, 150, 20);
		gameoverText = createTextField(null, "", 270, 300, 20, 0xFF0000);
		block = new Array(21);
		for (var i:int = 0; i < block.length; i++) block[i] = new Array(12);
		initField();			
		
		fieldStack = new Array();
		linesStack = new Array();
		blocksStack = new Array();
		
		bgm = true;
		snd = new Sound();
		//from http://upload.wikimedia.org/wikipedia/en/f/fe/Korobeiniki.midsnd.load(new URLRequest("http://yambi.mydns.jp/resource/Korobeiniki.mp3"));        
		channel = snd.play(0, int.MAX_VALUE);
            		
            	effects = new Array();
            	effects.push(new Sound());
            	//http://utm-game-web.hp.infoseek.co.jp/free-sound.htm
            	effects[0].load(new URLRequest("http://yambi.mydns.jp/resource/patu_mod.mp3"));

		createBlock();
		addEventListener(Event.ENTER_FRAME, onEnterFrame);
		stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
	}
		
	private function initField():void{
	for (var y:int = 0; y < 21; y++){
		for (var x:int = 0; x < 12; x++){
			if (y == 20 || x == 0 || x == 11) block[y][x] = 9;
				else block[y][x] = 0;
			}
		}
	field = clone(block);	
	}
		
	private function onEnterFrame(event:Event):void
	{
		if (frameCount++ % 15 == 0 && !stop && !gameover){
			if (checkOverlap(py + 1, px)) lockBlock(), createBlock();
			else moveBlock(py + 1, px);
			}
		draw();
	}
		
	private function draw():void
	{
		graphics.clear();
		var hsv:ColorHSV = new ColorHSV();
		var matrix:Matrix = new Matrix();
		var color:int; // 変数定義、重複避け
		matrix.createGradientBox(20, 20, 45 * Math.PI / 180);
			

		for (var y:int = 0; y < 21; y++)
		{
			for (var x:int = 0; x < 12; x++)
			{
				matrix.createGradientBox(20, 20, 45 * Math.PI / 180, x * 20, y * 20);
				if (block[y][x] == 0)
				{
					if(y>=h){
						graphics.beginGradientFill("linear", [0xEEEEEE, 0xCCCCCC], [1.0, 1.0], [0, 255], matrix);
						graphics.drawRect(x * 20, y * 20, 20, 20);
						graphics.endFill();
						}
						else{
							graphics.beginGradientFill("linear", [0x999999, 0x777777], [1.0, 1.0], [0, 255], matrix);
							graphics.drawRect(x * 20, y * 20, 20, 20);
							graphics.endFill();			
						}
					}
					else if (block[y][x] == 9)
					{
						//graphics.beginGradientFill("linear", [0xFF556F, 0xFF979C], [1.0, 1.0], [0, 255], matrix);
						graphics.beginGradientFill("linear", [0x777777, 0x333333], [1.0, 1.0], [0, 255], matrix);
						graphics.drawRect(x * 20, y * 20, 20, 20);
						graphics.endFill();
					}
					else
					{
						color = Block.color[block[y][x] - 1];
						hsv.r = color >> 16 & 0xFF, hsv.g = color >> 8 & 0xFF, hsv.b = color & 0xFF;
						hsv.s = s;
						hsv.v = v;
						graphics.beginGradientFill("linear", [hsv.value, Block.color[block[y][x] - 1]], [1.0, 1.0], [0, 255], matrix);
						//graphics.beginFill(hsv.value);
						graphics.drawRect(x * 20, y * 20, 20, 20);
						graphics.endFill();
					}
				}
			}
			

		graphics.beginFill(0x000000);
		graphics.drawRect(0,20*h,240,2);
		graphics.endFill();
			
		color = Block.color[nextBlock];
		hsv.r = color >> 16 & 0xFF, hsv.g = color >> 8 & 0xFF, hsv.b = color & 0xFF;
		hsv.s = s;
		hsv.v = v;
			
			
		for (y = 0; y < 4; y++)
		{
			for (x = 0; x < 4; x++)
			{
				if (nextDrawBlock[y][x])
				{
					matrix.createGradientBox(20, 20, 45 * Math.PI / 180, 350 + x * 20, 10 + y * 20);
					graphics.beginGradientFill("linear", [hsv.value, Block.color[nextBlock]], [1.0, 1.0], [0, 255], matrix);
					graphics.drawRect(350 + x * 20, 10 + y * 20, 20, 20);
					graphics.endFill();
				}
			}
		}
		linesText.text = "lines: " + String(lines);
		gameoverText.text = gameover?"Game Over!!":"";
	}
		
	private function createBlock():void
	{
		py = 0;
		px = 4;
			
		blockType = nextBlock;
		nextBlock = seq[++blocks%seq.length];
		nextDrawBlock = clone(Block.block[nextBlock]);
		//nextBlock = Math.random() * Block.block.length;

		blocksText.text = "blocks: " + blocks;
			
		for (var y:int = 0; y < 4; y++)
		{
			for (var x:int = 0; x < 4; x++)
			{
				if (Block.block[blockType][y][x] && block[py + y][px + x]){
					 gameover = true;
				}
				block[py + y][px + x] += Block.block[blockType][y][x];
			}				
		}
	}
		
	private function moveBlock(yy:int, xx:int):void
	{
		if(gameover) return;
		for (var y:int = 0; y < 4; y++)
		{
			for (var x:int = 0; x < 4; x++)
			{
				block[py + y][px + x] -= Block.block[blockType][y][x];
			}				
		}
			
		py = yy;
		px = xx;
			
		for (y = 0; y < 4; y++)
		{
			for (x = 0; x < 4; x++)
			{
				block[py + y][px + x] += Block.block[blockType][y][x];
			}				
		}
			
		draw();
	}
		
	private function checkOverlap(yy:int, xx:int):Boolean{
		for (var y:int = 0; y < 4; y++){
			for (var x:int = 0; x < 4; x++)	{
				if (Block.block[blockType][y][x]){
					if (field[yy + y][xx + x] != 0) return true;
				}
			}				
		}
		return false;
	}
		
	private function lockBlock():void
	{
		fieldStack.push(clone(field));
		linesStack.push(lines);
		blocksStack.push(blocks);
		
		for (var y:int = 0; y < 21; y++)
		{
			for (var x:int = 0; x < 12; x++)
			{
				field[y][x] = block[y][x];
			}
		}
			
		checkLines();
			
		for (y = 0; y < 21; y++)
		{
			for (x = 0; x < 12; x++)
			{
				block[y][x] = field[y][x];
				if(y<h&&field[y][x]>0&&field[y][x]<9){
					gameover = true;
				}
			}
		}			
	}
		
	private function controlBlock(yy:int, xx:int):void
	{
		if (!checkOverlap(py + yy, px + xx)) moveBlock(py + yy, px + xx)
		else if (yy>0) lockBlock(), createBlock();
	}
		
	private function onKeyDown(event:KeyboardEvent):void
	{
		if (event.keyCode == 37) controlBlock(0, -1); // ←
		if (event.keyCode == 40) controlBlock(1,  0); // ↓
		if (event.keyCode == 39) controlBlock(0,  1); // →
		if (event.keyCode == 38) turnBlock(); // ↑
		if (event.keyCode == 65) controlBlock(0, -1); // A
		if (event.keyCode == 68) controlBlock(0,  1); // D
		if (event.keyCode == 83) controlBlock(1,  0); // S
		if (event.keyCode == 87) turnBlock(); // W
		if (event.keyCode == 82) restart();//R
		if (event.keyCode == 80) pause();//P
		if (event.keyCode == 77) toggleBGM();//M
		if (event.keyCode == 85) undo(); 
		if (event.keyCode == Keyboard.SPACE) turnBlock();
		if (event.keyCode == Keyboard.ENTER) turnBlock();
	}
		
	private function undo():void{
		if(fieldStack.length==0)return;
		field = fieldStack.pop();
		block = clone(field);
		lines = linesStack.pop();
		blocks = blocksStack.pop()-1;
		gameover = false;
		createBlock();
	}
		
	private function toggleBGM():void{
		var cp:int = channel.position;
		if(bgm)channel.stop();
		else channel = snd.play(cp,int.MAX_VALUE);
		bgm = !bgm;
	}
	private function playEffect(num:int):void{
		effects[num].play();
	}
		
	private function restart():void{
		gameover = false;
		lines = 0;
		blocks = 0;	
		nextBlock = seq[0];
		initField();

		fieldStack = new Array();
		linesStack = new Array();
		blocksStack = new Array();
		createBlock();
	}
		
	private function pause():void{
		stop = !stop;
	}
		
	private function turnBlock():void
	{
		if(gameover)return;
		var temp:Array = clone(Block.block[blockType]);
		for (var y:int = 0; y < 4; y++)
		{
			for (var x:int = 0; x < 4; x++)
			{
				Block.block[blockType][y][x] = temp[3 - x][y];
			}
		}
			
		if (checkOverlap(py, px))
		{
			Block.block[blockType] = clone(temp);
			return;
		}
			
		for (y = 0; y < 4; y++)
			{
			for (x = 0; x < 4; x++)
			{
				block[py + y][px + x] -= temp[y][x];
				block[py + y][px + x] += Block.block[blockType][y][x];
			}
		}
					
		draw();
	}
		
	private function checkLines():void
	{
		var found:Boolean;
			
		for (var y:int = 19; y >= 0; y--)
		{
			found = true;
			for (var x:int = 1; x <= 11; x++)
			{
				if (field[y][x] == 0)
				{
					found = false;
					break;
				}
			}
			if (found)
			{
				playEffect(0);
				for (var xx:int = 1; xx <= 11; xx++) field[y][xx] == 0;
				for (var yy:int = y; yy >= 1; yy--)
				{
					for (xx = 1; xx <= 11; xx++)
					{
						field[yy][xx] = field[yy - 1][xx];
					}
				}
				y++;
				lines++;
			}
		}
	}
		
	private function createTextField(parent:Sprite = null, text:String = "", x:int = 0, y:int = 0, fontSize:int = 13,c:uint=0xFFFFFF):TextField
	{
		var tf:TextField = new TextField();
		tf.x = x, tf.y = y;
		tf.defaultTextFormat = new TextFormat("_typeWriter", fontSize, c);
		tf.text = text;
		tf.selectable = false;
		tf.autoSize = TextFieldAutoSize.LEFT;
		if (parent) parent.addChild(tf);
		else this.addChild(tf);
			
		return tf;
	}
		
	private function clone(arg:*):*
	{
		var b:ByteArray = new ByteArray();
		b.writeObject(arg);
		b.position = 0;
		return b.readObject();
	}
}


class Block
{
	public static var block:Array = [[[0, 0, 0, 0],
								      [0, 1, 1, 0],
							          [0, 1, 1, 0],
							          [0, 0, 0, 0]],
									 [[0, 0, 2, 0],
								      [0, 0, 2, 0],
							          [0, 0, 2, 0],
							          [0, 0, 2, 0]],
									 [[0, 0, 0, 0],
								      [0, 3, 3, 0],
							          [0, 3, 0, 0],
							          [0, 3, 0, 0]],
									 [[0, 0, 4, 0],
								      [0, 4, 4, 0],
							          [0, 4, 0, 0],
							          [0, 0, 0, 0]],
									 [[0, 5, 0, 0],
								      [0, 5, 5, 0],
							          [0, 0, 5, 0],
							          [0, 0, 0, 0]],
									 [[0, 0, 0, 0],
								      [0, 6, 0, 0],
							          [6, 6, 6, 0],
							          [0, 0, 0, 0]],
									 [[0, 0, 0, 0],
								      [0, 7, 7, 0],
							          [0, 0, 7, 0],
							          [0, 0, 7, 0]]];
	
	//
	public static var color:Array = [0xFFFF00, 0x00FFFF, 0x0000FF, 0xFF0000, 0x00FF00, 0xAA00FF, 0xFFA500]; 
	
	public function Block(){}
}