之前编写过一个单机版的游戏
letters,晚上睡不着,稍加改动,变成联机版的了。
静态页面 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> 服务程序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])+",");
%>
当然服务程序如果直接写servlet可以更优化,不过我写servlet很依赖IDE或者手册,用jsp写就比较容易贯彻裸奔精神了。直接用tomcat发布出去即可运行(注意静态页面中两处hardcode的“
http://localhost:8080/letters/letters.jsp”有可能需要根据发布环境做相应的修改)。服务程序代码做的相当简单,改asp版应该也不为难。详细的说明春节后补充,简单的介绍一下数据结构:
1 每个字母的位置由一个32位十六进制数字表示,前16位为横坐标,后16位为纵坐标,坐标空间65536*65536
2 application中维持一个所有字母的位置列表,通过“letters”这个key引用。
3 参数格式为pos:被移动的字母的序号,data:为该字母的新位置。
点击这里下载源码