>这个系列的教程上次更新还是在八月,辛苦大家等了这么久。这段时间研究了很久各种东西,有时候找教程真是很烦心的事。比如说最近研究QT把,稍微找一个偏技术一点的问题,几乎查到的结果就都是相互转载来的,打开哪篇都差不多,而实际上出现问题的可能不止一个。找QT如何使用正则表达式的文章,基本上搜索出来的大部分文章都是在讲解正则表达式的各种符号怎么使用,而和QT本身的关系不大,最重要的QRegExp讲解被一笔带过,而且按照他们那些文章里面的写法不是无法通过编译就是匹配不到东西。还有再早些时候研究做mc的mod,很多教程都是过时的,或者因为种种原因有各种毛病,还有一个看似不错的教程,并且是讲OpenGL的,可是只更新了一个章节,然后下次更新就不知道要等到何年何月了。有时候我在想,好好花点时间提升文章质量会好一点(那些都是大佬的文章,更新慢,但确实还行),可是,等那么久也未必是很好的事吧、
好了,做了一万个实验后总算有时间来更新文章了、
要实现键盘控制其实不是很难的事,尤其是之前已经实现了鼠标控制的情况下。
我们可以考虑监听键盘onkeydown事件,监控用户输入,然后通过camera的position值(x,y,z),来实现位置的移动。因为之前已经做过鼠标控制了,我认为大家做这个应该不是很难,我们在之前鼠标控制的代码前加一段键盘控制代码:
- window.onkeydown=function(ev){
- //alert(ev.keyCode);
- switch(ev.keyCode){
- case 65://左
- mt.camera.position.x--;
- break;
- case 68://右
- mt.camera.position.x++;
- break;
- case 87://前
- mt.camera.position.z--;
- break;
- case 83://后
- mt.camera.position.z++;
- break;
- }
- }
大家可能比较好奇为何前后的加减是反过来的,这里说明一下,这是因为坐标系的缘故,本来是打算让大家回顾下最开始的代码,不过原来写教程的时候因为当时传图不方便,那么大家可以参考下之前鼠标控制的(稍微往下翻一点)那张图(传送门)。由于不考虑坐标被旋转,坐标x轴水平向右,y轴竖直向上,z轴垂直屏幕向外(水平向后),所以显然,默认情况往前走就要减少z轴坐标,往后反之。
好了现在游戏是可以通过键盘控制了,不过如果你有一定基础或是足够细心,甚至只要你自己去试一试也许就会发现有问题了,不过这个问题我先留着,你们不知道的先想想为什么会这样。下面附上本次最终源代码:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>webgl互交测试2</title>
- <style>
- *{
- padding: 0;
- margin: 0;
- }
- #b{
- width: 200px;
- height: 500px;
- background: #000;
- }
- </style>
- </head>
- <body>
- <div id="b">
- <div id="canvas-frame"></div>
- </div>
- <script src="three-js/build/three.js" data-ke-src="https://raw.github.com/mrdoob/three.js/master/build/three.js"></script>
- <script src="three-js/examples/js/libs/stats.min.js"></script>
- <script>
- function mythree(id){
- this.dom=document.getElementById(id);
- this.dom.style.width=window.innerWidth+"px";
- this.dom.style.height=window.innerHeight+"px";
- this.scene = new THREE.Scene();//场景
- this.camera=new THREE.PerspectiveCamera(75, this.dom.offsetWidth / this.dom.offsetHeight, 0.1, 1000);
- this.camera.position.set(0,200,0);
- //this.camera.lookAt(this.scene.position);
- this.renderer = new THREE.WebGLRenderer();//渲染器
- this.renderer.setSize(this.dom.offsetWidth,this.dom.offsetHeight);//设置渲染器大小
- this.renderer.setClearColorHex(0x000000, 1);//设置渲染器颜色
- this.dom.appendChild(this.renderer.domElement);
- //document.body.appendChild(this.renderer.domElement);
- //this.camera.position.z = 180;//设置相机位置
- this.stats = new Stats();
- this.stats.domElement.style.position = 'absolute';
- this.stats.domElement.style.left = '0px';
- this.stats.domElement.style.top = '0px';
- this.dom.appendChild(this.stats.domElement);
- this.rander=(function (obj){
- return function(){
- obj.renderer.render(obj.scene, obj.camera);//渲染
- requestAnimationFrame(obj.rander);
- obj.stats.update();
- }
- })(this);
- this.rander();
- /*this.renderer.domElement.onmousemove=function(ev){
- alert(4)
- }*/
- }
- var mt=new mythree('b');
- var light = new THREE.DirectionalLight(0xffffff,1.0,0); //设置平行光源
- light.position.set(200,100,150); //设置光源向量
- mt.scene.add(light); //追加光源到场景
- var ca=new THREE.Mesh(
- new THREE.CubeGeometry(40,100,40),
- new THREE.MeshLambertMaterial({color: 0x0088ff})
- );//创建实物
- ca.position.set(0,0,0);
- mt.scene.add(ca);
- c=new THREE.Mesh(
- new THREE.CubeGeometry(1,400,400),
- new THREE.MeshLambertMaterial({color: 0x0088ff})
- );//创建实物
- c.position.set(-200,200,0);
- mt.scene.add(c);
- c=new THREE.Mesh(
- new THREE.CubeGeometry(400,1,400),
- new THREE.MeshLambertMaterial({color: 0x0088ff})
- );//创建实物
- c.position.set(0,-1,0);
- mt.scene.add(c);
- c=new THREE.Mesh(
- new THREE.CubeGeometry(400,400,1),
- new THREE.MeshLambertMaterial({color: 0x0088ff})
- );//创建实物
- c.position.set(0,200,-200);
- mt.scene.add(c);
- window.onkeydown=function(ev){
- //alert(ev.keyCode);
- switch(ev.keyCode){
- case 65:
- mt.camera.position.x--//=Math.sin();
- break;
- case 68:
- mt.camera.position.x++;
- break;
- case 87:
- mt.camera.position.z--;
- break;
- case 83:
- mt.camera.position.z++;
- break;
- }
- }
- list=null;
- mt.camera.eulerOrder='YXZ';//修改旋转顺序 默认为xyz
- //这一步可以使得绕x轴旋转时参考已经旋转的y轴的量(相当于让x轴也随y轴旋转了),能减少后续工作
- //不做这一步还会出现很多问题
- mt.dom.onmousemove=function(ev){
- if(!ev.x) ev.x=ev.layerX;
- if(!ev.y) ev.y=ev.layerY;
- if(list){
- mt.camera.rotation.y-=(ev.x-list.x)*0.01;
- mt.camera.rotation.x-=(ev.y-list.y)*0.01;//*Math.cos(mt.camera.rotation.y);
- //mt.camera.rotation.z+=(ev.y-list.y)*0.01*Math.sin(mt.camera.rotation.y);
- //console.log((ev.y-list.y)*0.01*Math.cos(mt.camera.rotation.y))
- }
- list={x:ev.x,y:ev.y};
- }
- </script>
- </body>
- </html>