1 调试环境是Win7/10 IIS 后台采用VS2008, C#
后台采用无界面程序,直接在page_load里面处理数据,为了多个客户端共享数据,
采用asp.net里面的Application["posX"]的方式存储共享数据,其实可以有更多的方式,比如XML文件,数据库等。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.SessionState; //Application对象
public partial class _Default : System.Web.UI.Page
{
protected string str = "";
protected void Page_Load(object sender, EventArgs e)
{
Application.Lock();
//存储数据,有数据发送,则接收数据
if (Request.RequestType.ToString() == "POST")
{
Application["posX"] = Request["posX"];
Application["posY"] = Request["posY"];
}
//如果没有建立对象,则建立对象并赋初值
if (Application["posX"] == null || Application["posY"] == null)
{
Application["posX"] = "0.0";
Application["posY"] = "0.0";
}
//返回信息,拼接XY坐标,每个数据用";"做分隔
str = Request.RequestType.ToString()+";";
str += Application["posX"].ToString()+";";
str += Application["posY"].ToString()+";";
Response.Write(str);
Application.UnLock();
}
}
2 前端采用ThreeJS,使用JavaScript进行操作,在键盘函数里通过POST发送数据,自己的项目可以自己决定发送位置。
//键盘函数
function WxpKeyPressed(e) {
var key = event.keyCode;
//if (!boundingBox)
// document.getElementById("notice").innerHTML = "请先选中物体" + key.toString();
switch (key) {
case 87: /*w*/
selectedObject.position.y += 0.2;
break;
case 65: /*a*/
selectedObject.position.x -= 0.2;
break;
case 83: /*s*/
selectedObject.position.y -= 0.2;
break;
case 68: /*d*/
selectedObject.position.x += 0.2;
break;
}
xhr.onreadystatechange=WxpCallBack;
xhr.open("POST","default.aspx",true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
//获取当前值
positionX=cube.position.x;
positionY=cube.position.y;
//组合发送post串
var str=new String("posX=");
str=str+positionX.toFixed(3); //一定要取小数位数,否则会有很多小数位
str=str+"&posY=";
str=str+positionY.toFixed(3); //一定要取小数位数,否则会有很多小数位
xhr.send(str);
}
3 回调函数解析服务器端发来的字符串,以后可以使用JSON
//主要是解析接收到的字符
function WxpCallBack()
{
if(xhr.readyState==4)
if(xhr.status==200)
{
var res=xhr.responseText;
var pos=res.indexOf(";");
//取第一个逗号
res=res.slice(pos+1); //去掉第一个逗号之前的数据
//取第二个逗号
pos=res.indexOf(";");
var s1=res.slice(0,pos);
res=res.slice(pos+1); //去掉第二个逗号之前的数据
//取第三个逗号
pos=res.indexOf(";");
var s2=res.slice(0,pos);
// if(s1.indexOf("POST")>0)
//{
//document.getElementById("notice").innerHTML =s1.toString();
//}
//else
// document.getElementById("notice").innerHTML = s1.toString();
positionX=s1;
positionY=s2;
cube.position.x=Number(s1);
cube.position.y=Number(s2);
document.getElementById("notice").innerHTML ="x:"+s1.toString()+" y:"+s2.toString();
}
}
4 在render函数里,一直调用GET请求,保持位置坐标XY一致。当然,可以根据实际需求放到恰当位置。
//渲染场景
function WxpRender() {
stats.begin();
//get测试
//简单获取
xhr.onreadystatechange=WxpCallBack;
xhr.open("GET","default.aspx",true);
xhr.send(null);
//GUI更新必要的参数
//cube.rotation.z += GuiControls.rotationSpeed;
camera.position.x = GuiControls.camerPositionX;
camera.position.y = GuiControls.camerPositionY;
camera.position.z = GuiControls.camerPositionZ;
WxpTexture.offset.x += 0.006;
//先用画布将文字画出
var canvas = document.createElement("canvas");
var ctx = canvas.getContext("2d");
ctx.fillStyle = "#0000ff";
ctx.font = "20px Arial";
ctx.lineWidth = 1;
//绘制矩形框
//ctx.fillRect(0,0,200,100);
ctx.strokeStyle="#ff0000";
ctx.moveTo(1,1);
ctx.lineTo(200,1);
ctx.lineTo(200,100);
ctx.lineTo(1,100);
ctx.lineTo(1,1);
ctx.lineTo(100,50);
ctx.stroke();
ctx.strokeStyle="#0000ff";
ctx.beginPath();
ctx.arc(100,50,Math.random(5)*40,0,2*Math.PI);
ctx.stroke();
var d=new Date();
var txt=d.toLocaleTimeString();
ctx.fillText(txt,4,20);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true;
//使用Sprite显示文字
var material = new THREE.SpriteMaterial({map:texture});
textObj.material=material;
//鼠标控制旋转
//cube.rotation.z=mouseMoveX*0.02;
//document.getElementById("notice").innerHTML = cube.rotation.x.toFixed(2).toString();
//divRender();
//console.log(scene);
if(selectedObject)
{
if (boundingBox)
scene.remove(boundingBox);
//简单的包围盒
// boundingBox = new THREE.BoxHelper(selectedObject, 0x0000ff);
// scene.add(boundingBox);
//完整的线框
var edgesMtl = new THREE.LineBasicMaterial({color: 0xff0000});
var coneEdges = new THREE.EdgesGeometry(selectedObject.geometry, 1);
coneEdges.lineWidth=1;
boundingBox = new THREE.LineSegments(coneEdges, edgesMtl);
scene.add(boundingBox);
//控制位置
boundingBox.position.set(selectedObject.position.x,
selectedObject.position.y,
selectedObject.position.z);
//控制角度
boundingBox.rotation.set(selectedObject.rotation.x,
selectedObject.rotation.y,
selectedObject.rotation.z);
//控制比例
boundingBox.scale.set( selectedObject.scale.x,
selectedObject.scale.y,
selectedObject.scale.z);
}
//渲染场景
renderer.render(scene, camera);
stats.end();
//通过requestAnimationFrame方法在特定时间间隔重新渲染场景,循环调用
requestAnimationFrame(WxpRender);
}
最后给一张效果图,这个坐标可以控制红色方块的位置。主体是IE浏览器效果,小图是360浏览器效果。红色方块的位置始终一致。