求俄罗斯方块HTML代码

求俄罗斯方块HTML代码,第1张

<html>

<head>

<title>标题</title>

</head>

<body>

<style>

span.btn

{

BORDER-RIGHT: #7b9ebd 1px solid

PADDING-RIGHT: 2px

BORDER-TOP: #7b9ebd 1px solid

PADDING-LEFT: 2px

FONT-SIZE: 12px

FILTER: progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#ffffff, EndColorStr=#cecfde)

BORDER-LEFT: #7b9ebd 1px solid

COLOR: black

PADDING-TOP: 2px

BORDER-BOTTOM: #7b9ebd 1px solid

background-color: #CCCCCC

}

</style>

<script language="javascript">

var doing

var candown=0

var wnum=13

var hnum=18

var grid=new Array()

var gridBuf=new Array()

for(i=0i<=hnumi++){

grid[i]=new Array()

gridBuf[i]=new Array()

for(j=0j<=wnumj++){

if(j>0 &&j<wnum &&i<hnum){

grid[i][j]=0

gridBuf[i][j]=0

}else{

grid[i][j]=1

gridBuf[i][j]=1

}

}

}

var boxdata=

[

[

[1,1,1,1],

[0,0,0,0],

[0,0,0,0],

[0,0,0,0]

],

[

[1,1,1,0],

[1,0,0,0],

[0,0,0,0],

[0,0,0,0],

],

[

[1,1,1,0],

[0,1,0,0],

[0,0,0,0],

[0,0,0,0]

],

[

[1,1,1,0],

[0,0,1,0],

[0,0,0,0],

[0,0,0,0]

],

[

[1,1,0,0],

[0,1,1,0],

[0,0,0,0],

[0,0,0,0]

],

[

[0,1,1,0],

[1,1,0,0],

[0,0,0,0],

[0,0,0,0]

],

[

[1,1,0,0],

[1,1,0,0],

[0,0,0,0],

[0,0,0,0]

]

]

var colors=["black","#A0A0A0","red","#FF8000","yellow","pink"]

var gotLine=0

var box

var bGameOver=false

function getHeight(arr)

{

var i,j

for(i=3i>=0i--)

for(j=0j<4j++)

if(arr[i][j]) return i

}

function getWidth(arr)

{

var i,j

for(i=3i>=0i--)

for(j=0j<4j++)

if(arr[j][i]) return i

}

function Box(x,y,arr,color)

{

this.arr=arr

this.x=x

this.y=y

this.w=getWidth(arr)

this.h=getHeight(arr)

this.color=color

this.active=true

this.clearOldBox=function()

{

for(var j=0j<=this.hj++)

for(var i=0i<=this.wi++)

if(this.arr[j][i]>0) grid[this.y+j][this.x+i]=0

}

this.putNewBox=function()

{

for(var j=0j<=this.hj++)

for(var i=0i<=this.wi++)

if(this.arr[j][i]>0) grid[this.y+j][this.x+i]=this.color

}

this.moveLeft=function()

{

this.clearOldBox()

var _x=this.x-1

if(this.canMove(_x,this.y)) this.x=_x

this.putNewBox()

drawGrid()

}

this.moveRight=function()

{

this.clearOldBox()

var _x=this.x+1

if(this.canMove(_x,this.y)) this.x=_x

this.putNewBox()

drawGrid()

}

this.moveDown=function()

{

this.clearOldBox()

var _y=this.y+1

if(this.canMove(this.x,_y)){

this.y=_y

this.putNewBox()

drawGrid()

}else{

this.putNewBox()

drawGrid()

checkLineFull()

return

}

}

this.rotate=function()

{

var tmp=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]

for(j=0j<=this.hj++)

for(i=0i<=this.wi++)

tmp[this.w-i][j]=this.arr[j][i]

var newBox=new Box(this.x,this.y,tmp,this.color)

this.clearOldBox()

if(! newBox.canMove(this.x,this.y)) this.putNewBox()

else

{

box=newBox

box.putNewBox()

drawGrid()

}

}

this.canMove=function(x,y)

{

for(var j=0j<=this.hj++)

for(var i=0i<=this.wi++)

{

if(grid[y+j][x+i]!=0 &&this.arr[j][i]!=0){ candown=1return false}

}

return true

}

}

function drawGrid()

{

for(var j=0j<hnumj++)

for(var i=0i<wnumi++)

{

if( grid[j][i]!=gridBuf[j][i])

{

paintCell(j,i,grid[j][i])

}

gridBuf[j][i]=grid[j][i]

}

}

function paintCell(i,j,color)

{

var htmlGrid=document.getElementById("TetrisGrid").firstChild

htmlGrid.childNodes[i].childNodes[j].style.backgroundColor=colors[color]

}

function init()

{

var html='<table id="TetrisGrid" cellspacing=1 style="background-color:green"><tbody>'

for(var i=0i<=hnumi++)

{

html+='<tr>'

for(var j=0j<=wnumj++)

{

html+='<td width="20" height="20" style="background-color:'+colors[grid[i][j]]+'"></td>'

}

html+='</tr>\r\n'

}

html+='</tbody></table>'

document.write(html)

}

function checkLineFull()

{

var full,i,j,i2

var y3=box.y+box.h

var y4=box.y

for(i=y3i>=y4)

{

full=1

for(j=0j<wnumj++)

if(grid[i][j]==0){full=0break}

if(full==0){ --icontinue}

for(i2=ii2>0i2--)

for(j=0j<wnumj++)

grid[i2][j]=grid[i2-1][j]

drawGrid()

y4++

gotLine++

}

checkGameOver()

}

function checkGameOver()

{

var bOver=false

for(var j=1j<wnumj++)

if(grid[0][j]>0){ bOver=truebreak}

if(!bOver){

box=new Box((wnum-1)/2,0,boxdata[Math.floor(Math.random()*7)],Math.floor(Math.random()*5)+1)

box.putNewBox()

}

else

{

bGameOver=true

msg.innerHTML="游戏结束! 您的得分为"+gotLine*100

window.clearTimeout(doing)

}

}

function document_onkeydown()

{

if(bGameOver) return

switch(event.keyCode)

{

case 32:

down()

break

case 37:

box.moveLeft()

break

case 39:

box.moveRight()

break

case 38:

box.rotate()

break

case 40:

box.moveDown()

break

case 80:

stop()

break

case 66:

window.location.reload()

break

case 67:

restart()

break

}

}

function down(){

if(window.event.keyCode==32){

clearTimeout(doing)

for(i=0i<hnumi++){

if(candown==0){

box.moveDown()

}else{

break

}

}

candown=0

doing=window.setTimeout('moveDownBox()',interval)

}

}

var interval

function moveDownBox()

{

interval=1000-10*(gotLine>80?80 :gotLine)

msg.innerHTML=" 等级:"+Math.floor(gotLine/10)+";得分:"+gotLine*100

box.moveDown()

doing=window.setTimeout('moveDownBox()',interval)

}

function startGame()

{

init()

doing=window.setTimeout('moveDownBox()',1000)

bGameOver=false

box=new Box((wnum-1)/2,0,boxdata[Math.floor(Math.random()*7)],Math.floor(Math.random()*5)+1)

box.putNewBox()

drawGrid()

}

var status

function stop(){

status=1

window.clearTimeout(doing)

}

function restart(){

if(status==1){

status=0

doing=window.setTimeout('moveDownBox()',1000)

}

}

function keydown(){

if (document.all)document_onkeydown()

}

</script>

<BODY onLoad="window.focus()" onkeydown="keydown()">

<table width="100%" height="100%" border="0" align="center" cellpadding="0" cellspacing="0">

<tr>

<td>

<table id="maintable" border="0" align="center" cellpadding="0" cellspacing="0">

<tr>

<td align="center">

<span class="btn" style="width:100%height:24pxbackground-color:#F0C0C0color:#0000FFvertical-align:middletext-align:center">俄罗斯方块</span></td>

</tr>

<tr>

<td style="height:20pxbackground-color:blackcolor:#00FF00font-size:12px"><table height="20" border="0" cellpadding="0" cellspacing="0">

<tr style="font-size:12pxcolor:#FFFFFF">

<td width="100%"><a style="cursor:hand" onclick="window.location.reload()">开始(B)</a> <a style="cursor:hand" onclick="stop()">暂停(P)</a> <a style="cursor:hand" onclick="restart()">继续(C)</a></td>

</tr>

</table></td>

</tr>

<tr>

<td style="height:20pxbackground-color:blackcolor:#00FF00font-size:12px" id="msg">等级:0;得分:0</td>

</tr>

<tr>

<td height="20">

<script language=javascript>

maintable.style.width=(wnum+1)*20

startGame()

</script>

</td>

</tr>

</table></td>

</tr>

</table>

</body>

</html>

<html>

<head>

<meta http-equiv="Content-Type" content="text/htmlcharset=gb2312">

<meta name="GENERATOR" content="Microsoft FrontPage 6.0">

<meta name="ProgId" content="FrontPage.Editor.Document">

<title>俄罗斯方块游戏</title>

<style>

TD{width: 20height: 20}

</style>

</head>

<body bgcolor="#000000" text="#0099FF" link="#0099FF" vlink="#0099FF" alink="#0099FF" style="line-height: 150%">

<script>

document.body.innerHTML += '<DIV id="stage" style="position: absolutetop: 0left: 0"></DIV>' //游戏场地

document.body.innerHTML += '<div id="element_stage" style="position: absolutetop: 3left: 500width: 159height: 152"></div>'//预显表

document.body.innerHTML += '<div id="obj_stage" style="position: absolutetop: 0left: 132display: blockz-index: 100"></div>'//活动层

var element_html = '<table id="element_table" border="1" width="100%" height="100%" bordercolor="#000000" cellspacing="0" cellpadding="0">'

var obj_html = '<table id="obj_table" border="1" bordercolor="#000000" cellspacing="0" cellpadding="0">'

for(h=0h<=4h++) //-------生成预显表 和 活动层-------//

{

element_html += "<tr>"

obj_html += "<tr>"

for(w=0w<=4w++)

{

element_html += "<td bgcolor=\"\" value=\"0\"></td>"

obj_html += "<td bgcolor=\"\" value=\"0\"></td>"

}

element_html += "</tr>"

obj_html += "</tr>"

}

element_html += "</table>"

obj_html += "</table>"

element_stage.innerHTML = element_html

obj_stage.innerHTML = obj_html

document.body.innerHTML +='<p align="right">第 <span id="game_number">1</span>局</p><p align="right">消除行数<br><span id="game_line">0</span></p><p align="right">游戏得分<br><span id="game_score">0</span></p>p align="right"></p><p align="right"><a href="javascript:" value="0" onclick="If_play(this.value)">开 始</a></p>'

var map = new Array( //地图

"111000000000000111","111000000000000111","111000000000000111","111000000000000111","111000000000000111",

"111000000000000111","111000000000000111","111000000000000111","111000000000000111","111000000000000111",

"111000000000000111","111000000000000111","111000000000000111","111000000000000111","111000000000000111",

"111000000000000111","111000000000000111","111000000000000111","111000000000000111","111000000000000111",

"222222222222222222","222222222222222222"

)

//-------------L------------// //演员表

var L1 = new Array("0000","1000","1000","1100")

var L2 = new Array("0000","0000","0010","1110")

var L3 = new Array("0000","0110","0010","0010")

var L4 = new Array("0000","1110","1000","0000")

//-------------L-------------//

//-------------J------------//

var J1 = new Array("0000","0010","0010","0110")

var J2 = new Array("0000","0000","1110","0010")

var J3 = new Array("0000","1100","1000","1000")

var J4 = new Array("0000","0000","1000","1110")

//-------------J-------------//

//-------------Z------------//

var Z1 = new Array("0000","0000","1100","0110")

var Z2 = new Array("0000","0100","1100","1000")

var Z3 = new Array("0000","0000","1100","0110")

var Z4 = new Array("0000","0100","1100","1000")

//-------------Z-------------//

//-------------S------------//

var S1 = new Array("0000","0000","0110","1100")

var S2 = new Array("0000","0100","0110","0010")

var S3 = new Array("0000","0000","0110","1100")

var S4 = new Array("0000","0100","0110","0010")

//-------------S-------------//

//-------------T------------//

var T1 = new Array("0000","0000","0100","1110")

var T2 = new Array("0000","0010","0110","0010")

var T3 = new Array("0000","1110","0100","0000")

var T4 = new Array("0000","1000","1100","1000")

//-------------T-------------//

//-------------M------------//

var M1 = new Array("0000","0000","1100","1100")

var M2 = new Array("0000","0000","1100","1100")

var M3 = new Array("0000","0000","1100","1100")

var M4 = new Array("0000","0000","1100","1100")

//-------------M-------------//

//-------------I------------//

var I1 = new Array("1000","1000","1000","1000")

var I2 = new Array("0000","0000","0000","1111")

var I3 = new Array("0010","0010","0010","0010")

var I4 = new Array("0000","0000","0000","1111")

//-------------I-------------//

//-------------演员位置表-------------//

var players = new Array("I","J","T","L","Z","S","M")

//----生成地图--------//

function get_color(color_value)

{

if(color_value=="1"||color_value=="2")

return "#000080"

else

return "#000000"

}

var map_html = '<table id="map_table" border="1" cellspacing="0" cellpadding="0" bgcolor="#000000" bordercolor="#000000">'

for(h=0h<map.lengthh++)

{

map_html+="<tr>"

for(w=0w<map[0].lengthw++)

{

map_html+="<td value=\""+map[h].charAt(w)+"\" bgcolor=\""+get_color(map[h].charAt(w))+"\">"

}

map_html +="</tr>"

}

map_html+="</table>"

stage.innerHTML = map_html

//----生成地图--------//

/****************************************** 上面是准备的代码****************************************************/

function Y_X(y,x) //设置角的对象

{

this.x = x

this.y = y

}

var game_l_u_angle = new Y_X(0,6) //方快初始 左上角 和 右上角 的 x y 坐标

var game_r_d_angle = new Y_X(3,9)

var left_up_angle = new Y_X(game_l_u_angle.y,game_l_u_angle.x)//现在的 左上角的 x y 坐标

var right_down_angle = new Y_X(game_r_d_angle.y,game_r_d_angle.x)//现在的 右上角 的 x y 坐标

var block_color_1 = "#0099FF"//现在的方块的颜色

var block_color_0 = "" //背景颜色

var map_color_1 = "#000080"//map 背景颜色 1

var map_color_0 = "#000000" //背景颜色 0

var block_width = "22"//方块 的 边长

var block_height = "20"

var game_speed = 540 //游戏速度

var game_max_speed = Math.floor(game_speed/20)

var SHAPES = new Array("I","M","Z","J","T","S","L")// 方块形状数组

var shape_now = SHAPES[returnONE(6)] //现在的方块形状

var shape_will = SHAPES[returnONE(6)]//将来的方块形状

var shape_num = 1

var obj_start_left = 132//方块起始位置

var obj_start_top = 0

var can_move_block = false //设置用户是否可以移动方块

var can_play = false //游戏的开始

var one_score = 10 //一个的得分

var block_score = 4*one_score //一个方块的得分

var line_score = 12*one_score //一行的得分

/*******************************************上面是数据********************下面是具体运行 函数************************/

//------------返回任意数--------------------//

function returnONE(JSnum){

JSnum = Math.round(JSnum*Math.random()*100/100)

return JSnum

}

//--------------返回最高-----------------------//

function return_TOP()

{

var block_value = ""

for(h=0h<4h++)

{

for(w=0w<4w++)

{

block_value = obj_table.rows(h).cells(w).value

if(block_value=="1")

return (h + left_up_angle.y)

}

}

}

//---------设置 obj 显示 指定 的 type+num 方块 -----------//

function set_block(obj,type,num)

{

var block = eval(type+num)//获得 指定 方块

var block_value = ""

var block_color = ""

for(h=0h<block.lengthh++)

{

for(w=0w<block[0].lengthw++)

{

block_value = block[h].charAt(w)

block_color = eval("block_color_" + block_value )

with(obj.rows(h).cells(w))

{

bgColor = block_color

value = block_value

}

}

}

}

//-------------使 obj 相对移动--------------//

function move_block_by(x,y)

{

left_up_angle.x += x

left_up_angle.y += y

right_down_angle.x += x

right_down_angle.y += y

obj_stage.style.pixelLeft = left_up_angle.x * block_width

obj_stage.style.pixelTop = left_up_angle.y * block_height

}

//---------------判断 是否 可以 移动 或变形 -------------//

function If_can_move(l_x,l_y,r_x,r_y) //用于常规判断

{

var obj_value = ""

var map_value = ""

var checker = 0

for(obj_h=0,h=l_yh<=r_yh++,obj_h++)

{

for(obj_w=0,w=l_xw<=r_xw++,obj_w++)

{

obj_value = obj_table.rows(obj_h).cells(obj_w).value

map_value = map_table.rows(h).cells(w).value

checker = parseInt(obj_value)+parseInt(map_value)

if(map_value=="2")

{

if(checker>2)

return false

}

else

{

if(checker>1)

return false

}

}

}

return true

}

function test_block(){} //用来生成载block value 的 测试对象

var tester = null

function If_can_move_test(l_x,l_y,r_x,r_y) //用于变形判断

{

var obj_value = ""

var map_value = ""

var checker = 0

for(obj_h=0,h=l_yh<=r_yh++,obj_h++)

{

for(obj_w=0,w=l_xw<=r_xw++,obj_w++)

{

obj_value = eval("tester.value_"+obj_h+"_"+obj_w)

map_value = map_table.rows(h).cells(w).value

checker = parseInt(obj_value) + parseInt(map_value)

if(map_value=="2")

{

if(checker>2)

return false

}

else

{

if(checker>1)

return false

}

}

}

return true

}

//--------------设置背景颜色----------------------//

function set_map_bgcolor(l_x,l_y,r_x,r_y)

{

var obj_value = ""

for(obj_h=0,h=l_yh<=r_yh++,obj_h++)

{

for(obj_w=0,w=l_xw<=r_xw++,obj_w++)

{

obj_value = obj_table.rows(obj_h).cells(obj_w).value

if(obj_value=="1")

{

with(map_table.rows(h).cells(w))

{

value = obj_value

bgColor = eval("block_color_"+obj_value)

}

}

}

}

}

//---------------消除 行 --------------------------------//

function delete_line(l_y,r_y)

{

var value_1_num = 0//为 1 的块数

var can_delete_num = map[0].length//可以删除的 value = 1 的 block 的总数

var can_delete = true

var the_block_value = "" //现在的block的value

for(h=l_yh<=r_yh++)

{

for(w=0w<can_delete_numw++)

{

the_block_value = map_table.rows(h).cells(w).value

if(the_block_value=="0"||the_block_value=="2")

{

can_delete = false

}

}

if(can_delete) //如果全部为1的话

{

map_table.deleteRow(h)

map_table.insertRow(0)

for(w=0w<map[0].lengthw++)

{

map_table.rows(0).insertCell()

map_table.rows(0).cells(w).value = map[0].charAt(w)

map_table.rows(0).cells(w).bgColor = eval("map_color_"+map[0].charAt(w))

}

game_line.innerText = ""+ (parseInt(game_line.innerText) + 1) + ""

game_score.innerText = ""+ (parseInt(game_score.innerText) + line_score) + ""

}

can_delete = true

}

}

//--------------方块 移动 主进程 down ----------------//

function down_block()

{

if(!can_play)

return

var check_l_y = left_up_angle.y + 1

var check_r_y = right_down_angle.y + 1

var judger = If_can_move(left_up_angle.x,check_l_y,right_down_angle.x,check_r_y)

if(judger)

{

move_block_by(0,1)

setTimeout("down_block()",game_speed)

}

else

{

can_move_block = false

var block_top = return_TOP()

if(block_top<=(game_l_u_angle.y+2))

{

if(confirm("游戏结束,是否继续?"))

{

window.location.reload()

}

else

{

return

}

}

else

{

set_map_bgcolor(left_up_angle.x,left_up_angle.y,right_down_angle.x,right_down_angle.y) //设置背景颜色和value

game_score.innerText = ""+ (parseInt(game_score.innerText) + block_score) + ""

if(parseInt(game_score.innerText)>=(parseInt(game_number.innerText)*20000)) //如果达到过局的分数

{

game_number.innerText = ""+(parseInt(game_number.innerText)+1)+""

game_speed = game_speed - 60

if(game_speed <=0 )

{

game_speed = 540 - (parseInt(game_number.innerText)-1)*60

if(game_speed <0)

{

alert("Win All")

return

}

}

game_max_speed = Math.floor(game_speed/20)

}

obj_stage.style.display = "none"

delete_line(left_up_angle.y,right_down_angle.y)

shape_now = shape_will

shape_will = SHAPES[returnONE(6)]

shape_num =1

set_block(obj_table,shape_now,shape_num)

set_block(element_table,shape_will,shape_num)

left_up_angle.x = game_l_u_angle.x

left_up_angle.y = game_l_u_angle.y

right_down_angle.x = game_r_d_angle.x

right_down_angle.y = game_r_d_angle.y

obj_stage.style.pixelLeft = left_up_angle.x * block_width

obj_stage.style.pixelTop = left_up_angle.y * block_height

obj_stage.style.display = "block"

can_move_block = true

setTimeout("down_block()",game_speed)

}

}

}

//-------------- 获取 用户输入 方向 -------------- //

function document.onkeydown()

{

if(!can_play) //如果不能玩,退出

return

if(!can_move_block) //如果不能移动。则退出

return

var key_code = event.keyCode

if(key_code == 37)

{

var check_l_x = left_up_angle.x - 1

var check_r_x = right_down_angle.x - 1

var judger= If_can_move(check_l_x,left_up_angle.y,check_r_x,right_down_angle.y)

if(judger)

move_block_by(-1,0)

else

return

}

if(key_code == 39)

{

var check_l_x = left_up_angle.x + 1

var check_r_x = right_down_angle.x + 1

var judger= If_can_move(check_l_x,left_up_angle.y,check_r_x,right_down_angle.y)

if(judger)

move_block_by(1,0)

else

return

}

if(key_code == 38)

{

shape_num++

if(shape_num>4)

shape_num = 1

tester = null

tester = new test_block()

var test_shape = eval(shape_now + shape_num)

for(h=0h<test_shape.lengthh++)

{

for(w=0w<test_shape[0].lengthw++)

{

eval("tester.value_"+h+"_"+w+"=test_shape["+h+"].charAt("+w+")")

}

}

var judger = If_can_move_test(left_up_angle.x,left_up_angle.y,right_down_angle.x,right_down_angle.y)

if(!judger)

{

shape_num--

}

else

{

set_block(obj_table,shape_now,shape_num)

}

}

if(key_code == 40)

{

game_speed = game_max_speed

}

}

function document.onkeyup()

{

game_speed = 540 - (parseInt(game_number.innerText)-1)*60

}

//-----------------游戏控制-----------------------////

function start_game(){ //游戏开始

can_play = true

can_move_block =true

set_block(obj_table,shape_now,shape_num)

set_block(element_table,shape_will,shape_num)

down_block()

}

function pause_game() //暂停 游戏

{

can_play = false

can_move_block =false

}

function If_play(play_value)

{

if(play_value=="0") //如果是刚开始

{

start_game()

event.srcElement.value = "1"

event.srcElement.innerText = "暂 停"

}

if(play_value=="1")

{

pause_game()

event.srcElement.value = "2"

event.srcElement.innerText = "开 始"

}

if(play_value == "2")

{

can_play = true

can_move_block =true

down_block()

event.srcElement.value = "1"

event.srcElement.innerText = "暂 停"

}

}

</script>

</body>

</html>

顾名思义,俄罗斯方块自然是俄罗斯人发明的。这位伟人叫做阿列克谢·帕基特诺夫(Alexey Pazhitnov) 。

然而,很少有人知道,这个著名的游戏在80年代曾经在法律界掀起轩然大波,那就是著名的俄罗斯方块产权之争。这次产权争夺,几家欢喜,几家哀愁,几家公司倒闭,几家公司赚钱,其中的是是非非,一言难尽。

欧美列强窃取瓜分:版权之争由此开始

1985年6月工作于莫斯科科学计算机中心的阿列克谢·帕基特诺夫在玩过一个拼图游戏之后受到启发,从而制作了一个以Electronica 60(一种计算机)为平台的俄罗斯方块的游戏。后来经瓦丁·格拉西莫夫(Vadim Gerasimov)移植到PC上,并且在莫斯科的电脑界传播。帕基特诺夫因此开始小有名气。

PC版俄罗斯方块在匈牙利的布达佩斯被当地的一群电脑专家移植到了Apple II 和 Commodore 64 上,这些版本的软件引起了当时英国一个叫Andromeda的游戏公司经理罗伯特·斯坦恩(Robert Stein)的注意,他向帕基特诺夫以及匈牙利的电脑专家们收购了俄罗斯方块的版权,并且在买到版权之前把它们倒手卖给了英国的Mirrorsoft (注意不是Microsoft!) 以及美国的Spectrum Holobyte。(什么人……)

1986年11月斯坦恩和帕基特诺夫经过谈判,就版权收购问题未取得成果。斯坦恩甚至直接飞到莫斯科和帕基特诺夫面谈,但是空手而归。由于俄罗斯人对于已经在西方兴起的电子游戏产业知道不多,斯坦恩决定窃取Tetris的版权,于是他放出谣言说这是匈牙利人开发的游戏。

与此同时,PC版的俄罗斯方块已经由英国的Mirrorsoft出品并且在欧洲销售,受到当时人们的极大关注。不仅仅因为这个游戏好玩,而且这是“第一个来自铁幕国家的游戏。”当时的游戏宣传海报上有浓郁的冷战色彩,比如战争画面,加加林太空飞行等。而斯坦恩仍然没有正式合法的版权。

1987年6月斯坦恩最终取得了在IBM-PC及其兼容机上的Tetris的版权,版权机种包括“其他任何电脑系统”。但是,他没有和苏联方面签署协议,也就是说,这个版权是不完全的。(译者注: 这个“其他任何电脑系统”在原文中的描述是"any other computer system",这种说法在当时看来也很不严密,从而为后来的产权之争埋下了伏笔)

1988年1月Tetris在电脑平台的热销,一时造成“洛阳纸贵”(伦敦磁盘贵??)的局面。而当CBS晚报采访了俄罗斯方块之父帕基特诺夫之后,斯坦恩盗窃版权的计划彻底泡汤了。(活该!)一个新的公司ELORG(Electronorgtechinca,苏联一家软件公司)开始和斯坦恩就游戏程序问题进行协商。ELORG的负责人亚历山大·阿列欣科( Alexander Alexinko)知道斯坦恩虽然没有版权,但是会以手中的游戏开发程序为筹码威胁中断谈判。

任天堂也来掺和:三路人马夹击“装在套子里的人”

1988年5月经过几个月的争吵之后,筋疲力尽的斯坦恩终于和ELORG签定了PC俄罗斯方块版权的合约。当时的合约禁止开发街机版和掌机版的方块游戏,而电脑版的Tetris则成为当时最畅销的游戏。

1988年7月斯坦恩与阿列欣科商谈开发街机版俄罗斯方块的问题。阿列欣科当时尚未从斯坦恩那里拿到一分钱的版权费,但是同时的Spectrum 和 Mirrorsoft已经开始向电子游戏商出售了俄罗斯方块的版权。Spectrum 将Tetris的游戏机和PC在日本的版权卖给了Bullet-Proof Software (FC和GB版俄罗斯方块的制作商),而Mirrorsoft则把它在日本和北美的版权卖给了美国的Atari。这样一来两家公司的矛盾就开始了。 1988年11月,BPS在FC上发行的俄罗斯方块(大家不很熟悉的俄罗斯方块1)在日本发售,销量达200万份。

1988年11月随着GB的开发,NOA(任天堂美国分公司)的经理荒川实(任天堂山内溥老爷子的女婿)希望将Tetris做成GB上的游戏。于是他联系了BPS的总裁亨克·罗杰斯(Henk Rogers), 罗杰斯再与斯坦恩联系的时候却吃了闭门羹。于是他直接去莫斯科购买版权。而斯坦恩觉察出风头,也乘飞机前往莫斯科;与此同时,Spectrum的负责人罗伯特·麦克斯韦(Robert Maxwell)的儿子凯文·麦克斯韦(Kevin Maxwell) 也在向莫斯科进发。就这样,三路人马几乎在同时赶到了冰天雪地的红色都市。

1989年2月21日罗杰斯首先会见了ELORG的代表叶甫盖尼·别里科夫(Evgeni Belikov,和那个“装在套子里的人”同名)。他给帕基特诺夫等苏联人留下了深刻印象,并且签了手掌机方块游戏的版权。之后他向俄国人展示了FC版Tetris,这使别里科夫极为震惊。因为他并没有授予罗杰斯家用机的版权!罗杰斯则向他们说这是向TENGEN购买的版权,但是别里科夫也从没听说过TENGEN这个公司的名字。罗杰斯为了缓和尴尬的局面,将斯坦恩隐瞒的事实如数告诉了别里科夫,并且答应付给苏联方面更多支票作为已经卖出的FC版俄罗斯方块的版权费用。这时罗杰斯发现自己有机会买到Tetris全部机种的版权(但是当时还没买),虽然Atari会对他虎视耽耽,但是别忘了,他和BPS的背后还有任天堂这个大靠山给自己撑腰。

注意:罗伯特·斯坦恩原先所签的协议只是电脑版Tetris的版权,其他的版权并不是他的。

后来,斯坦恩和ELORG重新签署了协议。别里科夫强迫他重签的合约中修改的内容是:“电脑的定义:包含有中央处理器,监视器,磁盘驱动器,键盘和 *** 作系统的机器”。而斯坦恩当时却没有仔细看这些定义。(这回轮到他犯混了……)后来他才意识到这是罗杰斯从自己手中抢走版权而耍的花招。但是为时已晚。第二天他被告知虽然签署的文件已经不能改后来,但是他还可以得到街机版Tetris的开发权。三天之后,他签下了街机版的协议。

FC版权风云再起:

充分体现国家干预经济1989年2月22日凯文·麦克斯韦访问了ELORG。别里科夫拿出罗杰斯给他的FC游戏卡向他询问这件事情。麦克斯韦在卡带上看到了Mirrorsoft的名字后才想起他的公司已经把部分版权倒卖给了Atari。(糊涂人办糊涂事……)当他想继续谈街急和手掌机版权的问题的时候,却发现自己他能够签的,就只有除电脑,街机,家用机和掌机以外的协议了。(其实等于没有协议可签,除非他发明一种新的娱乐系统,比方说俄罗斯方块积木……)在糊涂之余这家伙灵机一动,告诉别里科夫说此卡带为盗版(汗……),然后也要签家用机的协议。最后的结果是:凯文·麦克斯韦只带走一张白纸,罗伯特·斯坦恩带走了街机协议书。由于麦克斯韦声称所有的FC卡都是盗版,ELORG保留了家用机的版权,没卖给任何人。假如麦克斯韦想获得家用机版权的话,就必须出价比任天堂高才行。亨克·罗杰斯买到了掌机的版权,并且通知了荒川实。BPS就制作GB版Tetris向任天堂达成交易:这笔交易额高大500万-1000万美元。

GB版的俄罗斯方块

GB版俄罗斯方块1989年3月15日亨克·罗杰斯回到莫斯科,并且代表任天堂出巨资收购家用机版Tetris的版权。版权费的价格虽然没有向外界透露,但是这个数字将是Mirrorsoft永远拿不出来的。连荒川实和NOA的首席执行官霍华德·林肯(Howard Lincoln)都亲自前往苏联助阵。

1989年3月22日ELORG和任天堂的家用机协议终于达成。任天堂方面坚持加入一款声明,在协议签定之后,如果和其他出现法律纠纷,苏联方面必须派人去美国的法庭上做证。实际上,这种法律上的争端将是不可避免的。据说ELORG仅仅得到的定金有300-500万美元之多。别里科夫向Mirrorsoft通知,说Mirrorsoft, Andromeda和Tengen都没有家用机的版权,现在版权都归任天堂所有。当天晚上任天堂和BPS的头目们在莫斯科酒店里举行了庆祝party。

(各位看明白了,现在家用机和掌机的版权已经被任天堂和BPS分别掌握在手中。无论是Atari还是Tengen都没有权利制作FC版的俄罗斯方块。)

1989年3月31日霍华德·林肯 愉快(幸灾乐祸?)地向Atari发去最后通牒(传真),告诉他们立刻停止FC(NES)版的俄罗斯方块游戏。这使得Atari和麦克斯韦都十分震怒。他们以Tengen的名义回信说在4月7日那天他们就已经享有家用机俄罗斯方块的版权了。

1989年4月13日Tengen撰写了一份申请书,要求拥有Tetris的“影音作品,源程序和游戏音乐”版权。但是申请书中并没有提及阿列克谢·帕基特诺夫和任天堂的游戏版权问题。(忽视了阿列克谢·帕基特诺夫真是个大错误!)

与此同时,麦克斯韦利用自己掌握的媒体势力,企图夺回Tetris的阵地。甚至搬出了苏联与英国政府,对俄罗斯方块版权问题进行干预。(好大的面子啊!)结果挑起了苏共(!)与ELORG之间的矛盾。甚至连戈尔巴乔夫都向麦克斯韦保证“以后不用担心日本公司的问题”。(汗……这位麦克斯韦果然不是善主……伟大的苏联政府都对俄罗斯方块关注起来了……)在4月晚些时候,霍华德·林肯回到莫斯科的时候,发现ELORG已经在苏联政府的打压下抬不起头来,而就在那天半夜,NOA方面给他打电话,说Tengen已经起诉了任天堂。(山雨欲来风满楼啊……)

第二天,他面会了别里科夫,帕基特诺夫和其他几位ELORG的成员,以确保他们能够为任天堂的官司佐证。(这回合同里的条款可生效了)随后NOA立刻反诉Tengen,并且开始收集证据。

FC是电脑还是家用机?任天堂大获全胜

1989年5月17日Tengen在USA Today上登载了大幅Tertis广告,虽然法庭大战已经迫在眉睫。

1989年6月Tengen与任天堂的案子终于开庭审理论战主要围绕一个议题展开:NES(FC)究竟是电脑,还是电子游戏机。(大家不许笑,在法庭上这可是很严肃的话题)Atari认为NES是电脑系统,因为它拥有扩展机能,而且日本的Famicom也有网络功能存在。而任天堂的证据则更加切题:ELORG中的苏联人从来没有意向出售Tetris的家用机版权,而所谓的“电脑”的概念则早在和斯坦恩的协议中提到了。

1989年6月15日法庭召开听证会,讨论关于任天堂和Tengen互相命令对方终止生产和销售各自的Tetris软件的行为。法官福恩·史密斯(Fern Smith)宣布Mirrorsoft 与 Spectrum Holobyte均没有家用机版权,因此他们提供给Tengen的权利也不能生效。任天堂的请求最后得到了许可。

1989年6月21日Tengen版的俄罗斯方块全部撤下了货架,该游戏卡带的生产也被迫中止。数十万份软件留在包装盒里,封存在仓库中。

1989年7月任天堂NES版Tetris在美国发售。全美销量大约300万。与此同时,和GB版Tetris捆绑销售的Game Boy席卷美国,美利坚大地上刮起一阵方块旋风。

关于Tetris的混战此时已经告一段落。而任天堂和Tengen之间的法庭纠纷则一直持续到1993年。

尾声:狂赚钱与做白工?!还好玩家没吃亏

尾声Atari Games仍然开发了街机版的Tetris,共卖出约2万台机器。近来Atari Games 被 Williams/WMS收购,而那些封存在仓库里的NES版Tetris的命运则没人知道。Tengen不能从其他途径把它们处理掉,所以估计这些软件都被销毁了。但是据说仍然有约10万份Tengen版的Tetris流入了市场。

我们今天在64合一等游戏D版卡里玩到的所谓“俄罗斯方块2”其实就是当年的Tengen版,平心而论,这一版的方块比BPS的版本要好玩许多。首先,这版的 *** 作感和按键设定十分到位,AB分别是正转和反转,而BPS版是用十字键的下来转动,只支持一个方向,按A就直接“啪”地落下来,手感十分不爽;其次,它支持的二人对战,与电脑竞争和合作的模式也让人耳目一新。还有,音乐也是没的说。

罗伯特·斯坦恩,这个版权问题的始作俑者,在Tetris上总共只赚了25万美元。本来他可以挣多点钱的,但是Atari和Mirrorsoft在付他版税的时候没有给足。(应得的报应……)Spectrum Holobyte 则需要和ELORG重新协商,以确保电脑版Tetris的版权。

罗伯特·麦克斯韦的媒体堡垒在混战中逐渐分崩离析,老麦克斯韦在做生意时做幕后黑手的事实也在调查中,而他却突然暴病身亡。(气死的……)Mirrorsoft 英国公司也惨淡地退出了历史舞台。

真正的大赢家是BPS的总裁亨克·罗杰斯,还有幕后的任天堂。俄罗斯方块究竟为任天堂赚了多少银子呢?答案恐怕永远说不清了。想一想吧,在美国GB都是和Tetris捆绑销售,以增加GB的出货量……然后因为Tetris买了GB的人还会买其他的GB卡……要是这么算起来的话,那利润简直就像滚雪球一样了。现在GB版的Tetris(Z版)总共生产了3000万张。(后来GB的俄罗斯方块又在SFC上出了复刻版,和《马里奥医生》一起出现在屏幕上,成为不朽之作。)

至于苏联方面,除了苏联政府,谁也没有从Tetris那里得到多少好处。苏联解体之后,原ELORG的人员都四散到了全国乃至世界各地,许多人继续开发游戏(比方说帕基特诺夫)。

阿列克谢·帕基特诺夫几乎没有从Tetris上赚到一分钱。ELORG本来打算给他Tetris的销售权,但是旋即取消了这笔交易。不过帕基特诺夫仍然为自己能够制作出这么一个世界闻名的优秀游戏而欣慰。他从科学院里得到一台286(当时在苏联可是了不起的电脑)作为奖励。而且分到了比同事们家宽敞明亮的房子。在1996年,亨克·罗杰斯支付给他一笔报酬(还算是个知恩图报的人),帕基特诺夫组建了Tetris Company LLC 公司,终于能够自己创作游戏,并且收取版权费了。

注:当年俄罗斯方块红遍世界的各个角落,一个本来是吃大锅饭的人在消极怠工的时候发明的娱乐工具成了造福全人类的宝贝,它的价值远远超越了开发这个软件时候的预想。Atari虽然在法庭上惨败,但是拜亚洲盗版商人所赐,Tengen版的俄罗斯方块已经在中国玩家心目中生根发芽,长叶开花,任天堂的正统Tetris在中国反而没人玩了。其实说了那么多,归根到底,平平淡淡才是真。有机会的话,下载一个FC的模拟器和一个64合一的经典ROM,回家体会一下俄罗斯方块的魅力吧……


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/7067451.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-01
下一篇 2023-04-01

发表评论

登录后才能评论

评论列表(0条)

保存