前段时间研究了一下prototype.js的源代码,感觉真是一个漂亮的东东,于是在她的基础上写了这个俄罗斯,还有很多bug,望大家指正。
〉〉〉〉〉〉〉〉2007.07.12改版,支持IE,FF,NS
要运行,需要注意下面这一点:
因为是基于prototype.js的脚本,所以prototype.js是必须的,大家可以到下面的链接去下载
http://www.prototypejs.org/download
下载后与下面的代码放置到同一个目录下(注意),就可以玩了。
下面是俄罗斯的具体代码,随便保存一个文件就可以了
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=gb2312">
<style>
.bt{border:1px solid orange;background-color:#FFFFFF;width:60};
</style>
<script language="javascript" src="prototype.js"></script>
<script language="javascript">
//###################
//Created by 刘肖冲[LxcJie] 2006.08.16
//* 2007.07.12改版,支持IE,FF,NS **
//***** 请保留出处,谢谢 *****
//***[prototype.js] Is Required***
//###################
var GameConfig = Class.create();
GameConfig.cellWidth = 15;
GameConfig.backWidthUnits = 15;
GameConfig.backHeightUnits = 24;
GameConfig.backBorderWidth = 1;
GameConfig.backgroundZIndex = 3;
//删除20行升一级
GameConfig.upLevelCellNum = 20;
var Debug = Class.create();
Debug.printArr = function(arr,divId){
var tempDiv = $(divId);
var str = "";
for(var i=0; i<arr.length; i++){
str += "<table border=0>";
str += "<tr>";
for(var j=0; j<arr[0].length; j++){
str += "<td>";
str += arr[i][j];
str += "</td>";
}
str += "</tr>";
}
tempDiv.innerHTML = str;
};
Debug.printCoordinates = function(x,y,divId){
var tempDiv = $(divId);
tempDiv.innerHTML = "X : " + x + " " + "Y : " + y;
};
var ColorProducer = Class.create();
ColorProducer.RED = "#FF0000";
ColorProducer.GREEN = "#00FF00";
ColorProducer.BLUE = "#0000FF";
ColorProducer.WHITE = "#FFFFFF";
ColorProducer.BLACK = "#000000";
ColorProducer.YELLOW = "#FFFF00";
ColorProducer.CYAN = "#00FFFF";
ColorProducer.PURPLE = "#FF00FF";
ColorProducer.prototype = {
initialize : function(){
},
getRandomColor : function(){
var redParts = this.getRandomNumber().toColorPart();
var yellowParts = this.getRandomNumber().toColorPart();
var blueParts = this.getRandomNumber().toColorPart();
return "#" + redParts.toUpperCase()
+ yellowParts.toUpperCase()
+ blueParts.toUpperCase();
},
getDirectColor : function(p1,p2,p3){
var redParts = new Number(p1).toColorPart();
var yellowParts = new Number(p2).toColorPart();
var blueParts = new Number(p3).toColorPart();
return "#" + redParts.toUpperCase()
+ yellowParts.toUpperCase()
+ blueParts.toUpperCase();
},
getRandomNumber : function(){
return new Number(Math.floor(Math.random() * 256));
}
};
///
var CellKindLib = Class.create();
CellKindLib.shapes = [];
GameConfig.cellKindNum = 7;//If add new cell,this is must be updated first,then add datas to array
var shape0 = [ //
[1,1,1,1] //####
]; //
var shape1 = [
[1,1], //##
[1,1] //##
];
var shape2 = [
[0,1,1], // ##
[1,1,0] //##
];
var shape3 = [
[1,1,0], //##
[0,1,1] // ##
];
var shape4 = [
[0,1,0], // #
[1,1,1] //###
];
var shape5 = [
[1,0,0], //#
[1,1,1] //###
];
var shape6 = [
[0,0,1], // #
[1,1,1] //###
];
/* var shape7 = [
[1,0,1], //# #
[1,1,1] //###
];
var shape8 = [
[1,0,0], //#
[1,1,1], //###
[0,0,1] // #
];
var shape9 = [
[0,0,1], // #
[1,1,1], //###
[1,0,0] //#
];
var shape10 = [
[1,1,1], //###
[0,1,0], // #
[0,1,0] // #
];
var shape11 = [
[0,1,0], // #
[1,1,1], //###
[0,1,0] // #
];
*/
for(var i=0; i<GameConfig.cellKindNum; i++){
CellKindLib.shapes[i] = eval("shape" + i);
}
/
var ShapeConfig = Class.create();
ShapeConfig.prototype = {
initialize : function(dataArray){
this.datas = dataArray;
},
setDatas : function(dataArray){
this.datas = dataArray;
}
};
var CellProducer = Class.create();
CellProducer.prototype = {
initialize : function(pWidth, pColor)
{
this.width = pWidth==null?0:pWidth;
this.color = pColor==null?"#000000":pColor;
},
setWidth : function(pWidth){
this.width = pWidth;
},
setColor : function(pColor){
this.color = pColor;
},
getCellString : function(pIsEmpty){
if(pIsEmpty){
return "<td style='width:" + this.width + ";height:"
+ this.width + ";border:0px solid black;font-size:12px'>" + "</td>"
} else {
return "<td style='width:" + this.width + ";height:"
+ this.width + ";background-color:"
+ this.color + ";border:0px solid black;font-size:12px'>" + "</td>"
}
}
};
var ShapeCreator = Class.create();
ShapeCreator.prototype = {
initialize : function(){
},
createShape : function(shapeConfig){
var cellProducerFill = new CellProducer(GameConfig.cellWidth,ColorProducer.RED);//RED
var shapeString = "";
shapeString += "<table border=0 cellspacing=0 cellpadding=0 style='z-index:3'>";
for(var i=0; i<shapeConfig.datas.length; i++){
shapeString += "<tr>";
for(var j=0; j<shapeConfig.datas[0].length; j++){
if(shapeConfig.datas[i][j] == 1){
shapeString += cellProducerFill.getCellString(false);
} else {
shapeString += cellProducerFill.getCellString(true);
}
}
shapeString += "</tr>";
}
shapeString += "</table>";
return shapeString;
}
};
///
var ShapeChanger = Class.create();
ShapeChanger.prototype = {
initialize : function(){
},
changeShape : function(arrDatas){
var rowNum = arrDatas.length;
var colNum = arrDatas[0].length;
var newArray = new Array(colNum);
for(var i=0; i<colNum; i++){
var tempArray = new Array(rowNum);
var num = 0;
for(var j=rowNum-1; j>=0; j--){
tempArray[num] = arrDatas[j][i];
num++;
}
newArray[i] = tempArray;
}
return newArray;
}
};
///
var BackgroundCreator = Class.create();
BackgroundCreator.prototype = {
initialize : function(){
this.dataArray = new Array(GameConfig.backHeightUnits);
this.backDiv = null;
for(var i=0; i<GameConfig.backHeightUnits; i++){
var arr = new Array(GameConfig.backWidthUnits);
for(var j=0; j<GameConfig.backWidthUnits; j++){
arr[j] = 0;
}
this.dataArray[i] = arr;
}
this._xMax = GameConfig.backWidthUnits;
this._yMax = GameConfig.backHeightUnits;
},
drawBackground : function(){
var backDiv = document.createElement("div");
var shadowDiv = document.createElement("div");
var controlDiv = $("control");
backDiv.id = "backDiv";
this.backDiv = backDiv;
var styleObj = new Object();
styleObj.width = GameConfig.backWidthUnits * GameConfig.cellWidth + GameConfig.backBorderWidth * 2;
styleObj.height = GameConfig.backHeightUnits * GameConfig.cellWidth + GameConfig.backBorderWidth * 2;
styleObj.position = "absolute";
styleObj.backgroundColor = "#FFFF99";//FFFF99
styleObj.border = GameConfig.backBorderWidth + "px solid orange";//orange
styleObj.margin = 0;
styleObj.padding = 0;
styleObj.left = Math.floor(screen.availWidth/2 - styleObj.width/2);
styleObj.top = 50;
styleObj.zIndex = 2;
Element.setStyle(backDiv,styleObj);
//Shadow
styleObj.backgroundColor = "#BABABA";//BABABA
styleObj.left = styleObj.left + 6;
styleObj.top = styleObj.top + 6;
styleObj.border = "";
styleObj.zIndex = 1;
Element.setStyle(shadowDiv,styleObj);
//Control Container
styleObj.left = styleObj.left + styleObj.width + 20;
styleObj.top = styleObj.top - 6;
styleObj.backgroundColor = "";
Element.setStyle(controlDiv,styleObj);
document.body.insertBefore(backDiv, $('startDiv'));
document.body.insertBefore(shadowDiv, $('startDiv'));
},
redrawBackground : function(){
var producer = new CellProducer(GameConfig.cellWidth,"blue");
var tString = "<table border=0 cellpadding=0 cellspacing=0 style='z-index:3'>";
for(var i=0; i<this.dataArray.length; i++){
tString += "<tr>";
for(var j=0; j<this.dataArray[0].length; j++){
if(this.dataArray[i][j] == 1){
tString += producer.getCellString(false);
} else {
tString += producer.getCellString(true);
}
}
tString += "</tr>";
}
tString += "</table>";
//Debug.printArr(this.dataArray,"myDiv4");
this.backDiv.innerHTML = tString;
}
};
//
var GameTool = Class.create();
GameTool.getLeft = function(obj){
return parseInt(Element.getStyle(obj,"left"),10);
};
GameTool.setLeft = function(obj,pLeft){
var styleObj = new Object();
styleObj.left = pLeft;
Element.setStyle(obj,styleObj);
};
GameTool.getTop = function(obj){
return parseInt(Element.getStyle(obj,"top"),10);
};
GameTool.setTop = function(obj,pTop){
var styleObj = new Object();
styleObj.top = pTop;
Element.setStyle(obj,styleObj);
};
GameTool.getWidth = function(obj){
return parseInt(Element.getStyle(obj,"width"),10);
};
GameTool.getHeight = function(obj){
return parseInt(Element.getStyle(obj,"height"),10);
};
//
var DataProcesser = Class.create();
DataProcesser.prototype = {
initialize : function(){
this.delNum = 0;
},
getFirstNotEmptyRowNum : function(backDataArray){
var index = -1;
for(var i=0; i<backDataArray.length; i++){
if(parseInt(backDataArray[i].join(""),10) != 0){
index = i;
break;
}
}
return index
},
judgeCombineArray : function(pX,pY,backData,shapeData){
var colNum = shapeData[0].length;
var rowNum = shapeData.length;
var backNewArray = [];
var backNewArrayIndex = 0;
for(var i = pX; i<pX+rowNum; i++){
backNewArray[backNewArrayIndex] = backData[i].slice(pY,pY+colNum);
backNewArrayIndex++;
}
for(var i=0; i<rowNum; i++){
var backAR = backNewArray[i];
var shapeAR = shapeData[i];
if(this.judgeValidArray(backAR,shapeAR)==false)
return false;
}
return true;
},
judgeValidArray : function(backP,shapeP){
var backD = backP.join("");
var shapeD = shapeP.join("");
if(parseInt(backD & shapeD,10) == 0)
return true;
else
return false;
},
getCombinedArray : function(pX,pY,backData,shapeData){
var colNum = shapeData[0].length;
var rowNum = shapeData.length;
for(var i = 0; i<backData.length; i++){
for(var j = 0; j<backData[0].length; j++)
if(i >= pX && i < pX+rowNum && j>=pY && j<pY+colNum){
backData[i][j] = backData[i][j] | shapeData[i-pX][j-pY];
}
}
//Debug.printArr(backData,"myDiv4");
},
deleteFullRowArr : function(backArr){
var deletedArray = this.createEmptyBackArray();
var deletedArrayIndex = GameConfig.backHeightUnits - 1;
this.delNum = 0;
for(var i=backArr.length-1; i>=0; i--){
if(!this.rowIsFull(backArr[i])){
deletedArray[deletedArrayIndex] = backArr[i];
deletedArrayIndex--;
} else {
this.delNum ++;
}
}
//Debug.printArr(deletedArray,"myDiv1");
return deletedArray;
},
isNeedDel : function(backArr){
for(var i=backArr.length-1; i>=0; i--){
if(this.rowIsFull(backArr[i])){
return true;
}
}
return false;
},
rowIsFull : function(rowArr){
return rowArr.join("").indexOf("0")==-1?true:false;
},
createEmptyBackRow : function(){
var arr = new Array(GameConfig.backWidthUnits);
for(var i=0; i<GameConfig.backWidthUnits; i++){
arr[i] = 0;
}
return arr;
},
createEmptyBackArray : function(){
var newArray = new Array(GameConfig.backHeightUnits);
for(var i=0; i<GameConfig.backHeightUnits; i++){
newArray[i] = this.createEmptyBackRow();
}
return newArray;
}
};
//
var MainCreator = Class.create();
MainCreator.prototype = {
initialize : function(pBackObj){
this.currentCell = null;
this.nextCell = null;
this.backObj = pBackObj;
this.changer = new ShapeChanger();
this.creator = new ShapeCreator();
this.curDatasArray = null;
this.nextDatasArray = null;
this._x = 0;
this._y = 0;
this.interControl = null;
this.delNum = 0;
this.level = 1;
},
getRandomKindIndex : function(){
return Math.floor(Math.random() * (GameConfig.cellKindNum));
},
refreshBack : function(pBackObj){
this.backObj = pBackObj;
},
refresh : function(){
Element.remove(this.currentCell);
this.currentCell.innerHTML = this.nextCell.innerHTML;
this.curDatasArray = this.nextDatasArray;
this.createNextCell()
$("nextCell").innerHTML = main.nextCell.innerHTML;
this.showCell(this.currentCell);
this.setCurrentCellInitPos();
var proc = new DataProcesser();
if(proc.judgeCombineArray(this._y,this._x,this.backObj.dataArray,this.curDatasArray) == false){
alert("Game Over!");
clearInterval(this.interControl);
}
Debug.printArr(this.curDatasArray,"myDiv");
},
restart : function(objName){
clearInterval(this.interControl);
var proc = new DataProcesser();
this.backObj.dataArray = proc.createEmptyBackArray();
this.backObj.redrawBackground();
this.refresh();
this.delNum = 0;
this.level = 1;
$("delRow").innerHTML = this.delNum;
$("level").innerHTML = this.level;
$("pause").value = "Pause";
this.interControl = setInterval(objName+'.moveCurrentCellDown()',this.getSpeedByLevel());
},
createCurrentCell : function(){
var nextShapeId = this.getRandomKindIndex();
this.curDatasArray = CellKindLib.shapes[nextShapeId];
var shapeString = this.creator.createShape(new ShapeConfig(this.curDatasArray));
var oDiv = document.createElement("div");
oDiv.id = "currentCell";
oDiv.innerHTML = shapeString;
var styleObj = new Object();
styleObj.position = "absolute";
styleObj.left = 0;
styleObj.top = 0;
styleObj.zIndex = GameConfig.backgroundZIndex++;
Element.setStyle(oDiv,styleObj);
this.currentCell = oDiv;
Debug.printArr(this.curDatasArray,"myDiv");
},
createNextCell : function(){
var nextShapeId = this.getRandomKindIndex();
this.nextDatasArray = CellKindLib.shapes[nextShapeId];
var shapeString = this.creator.createShape(new ShapeConfig(this.nextDatasArray));
var oDiv = document.createElement("div");
oDiv.id = "nextCell";
oDiv.innerHTML = shapeString;
var styleObj = new Object();
styleObj.position = "absolute";
styleObj.left = 0;
styleObj.top = 0;
Element.setStyle(oDiv,styleObj);
this.nextCell = oDiv;
},
showCell : function(pCell){
document.body.appendChild(pCell);
},
setCellPosition : function(pCell,pTop,pLeft){
var styleObj = new Object();
styleObj.top = pTop;
styleObj.left = pLeft;
Element.setStyle(pCell,styleObj);
},
setCurrentCellInitPos : function(){
var initLeft = 0;
var initTop = 0;
//Shape Column Numbers
var curCellCols = this.curDatasArray[0].length;
var startCellIndex = Math.floor((GameConfig.backWidthUnits - curCellCols)/2);
//Init Cell Position
this._x = startCellIndex;
this._y = 0;
//Debug.printCoordinates(this._x,this._y);
var leftMargin = startCellIndex * GameConfig.cellWidth;
initLeft = GameTool.getLeft(this.backObj.backDiv) + GameConfig.backBorderWidth + leftMargin;
initTop = GameTool.getTop(this.backObj.backDiv) + GameConfig.backBorderWidth;
this.setCellPosition(this.currentCell,initTop,initLeft);
},
getCurrentWidth : function(){
return this.curDatasArray[0].length;
},
getCurrentHeight : function(){
return this.curDatasArray.length;
},
changeCurrentCell : function(){
var nextShapeWidth = this.curDatasArray.length;
var nextShapeHeight = this.curDatasArray[0].length;
if(this.backObj._xMax - this._x < nextShapeWidth)
return
if(this.backObj._yMax - this._y < nextShapeHeight)
return;
var changedArr = this.changer.changeShape(this.curDatasArray);
this.currentCell.innerHTML = this.creator.createShape(new ShapeConfig(changedArr));
this.curDatasArray = changedArr;
Debug.printArr(this.curDatasArray,"myDiv");
Debug.printCoordinates(this._x,this._y,"myDiv2");
},
moveCurrentCellDown : function(){
var proc = new DataProcesser();
//Debug.printArr(this.backObj.dataArray,"myDiv1");
if(this._y < this.backObj._yMax - this.getCurrentHeight()){
if(proc.judgeCombineArray(this._y+1,this._x,this.backObj.dataArray,this.curDatasArray)){
this._y ++;
GameTool.setTop(this.currentCell,GameTool.getTop(this.currentCell) + GameConfig.cellWidth);
} else {
proc.getCombinedArray(this._y,this._x,this.backObj.dataArray,this.curDatasArray);
this.backObj.redrawBackground();
this.refresh();
}
} else {
proc.getCombinedArray(this._y,this._x,this.backObj.dataArray,this.curDatasArray);
this.backObj.redrawBackground();
this.refresh();
}
if(proc.isNeedDel(this.backObj.dataArray)){
this.backObj.dataArray = proc.deleteFullRowArr(this.backObj.dataArray);
this.backObj.redrawBackground();
this.delNum += proc.delNum;
$("delRow").innerHTML = this.delNum;
if(this.delNum >0 && this.delNum <=GameConfig.upLevelCellNum){
this.level = 1;
} else if(this.delNum > GameConfig.upLevelCellNum && this.delNum <=GameConfig.upLevelCellNum*2){
this.level = 2;
} else if(this.delNum > GameConfig.upLevelCellNum*2 && this.delNum <=GameConfig.upLevelCellNum*3){
this.level = 3;
} else if(this.delNum > GameConfig.upLevelCellNum*3 && this.delNum <=GameConfig.upLevelCellNum*4){
this.level = 4;
} else if(this.delNum > GameConfig.upLevelCellNum*4 && this.delNum <=GameConfig.upLevelCellNum*5){
this.level = 5;
} else if(this.delNum > GameConfig.upLevelCellNum*5 && this.delNum <=GameConfig.upLevelCellNum*6){
this.level = 6;
} else if(this.delNum > GameConfig.upLevelCellNum*6 && this.delNum <=GameConfig.upLevelCellNum*7){
this.level = 7;
} else if(this.delNum > GameConfig.upLevelCellNum*7 && this.delNum <=GameConfig.upLevelCellNum*8){
this.level = 8;
} else if(this.delNum > GameConfig.upLevelCellNum*8){
this.level = 9;
}
$("level").innerHTML = this.level;
this.addSpeed('main');
}
Debug.printCoordinates(this._x,this._y,"myDiv2");
},
moveCurrentCellLeft : function(){
var proc = new DataProcesser();
if(this._x > 0){
if(proc.judgeCombineArray(this._y,this._x-1,this.backObj.dataArray,this.curDatasArray)){
this._x --;
GameTool.setLeft(this.currentCell,GameTool.getLeft(this.currentCell) - GameConfig.cellWidth);
}
}
Debug.printCoordinates(this._x,this._y,"myDiv2");
},
moveCurrentCellRight : function(){
var proc = new DataProcesser();
if(this._x < this.backObj._xMax - this.getCurrentWidth()){
if(proc.judgeCombineArray(this._y,this._x+1,this.backObj.dataArray,this.curDatasArray)){
this._x ++;
GameTool.setLeft(this.currentCell,GameTool.getLeft(this.currentCell) + GameConfig.cellWidth);
}
}
Debug.printCoordinates(this._x,this._y,"myDiv2");
},
play : function(objName){
this.createCurrentCell();
this.showCell(this.currentCell);
this.setCurrentCellInitPos();
this.createNextCell()
$("nextCell").innerHTML = this.nextCell.innerHTML;
var inter = setInterval(objName + '.moveCurrentCellDown()',this.getSpeedByLevel());
this.interControl = inter;
},
pause : function(){
clearInterval(this.interControl);
},
resume : function(objName){
var inter = setInterval(objName + '.moveCurrentCellDown()',this.getSpeedByLevel());
this.interControl = inter;
},
addSpeed : function(objName){
clearInterval(this.interControl);
var inter = setInterval(objName + '.moveCurrentCellDown()',this.getSpeedByLevel());
this.interControl = inter;
},
getSpeedByLevel : function(){
if(this.level > 9)
this.level = 9;
if(this.level == 2)
return 100;
return (10-this.level) * 100;
}
}
function mainPause(obj){
if(obj.value == "Pause"){
obj.value = "Resume";
main.pause();
} else {
obj.value = "Pause";
main.resume('main');
}
}
</script>
</head>
<body>
<div id="startDiv"></div>
<div id="myDiv1" style="font-color:yellow;border:2px solid black;background-color:gray;width:280px;text-align:center">Debug Information</div>
<br>
<div id="myDiv" style="border:2px solid black;background-color:gray;width:280px"></div>
<br>
<div id="myDiv3" style="border:2px solid black;background-color:gray;width:280px"></div>
<br>
<div id="myDiv2" style="border:2px solid black;background-color:gray;width:280px"></div>
<br>
<div id="myDiv4" style="border:2px solid black;background-color:gray;width:280px"></div>
<div id="control" style="font-size:12px">
<div id="nextCell" style="border:1px solid orange;background-color:#FFFF99;width:60;height:60;padding:10px"></div>
<br><br>
<div><input type="button" value="Restart" class="bt" οnclick="main.restart('main');"></div>
<br>
<div><input type="button" id="pause" value="Pause" class="bt" οnclick="mainPause(this)"></div>
<br>
<span>Delete : </span><span id="delRow">0</span>
<br>
<span>Levels : </span><span id="level">1</span>
<br><br>
<div style="border:1px solid orange;background-color:#FFFF99;width:60;padding:10px">W:变化<br> A:左移<br> D:右移<br> S:下移<br></div>
</div>
<script>
function hideDebugDiv(isDebug){
if(isDebug){
Element.hide($("myDiv1"));
Element.hide($("myDiv"));
Element.hide($("myDiv2"));
Element.hide($("myDiv3"));
Element.hide($("myDiv4"));
}
}
//设为false可以显示Debug信息
hideDebugDiv(true);
</script>
<script language="javascript">
var gameBackground = new BackgroundCreator();
gameBackground.drawBackground();
var main = new MainCreator(gameBackground);
main.play('main');
Event.observe(document, 'keypress', function(event) {
var key = 0;
//If browser is netscape(NS)
if(event.which){
key = event.which;
} else {
key = event.keyCode;
}
//W Move Up
if(key == 87 || key == 119){
main.changeCurrentCell();
}
//S Move Down
if(key == 83 || key == 115){
main.moveCurrentCellDown();
}
//A Move Left
if(key == 65 || key == 97){
main.moveCurrentCellLeft();
}
//D Move Right
if(key == 68 || key == 100){
main.moveCurrentCellRight();
}
});
</script>
</body>
</html>