一個算是基本中的基本的東西~
我是拿來練習Vector的部分~
用這個練習 Vector得到了很多的部分~
例如 一些檢驗的部分~ 非常的嚴謹~
Vector 如果超出所引範圍會報錯~
但是 array 不會~
Vector 就算是有限定了長度 如果不是設定固定~
也是可以利用 push去增加的
Vetor的排序較快! Array慢很多~
基本上這是一個很堅單的東東~
所以我就沒太多講解了~
如果有高手願意提供更好的寫法我也願意學習~
話說 Vector版的寶石方塊~
比我用 array的還慢~
理論上應該可以寫的比 array版的快~不過我是寫不出來了!
下面是我的原始碼!
vo 的部分 是地板的類別 目的是讓 vector可以使用
package vo
{
import flash.display.MovieClip;
public class jwFloor extends Object
{
public var mc:MovieClip;
public var type:int = 1;
public function jwFloor(
_mc:MovieClip,
_type:int = 1
)
{
super();
mc = _mc;
type = _type;
}
}
}
gameEvent 這個是放這遊戲傳出的動作 基本上有兩個 消去地板時傳出的 和結束遊戲傳出的
這個是如果整個遊戲中 沒有任何兩個方塊互換 可以消去時會傳出這個!
package gameEvent
{
import flash.events.Event;
public class gameOverEvent extends Event
{
public static const GAME_OVER:String = 'gameOver';
public function gameOverEvent(type:String, bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
}
}
}
這個是每次消去方塊時會傳出
package gameEvent
{
import flash.events.Event;
public class HitCountEvent extends Event
{
public static const HIT_COUNT_EVENT:String = 'gameHitCountEvent';
public var hit:int = 0; //總共有幾組方塊 在這一次操作中消去
public var countFloorMax:int = 0;// 這一次最大消去數量
public var totalFloor:int = 0; // 總共消去的地板數量
public function HitCountEvent(type:String,
hit:int = 0,
countFloorMax:int = 0,
totalFloor:int = 0,
bubbles:Boolean=false, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
this.hit = hit;
this.countFloorMax = countFloorMax;
this.totalFloor = totalFloor;
}
}
}
下面這個是 整個遊戲的主體!
package
{
import caurina.transitions.Tweener;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import gameEvent.HitCountEvent;
import gameEvent.gameOverEvent;
import vo.jwFloor;
public class bejeweledGame extends Sprite
{
private var horNum:int = 10;
private var verNum:int = 10;
private var jwMap:Vector.<Vector.<jwFloor>>;
private var floorClasVec:Vector.<Class>;
private var selectMC:Sprite;
private var moveFlag:Boolean = false;
private var countHit:int = 0;
private var countFloor:int = 0;
private var totalFloor:int = 0;
public var hitPoint1:Point = new Point(-1,-1);
public var hitPoint2:Point = new Point(-1,-1);
//
private const moveFloorTime:Number = 0.3; // 兩塊地板移動使用的時間!
private const actionDelay:Number = 0.1; // 動作結束後的延遲時間!
private const clearFloorTime:Number = 0.5;// 清理地板時間
public function bejeweledGame(_fcv:Vector.<Class>,
_horNum:int=10,
_verNum:int=10)
{
super();
this.addEventListener(Event.ADDED_TO_STAGE, onInitFun);
floorClasVec = _fcv;
horNum = _horNum;
verNum = _verNum;
countHit = 0;
countFloor = 0;
totalFloor = 0;
}
private function onInitFun(e:Event):void
{
this.removeEventListener(Event.ADDED_TO_STAGE, onInitFun);
jwMap = new Vector.<Vector.<jwFloor>>(verNum);
for(var i:int=0;i<verNum;i++)
{
var tempV:Vector.<jwFloor> = new Vector.<jwFloor>(horNum);
jwMap[i]= tempV;
for(var j:int=0;j<horNum;j++)
{
do{
var tempRn:int = Math.random()*floorClasVec.length;
var cla:Class = floorClasVec[tempRn];
jwMap[i][j] = new jwFloor(new cla() as MovieClip, tempRn);
}while(hk(j,i)>2||vk(j,i)>2)
this.addChild(jwMap[i][j].mc);
jwMap[i][j].mc.x = j*jwMap[i][j].mc.width;
jwMap[i][j].mc.y = i*jwMap[i][j].mc.height;
jwMap[i][j].mc.dx = j;
jwMap[i][j].mc.dy = i;
}
}
selectMC = new Sprite();
selectMC.graphics.lineStyle(3,0xff0000,1);
selectMC.graphics.drawRect(0,0,jwMap[0][0].mc.width, jwMap[0][0].mc.height);
selectMC.mouseEnabled = false;
selectMC.mouseChildren = false;
selectMC.visible = false;
this.addChild(selectMC);
this.addEventListener(MouseEvent.CLICK, onClickFun);
}
// 點擊檢測
private function onClickFun(e:MouseEvent):void
{
var mc:MovieClip = e.target as MovieClip;
if(moveFlag) return;
if(!mc)return;
if(mc.dx == undefined){
mc = mc.parent as MovieClip;
}
if(mc.dx == undefined) return;
var x:int = mc.dx;
var y:int = mc.dy;
var sx:int = int(selectMC.x / mc.width);
var sy:int = int(selectMC.y / mc.height);
if((((x==sx+1||x==sx-1)&&y==sy)||
((y==sy+1||y==sy-1)&&x==sx)))
{
switchFloor( x, y, sx, sy);
if(hk(x,y)>2 ||
vk(x,y)>2 ||
hk(sx,sy)>2 ||
vk(sx,sy)>2)
{
selectMC.x = -10;
selectMC.y = -10;
selectMC.visible = false;
Tweener.addTween(selectMC, {alpha:1,
time:moveFloorTime+actionDelay,
onComplete:SwitchMoveEndFun,
onCompleteParams:[sy>y?sy:y]});
return;
}else{
switchFloor( x, y, sx, sy);
}
}
selectMC.x = mc.x;
selectMC.y = mc.y;
selectMC.visible = true;
if(!getHit()) this.dispatchEvent(new gameOverEvent(gameOverEvent.GAME_OVER));
return;
}
//
private function SwitchMoveEndFun(maxY:int):void
{
clearFloor(maxY);
}
//
private function clearFloor(MaxY:int):void
{
var typeNum:int = -1;
var cont:int = 1;
var flagF:Boolean = false;
for(var i:int=0;i<this.verNum;i++)
{
typeNum = -1;
cont = 1;
for(var j:int=0;j<horNum;j++)
{
if(jwMap[i][j].type == typeNum)
{
cont++;
}else{
if(cont >= 3) flagF = clearHorFloor(j, i, cont);
cont = 1;
typeNum = jwMap[i][j].type;
}
}
if(cont >= 3) flagF = clearHorFloor(j, i , cont);
}
if(flagF){
Tweener.addTween(selectMC, {alpha:1, time:this.clearFloorTime+this.actionDelay, onComplete:HorMoveEndFun});
}else{
clearFloor2();
}
}
// 橫向清除動畫結束!
private function HorMoveEndFun():void
{
clearFloor2();
}
//
private function clearFloor2():void
{
var typeNum:int = -1;
var cont:int = 1;
var flagF:Boolean = false;
for(var j:int = 0;j<horNum;j++)
{
typeNum = -1;
cont = 1;
for(var i:int=0;i<verNum;i++)
{
if(jwMap[i][j])
{
if(jwMap[i][j].type == typeNum)
{
cont++;
}else{
if(cont >= 3) flagF = clearHVerFloor(j, i , cont);
cont = 1;
typeNum = jwMap[i][j].type;
}
}else{
if(cont >= 3) flagF = clearHVerFloor( j, i , cont);
cont = 1;
typeNum = -1;
}
}
if(cont >= 3) flagF = clearHVerFloor(j, i, cont);
}
//
if(flagF){
Tweener.addTween(selectMC, {alpha:1, time:this.clearFloorTime+this.actionDelay, onComplete:VerMoveEndFun});
}else{
clearFloor3();
}
}
//
private function VerMoveEndFun():void
{
clearFloor3();
}
//
private function clearFloor3():void
{
var typeNum:int = -1;
var cont:int = 1;
var flagF:Boolean = false;
// 垂直落下
var tempFloor:Vector.<jwFloor>;
for(var j:int=0;j<this.horNum;j++)
{
tempFloor = new Vector.<jwFloor>();
for(var i:int=0;i<this.verNum;i++) if(jwMap[i][j]) tempFloor.push(jwMap[i][j]);
for(i=verNum-1;i>=0;i--)
{
if(tempFloor.length>0){
jwMap[i][j] = tempFloor.pop();
}else{
var tempRn:int = Math.random()*floorClasVec.length;
var cla:Class = floorClasVec[tempRn];
jwMap[i][j] = new jwFloor(new cla() as MovieClip, tempRn);
this.addChild(jwMap[i][j].mc);
jwMap[i][j].mc.x = j*jwMap[i][j].mc.width;
jwMap[i][j].mc.y = 0 - (jwMap[i][j].mc.height*(this.verNum-i));
flagF = true;
}
fixFloor( j, i);
}
}
if(!flagF){
trace("連擊! " + countHit + " Hit. 一共消除: " + totalFloor + " 消除最大長度: " + countFloor);
moveFlag = false;
this.dispatchEvent(
new HitCountEvent(HitCountEvent.HIT_COUNT_EVENT,
countHit,countFloor,totalFloor));
countHit = 0;
totalFloor = 0;
countFloor = 0;
}else{
Tweener.addTween(selectMC,
{x:selectMC.x,
time:this.moveFloorTime+this.actionDelay,
onComplete:clearFloor,
onCompleteParams:[verNum]});
}
}
// 橫向清除 FLOOR
private function clearHorFloor( x:int, y:int, long:int):Boolean
{
for(var i:int=1;i<=long;i++)
{
if(jwMap[y][(x-i)] || jwMap[y][(x-i)] != null)
{
//this.removeChild(jwMap[y][(x-i)].mc);
Tweener.addTween(jwMap[y][(x-i)].mc, {alpha:0, time:clearFloorTime});
jwMap[y][(x-i)] = null;
moveFlag = true;
}
}
countHit++;
totalFloor+=long;
if(long > countFloor) countFloor = long;
return true;
}
// 垂直清除FLOOR
private function clearHVerFloor( x:int, y:int, long:int):Boolean
{
for(var i:int=1;i<=long;i++)
{
if(jwMap[(y-i)][(x)] || jwMap[y-i][(x)] != null)
{
//this.removeChild(jwMap[(y-i)][(x)].mc);
Tweener.addTween(jwMap[(y-i)][(x)].mc, {alpha:0, time:clearFloorTime});
jwMap[(y-i)][(x)] = null;
moveFlag = true;
}
}
countHit++;
totalFloor+=long;
if(long > countFloor) countFloor = long;
return true;
}
// 兩個互換!
private function switchFloor( x1:int, y1:int,
x2:int, y2:int, testMode:Boolean = false):void
{
var tempFloor:jwFloor = jwMap[y1][x1];
jwMap[y1][x1] = jwMap[y2][x2];
jwMap[y2][x2] = tempFloor;
fixFloor(x1,y1, testMode);
fixFloor(x2,y2, testMode);
}
//
private function fixFloor(x:int,y:int, testMode:Boolean = false):void
{
if(jwMap[y][x].mc){
jwMap[y][x].mc.dx = x;
jwMap[y][x].mc.dy = y;
if(testMode){
jwMap[(y)][(x)].mc.x = x*jwMap[y][x].mc.width;
jwMap[(y)][(x)].mc.y = y*jwMap[y][x].mc.height;
}else{
Tweener.addTween(jwMap[(y)][(x)].mc, {
x:x*jwMap[y][x].mc.width,
y:y*jwMap[y][x].mc.height,
time:moveFloorTime});
}
// jwMap[y][x].mc.x = x*jwMap[y][x].mc.width;
// jwMap[y][x].mc.y = y*jwMap[y][x].mc.height;
}
}
// 垂直檢查
private function hk(x:int, y:int):int
{
var nowCoun:int = 1;
var tempY:int = y;
var type:int = jwMap[y][x].type;
while(twoPointCheck2(type, x, tempY-1))
{
tempY--;
nowCoun++;
}
tempY = y;
while(twoPointCheck2(type, x, tempY+1))
{
tempY++;
nowCoun++;
}
return nowCoun;
}
// 水平檢查
private function vk(x:int, y:int):int
{
var nowCoun:int = 1;
var tempX:int = x;
var type:int = jwMap[y][x].type;
while(twoPointCheck2(type,tempX-1,y))
{
tempX--;
nowCoun++;
}
tempX = x;
while(twoPointCheck2(type, tempX+1,y))
{
tempX++;
nowCoun++;
}
return nowCoun;
}
// 兩個點的 type 是否一樣!!
private function twoPointCheck2(typeNum:int, x:int, y:int):Boolean
{
if(x < 0 || y < 0) return false;
if(x >= horNum || y >= verNum) return false;
if(jwMap[y] == null) return false;
if(jwMap[y][x] == null) return false;
return typeNum == jwMap[y][x].type;
}
// 提示
public function getHit():Boolean
{
for(var i:int=0;i<verNum-1;i++)
{
for(var j:int= 0;j<horNum-1;j++)
{
switchFloor(j, i , j, i+1,true);
if( hk(j,i)>2 ||
vk(j,i)>2 ||
hk(j,i+1)>2 ||
vk(j,i+1)>2)
{
trace("(" +(j+1) + "," +(i+1)+")->" + "("+(j+1)+","+(i+2)+")");
switchFloor(j, i , j, i+1,true);
hitPoint1 = new Point(j+1,i+1);
hitPoint2 = new Point(j+1,i+2);
return true;
break;
}
switchFloor(j, i , j, i+1,true);
//
switchFloor(j, i , j+1, i,true);
if( hk(j,i)>2 ||
vk(j,i)>2 ||
hk(j+1,i)>2 ||
vk(j+1,i)>2)
{
trace("(" +(j+1) + "," +(i+1)+")->" + "("+(j+2)+","+(i+1)+")");
switchFloor(j, i , j+1, i,true);
hitPoint1 = new Point(j+1,i+1);
hitPoint2 = new Point(j+2,i+1);
return true;
break;
}
switchFloor(j, i , j+1, i,true);
}
}
hitPoint1 = new Point(-1,-1);
hitPoint2 = new Point(-1,-1);
return false;
}
// 清除全部!
public function clearAll():void
{
for(var i:int=0;i<verNum-1;i++)
{
for(var j:int= 0;j<horNum-1;j++)
{
if(jwMap[i][j])
{
this.addChild(jwMap[i][j].mc);
}
jwMap[i][j] = null;
}
jwMap[i] = null;
}
var len:int = floorClasVec.length;
for(i=0;i<len;i++)
{
floorClasVec.pop();
}
floorClasVec = null;
this.removeChild(selectMC);
selectMC = null;
countHit = 0;
this.removeEventListener(MouseEvent.CLICK, onClickFun);
}
}
}
//
這整個是我的寶石方塊的程式碼~
有用到 tweener的類別~
其中一開始傳入的 _fcv 是存放本次有多少種不同的地板!
//
只有主體的SWF
主體的程式碼(我沒打包我的函數庫!)
有開始結束的版本!
沒有留言 :
張貼留言