接上一节,游戏控制首先要解决的就是碰撞检测了

这里用到了学习笔记(三)射线检测的内容了

以鸟为射线原点,向前、上、下分别发射3个射线,射线的长度较短大概为10~30.

根据上一节场景的建设,我把y轴设为前进方向,z轴设为高度~

如果射线返回有结果,那么说明鸟遇到了障碍物。代码如下:

                var raycaster1 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 1, 0), 0, 30)
var raycaster2 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, 1), 0, 10)
var raycaster3 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, -1), 0, 10)
//
var intersections1 = raycaster1.intersectObjects(objects);
var intersections2 = raycaster2.intersectObjects(objects);
var intersections3 = raycaster3.intersectObjects(objects);
//如果前方有物体,向前速度为0
if (intersections1.length > 0)
{
velocity.y = 0;
} //如果上方有物体,向上速度为0或为负值
if (intersections2.length > 0 )
{
if (velocity.z > 0)
{
velocity.z = 0;
} }
//如果下方有物体,向下速度为0或为正值
if (intersections3.length > 0) {
if (velocity.z < 0)
{
velocity.z = 0;
} } if (birdmesh.position.z < 10)
{
birdmesh.position.z = 10;
} if (birdmesh.position.z > 575) {
birdmesh.position.z = 575;
} if (velocity.y==0)
{
alert('您已死亡!');
}

其次需要解决的就是飞行前进和重力下降的问题

首先新建一个

var velocity = new THREE.Vector3();

用velocity.x和.y以及.z来表示像3个方向的速度。

y方向为前进方向,给定一个固定值就行,检测到碰撞停止。

x方向不用管,因为x方向没有运动。

z方向为高度方向,要做到鼠标点击飞高一段距离,然后重力下降。

首先鼠标点击给定一个固定的向上的速度,然后速度加速递减(重力效果),代码如下

                    window.addEventListener('mousedown', function (event) {

                        velocity.z = 500;
                        mixer.clipAction(clip).setDuration(0.1).play();
                        
                        
                       
                    }, false);                     window.addEventListener('mouseup', function (event) {
                        
                        mixer.clipAction(clip).setDuration(1).play();                     }, false); var delta = clock.getDelta(); //这里100就是速度的一个因子,数值越大,重力效果越明显;
velocity.z -= 9.8 * 100 * delta; birdmesh.position.z += velocity.z*delta;
birdmesh.position.y += velocity.y * delta; velocity.y = 200;

另外上面代码仔细观察,你会发现鼠标点击和松开给定的鸟煽动翅膀的速度是不一样的

mixer.clipAction(clip).setDuration(1).play()

这是为了达到点击鼠标有鸟在努力向上飞的视觉效果~。

先写到这。全部源码先贴在这吧,其实上传工程的效果是最好的,但还没整理好。这个练手还没完!

预告后面两节

后1节:飞行类小游戏转置为win10通用UWP应用(我将上传至微软商店,敬请期待!)

后2节:飞行类小游戏转置为手机安卓应用

最后目前全部源码~

<!DOCTYPE html>
<html lang="en">
<head>
<title>练手</title>
<meta charset="utf-8"> </head>
<body> <script src="build/three.js"></script>
<script src="js/Detector.js"></script> <script src="js/controls/OrbitControls.js"></script> <script>
if (!Detector.webgl) Detector.addGetWebGLMessage(); var camera, scene, renderer; var clock = new THREE.Clock();
//var controls; var velocity = new THREE.Vector3();
var birdmesh;
var objects = [];
init();
animate(); function init()
{
container = document.createElement( 'div' );
document.body.appendChild( container );
//
camera = new THREE.PerspectiveCamera(80, window.innerWidth / window.innerHeight, 1, 100000);
camera.up.set(0, 0, 1);
camera.lookAt(new THREE.Vector3(-1, 1, 0)); scene = new THREE.Scene();
//
scene.add( new THREE.HemisphereLight( 0x443333, 0x222233 ) );
var light = new THREE.DirectionalLight( 0xffffff, 1 );
light.position.set( 1, 1, 1 );
scene.add( light );
//------添加内容 //---地板,平面
geometry = new THREE.PlaneGeometry(512, 200000); //geometry.rotateX(-Math.PI / 2); var texture = new THREE.TextureLoader().load('img/dd.jpg');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(8, 800)
material = new THREE.MeshBasicMaterial({ map: texture }); //material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } );
mesh = new THREE.Mesh(geometry, material);
mesh.position.set(0, 0, 0);
scene.add(mesh);
objects.push(mesh); ////箱子1
//geometry = new THREE.BoxGeometry(2, 2, 2);
//material = new THREE.MeshBasicMaterial({color:0x000000});
//mesh = new THREE.Mesh(geometry, material);
//mesh.position.set(0,0,0);
//scene.add(mesh); ////箱子2
//geometry = new THREE.BoxGeometry(2, 2, 2);
//material = new THREE.MeshBasicMaterial({ color: 0xff0000 });
//mesh = new THREE.Mesh(geometry, material);
//mesh.position.set(100, 0, 0);
//scene.add(mesh); ////箱子3
//geometry = new THREE.BoxGeometry(2, 2, 2);
//material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
//mesh = new THREE.Mesh(geometry, material);
//mesh.position.set(0, 100, 0);
//scene.add(mesh); ////箱子4
//geometry = new THREE.BoxGeometry(2, 2, 2);
//material = new THREE.MeshBasicMaterial({ color: 0x0000ff });
//mesh = new THREE.Mesh(geometry, material);
//mesh.position.set(0, 0, 100);
//scene.add(mesh); //天空盒
var textureLoader = new THREE.TextureLoader();
var materials = [
new THREE.MeshBasicMaterial({ map: textureLoader.load('img/px.jpg') }), // right
new THREE.MeshBasicMaterial({ map: textureLoader.load('img/nx.jpg') }), // left
new THREE.MeshBasicMaterial({ map: textureLoader.load('img/py.jpg') }), // top
new THREE.MeshBasicMaterial({ map: textureLoader.load('img/ny.jpg') }), // bottom
new THREE.MeshBasicMaterial({ map: textureLoader.load('img/pz.jpg') }), // back
new THREE.MeshBasicMaterial({ map: textureLoader.load('img/nz.jpg') }) // front
];
mesh = new THREE.Mesh(new THREE.BoxGeometry(100000, 100000, 100000, 7, 7, 7), new THREE.MultiMaterial(materials));
mesh.scale.x = -1;
scene.add(mesh); //连续障碍物
for (var i = 0; i < 50;i++) {
var ht=Math.random() * 450;
geometry = new THREE.BoxGeometry(80, 20, ht);
material = new THREE.MeshBasicMaterial({ color: Math.random() * 0xffffff });
mesh = new THREE.Mesh(geometry, material); mesh.position.x =0;
mesh.position.y = (i+1) * 500;
mesh.position.z = ht / 2;
scene.add(mesh); objects.push(mesh); geometry = new THREE.BoxGeometry(80, 20, 450-ht);
mesh = new THREE.Mesh(geometry, material);
mesh.position.x = 0;
mesh.position.y = (i + 1) * 500;
mesh.position.z = ht + 140 + (450 - ht) / 2;
scene.add(mesh); objects.push(mesh); } //鸟
var loader = new THREE.JSONLoader(); loader.load( "models/animated/flamingo.js", function( geometry ) {
geometry.computeVertexNormals();
geometry.computeMorphNormals();
var material = new THREE.MeshPhongMaterial( {
color: 0xffffff,
morphTargets: true,
morphNormals: true,
vertexColors: THREE.FaceColors,
shading: THREE.SmoothShading
} );
birdmesh = new THREE.Mesh( geometry, material );
birdmesh.position.x = 0;
birdmesh.position.y = 0;
birdmesh.position.z = 200;
birdmesh.scale.set(0.2, 0.2, 0.2);
birdmesh.rotateX(-Math.PI / 2);
birdmesh.rotateZ(Math.PI);
scene.add(birdmesh);
mixer = new THREE.AnimationMixer(birdmesh); var clip = THREE.AnimationClip.CreateFromMorphTargetSequence('bd', geometry.morphTargets, 30);
mixer.clipAction(clip).setDuration(1).play(); window.addEventListener('mousedown', function (event) { velocity.z = 500;
mixer.clipAction(clip).setDuration(0.1).play(); }, false); window.addEventListener('mouseup', function (event) { mixer.clipAction(clip).setDuration(1).play(); }, false); } ); renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
container.appendChild( renderer.domElement ); //控制 //var controls = new THREE.OrbitControls(camera, renderer.domElement);
//controls.addEventListener('change', render);
//controls.target.set(0, 0, 0);
//controls.update(); //
window.addEventListener('resize', function onWindowResize(event) {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = 0.5 * window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}, false); } //
function animate() { requestAnimationFrame( animate );
render(); } function render() { var delta = clock.getDelta(); //这里100就是速度的一个因子,数值越大,重力效果越明显,等效于velocity.y =(velocity.y*0.01- 9.8 * delta)*100;
velocity.z -= 9.8 * 100 * delta; birdmesh.position.z += velocity.z*delta;
birdmesh.position.y += velocity.y * delta; velocity.y = 200; var raycaster1 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 1, 0), 0, 30)
var raycaster2 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, 1), 0, 10)
var raycaster3 = new THREE.Raycaster(birdmesh.position, new THREE.Vector3(0, 0, -1), 0, 10)
//
var intersections1 = raycaster1.intersectObjects(objects);
var intersections2 = raycaster2.intersectObjects(objects);
var intersections3 = raycaster3.intersectObjects(objects);
//是否检测到 if (intersections1.length > 0)
{
velocity.y = 0;
} if (intersections2.length > 0 )
{
if (velocity.z > 0)
{
velocity.z = 0;
} } if (intersections3.length > 0) {
if (velocity.z < 0)
{
velocity.z = 0;
} } if (birdmesh.position.z < 10)
{
birdmesh.position.z = 10;
} if (birdmesh.position.z > 575) {
birdmesh.position.z = 575;
} if (velocity.y==0)
{
alert('您已死亡!');
} mixer.update(delta); camera.position.set(birdmesh.position.x+100, birdmesh.position.y - 50, birdmesh.position.z); renderer.clear();
renderer.render( scene, camera );
}
</script> </body>
</html>

WEBGL学习笔记(七):实践练手1-飞行类小游戏之游戏控制的更多相关文章

  1. Typescript 学习笔记四:回忆ES5 中的类

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  2. (转)Qt Model/View 学习笔记 (七)——Delegate类

    Qt Model/View 学习笔记 (七) Delegate  类 概念 与MVC模式不同,model/view结构没有用于与用户交互的完全独立的组件.一般来讲, view负责把数据展示 给用户,也 ...

  3. java jvm学习笔记七(jar包的代码认证和签名)

    欢迎装载请说明出处:http://blog.csdn.net/yfqnihao 前言: 如果你循序渐进的看到这里,那么说明你的毅力提高了,jvm的很多东西都是比较抽像的,如果不找相对应的代码来辅助理解 ...

  4. java之jvm学习笔记五(实践写自己的类装载器)

    java之jvm学习笔记五(实践写自己的类装载器) 课程源码:http://download.csdn.net/detail/yfqnihao/4866501 前面第三和第四节我们一直在强调一句话,类 ...

  5. Learning ROS for Robotics Programming Second Edition学习笔记(七) indigo PCL xtion pro live

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

  6. Typescript 学习笔记七:泛型

    中文网:https://www.tslang.cn/ 官网:http://www.typescriptlang.org/ 目录: Typescript 学习笔记一:介绍.安装.编译 Typescrip ...

  7. python3.4学习笔记(七) 学习网站博客推荐

    python3.4学习笔记(七) 学习网站博客推荐 深入 Python 3http://sebug.net/paper/books/dive-into-python3/<深入 Python 3& ...

  8. Go语言学习笔记七: 函数

    Go语言学习笔记七: 函数 Go语言有函数还有方法,神奇不.这有点像python了. 函数定义 func function_name( [parameter list] ) [return_types ...

  9. webgl学习笔记五-纹理

    写在前面 建议先阅读下前面我的三篇文章. webgl学习笔记一-绘图单点 webgl学习笔记二-绘图多点 webgl学习笔记三-平移旋转缩放 术语 : 纹理 :图像 图形装配区域 :顶点着色器顶点坐标 ...

随机推荐

  1. <aop:aspectj-autoproxy />

    通过配置织入@Aspectj切面 虽然可以通过编程的方式织入切面,但是一般情况下,我们还是使用spring的配置自动完成创建代理织入切面的工作. 通过aop命名空间的<aop:aspectj-a ...

  2. Pjax无刷新跳转页面实现,支持超链接与表单提交

    什么是pjax? 当你点击一个站内的链接的时候,不是做页面跳转,而是只是站内页面刷新.这样的用户体验,比起整个页面都闪一下来说, 好很多. 其中有一个很重要的组成部分, 这些网站的ajax刷新是支持浏 ...

  3. (转)C#开发微信门户及应用(1)--开始使用微信接口

    http://www.cnblogs.com/wuhuacong/p/3613826.html 微信应用如火如荼,很多公司都希望搭上信息快车,这个是一个商机,也是一个技术的方向,因此,有空研究下.学习 ...

  4. inherit 关键字使得元素获取其父元素的计算值

    它可以应用于任何CSS属性,包括CSS简写 all. 对于继承属性,inherit 关键字只是增强了属性的默认行为,只有在重载(overload)其它规则的时候被使用.对于非继承属性,inherit ...

  5. 初识 Django

    HTTP协议 HTTP(hypertext transport protocol),即超文本传输协议.这个协议详细规定了浏览器和万维网服务器之间互相通信的规则. HTTP就是一个通信规则,通信规则规定 ...

  6. CallableStatement的用法

    CallableStatement 对象为所有的 DBMS 提供了一种以标准形式调用已储存过程的方法.已储存过程储存在数据库中.对已储存过程的调用是 CallableStatement 对象所含的内容 ...

  7. eas之网络互斥功能示手工控制

    public void doMutexService()    {        IMutexServiceControl mutex = MutexServiceControlFactory.get ...

  8. 理解Linux CPU负载和 CPU使用率

    CPU负载和 CPU使用率 这两个从一定程度上都可以反映一台机器的繁忙程度. cpu使用率反映的是当前cpu的繁忙程度,忽高忽低的原因在于占用cpu处理时间的进程可能处于io等待状态但却还未释放进入w ...

  9. python的多版本安装以及常见错误(长期更新)

    (此文长期更新)Python安装常见错误汇总 注:本教程以python3.6为基准 既然是总结安装过程中遇到的错误,就顺便记录一下我的安装过程好了. 先来列举一下安装python3.6过程中可能需要的 ...

  10. DataInputStream 数据类型数据输入输出流

    package IOliu; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.FileI ...