之前編寫(xiě)過(guò)一個(gè)單機(jī)版的游戲letters,晚上睡不著,稍加改動(dòng),變成聯(lián)機(jī)版的了。
靜態(tài)頁(yè)面 letters.htm

<SCRIPT>
var isIE=!!document.all;

function checkMouseMove(event)
{

if (window.activeElement)
{
var elm = window.activeElement;
elm.style.left = event.clientX-elm.innerX;
elm.style.top = event.clientY-elm.innerY;
if(xmlhttp)xmlhttp.abort();
if(timer)clearTimeout(timer);
}
}

function releaseMouse(event)
{

if (window.activeElement)
{
var x = activeElement.offsetLeft;
var y = activeElement.offsetTop;
var pos = activeElement.id;
var data =y.toString(16);
data = x.toString(16)+"0000".substr(data.length)+data;
var url = "http://localhost:8080/letters/letters.jsp?pos="+pos+"&data="+data;
if(xmlhttp)xmlhttp.abort();
xmlhttp = window.XMLHttpRequest?(new XMLHttpRequest()):(new ActiveXObject("Microsoft.XMLHTTP"));
xmlhttp.onreadystatechange= handleXML;
xmlhttp.open("GET",url,true);
xmlhttp.send(null);
window.activeElement = null;
}
}

function drag(event)
{
if (event.button>1) return;
var elm = isIE?event.srcElement:event.target;
window.activeElement = elm;
elm.oldX = elm.offsetLeft;
elm.oldY = elm.offsetTop;
elm.innerX = event.clientX - elm.oldX;
elm.innerY = event.clientY - elm.oldY;
}


function slideTo(id,x,y)
{
var d=3;
var e = document.getElementById(id);
var l = e.style.left?parseInt(e.style.left):0;
var t = e.style.top?parseInt(e.style.top):0;
if(Math.abs(l-x)<=d && Math.abs(t-y)<=d) return;
if(l!=x) e.style.left=l+(l<x?d:-d);
if(t!=y) e.style.top=t+(t<y?d:-d);
if(e.timer) clearTimeout(e.timer);
e.timer=setTimeout("slideTo("+id+","+x+","+y+")",3)
}


function jumpTo(id,x,y)
{
var e = document.getElementById(id);
if(e.timer) clearTimeout(e.timer);
e.style.left=x;
e.style.top=y;
}

var xmlhttp;

function refreshPos()
{
if(xmlhttp) return;
xmlhttp = window.XMLHttpRequest?(new XMLHttpRequest()):(new ActiveXObject("Microsoft.XMLHTTP"));
xmlhttp.onreadystatechange= handleXML;
xmlhttp.open("GET","http://localhost:8080/letters/letters.jsp",true);
xmlhttp.setRequestHeader("If-Modified-Since","0");
xmlhttp.send(null);
}

function handleXML()
{

if(xmlhttp.readyState==4&&xmlhttp.status==200)
{
var posList = xmlhttp.responseText.split(",");
if(posList.length>=n)

for(var i=0;i<n;i++)
{
var p = posList[i];
var x = parseInt(p.substring(0,p.length-4),16);
var y = parseInt(p.substr(p.length-4),16);
if(!timer) jumpTo(i,x,y);
else slideTo(i,x,y);
}
xmlhttp=null;
timer = setTimeout("refreshPos()",500);
}
}
var n=104;
var timer;
window.onload=refreshPos;
</SCRIPT>
</HEAD>

<style>
b{
}{position:absolute;cursor:pointer;font-size:20}</style>
<BODY onmousemove="checkMouseMove(event)" onmouseup="releaseMouse(event)" oncontextmenu="return false" onselectstart="return false" ondblclick="return false">
<div style="background-color:yellow;width:600;height:500;overflow:hidden">

<SCRIPT>
for(var i=0;i<n;i++)
document.write("<b onmousedown=\"drag(event)\" id=\""+i+"\" style=\"color:#"+(Math.floor(Math.random()*(1<<24))|(1<<23)).toString(16)+"\" onbeforselect=\"return false\">"+String.fromCharCode(i%26+65)+"</b>");
</SCRIPT>
</div>
服務(wù)程序letters.jsp:

<%
@ page contentType="text/html; charset=GBK" %>

<%
! int[] letters;
int maxLetters = 104;

%><%
letters = (int[])application.getAttribute("letters");
if(null == letters){
letters = new int[maxLetters];
for(int i=0;i<maxLetters;i++) letters[i]=(Math.round(i/26)*15+1)+(((i%26+1)*15)<<16);
application.setAttribute("letters",letters);
}
String stPos = request.getParameter("pos");
String stData = request.getParameter("data");
if(stPos!=null && stData !=null){
try{
int pos = Integer.parseInt(stPos);
int data = Integer.parseInt(stData,16);
letters[pos]=data;
}catch(Exception e){
e.printStackTrace();
}
}
for(int i=0;i<maxLetters;i++) out.print(Integer.toHexString(letters[i])+",");
%>

當(dāng)然服務(wù)程序如果直接寫(xiě)servlet可以更優(yōu)化,不過(guò)我寫(xiě)servlet很依賴(lài)IDE或者手冊(cè),用jsp寫(xiě)就比較容易貫徹裸奔精神了。直接用tomcat發(fā)布出去即可運(yùn)行(注意靜態(tài)頁(yè)面中兩處hardcode的“http://localhost:8080/letters/letters.jsp”有可能需要根據(jù)發(fā)布環(huán)境做相應(yīng)的修改)。服務(wù)程序代碼做的相當(dāng)簡(jiǎn)單,改asp版應(yīng)該也不為難。詳細(xì)的說(shuō)明春節(jié)后補(bǔ)充,簡(jiǎn)單的介紹一下數(shù)據(jù)結(jié)構(gòu):
1 每個(gè)字母的位置由一個(gè)32位十六進(jìn)制數(shù)字表示,前16位為橫坐標(biāo),后16位為縱坐標(biāo),坐標(biāo)空間65536*65536
2 application中維持一個(gè)所有字母的位置列表,通過(guò)“l(fā)etters”這個(gè)key引用。
3 參數(shù)格式為pos:被移動(dòng)的字母的序號(hào),data:為該字母的新位置。
點(diǎn)擊這里下載源碼
靜態(tài)頁(yè)面 letters.htm


























































































































服務(wù)程序letters.jsp:






























當(dāng)然服務(wù)程序如果直接寫(xiě)servlet可以更優(yōu)化,不過(guò)我寫(xiě)servlet很依賴(lài)IDE或者手冊(cè),用jsp寫(xiě)就比較容易貫徹裸奔精神了。直接用tomcat發(fā)布出去即可運(yùn)行(注意靜態(tài)頁(yè)面中兩處hardcode的“http://localhost:8080/letters/letters.jsp”有可能需要根據(jù)發(fā)布環(huán)境做相應(yīng)的修改)。服務(wù)程序代碼做的相當(dāng)簡(jiǎn)單,改asp版應(yīng)該也不為難。詳細(xì)的說(shuō)明春節(jié)后補(bǔ)充,簡(jiǎn)單的介紹一下數(shù)據(jù)結(jié)構(gòu):
1 每個(gè)字母的位置由一個(gè)32位十六進(jìn)制數(shù)字表示,前16位為橫坐標(biāo),后16位為縱坐標(biāo),坐標(biāo)空間65536*65536
2 application中維持一個(gè)所有字母的位置列表,通過(guò)“l(fā)etters”這個(gè)key引用。
3 參數(shù)格式為pos:被移動(dòng)的字母的序號(hào),data:為該字母的新位置。
點(diǎn)擊這里下載源碼