265行 JavaScript 代码实现第一人称引擎

原文:A
first-person engine in 265 lines
(2014-6-11)
翻译:Jaward华仔


今天,让我们进入一个可以伸手触摸的世界吧。在这篇文章里,我们将从零开始快速完成一次第一人称探索。本文没有涉及复杂的数学计算,只用到了光线投射技术。你可能已经见识过这种技术了,比如《上古卷轴2
: 匕首雨》、《毁灭公爵3D》还有 Notch Persson 最近在 ludum dare 上的参赛作品。Notch 认为它够好,我就认为它够好! 【Demo (arrow keys /
touch)
】【Source

用了光线投射就像开挂一样,作为一名懒得出油的程序员,我表示非常喜欢。你可以舒畅地浸入到3D环境中而不受“真3D”复杂性的束缚。举例来说,光线投射算法消耗线性时间,所以不用优化也可以加载一个巨大的世界,它执行的速度跟小型世界一样快。水平面被定义成简单的网格而不是多边形网面树,所以即使没有
3D 建模基础或数学博士学位也可以直接投入进去学习。

利用这些技巧很容易就可以做一些让人嗨爆的事情。15分钟之后,你会到处拍下你办公室的墙壁,然后检查你的 HR
文档看有没有规则禁止“工作场所枪战建模”。

玩家

我们从何处投射光线?这就是玩家对象(Palyer)的作用,只需要三个属性 x,y,direction。

function Player(x, y, direction) {
this.x = x;
this.y = y;
this.direction = direction;
}

地图

我们将地图存作简单的二维数组。数组中,0代表没墙,1代表有墙。你还可以做得更复杂些,比如给墙设任意高度,或者将多个墙数据的“故事(stories)”打包进数组。但作为我们的第一次尝试,用0-1就足够了。

function Map(size) {
this.size = size;
this.wallGrid = new Uint8Array(size * size);
}

投射一束光线

这里就是窍门:光线投射引擎不会一次性绘制出整个场景。相反,它把场景分成独立的列然后一条一条地渲染。每一列都代表从玩家特定角度投射出的一条光线。如果光线碰到墙壁,引擎会计算玩家到墙的距离然后在该列中画出一个矩形。矩形的高度取决于光线的长度——越远则越短。

绘画的光线越多,显示效果就会越平滑。

1.找到每条光线的角度

我们首先找出每条光线投射的角度。角度取决于三点:玩家面向的方向,摄像机的视野,还有正在绘画的列。

var angle = this.fov * (column / this.resolution - 0.5);
var ray = map.cast(player, player.direction + angle, this.range);

2.通过网格跟踪每条光线

接下来,我们要检查每条光线经过的墙。这里的目标是最终得出一个数组,列出了光线离开玩家后经过的每面墙。

从玩家开始,我们找出最接近的横向(stepX)和纵向(stepY)网格坐标线。移到最近的地方然后检查是否有墙(inspect)。一直重复检查直到跟踪完每条线的所有长度。

   function ray(origin) {
var stepX = step(sin, cos, origin.x, origin.y);
var stepY = step(cos, sin, origin.y, origin.x, true);
var nextStep = stepX.length2 < stepY.length2
? inspect(stepX, 1, 0, origin.distance, stepX.y)
: inspect(stepY, 0, 1, origin.distance, stepY.x);

if (nextStep.distance > range) return [origin];
return [origin].concat(ray(nextStep));
}

寻找网格交点很简单:只需要对 x 向下取整(1,2,3…),然后乘以光线的斜率(rise/run)得出 y。

   var dx = run > 0 ? Math.floor(x + 1) - x : Math.ceil(x - 1) - x;
var dy = dx * (rise / run);

现在看出了这个算法的亮点没有?我们不用关心地图有多大!只需要关注网格上特定的点——与每帧的点数大致相同。样例中的地图是32×32,而32,000×32,000的地图一样跑得这么快!

3.绘制一列

跟踪完一条光线后,我们就要画出它在路径上经过的所有墙。

阅读全文

265行 JavaScript 代码实现第一人称引擎,布布扣,bubuko.com

时间: 2024-08-05 07:18:29

265行 JavaScript 代码实现第一人称引擎的相关文章

【转】265行JavaScript代码的第一人称3D H5游戏Demo

译文:http://blog.jobbole.com/70956/ 原文:http://www.playfuljs.com/a-first-person-engine-in-265-lines/ 这是一篇关于利用 Canvas 实现3D 游戏场景绘制的文章,看完感觉很受启发,所以自己准备总结一下.我们先看下最终效果: 很酷是不是.原作者只使用了265行代码就实现了这么炫酷的效果.代码写的也很清晰明了,并且原文也对原理也进行了解释.本篇就直接将原作者的代码全部贴上来大家观赏观赏. 1 <!doct

265行JavaScript代码的第一人称3D H5游戏Demo【个人总结1】

本文目的是分解前面的代码.其实,它得逻辑很清楚,只是对于我这种只是用过 Canvas 画线的人来说,这个还是很复杂的.我研究这个背景天空也是搞了一天,下面就是只加载天空的代码. 在线效果点击:http://1.codemo2.sinaapp.com/3d_demo_265line/index.html   [可以用键盘“左右”键控制][手机浏览器触控有些异常] 原理大概就是: 1. 创建主循环 一个无限循环 2. 主循环内重复调用绘制方法 3. 绘制方法: 针对 Player 的位置和方向,绘制

大神手把手教你写一个页面模板引擎,只需20行Javascript代码!

只用20行Javascript代码就写出一个页面模板引擎的大神是AbsurdJS的作者,下面是他分享的全文,转需. 不知道你有木有听说过一个基于Javascript的Web页面预处理器,叫做AbsurdJS.我是它的作者,目前我还在不断地完善它.最初我只是打算写一个CSS的预处理器,不过后来扩展到了CSS和HTML,可以用来把Javascript代码转成CSS和HTML代码.当然,由于可以生成HTML代码,你也可以把它当成一个模板引擎,用于在标记语言中填充数据. 于是我又想着能不能写一些简单的代

使用Direct2D实现一个简单第一人称引擎

这篇文章是对"a first person engine in 265 lines"[1]的一个Direct2D版的移植.看到这篇文章我立刻就想到了QUAKE,当然QUAKE使用了比这个更高效的技术.但是这个技术无疑更简单,更娱乐,同时也算是一种RayCast原理的使用.于是就想到用Direct2D做一个看看. 由于对Html5不熟,同时参考了Fredrik Wallgren[2]. 同时也参考了MS提供的Direct2D事例[3]. 代码托管:https://d2dfpsengine

60行JavaScript代码俄罗斯方块

教你看懂网上流传的60行JavaScript代码俄罗斯方块游戏 早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下(主要是以注释的形式). 我用C写一个功能基本齐全的俄罗斯方块的话,大约需要1000行代码的样子.所以60行乍一看还是很让人吃惊的. 但是读懂了代码之后发现其实整个程序并没有使用什么神秘的技术,只不过是利用一些工具或者JavaScript本身的技巧大大简化了代码. 总结起来主要是以下三点 1.使用eval

教你看懂网上流传的60行JavaScript代码俄罗斯方块游戏

早就听说网上有人仅仅用60行JavaScript代码写出了一个俄罗斯方块游戏,最近看了看,今天在这篇文章里面我把我做的分析整理一下(主要是以注释的形式). 我用C写一个功能基本齐全的俄罗斯方块的话,大约需要1000行代码的样子.所以60行乍一看还是很让人吃惊的. 但是读懂了代码之后发现其实整个程序并没有使用什么神秘的技术,只不过是利用一些工具或者JavaScript本身的技巧大大简化了代码. 总结起来主要是以下三点 1.使用eval来产生JavaScript代码,减小了代码体积 2.以字符串作为

【转】265行代码实现第一人称游戏引擎

原文:html5gamedev.org/?p=2383 总在有个自以为很先进的理念后不久就在网上找到别人的实现! 今天,让我们进入一个可以伸手触摸的世界吧.在这篇文章里,我们将从零开始快速完成一次第一人称探索.本文没有涉及复杂的数学计算,只用到了光线投射技术.你可能已经见识过这种技术了,比如<上古卷轴2 : 匕首雨>.<毁灭公爵3D>还有 Notch Persson 最近在 ludum dare 上的参赛作品.Notch 认为它够好,我就认为它够好! 用了光线投射就像开挂一样,作为

这几行 javascript 代码能让你的浏览器崩溃?

先上Demo,有兴趣的可以先试一下: http://www.zeakhold.com/crash/ (温馨提示:访问前请保存好浏览器其他窗口的任务,整人被打概不负责嘿嘿~) 事情还是得从 IT Security Tweets ™   的一篇推文说起: 也就是说,这段 javascript 代码,能让浏览器崩溃并且能让iPhone重启?! 于是打开电脑跃跃欲试,当满怀好奇地在浏览器上执行了这段代码后发现: Chrome 立马陷入了卡死的状态,更要命的是点击关闭窗口没响应!! 打开任务管理器,发现C

150行JavaScript代码实现增强现实

增强现实技术(Augmented Reality,简称 AR),是一种实时地计算摄影机影像的位置及角度并加上相应图像.视频.3D模型的技术,这种技术的目标是在屏幕上把虚拟世界套在现实世界并进行互动.这种技术1990年提出.随着随身电子产品CPU运算能力的提升,预期增强现实的用途将会越来越广. 本文介绍使用JavaScript开源框架AR.js实现的增强现实的Hello World例子. 先看效果: 首先在手机浏览器里打开我部署在github page上的这个demo应用: https://i04