/* 스트라이트 통합 이미지를 관리하는 클래스 */ $class({ CSpriteBase : { SINGLETON : true, /*imgURL : 'http://c2down.cyworld.co.kr/download?fid=64221616d7c6410657fb16fbdf802ae3&name=sprite.gif',*/ imgURL : '/bomblink/img/sprite2.gif', spriteSize:[ [29,29], // bomb [32,32] // fire ], spritePos : [ [[0,0],[29,0],[58,0],[87,0],[0,29],[29,29]], // bomb + explosion [[0,58],[32,58]] // fire ], /* create sprite */ get : function(index,parent) { var ret=new CSprite(this.spriteSize[index][0],this.spriteSize[index][1],this.imgURL,this.spritePos[index],parent); return ret; } } }); /* 분할된 스프라이트 이미지를 표시하는 div 래핑 클래스 */ $class({ CSprite : { element : null, arrPos : null, curShape : null, parentPos:null, /* 통합 이미지에서 잘라내어 div로 표시하는 element를 생성한다 */ init : function(width,height,url,arrPos,parent) { this.element=document.createElement('div'); $style(this.element,'background','transparent url('+$factory.get(CSpriteBase).imgURL+') no-repeat 0px 0px'); $style(this.element,'backgroundPosition','0px 0px'); $style(this.element,'styleFloat','left'); $style(this.element,'position','absolute'); $style(this.element,'zIndex','1'); $dom.hide(this.element); if (parent) this.parentPos=$dom.getPos(parent); parent = parent || document.body; parent.appendChild(this.element); $dom.setSize(this.element,width,height); this.arrPos=arrPos; this.shape(0); }, /* 스프라이트의 모양을 바꾼다 */ shape : function(index) { this.curShape=index; $style(this.element,'backgroundPositionX',-this.arrPos[index][0]+'px'); $style(this.element,'backgroundPositionY',-this.arrPos[index][1]+'px'); }, /* 스프라이트를 보인다 */ show : function() { $dom.show(this.element); }, /* 스프라이트를 숨긴다 */ hide : function() { $dom.hide(this.element); }, /* 스프라이트 위치를 지정한다. parentElement를 지정하면, 이에 대한 상대좌표로 지정할 수 있다. */ setPos : function(x,y,parentElement) { $dom.setPos(this.element,x,y,parentElement); }, /* 스프라이트 위치를 얻는다. parentElement를 지정하면, 이에 대한 상대좌표를 반환한다. */ getPos : function(parentElement) { return $dom.getPos(this.element,parentElement); }, /* 스프라이트를 표시하는 div를 반환 */ getElement : function () { return this.element; }, /* 스프라이트의 현재 모양을 반환 */ getShape : function() { return this.curShape; } } }); /* 개별 폭탄 클래스 */ $class({ CBomb : { sprite : null, // CSprite direction : 0, // 0 : right, 1 : bottom, 2 : left, 3 : top fireLevel : 4, // 폭발 단계 /* 폭탄 위치 */ x : 0, y : 0, bombTable : null, dropY : 0, /* 이벤트 매핑 */ EVENT_MAP : { click : 'onClick', // 폭탄 클릭 fire : 'onFire', // 폭탄 폭발 drop : 'onDrop' // 폭탄 떨어짐 }, /* 폭탄 스프라이트를 생성*/ init : function (bombTable,clickEnable) { this.bombTable=bombTable; this.sprite = $factory.get(CSpriteBase).get(0,bombTable.element); this.direction = this.sprite.getShape(); if (clickEnable==true) $event(this.sprite.getElement(),this); // 맨 밑줄의 폭탄은 클릭할 수 없다. this.sprite.show(); }, /* 폭탄을 클릭 가능하게 함 */ enable : function() { $event(this.sprite.getElement(),this); }, /* 폭탄의 위치 지정 */ setPos : function (x,y) { this.x=x; this.y=y; this.sprite.setPos(x*29,y*29,this.bombTable.element); }, /* 폭탄의 심지 방향 지정 */ setDirection : function(dir) { this.direction=dir; this.sprite.shape(dir); }, /* 현재 폭탄의 심지 방향 반환 */ getDirection : function() { return this.direction; }, /* 폭탄의 폭발 애니메이션을 보여준다 */ showExplosion : function () { if (this.fireLevel<6) { this.sprite.shape(this.fireLevel); this.fireLevel++; window.setTimeout(this.showExplosion.bind(this),100); } else { this.fireLevel=4; this.sprite.hide(); $event.fire(this.bombTable,'explosion',this.x,this.y); } }, /* 폭탄 클릭 이벤트 핸들러 - 폭탄 심지의 방향을 바꾼다 */ onClick : function (evt,src,type) { this.direction++; if (this.direction>3) this.direction=0; this.sprite.shape(this.direction); }, /* 인접 폭탄이 폭발했다 - 심지가 폭발 방향을 향하고 있으면, 자신도 폭발한다 */ onFire : function(evt,src,type,x,y) { if ((this.direction==0 && y==this.y && x==this.x+1)|| (this.direction==1 && y==this.y+1 && x==this.x)|| (this.direction==2 && y==this.y && x==this.x-1)|| (this.direction==3 && y==this.y-1 && x==this.x)) { $event.fire(this.bombTable,'fireBomb',this.x,this.y); this.doFire(); } }, /* 인접 폭탄들에 폭발 메시지를 보낸다 */ doFire : function() { var arrSiblings=this.bombTable.getSiblingBomb(this.x,this.y); for(var i=0;i<4;i++) { if (arrSiblings[i] && this.direction!=i) $event.post(arrSiblings[i],'fire',this.x,this.y); // 비동기로 메시지를 전송한다. } this.showExplosion(); }, /* 폭탄이 아래로 떨어진다 */ onDrop : function() { this.dropY=0; window.setTimeout(this.doDrop.bind(this),100); }, /* 실제 폭탄이 떨어지는 애니메이션 구현 */ doDrop : function() { var finish=false; this.dropY+=15; if (this.dropY>29) { this.dropY=29; if (this.direction==1) this.setDirection(3); else if (this.direction==3) this.setDirection(1); finish=true; } this.sprite.setPos(this.x*29,this.y*29+this.dropY,this.bombTable.element); if (finish) { /* 폭탄이 모두 떨어지면 폭탄 테이블에 알린다 */ this.y++; $event.fire(this.bombTable,'dropComplete',this,this.x,this.y-1); } else { window.setTimeout(this.doDrop.bind(this),100); } } } }); /* 불꽃 클래스 */ $class({ CFire : { sprite : null, fireShape : 0, lane : null, bShow : true, /* 불꽃 스프라이트를 생성하고 애니메이션을 시작한다 */ init : function (lane) { this.lane=lane; this.sprite = $factory.get(CSpriteBase).get(1,lane.element); this.sprite.setPos(0,0,lane.element); this.fireShape = this.sprite.getShape(); this.show(); this.animate(); }, /* 불꽃을 보인다 */ show : function() { this.bShow=true; this.sprite.show(); }, /* 불꽃을 숨긴다 */ hide : function() { this.bShow=false; this.sprite.hide(); }, /* 불꽃 스프라이트 이미지를 주기적으로 바꾸어 애니메이션 구현 */ animate : function() { this.fireShape++; if (this.fireShape>1) this.fireShape=0; this.sprite.shape(this.fireShape); if (this.bShow==true) window.setTimeout(this.animate.bind(this),400); }, /* 불꽃을 아래로 한 칸 이동시킨다 */ moveDown : function() { var pos = this.sprite.getPos(); pos.y+=29; this.sprite.setPos(pos.x,pos.y); } } }); /* 폭탄들이 배열되는 폭탄 테이블 클래스 */ $class({ CBombTable : { arrBombTable : null, size : {width : 0,height : 0}, element : null, parentElement : null, /* 이벤트 맵 */ EVENT_MAP : { explosion : 'onExplosion', // 폭탄 폭발 완료 dropComplete : 'onDropComplete', // 폭탄 떨어짐 완료 fireBomb : 'onFireBomb' // 폭탄 폭발 시작 }, // 폭탄 테이블 div를 생성한다. init : function(width,height,parent) { this.size.width=width; this.size.height = height; this.arrBombTable=new Array(width*height); parent = parent || document.body; this.parentElement=parent; parent.innerHTML=''; this.element=$('_bomblink_bombtable'); }, // 폭탄의 심지 방향을 랜덤으로 하여 현재 레벨에 맞게 폭탄을 생성한다. createLevel : function(level) { if (level<5) level=3; var height = Math.min(level,10); for(var y=this.size.height-(level+1);y0)?this.arrBombTable[x-1+y*this.size.width]:null, // left (y>0)?this.arrBombTable[x+(y-1)*this.size.width]:null]; // top }, // 불꽃이 지나갈 때 마다 체크하여 해당 위치의 폭탄에 폭발 메시지 전달 fire : function(y,x) { // x : 0 - left, 1 - right if (y==this.size.height-1) return; if (x==0) { // left var bomb=this.getBomb(0,y); if (bomb) $event.fire(bomb,'fire',-1,y); } else { // right var bomb=this.getBomb(this.size.width-1,y); if (bomb) $event.fire(bomb,'fire',this.size.width,y); } bomb=null; }, // 폭탄을 1줄 추가한다 tableUp : function() { for(var y=0;y0;index-=this.size.width) { var bomb=this.arrBombTable[index]; if (bomb) { this.arrBombTable[index]=null; $event.fire(bomb,'drop'); } } }, // 폭탄 떨어짐 완료 - 만약 해당 폭탄의 아래가 비었으면 계속 떨어지게 한다 onDropComplete : function(evt,src,type,bomb,x,y) { var index=x+(y+1)*this.size.width; this.arrBombTable[index]=bomb; if (this.arrBombTable[index+this.size.width]==null) { this.arrBombTable[index]=null; $event.fire(bomb,'drop'); } bomb=null; }, // 현재 폭탄 테이블의 상태를 디버그 창에 표시 dumpTable : function() { $debug.outputLn('============================================='); for(var y=0;y