
// 勝手にオンライン対戦化 by keno42 // 追加ルール // * ゲーム開始時は右の青い四角のいずれか(emptyのもの)をクリックしてください // * 2列以上消すと消した列数-1だけ敵にラインを送り込みます // * 敵を倒すと、敵のスコアの半分を自分のスコアにプラスします // * 自分でラインを消したときのLEVELの増え方がゆるやかになっています // * 敵を倒すとLEVELが+1されます //-------------------------------------------------------------------------------- // TETRISiON ~ もし水口哲也がテトリスを作ったら //-------------------------------------------------------------------------------- // < controls > // move;[Left]-[Right]/ drop;[Down]/ hard-drop;[Up]/ L-turn;[Z]/ R-turn;[X] // swap;[C] = Swap current block and stocked block. // < special rules > // 1) The level increases by 1 erasing. // 2) The game is finished at level 32. // 3) The field has only 8 rows. // 4) You can erase lines with "chain combo". // 5) You can stock 1 block and swap it wherever. // 6) The bonus is doubled over level 24. // 7) [bonus] = ([erased line count]^2 + [chain combo count]^2) * 100 // < notice > // This flash uses cookie to keep hi-score. // If you do not want, please press "CLEAR COOKIE" button. //-------------------------------------------------------------------------------- package { import flash.filters.ConvolutionFilter; import flash.net.*; import flash.geom.*; import flash.events.*; import flash.display.*; import flash.filters.GlowFilter; import flash.utils.escapeMultiByte; import frocessing.color.FColor; import frocessing.math.FMath; import net.user1.reactor.AttributeEvent; import net.user1.reactor.IClient; import net.user1.reactor.Reactor; import net.user1.reactor.ReactorEvent; import net.user1.reactor.Room; import net.user1.reactor.RoomEvent; import net.user1.reactor.RoomManagerEvent; import net.user1.reactor.RoomSettings; import net.user1.reactor.Status; import net.user1.reactor.UpdateLevels; import org.libspark.betweenas3.BetweenAS3; import org.libspark.betweenas3.easing.Bounce; import org.libspark.betweenas3.easing.Expo; import org.libspark.betweenas3.tweens.ITween; import com.bit101.components.*; import org.si.sion.events.*; import net.wonderfl.score.basic.*; public class Main extends Sprite { private const TOP_LEFT_MARGIN:int = 32; private const NEXT_TEXT_X:int = 257; private const NEXT_BOX_WIDTH:int = 90; private const NEXT_BOX_GAP:int = 12; private const MAIN_BLOCK_SIZE:int = 25; private const SMALL_BLOCK_SIZE:int = 12; private const LINE_BLOCKS:int = 8; private const ENEMY_LEFT_MARGIN:int =TOP_LEFT_MARGIN + 2 * NEXT_BOX_GAP + NEXT_BOX_WIDTH + MAIN_BLOCK_SIZE * LINE_BLOCKS; private const NEXT_BLOCK_X:int = 315; private const NEXT_BLOCK_Y:int = 102; private const ROOM_WIDTH:int = 180; private const ROOM_HEIGHT:int = 40; private const ROOM_X:int = 270; private const ROOM_Y:int = 32; private const ROOM_GAP:int = 10; private const ROOM_NUMBER:int = 8; private var r:Reactor = new Reactor(); private var roomObjs:Array = []; private var roomQualifier:String = "w.tso"; private var roomName:String = "g"; // g4_1 for room #5, player #2 private var gameRoomName:String = "w.tsop"; private var room:Room; private var playingRoom:Room; private var sion:SiON, pv3d:PV3D; private var screen:BitmapData = new BitmapData(465,465,false), canvas:Shape = new Shape(), g:Graphics = canvas.graphics; private var blockTextures:Vector.<BitmapData> = new Vector.<BitmapData>(7, true), dropBlock:BitmapData = new BitmapData(200, 200, true); private var blockSmallTextures:Vector.<BitmapData> = new Vector.<BitmapData>(7, true); private var scoreLabel:Label, levelLabel:Label, linesLabel:Label, msgb:Label, msgw:Label, msgs:Label , bsf:BasicScoreForm, bsrv:BasicScoreRecordViewer; private var nameLabel:Label, enemyLabel:Label, winsLabel:Label; private var msgbd:BitmapData = new BitmapData(200, 80, true, 0), mmat:Matrix=new Matrix(3,0,0,3), msg:Bitmap, messageTween:ITween; private var smat:Matrix=new Matrix(1.04,0,0,1.04,-4.65,-9.3), scolt:ColorTransform=new ColorTransform(); private var idField:Vector.<uint>=new Vector.<uint>(200), stockID:uint, nextID:uint, dropID:uint; private var eidField:Vector.<uint> = new Vector.<uint>(200); private var dropX:int, dropY:int, dropR:int, drawX:Number, drawY:Number, drawR:Number = 0.0, speed:Number; private var frameCount:int, phase:int, score:int, level:Number, lines:int, bestResult:*, wins:int; private var pt:Point=new Point(), rc:Rectangle = new Rectangle(), mat:Matrix = new Matrix(); private var keyPushed:int, keyPressed:int, slideCount:int, _joined:Boolean = false; private var delLineFlag:int, delLines:int, delChains:int, lineBrghtness:Number, scaleEffect:int; private var mainSprite:Sprite = new Sprite(); private var lobbySprite:Sprite = new Sprite(); private var challengerLabel:DisplayObject; private var youWonLabel:DisplayObject; private var tetromino:Array = [ Vector.<int>([0x0660, 0x0660, 0x0660, 0x0660, 4]), Vector.<int>([0x2222, 0x0f00, 0x4444, 0x00f0, 4]), Vector.<int>([0x0622, 0x0740, 0x4460, 0x02e0, 4]), Vector.<int>([0x0264, 0x0063, 0x0132, 0x0630, 3]), Vector.<int>([0x0644, 0x0470, 0x2260, 0x0e20, 4]), Vector.<int>([0x0462, 0x0036, 0x0231, 0x0360, 3]), Vector.<int>([0x0262, 0x0072, 0x0232, 0x0270, 3]) ]; public var backcolor:int; // controled by betweenas3 //---------------------------------------- main function Main() : void { _myName = loaderInfo.parameters["viewer.displayName"]; if ( _myName == null ) _myName = "Anonymous"; pv3d = new PV3D(); sion = new SiON(_onBeat, _onNoteOn); addEventListener(Event.ADDED_TO_STAGE, _onAddedToStage); addEventListener(Event.ENTER_FRAME, _onEnterFrame); r.addEventListener(ReactorEvent.READY, onReady); r.connect("tryunion.com", 80); } //---------------------------------------- handlers private function _onAddedToStage(e:Event) : void { //mainSprite.alpha = 0.5; stage.frameRate = 30; Style.LABEL_TEXT = 0x808080; Style.BUTTON_FACE = 0x404040; Style.PANEL = 0x404040; //Style.BACKGROUND addChild(new Bitmap(screen)); addChild(mainSprite); addChild(lobbySprite); for ( var i:int = 0; i < ROOM_NUMBER; i++ ) { var roomObj:RoomObject = new RoomObject(ROOM_WIDTH, ROOM_HEIGHT, i); lobbySprite.addChild(roomObj); roomObjs.push(roomObj); roomObj.addEventListener(MouseEvent.CLICK, onClick); roomObj.x = ROOM_X; roomObj.y = ROOM_Y + (ROOM_HEIGHT + ROOM_GAP) * i ; } lobbySprite.mouseChildren = false; if ( r.isReady() ) { _startWatching(); } else { _isWaitingForWatching = true; } _effectButton(225, 444).setSize(78, 18); _scoreButton(305, 444).setSize(78, 18); _tweetButton(385, 444).setSize(78, 18); _resetButton(2, 444).setSize(78, 18); challengerLabel = _makeLabel(mainSprite, "HERE COMES A NEW CHALLENGER!!", 2); youWonLabel = _makeLabel(mainSprite, "YOU WON!!", 3); new Label(mainSprite, NEXT_TEXT_X, TOP_LEFT_MARGIN, "NEXT"); new Label(mainSprite, NEXT_TEXT_X, TOP_LEFT_MARGIN + NEXT_BOX_WIDTH + NEXT_BOX_GAP, "STOCK"); nameLabel = _status(TOP_LEFT_MARGIN, 0, "PLAYING AS : " + _myName); enemyLabel = _status(257, 242, "ENEMY :"); winsLabel = _status(257, 282, "WINS :"); levelLabel = _status(257, 322, "LEVEL :"); scoreLabel = _status(257, 362, "SCORE :"); linesLabel = _status(257, 402, "LINES :"); msgs = new Label(this, 64, 260, ""); msgs.scaleX = msgs.scaleY = 1.5; msgs.visible = false; msgs.filters = [new GlowFilter(0, 0.6, 2, 2)]; Style.LABEL_TEXT = 0x404040; msgb = new Label(null, 64, 200, ""); Style.LABEL_TEXT = 0xc0c0c0; msgw = new Label(null, 64, 200, ""); addChild(msg = new Bitmap(msgbd)); msg.x = 32; msg.alpha = 0; phase = TITLE; _loadCookie(); _initialize(); _startTitle(); } private function _makeLabel(target:DisplayObjectContainer, label:String, scale:Number):DisplayObject { var temp:Sprite = new Sprite(); new Label(temp, 0, 0, label); var bmpData:BitmapData = _makeRedOutlinedBitmapData(temp); while ( temp.numChildren ) temp.removeChildAt(0); temp.addChild(new Bitmap( bmpData ) ); temp.scaleX = temp.scaleY = scale; temp.x = 466; temp.y = 200; return target.addChild(temp); } private function _makeRedOutlinedBitmapData(DO:DisplayObject):BitmapData { var tempBmp:BitmapData = new BitmapData(DO.width + 2, DO.height + 2, true, 0x0); tempBmp.draw(DO, new Matrix(1, 0, 0, 1, 1, 0), new ColorTransform(1, 0, 0)); tempBmp.draw(DO, new Matrix(1, 0, 0, 1, 1, 2), new ColorTransform(1, 0, 0)); tempBmp.draw(DO, new Matrix(1, 0, 0, 1, 0, 1), new ColorTransform(1, 0, 0)); tempBmp.draw(DO, new Matrix(1, 0, 0, 1, 2, 1), new ColorTransform(1, 0, 0)); tempBmp.draw(DO, new Matrix(1, 0, 0, 1, 1, 1)); return tempBmp; } private function _onEnterFrame(e:Event) : void { _drawBackground(); phaseMain[phase](); _drawField(); keyPushed = 0; lineBrghtness *= 0.9; ++frameCount; } private function _onKeyDown(e:KeyboardEvent) : void { keyPressed = keyPushed = e.keyCode; } private function _onKeyUp(e:KeyboardEvent) : void { keyPressed = 0; } // union private var _isWaitingForWatching:Boolean = false; private function onReady(e:ReactorEvent):void { stage.addEventListener(KeyboardEvent.KEY_DOWN, _onKeyDown); stage.addEventListener(KeyboardEvent.KEY_UP, _onKeyUp); r.getRoomManager().addEventListener(RoomManagerEvent.ROOM_ADDED, onRoomAdded); r.getRoomManager().addEventListener(RoomManagerEvent.ROOM_COUNT, onRoomCount); r.getRoomManager().addEventListener(RoomManagerEvent.WATCH_FOR_ROOMS_RESULT, onWatchForRoomsResult); r.self().setAttribute("name", _myName); if ( _isWaitingForWatching ) _startWatching(); _isWaitingForWatching = false; } private var _roomNum:Number = 0; private function onRoomCount(e:RoomManagerEvent):void { _roomNum = r.getRoomManager().getNumRooms(roomQualifier); if ( _roomNum == _observingRoomNum ) { _lobbyReady(); } } private function _lobbyReady():void { for ( var i:int = 0; i < ROOM_NUMBER; i++ ) { var roomIndex:int = i; var roomObj:RoomObject = roomObjs[roomIndex]; var room:Room = r.getRoomManager().getRoom(roomQualifier+"."+roomName+i+"_0"); if ( !room ) { roomObj.setPlayer1(null, null); } else { var clients:Array = room.getOccupants(); if ( clients.length == 0 ) { roomObj.setPlayer1(null, null); } else { roomObj.setPlayer1(IClient(clients[0]).getAttribute("name"), IClient(clients[0]).getAttribute("wins")); } } room = r.getRoomManager().getRoom(roomQualifier+"."+roomName+i+"_1"); if ( !room ) { roomObj.setPlayer2(null, null); } else { clients = room.getOccupants(); if ( clients.length == 0 ) { roomObj.setPlayer2(null, null); } else { roomObj.setPlayer2(IClient(clients[0]).getAttribute("name"), IClient(clients[0]).getAttribute("wins")); } } } lobbySprite.mouseChildren = true; } // room join private function onClick(e:MouseEvent):void { _message("TETRISizer\nOnline", null, "Starting..."); lobbySprite.mouseChildren = false; var roomObj:RoomObject = RoomObject(e.target); var roomSettings:RoomSettings = new RoomSettings(); roomSettings.removeOnEmpty = true; roomSettings.maxClients = 1; if ( room && room.clientIsInRoom(r.self().getClientID()) ) { return; } room = r.getRoomManager().createRoom(roomQualifier + "." + roomName + roomObj.index +"_0" , roomSettings); room.addEventListener(RoomEvent.JOIN_RESULT, onJoinResult); room.join(); } private function onJoinResult(e:RoomEvent):void { var roomSettings:RoomSettings = new RoomSettings(); roomSettings.removeOnEmpty = true; roomSettings.maxClients = 1; switch( e.getStatus() ) { case Status.SUCCESS: _onJoin(Room(e.target).getRoomID().substr(roomQualifier.length + roomName.length + 1).split("_")[0]); break; default: room = r.getRoomManager().createRoom(Room(e.target).getRoomID().split("_")[0]+"_1", roomSettings); room.addEventListener(RoomEvent.JOIN_RESULT, onJoinResult2); room.join(); break; } } private function onJoinResult2(e:RoomEvent):void { switch( e.getStatus() ) { case Status.SUCCESS: _onJoin(Room(e.target).getRoomID().substr(roomQualifier.length + roomName.length + 1).split("_")[0]); break; default: lobbySprite.mouseChildren = true; _message("TETRISizer\nOnline", null, "Choose a room to join!"); break; } } private function _onJoin(roomIndex:String):void { var i:int; for (i=0; i<200; i++) eidField[i] = idField[i] = (i%10==0 || i%10==9 || i<10 || i>=190) ? 0xfffffff8 : 0; playingRoom = r.getRoomManager().createRoom(gameRoomName + roomIndex); playingRoom.addEventListener(RoomEvent.JOIN, onGameRoomJoin); playingRoom.addEventListener(RoomEvent.ADD_OCCUPANT, onAddOccupant); playingRoom.addEventListener(RoomEvent.REMOVE_OCCUPANT, onRemoveOccupant); playingRoom.addMessageListener("LOG", onLog); playingRoom.addMessageListener("CHANGE", onChange); playingRoom.addMessageListener("ERASE", onErase); playingRoom.addMessageListener("LOSE", onLose); playingRoom.addMessageListener("ATTACKED", onAttacked); playingRoom.join(); _isPlaying = false; } private function onAttacked(from:IClient, x:String, lines:String):void { var i:int = int(lines); while( i-- ) _attacked(eidField, int(x)); } private function onGameRoomJoin(e:RoomEvent):void { _joined = true; _updateGameRoom(playingRoom); } private function onRemoveOccupant(e:RoomEvent):void { _updateGameRoom(Room(e.target)); } private function onAddOccupant(e:RoomEvent):void { _updateGameRoom(Room(e.target)); if ( !e.getClient().isSelf() ) { playingRoom.sendMessage("LOG", false, null, makeLogMessage(idField)); if ( _isPlaying && score != 0) { _showChallengerLabel(); } } else { _isPlaying = true; } } private function _showChallengerLabel():void { BetweenAS3.serial( BetweenAS3.func(function():void { sion.se(3, 2, 2, 1); }), BetweenAS3.tween(challengerLabel, { x:0.5 * (stage.stageWidth - challengerLabel.width) }, { x:466 }, 1.0, Expo.easeOut), BetweenAS3.tween(challengerLabel, { transform: { colorTransform: { redOffset: 255, blueOffset: 255, greenOffset: 255 }}}, null, 0.125), BetweenAS3.tween(challengerLabel, { transform:{colorTransform: {redOffset: 0, blueOffset: 0, greenOffset: 0}}}, null, 0.125), BetweenAS3.tween(challengerLabel, { x: -465 }, null, 1.0, Expo.easeIn) ).play(); } private function _showYouWonLabel():void { BetweenAS3.serial( BetweenAS3.func(function():void { sion.se(4, 2, 5, 1); }), BetweenAS3.tween(youWonLabel, { x:0.5 * (stage.stageWidth - youWonLabel.width) }, { x:466 }, 1.0, Expo.easeOut), BetweenAS3.tween(youWonLabel, { transform: { colorTransform: { redOffset: 255, blueOffset: 255, greenOffset: 255 }}}, null, 0.125), BetweenAS3.tween(youWonLabel, { transform:{colorTransform: {redOffset: 0, blueOffset: 0, greenOffset: 0}}}, null, 0.125), BetweenAS3.tween(youWonLabel, { x: -465 }, null, 1.0, Expo.easeIn) ).play(); } private function makeLogMessage(field:Vector.<uint>):String { var str:String = ""; str = field.join(","); return str; } private function _updateGameRoom(room:Room):void { var occupants:Array = room.getOccupants(); if ( occupants.length > 1 ) { _enemyExist = true; _enemyName = IClient(occupants[0]).isSelf()?IClient(occupants[1]).getAttribute("name"):IClient(occupants[0]).getAttribute("name"); } else { _enemyExist = false; _enemyName = null; } _updateStatus(); } private function onLose(from:IClient, msg:String):void { wins ++; r.self().setAttribute("wins", String(wins)); _showYouWonLabel(); level += 1.0; score += Number(msg); sion.measure = int(level); pv3d.measure = int(level); _updateStatus(); if (level >= 32) _changePhase(CLEAR); } private function onErase(from:IClient, msg:String):void { var ys:Array = msg.split(","); for ( var i:int = 0; i < ys.length; i++ ) for (var x:int = 0; x < 8; x++) eidField[ys[i] * 10 + x + 31] = 0; _attackedLines += ys.length - 1; sion.se(1, 5, 6, 1); } private var _attackedLines:int = 0; private function onChange(from:IClient, msg:String):void { var changes:Array = msg.split(","); for each( var change:String in changes ) { var iAndValue:Array = change.split(":"); eidField[int(iAndValue[0])] = uint(iAndValue[1]); } } private function onLog(from:IClient, msg:String):void { var vec:Array = msg.split(","); var count:int = vec.length; var str:String = ""; for ( var i:int = 0; i < count; i++ ) { eidField[i] = vec[i]; } } private function onRoomAdded(e:RoomManagerEvent):void { if( e.getRoomIdQualifier() == roomQualifier ) _observeRoom(e.getRoomID()); } private function _observeRoom(roomID:String):void { var updateLevels:UpdateLevels = new UpdateLevels(); updateLevels.clearAll(); updateLevels.occupantList = true; updateLevels.sharedOccupantAttributesGlobal = true; var room:Room = r.getRoomManager().getRoom(roomID); room.addEventListener(RoomEvent.OBSERVE, onObserve); room.addEventListener(RoomEvent.REMOVED, onRemoved); room.addEventListener(RoomEvent.UPDATE_CLIENT_ATTRIBUTE, onUpdate); room.observe(null, updateLevels); } private function onUpdate(e:RoomEvent):void { if ( e.getChangedAttr().name == "wins" ) { _lobbyReady(); } } private var _observingRoomNum:Number = 0; private function onRemoved(e:RoomEvent):void { _roomNum = r.getRoomManager().getNumRooms(roomQualifier); _observingRoomNum--; if ( _observingRoomNum == _roomNum ) { _lobbyReady(); } } private function onObserve(e:RoomEvent):void { _observingRoomNum++; if ( _observingRoomNum == _roomNum ) { _lobbyReady(); } } private function _startWatching():void { r.getRoomManager().watchForRooms(roomQualifier); } private function onWatchForRoomsResult(e:RoomManagerEvent):void { // maybe SUCCESS.. if ( _roomNum == r.getRoomManager().getNumRooms(roomQualifier) ) { _lobbyReady(); } } //---------------------------------------- SiON events private function _onBeat(e:SiONTrackEvent) : void { lineBrghtness = 1; pv3d.tick(); } private function _onNoteOn(e:SiONTrackEvent) : void { if (e.eventTriggerID == 1) _whiteOut(); } //---------------------------------------- UI private function _status(x:Number, y:Number, label:String, target:DisplayObjectContainer = null) : Label { var inst:Label = new Label(target?target:mainSprite, x, y, label); inst.scaleX = inst.scaleY = 2; inst = new Label(target?target:mainSprite, x+90, y, ""); inst.scaleX = inst.scaleY = 2; return inst; } private function _resetButton(x:Number, y:Number) : PushButton { return new PushButton(this, x, y, "CLEAR COOKIE", function(e:Event) : void { var so:SharedObject = SharedObject.getLocal("savedData"); if (so) so.clear(); bestResult = {"wins":wins, "score":score, "level":level, "lines":lines}; if (phase == TITLE) { wins = lines = level = score = 0; _updateStatus(); } }); } private function _effectButton(x:Number, y:Number) : PushButton { return new PushButton(this, x, y, "EFFECT ON", function(e:Event) : void { e.target.label = _swapEffect() ? "EFFECT ON" : "EFFECT OFF"; }); } private function _scoreButton(x:Number, y:Number) : PushButton { return new PushButton(this, x, y, "SHOW RANKING", __showRanking); } private function __showRanking(e:Event) : void { new BasicScoreRecordViewer(this, 122.5, 112.5,'RANKING', 30, true); } private function _tweetButton(x:Number, y:Number) : PushButton { return new PushButton(this, x, y, "TWEET SCORE", function(e:Event) : void { navigateToURL(new URLRequest("http://twitter.com/home/?status=" + escapeMultiByte("[SiON TETRISizer Online] wins:"+ String(wins) +" score:" + String(score) + " http://wonderfl.net/c/cifX/ #TETRISizerOnline")), "_blank"); }); } //---------------------------------------- drawings private function _drawBackground() : void { g.clear(); var col:int = backcolor * 0x10101; if (scaleEffect > 0) { smat.tx = -4.65-scaleEffect*2+25; scolt.alphaMultiplier = ((scaleEffect>12) ? (25-scaleEffect) : scaleEffect)*0.04; screen.draw(screen, smat, scolt); --scaleEffect; g.beginFill(col, 0.1); } else g.beginFill(col, 0.25); g.drawRect(0, 0, 465, 465); g.endFill(); if (backcolor > 0) { g.beginFill(0x000000, backcolor * 0.001953125); g.drawRect(32, 32, 200, 400); g.endFill(); } pv3d.update(); screen.draw(pv3d); col = (int(lineBrghtness*63))*0x20304; if ( !mainSprite.visible ) { for ( var i:int = 0; i < 8; i++ ) { __drawVoidRect( ROOM_X, (ROOM_GAP+ROOM_HEIGHT)* i +ROOM_Y, ROOM_WIDTH, ROOM_HEIGHT, col); } } else { __drawVoidRect( TOP_LEFT_MARGIN, TOP_LEFT_MARGIN, 200, 400, col); __drawVoidRect( TOP_LEFT_MARGIN + 200 + NEXT_BOX_GAP, TOP_LEFT_MARGIN, NEXT_BOX_WIDTH, NEXT_BOX_WIDTH, col); __drawVoidRect( TOP_LEFT_MARGIN + 200 + NEXT_BOX_GAP, TOP_LEFT_MARGIN + NEXT_BOX_WIDTH + NEXT_BOX_GAP, NEXT_BOX_WIDTH, NEXT_BOX_WIDTH, col); __drawVoidRect( ENEMY_LEFT_MARGIN, TOP_LEFT_MARGIN, 96, 192, col); } screen.draw(canvas); } private function _drawField() : void { var dx:int, dy:int, x:int, y:int, f:int, id:uint, b:int, col:int; if ( !mainSprite.visible ) { return; } b = tetromino[col = (nextID & 7) - 1][dropR]; dy = tetromino[col][4] * 12.5; for (f=1, y=0; y<4; y++) for (x=0; x<4; x++, f<<=1) if (b & f) __drawSmallBlock(screen, col, x * SMALL_BLOCK_SIZE + NEXT_BLOCK_X- dy, y * SMALL_BLOCK_SIZE + NEXT_BLOCK_Y - dy); col = (stockID & 7) - 1; b = tetromino[col][dropR]; dy = tetromino[col][4] * 12.5; for (f = 1, y = 0; y < 4; y++) for (x = 0; x < 4; x++, f <<= 1) if (b & f) __drawSmallBlock(screen, col, x * SMALL_BLOCK_SIZE + NEXT_BLOCK_X - dy, y * SMALL_BLOCK_SIZE + NEXT_BLOCK_Y + NEXT_BOX_WIDTH + NEXT_BOX_GAP - dy); if (phase == MOVE) { dy = tetromino[(dropID & 7) - 1][4] * 12.5; mat.identity(); mat.translate(-dy, -dy); mat.rotate(-drawR * 1.5707963267948965); mat.translate((drawX - 1) * MAIN_BLOCK_SIZE + dy + 32, (drawY - 1) * MAIN_BLOCK_SIZE + dy + 32); screen.draw(dropBlock, mat); } col = (int(lineBrghtness*63))*0x20304; for (y=0; y<16; y++) for (x=0; x<8; x++) { id = idField[y*10+x+31]; __drawBlock(screen, (id & 7) - 1, dx = x * MAIN_BLOCK_SIZE + TOP_LEFT_MARGIN, dy = y * MAIN_BLOCK_SIZE + TOP_LEFT_MARGIN); if (id != idField[y*10+x+21] ) __drawRect(dx-1, dy-1, 27, 3, col); if (id != idField[y * 10 + x + 30]) __drawRect(dx - 1, dy - 1, 3, 27, col); // enemy if( _enemyExist ){ id = eidField[y*10+x+31]; __drawSmallBlock(screen, (id & 7) - 1, dx = x * SMALL_BLOCK_SIZE + ENEMY_LEFT_MARGIN, dy = y * SMALL_BLOCK_SIZE + TOP_LEFT_MARGIN); if (id != eidField[y*10+x+21] ) __drawRect(dx-1, dy-1, 14, 3, col); if (id != eidField[y * 10 + x + 30]) __drawRect(dx - 1, dy - 1, 3, 14, col); } } } private function _updateDropBlock() : void { var x:int, y:int, f:int, col:int = (dropID&7)-1, b:int = tetromino[col][dropR]; dropBlock.fillRect(dropBlock.rect, 0); for (f=1, y=0; y<4; y++) for (x=0; x<4; x++, f<<=1) if (b & f) __drawBlock(dropBlock, col, x * 25, y * 25); } private function __drawBlock(bd:BitmapData, col:int, dx:Number, dy:Number) : void { if (col == -1) return; pt.x = dx; pt.y = dy; bd.copyPixels(blockTextures[col], blockTextures[col].rect, pt); } private function __drawSmallBlock(bd:BitmapData, col:int, dx:Number, dy:Number) : void { if (col == -1) return; pt.x = dx; pt.y = dy; bd.copyPixels(blockSmallTextures[col], blockSmallTextures[col].rect, pt); } private function __drawVoidRect(x:Number, y:Number, w:Number, h:Number, col:int) : void { __drawRect(x-1, y-1, w+2, 3, col); __drawRect(x-1, y-1, 3, h+2, col); __drawRect(x+1, y+h-1, w, 3, col); __drawRect(x+w-1, y+1, 3, h, col); } private function __drawRect(x:Number, y:Number, w:Number, h:Number, col:int) : void { rc.x = x; rc.y = y; rc.width = w; rc.height = h; screen.fillRect(rc, col); } //---------------------------------------- texts private function _updateStatus() : void { enemyLabel.text = _enemyExist?_enemyName:""; winsLabel.text = ("00"+String(wins)).substr(-3, 3); scoreLabel.text = ("0000000000"+String(score)).substr(-8, 8); levelLabel.text = ("0"+String(int(level))).substr(-2, 2) + "/32"; linesLabel.text = ("00"+String(lines)).substr(-3, 3); } private function _message(text:String, subText:String=null, smallText:String=null) : void { msgbd.fillRect(msgbd.rect, 0); $(text, 0); if (subText) $(subText, 32); msg.y = (smallText) ? 160 : 200; if (messageTween && messageTween.isPlaying) messageTween.stop(); messageTween = BetweenAS3.to(msg, {"alpha":1}, 0.3); messageTween.play(); if (msgs.visible = (smallText != null)) { msgs.text = smallText; msgs.draw(); msgs.x = 132 - msgs.width * 0.75; msgs.y = 280; } function $(text:String, y:Number) : void { msgb.text = msgw.text = text; msgb.draw(); msgw.draw(); var w:Number = msgw.width * 1.5; _(msgb, 103 - w, y); _(msgb, 97 - w, y); _(msgb, 100 - w, y - 3); _(msgb, 100 - w, y + 3); _(msgw, 100 - w, y); function _(l:Label, x:Number, y:Number) : void { mmat.tx = x; mmat.ty = y; msgbd.draw(l, mmat); } } } private function _messageOff() : void { msgs.visible = false; if (messageTween && messageTween.isPlaying) messageTween.stop(); messageTween = BetweenAS3.to(msg, {"alpha":0}, 0.3); messageTween.play(); } //---------------------------------------- motions private function _slideAndRotate(dx:int, r:int) : void { if (_check(dx+dropX, dropY, (dropR + r) & 3) && (dropY-drawY<0.3 || _check(dx+dropX, dropY-1, (dropR + r) & 3))) { dropX += dx; dropR = (dropR + r) & 3; if (r != 0) _updateDropBlock() } } private function _stack() : void { var x:int, y:int, f:int, b:int = tetromino[(dropID & 7) - 1][dropR]; var str:String = ""; for (f = 1, y = 0; y < 4; y++) for (x = 0; x < 4; x++, f <<= 1) if (b & f) { idField[(y + dropY - 1) * 10 + x + dropX + 30] = dropID; str += ((y + dropY - 1) * 10 + x + dropX + 30) + ":" + dropID + ","; } playingRoom.sendMessage("CHANGE", false, null, str.substr(0,str.length-1)); sion.se(0); _changePhase(DELETE); } //---------------------------------------- evaluations private function _check(x_:int, y_:int, r_:int) : Boolean { var x:int, y:int, f:int, b:int = tetromino[(dropID&7)-1][r_]; for (f=1, y=0; y<4; y++) for (x=0; x<4; x++, f<<=1) if ((b & f) && idField[(y+y_-1)*10+x+x_+30] != 0) return false; return true; } private function _checkLine() : int { var x:int, y:int; for (delLineFlag=0, y=0; y<16; y++) { for (x=0; x<8; x++) if (idField[y*10+x+31] == 0) break; if (x == 8) delLineFlag |= 1<<y; } return delLineFlag; } private var dropData:String; private function _dropLine() : Boolean { dropData = ""; var x:int, y:int, ret:Boolean = false; for (y = 15; y >= 0; y--) for (x = 0; x < 8; x++) if (__checkDropBlock(y * 10 + x + 31)) { idField[y * 10 + x + 31] |= 0x80000000; dropData += (y * 10 + x + 31) + ":" + idField[y * 10 + x + 31] + ","; } for (y=15; y>=0; y--) for (x=0; x<8; x++) if (idField[y*10+x+31] & 0x80000000) { idField[y*10+x+41] = idField[y*10+x+31] & 0x7fffffff; idField[y*10+x+31] = 0; dropData += (y*10+x+41) + ":" + idField[y*10+x+41] + "," + (y*10+x+31) + ":0,"; ret = true; } if( dropData.length > 0 ) playingRoom.sendMessage("CHANGE", false, null, dropData.substr(0,dropData.length-1)); return ret; } private function __checkDropBlock(idx:int) : Boolean { if (idField[idx] == 0) return false; var id:uint = idField[idx], ret:Boolean; idField[idx] |= 0x80000000; ret = ((idField[idx+10] == 0 || idField[idx+10] == idField[idx]) && (idField[idx-1] != id || __checkDropBlock(idx-1)) && (idField[idx+1] != id || __checkDropBlock(idx+1)) && ((id&7) == 1 || idField[idx-10] != id || __checkDropBlock(idx-10))); { var temp:uint = idField[idx]; idField[idx] &= 0x7fffffff; if( temp != idField[idx] ) dropData += idx + ":" + idField[idx] + ","; } return ret; } //---------------------------------------- procedures private function _loadCookie() : void { var so:SharedObject = SharedObject.getLocal("savedData"); bestResult = (so && "bestResult" in so.data) ? (so.data.bestResult) : {"wins":0, "score":0, "level":0, "lines":0}; } private function _initialize() : void { FMath.randomSeed(uint(new Date().getTime())); nextID = FMath.random(8, 1) + 16; stockID = FMath.random(8, 1) + 8; lines = level = score = 0; lineBrghtness = 1; scaleEffect = 0; backcolor = 0; __createTexture(); _updateStatus(); } private function __createTexture() : void { for (var i:int=0; i<7; i++) { mat.createGradientBox(25, 25, 0.7853981633974483, 0, 0); g.clear(); g.beginGradientFill("linear", [FColor.HSVtoValue(45*i,0.25,1), FColor.HSVtoValue(45*i,0.75,0.75)], [0.375, 0.375], [0, 255], mat); g.drawRect(0, 0, 25, 25); blockTextures[i] = new BitmapData(25, 25, true, 0); blockTextures[i].draw(canvas); g.clear(); g.beginGradientFill("linear", [FColor.HSVtoValue(45*i,0.25,1), FColor.HSVtoValue(45*i,0.75,0.75)], [0.375, 0.375], [0, 255], mat); g.drawRect(0, 0, 12, 12); blockSmallTextures[i] = new BitmapData(12, 12, true, 0); blockSmallTextures[i].draw(canvas); } } private function _nextBlock() : void { if( _attackedLines > 0 ){ x = 1 + int(Math.random() * 8); playingRoom.sendMessage("ATTACKED", false, null, x, _attackedLines); while ( _attackedLines ) { _attackedLines--; _attacked(idField, x); } } dropID = nextID; nextID = ((nextID & 0x7ffffff8) + 8) | FMath.random(8, 1); _updateDropBlock(); dropX = drawX = 3; dropY = drawY = 0; speed = lines * 0.001 - int(level/10) * 0.003 + 0.01; slideCount = 0; if (!_check(dropX, dropY, dropR)) _changePhase(GAMEOVER); } private function _flipBlock() : void { var id:uint = dropID; dropID = stockID; if (_check(dropX, dropY, dropR)) { stockID = id; _updateDropBlock(); } else dropID = id; sion.se(0); } private function _swapEffect() : Boolean { _effect = !_effect; if (!_effect) pv3d.filters = null; return _effect; } private function _whiteOut() : void { BetweenAS3.to(this, {"backcolor":255}, 60/132*8).play(); } private function _blackOut() : void { BetweenAS3.to(this, {"backcolor":0}, 1.5).play(); } //---------------------------------------- phases private var TITLE:int=0, INTRO:int=1, MOVE:int=2, DELETE:int=3, GAMEOVER:int=4, CLEAR:int=5, RESULT:int=6, nextPhase:int = -1; private var phaseStart:Array = [_startTitle, _startIntro, _startMove, _startDelete, _startGameover, _startClear, _startResult]; private var phaseMain:Array = [_phaseTitle, _phaseIntro, _phaseMove, _phaseDelete, _returnToTitle, _returnToTitle, _doNothing]; private var phaseEnd:Array = [_endTitle, _endIntro, _endMove, _doNothing, _doNothing, _doNothing, _doNothing]; private function _doNothing() : void {} private var sendStr:String = ""; private function _changePhase(p:int) : void { if (nextPhase == -1) { nextPhase = p; phaseEnd[phase](); frameCount = 0; keyPushed = 0; do { phase = nextPhase phaseStart[phase](); } while (phase != nextPhase); nextPhase = -1; } else { nextPhase = p; } } //---------------------------------------- TITLE phase private function _startTitle() : void { mainSprite.visible = false; lobbySprite.visible = !mainSprite.visible; sion.start(); wins = bestResult.wins; score = bestResult.score; level = bestResult.level; lines = bestResult.lines; _updateStatus(); _message("TETRISizer\nOnline", null, "Choose a room to join!"); } private function _phaseTitle() : void {if (_joined) { _joined = false; _changePhase(INTRO); mainSprite.visible = true; lobbySprite.visible = !mainSprite.visible;} } private function _endTitle() : void { _initialize(); } //---------------------------------------- INTRO phase private function _startIntro() : void { _message("? Ready ?"); } private function _phaseIntro() : void { if (frameCount == 36) _message("! Go !"); else if (frameCount == 72) _changePhase(MOVE); } private function _endIntro() : void { _messageOff(); } //---------------------------------------- MOVE phase private function _startMove() : void { _nextBlock(); } private function _phaseMove() : void { drawY += (keyPressed == 40) ? 0.5 : speed; var y:int = int(drawY + 0.9999847412109375); if (y != dropY) { if (_check(dropX, dropY+1, dropR)) dropY = y; else { drawY = dropY = y - 1; slideCount += (keyPressed==40) ? 10 : 1; if (slideCount > 30)_stack(); } } if (keyPushed == 67) _flipBlock(); else if (keyPushed == 38) { while(_check(dropX, dropY+1, dropR)) dropY++; score += 30-dropY; _updateStatus(); _stack(); } else if (keyPushed) { drawR = dropR; _slideAndRotate(int(keyPushed==39)-int(keyPushed==37), int(keyPushed==90)-int(keyPushed==88)); drawR -= dropR; if (drawR == 3) drawR = -1; else if (drawR == -3) drawR = 1; sion.se(keyPushed, dropX*16-56); } drawX += (dropX - drawX) * 0.6; drawR *= 0.5; } private function _endMove() : void { delChains = delLines = 0; } //---------------------------------------- DELETE phase private function _startDelete() : void { if (_checkLine()) { var eraseData:String = ""; for (var y:int = 0; y < 16; y++) if (delLineFlag & (1 << y)) { eraseData += y + ","; delLines++; for (var x:int=0; x<8; x++) idField[y*10+x+31] = 0; } if( eraseData.length > 0 ) playingRoom.sendMessage("ERASE", false, null, eraseData.substr(0,eraseData.length-1)); delChains++; if (_effect) scaleEffect = 25; _message("! "+String(delLines)+" Lines !", String(delChains)+" Combo"); sion.se(1, 0, 8, 4); } else { if (delLines > 0) { score += (delLines * delLines + delChains * delChains) * ((level>23) ? 200 : 100); lines += delLines; level += 0.1 + 0.1 * int(level/4); _updateStatus(); } _messageOff(); if ( level >= 32 ) _changePhase(CLEAR); else _changePhase(MOVE); } } private function _attacked(target:Vector.<uint>, ax:int):void { for ( var y:int = 2; y < 18; y++ ) { for ( var x:int = 1; x < 9; x++ ) { target[y * 10 + x] = target[y * 10 + x + 10]; } } for ( x = 1; x < 9; x++ ) { if ( x != ax ) target[180 + x] = (ax) % 7 + 1; else target[180 + x] = 0; } } private function _phaseDelete() : void { if (frameCount < 16) for (var y:int=0; y<16; y++) if (delLineFlag & (1<<y)) { g.clear(); g.beginFill(0xffffff, frameCount*0.0625); g.drawRect(32, y*25+32, 200, 25); screen.draw(canvas); } if (frameCount > 12 && !_dropLine()) _changePhase(DELETE); } //---------------------------------------- GAMEOVER phase private function _startGameover() : void { _blackOut(); sion.end(); pv3d.end(); _message("GAME OVER", null, "Press any key"); playingRoom.sendMessage("LOSE", false, null, score * 0.5); playingRoom.leave(); room.leave(); } //---------------------------------------- CLEAR phase private function _startClear() : void { _blackOut(); sion.end(); pv3d.end(); _message("! FINISH !", null, "Press any key"); playingRoom.leave(); room.leave(); } private function _returnToTitle() : void { if (frameCount>30 && keyPushed) _changePhase(RESULT); } //---------------------------------------- RESULT phase private function _startResult() : void { if (score > bestResult.score) { _messageOff(); bestResult = {"wins":wins, "score":score, "level":level, "lines":lines}; var so:SharedObject = SharedObject.getLocal("savedData"); if (so) { so.data.bestResult = bestResult; so.flush(); } bsf = new BasicScoreForm(this, 92.5, 152.5, score, 'HI SCORE !', _onCloseBSF); bsf.onCloseClick = _onCloseBSF; } else _changePhase(TITLE); } private function _onCloseBSF(succeeded:Boolean = false) : void { if (bsf != null) removeChild(bsf); bsrv = new BasicScoreRecordViewer(this, 122.5, 112.5,'RANKING', 30, true, _onCloseBSRV); bsf = null; } private function _onCloseBSRV() : void { if (bsrv != null) removeChild(bsrv); bsrv = null; _changePhase(TITLE); } } } //---------------------------------------- global variables var _effect:Boolean = true; var _enemyExist:Boolean = false; var _enemyName:String = ""; var _myName:String = ""; var _isPlaying:Boolean = false; // View Class import flash.display.*; import com.bit101.components.*; class RoomObject extends Sprite { private var _playerNum:int = 0; private var _index:int = 0; private var _p1label:Label; private var _p2label:Label; private var _p1:int = -1; private var _p2:int = -1; private var _width:Number; private var _height:Number; public function RoomObject(width:Number, height:Number, index:int) { _width = width; _height = height; _index = index; _p1label = new Label(this, 5, 0, "loading..."); _p2label = new Label(this, 5, 20, "loading..."); setBG(0x0); } public function setPlayer1(name:String, wins:String ):void { if ( name ) { _p1 = int(wins); _p1label.text = "PLAYER 1: (" + _p1 + ")" + name; } else { _p1 = -1; _p1label.text = "empty"; } _updateNum(); } public function setPlayer2(name:String, wins:String ):void { if ( name ) { _p2 = int(wins); _p2label.text = "PLAYER 2: (" + _p2 + ")" + name; } else { _p2 = -1; _p2label.text = "empty"; } _updateNum(); } private function _updateNum():void { _playerNum = 0; if ( _p1 >= 0 ) { _playerNum++; } if ( _p2 >= 0 ) { _playerNum++; } if ( _playerNum == 2 ) { setBG(0xFF0000); this.mouseChildren = this.mouseEnabled = this.buttonMode = false; } else { setBG(0x0000FF); this.mouseChildren = this.mouseEnabled = this.buttonMode = true; } } public function setBG(col:uint):void { this.graphics.clear(); this.graphics.beginFill(col, 0.2); this.graphics.drawRect(0, 0, _width, _height); this.graphics.endFill(); } public function get index():int { return _index; } } //---------------------------------------- SiON import org.si.sion.*; import org.si.sion.events.*; import org.si.sion.effector.*; import org.si.sion.sequencer.*; import org.si.sound.*; import org.si.sound.synthesizers.*; class SiON extends SiONDriver { private var bs:BassSequencer = new BassSequencer("o3C", 15); private var dm:DrumMachine = new DrumMachine(0,0,0,2,2,2); private var back:SiONData, fill:SiONData, fill2:SiONData; private var analogSynth:AnalogSynth = new AnalogSynth(); function SiON(onBeat:Function, onNoteOn:Function) : void { super(); setVoice(0, new SiONVoice(5,2,63,63,-10,0,2,20)); back = compile("#EFFECT1{delay312,30,1};%5@0,40@v64,32q1s24$o6b-r2.;"); fill = compile("#A=o7[crgrfrcrgrfcrgfr];r1^1%6@0l16@v32,16q8$A(7)A(5);%2@f0,2,16q8s20@0,10%t1,1,0c1^1^8;%2q0s32l16v4[cc(]16;@v128%5@5q0s32,-128o3$c;");//) fill2= compile("#A=o7[drargrdrargaragr];%6@0l16@v16,8q8$AA"); bpm = 132; setSamplerData(0, render("%2@v128q0s32o4g16")); setSamplerData(1, render("#A=%6@0q0s20o3c*<<<g;A;kt7A")); setSamplerData(2, render("t160;#A=@v96q0s32l32o7e-crb-;A")); setSamplerData(3, render("t160;#A=%1@1@v128p2q0s32l32o5c<fcr<gb-frrb-16b-16;k4A;k-4A")); setSamplerData(4, render("t160;#A=@v128p2@al2i1@dt760q0s32l32o5cg<cf<ag>b-e-b-<e->>acagv11abv10adv8adv7adv6adv5adv4ad;k4A;k-4A")); setSamplerData(5, render("t160;#A=@v128p2@al2i1@dt760q0s32l32o5b;k-4A")); setSamplerData(6, render("t160;#A=@v128p2@al2i1@dt760q0s32l32o5c;k-4A")); setSamplerData(37, render("%6@0o7q8l64cb-f")); setSamplerData(39, render("%6@0o7q8l64gcd")); setSamplerData(88, render("%6@0o4q8l32g*<<g")); setSamplerData(90, render("%6@0o4q8l32f*<<f")); addEventListener(SiONTrackEvent.BEAT, onBeat); addEventListener(SiONTrackEvent.NOTE_ON_FRAME, onNoteOn); addEventListener(SiONEvent.STREAM_STOP, _onStreamStop); dm.volume = 0.6; bs.synthesizer = analogSynth; bs.volume = 0.4; analogSynth.setVCAEnvelop(0, 0.3, 0.7, 0.2); analogSynth.setVCFEnvelop(0.4, 0.3, 0.1, 0.6, 0.7); } public function set measure(m:int) : void { switch (m) { case 1: dm.bass.mute = false; break; case 4: dm.hihat.mute = false; break; case 8: bs.mute = false; bs.fadeIn(16); break; case 10: bpm = 105; break; case 12: bpm = 110; analogSynth.setVCFEnvelop(0.45, 0.3, 0.1, 0.6, 0.75); break; case 14: bpm = 115; analogSynth.setVCFEnvelop(0.5, 0.3, 0.1, 0.6, 0.8); break; case 16: bpm = 120; analogSynth.setVCFEnvelop(0.55, 0.3, 0.1, 0.6, 0.85); break; case 18: bpm = 125; analogSynth.setVCFEnvelop(0.6, 0.3, 0.1, 0.6, 0.85); break; case 20: bpm = 132; dm.snare.mute = false; dm.hihatPatternNumber = 2; break; case 24: sequenceOn(fill, null, 0, 0, 16); break; case 28: sequenceOn(fill2, null, 0, 0, 16); break; } } public function start() : void { bpm = 100; fadeIn(4); play(back); dm.snarePatternNumber = 0; dm.hihatPatternNumber = 13; dm.snare.mute = true; dm.hihat.mute = true; dm.bass.mute = true; bs.mute = true; dm.play(); bs.play(); } public function end() : void { fadeOut(4); } public function se(i:int, pan:int=0, len:int=0, qnt:int=1) : void { var t:SiMMLTrack = playSound(i, len, 0, qnt); t.effectSend1 = 32; t.pan = pan; } private function _onStreamStop(e:SiONEvent) : void { bs.stop(); dm.stop(); } } //---------------------------------------- PV3D import flash.events.Event; import flash.filters.GlowFilter; import org.libspark.betweenas3.BetweenAS3; import org.libspark.betweenas3.tweens.ITween; import org.papervision3d.materials.shadematerials.FlatShadeMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.lights.PointLight3D; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.view.BasicView; import org.papervision3d.core.math.Number3D; import org.papervision3d.core.geom.renderables.*; class PV3D extends BasicView { public var light:PointLight3D = new PointLight3D(), scale:Number, glows:Array = []; public var cube:Cube = new Cube(new MaterialsList({all:new FlatShadeMaterial(light, 0x203040, 0x000000)}),60,60,60,3,3,3); public var nvs:Vector.<Number3D> = new Vector.<Number3D>(cube.geometry.vertices.length); public var cbs:Vector.<Number3D> = new Vector.<Number3D>(cube.geometry.vertices.length); public var s:Vector.<Number> = new Vector.<Number>(cube.geometry.vertices.length); public var omegaX:Number=0.2, omegaY:Number=0.4, omegaZ:Number=0.7, omegaTween:ITween=null; function PV3D() { glows.push(new GlowFilter(0x405080,1,4,4)); glows.push(new GlowFilter(0x405080,1,8,8)); glows.push(new GlowFilter(0x405080,1,16,16)); glows.push(new GlowFilter(0x405080,1,32,32)); super(465, 465); scene.addChild(cube); scale = 1; for (var i:int=0; i<nvs.length; i++) { var v:Vertex3D = cube.geometry.vertices[i]; cbs[i] = new Number3D(v.x, v.y, v.z); nvs[i] = new Number3D(v.x, v.y, v.z); nvs[i].normalize(); s[i] = 1; } } public function update() : void { cube.scale += (scale - cube.scale) * 0.05; cube.rotationX += omegaX; cube.rotationY += omegaY; cube.rotationZ += omegaZ; for (var i:int=0; i<nvs.length; i++) { var n:Number3D = nvs[i], c:Number3D = cbs[i], v:Vertex3D = cube.geometry.vertices[i], r:Number = s[i]; v.x = n.x * r + c.x; v.y = n.y * r + c.y; v.z = n.z * r + c.z; s[i] += (1 - r) * 0.12; } for each(var f:Triangle3D in cube.geometry.faces) f.createNormal(); singleRender(); } public function end() : void { if (omegaTween && omegaTween.isPlaying) omegaTween.stop(); omegaTween = BetweenAS3.to(this, {"omegaX":0.2 ,"omegaY":0.4 ,"omegaZ":0.7}, 2); omegaTween.play(); scale = 1; filters = null; } public function tick() : void { for (var i:int=0; i<s.length; i++) s[i] += Math.random() * 6 * (scale - 1); } public function set measure(m:int) : void { scale = 1 + m*0.2; if (_effect && (m&7)==1) filters = [glows[m>>3]]; if (omegaTween && omegaTween.isPlaying) omegaTween.stop(); omegaTween = BetweenAS3.to(this, {"omegaX":$() ,"omegaY":$() ,"omegaZ":$()}, 4); omegaTween.play(); function $():Number { return (Math.random() - 0.5) * scale; } } }