In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

ぷよ雪

ぷよ雪
でっちあげプロトタイプ@November 8, 2009
今後やりたかったこと:
  ・ちゃんとテストする
  ・連鎖だとわかるように一連鎖ずつ消す
  ・落下・連鎖を滑らかに描画する
  ・ASの配列の扱い方を調べて書き直す
  ・ASのイベントと時間の扱い方を調べて書き直す
  ・ASのコーディング規約を調べて書き直す
Get Adobe Flash player
by naraba 12 Nov 2009

    Talk

    uwi at 09 Nov 2009 08:10
    横2のブロックが片側だけ接してても消去判定って行われるんだっけ? "B "ってなってるときに"AA"がおちてきた感じの
    naraba at 09 Nov 2009 18:07
    その場合は接してないほうを下まで落とした後で消去判定する。プログラム中ではvanishメソッドの前に必ずgroundメソッドを呼んでpuyoを落としきる

    Tags

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

// ぷよ雪
// でっちあげプロトタイプ@November 8, 2009
// 今後やりたかったこと:
//  ・ちゃんとテストする
//  ・連鎖だとわかるように一連鎖ずつ消す
//  ・落下・連鎖を滑らかに描画する
//  ・ASの配列の扱い方を調べて書き直す
//  ・ASのイベントと時間の扱い方を調べて書き直す
//  ・ASのコーディング規約を調べて書き直す
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.TimerEvent;
	import flash.utils.Timer;
	
	[SWF(width="400", height="450", frameRate="30", backgroundColor="0x4444FF")]
	public class PuyoSnow extends Sprite
	{
		private const CELL_WIDTH:int = 5;
		private const CELL_HEIGHT:int = 5;
		private const SCENE_WIDTH:int = 80;
		private const SCENE_HEIGHT:int = 90;
		private const BLANK:int = -1;
		private const FLOOR:int = -2;
		private const MARKING:int = -3;
		private const COLORS:Array = [0xFFFFFF, 0xDDDDFF, 0xBBBBFF, 0x9999FF];
		private var scene:Array = [];
		private var fallingPairs:Array = [];
		private var topLevelAt:Array = [];
		private var groundLevelAt:Array = [];
		private var fallTimer:Timer = new Timer(10);
		
		public function PuyoSnow()
		{
			Wonderfl.capture_delay(30);
			
			scene = new Array(SCENE_HEIGHT+1).map(function():* {
				return new Array(SCENE_WIDTH).map(function():* {
					return null;
				})
			});
			for (var i:int = 0; i < SCENE_WIDTH; i++) {
				for (var j:int = 0; j < SCENE_HEIGHT; j++) {
					scene[i][j] = BLANK;
				}
				scene[i][SCENE_HEIGHT] = FLOOR;
			}
			topLevelAt = new Array(SCENE_WIDTH).map(function():* {
				return SCENE_HEIGHT;
			});
			groundLevelAt = new Array(SCENE_WIDTH).map(function():* {
				return SCENE_HEIGHT;
			});
			stage.addEventListener(Event.ENTER_FRAME, function(e:Event):void {
				draw();
			});
			fallTimer.addEventListener(TimerEvent.TIMER, fallPairs);
			fallTimer.start();
		}

		private function makePair():void
		{
			fallingPairs.push(new Pair(SCENE_WIDTH, COLORS.length));
		}
		
		private function fallPairs(e:TimerEvent):void
		{
			if (Math.random() < .4) { makePair(); }
			for (var i:int = 0; i < fallingPairs.length; i++) {
				var pair:Pair = fallingPairs[i];
				var p1x:int = pair.p1.x;
				var p1y:int = pair.p1.y;
				var p2x:int = pair.p2.x;
				var p2y:int = pair.p2.y;
				if (scene[p1x][p1y+1] != BLANK || scene[p2x][p2y+1] != BLANK) {
					scene[p1x][p1y] = pair.p1.color;
					scene[p2x][p2y] = pair.p2.color;
					topLevelAt[p2x] = p2y;
					topLevelAt[p1x] = p1y;
					if (topLevelAt[p2x] <= 0 || topLevelAt[p1x] <= 0) {
						// どこかが上まで積もったら何も言わずにただ止まる
						fallTimer.stop();
					}
					fallingPairs.splice(i, 1);
					i -= 1;  // bug fix @ November 12, 2009
				} else {
					pair.fall();
				}
			}
			do { // 連鎖があってもノータイムで全部消す
				ground();
			} while (vanish());
		}
		
		private function ground():void
		{
			for (var i:int = 0; i < SCENE_WIDTH; i++) {
				for (var j:int = SCENE_HEIGHT; j >= topLevelAt[i]; j--) {
					if (scene[i][j] != BLANK) {
						groundLevelAt[i] = j;
						continue;
					}
					var k:int = j - 1;
					while (scene[i][k] == BLANK && k >= topLevelAt[i]) { k--; }
					if (scene[i][k] != BLANK) {
						scene[i][j] = scene[i][k];
						scene[i][k] = BLANK;
						groundLevelAt[i] = j;
					} else {
						topLevelAt[i] = groundLevelAt[i];
						break;
					}
				}
			}
		}
		
		private function vanish():Boolean
		{
			var didVanish:Boolean = false;
			for (var i:int = 0; i < SCENE_WIDTH; i++) {
				for (var j:int = SCENE_HEIGHT-1; j >= groundLevelAt[i]; j--) {
					var color:int = scene[i][j];
					if (color < 0) { continue; }
					var mode:Boolean = (markChunk(i, j, color) > 3);
					unmarkChunk(i, j, color, mode);
					didVanish = didVanish || mode;
				}
			}
			return didVanish;
		}
		
		private function markChunk(x:int, y:int, col:int):int
		{
			if (x < 0 || x >= SCENE_WIDTH) { return 0; }
			if (scene[x][y] == col) {
				scene[x][y] = MARKING;
				return 1 + markChunk(x-1, y, col) + markChunk(x+1, y, col) +
						markChunk(x, y-1, col) + markChunk(x, y+1, col);
			}
			return 0;
		}
		
		private function unmarkChunk(x:int, y:int, col:int, isVanishMode:Boolean):void
		{
			if (x < 0 || x >= SCENE_WIDTH) { return; }
			if (scene[x][y] == MARKING) {
				scene[x][y] = (isVanishMode ? BLANK : col);
				unmarkChunk(x-1, y, col, isVanishMode);
				unmarkChunk(x+1, y, col, isVanishMode);
				unmarkChunk(x, y-1, col, isVanishMode);
				unmarkChunk(x, y+1, col, isVanishMode);
			}
		}
		
		private function draw():void
		{
			graphics.clear();
            graphics.beginFill(0x2222FF);
            graphics.drawRect(0, 0, CELL_WIDTH*SCENE_WIDTH, CELL_HEIGHT*SCENE_HEIGHT);
            graphics.endFill();

            for each (var pair:Pair in fallingPairs) {
                drawPuyo(pair.p1.x, pair.p1.y, pair.p1.color);
		        drawPuyo(pair.p2.x, pair.p2.y, pair.p2.color);
            }
            for (var i:int = 0; i < SCENE_WIDTH; i++) {
				for (var j:int = SCENE_HEIGHT; j >= groundLevelAt[i]; j--) {
					var s:int = scene[i][j];
					if (s >= 0) { drawPuyo(i, j, s); }
				}
			}
		}
		
		private function drawPuyo(x:int, y:int, col:int):void
		{
			graphics.beginFill(COLORS[col]);
			graphics.drawEllipse(CELL_WIDTH*x, CELL_HEIGHT*y, CELL_WIDTH, CELL_HEIGHT);
			graphics.endFill();
		}	
	}
}

class Pair
{
	public var p1:Puyo;
	public var p2:Puyo;
	
	public function Pair(maxX:int, numColors:int)
	{
		var x:int = int(Math.random()*(maxX-1));
		p1 = new Puyo(x, 0, int(Math.random()*numColors));
		if (Math.random() < .5) {
			p2 = new Puyo(x+1, 0, int(Math.random()*numColors));
		} else {
			p2 = new Puyo(x, 1, int(Math.random()*numColors));
		}
	}
	
	public function fall():void
	{
		p1.y += 1;
		p2.y += 1;
	}
}

class Puyo
{
    public var x:int;
    public var y:int;
    public var color:int;
    
    public function Puyo(x:int, y:int, color:int)
    {
        this.x = x;
        this.y = y;
        this.color = color;
    }
}