精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

265行代碼實現第一人稱游戲引擎

開發 項目管理 后端
本文沒有涉及復雜的數學計算,只用到了光線投射技術。你可能已經見識過這種技術了,比如《上古卷軸2 : 匕首雨》、《毀滅公爵3D》還有 Notch Persson 最近在 ludum dare 上的參賽作品。Notch 認為它夠好,我就認為它夠好!

今天,讓我們進入一個可以伸手觸摸的世界吧。在這篇文章里,我們將從零開始快速完成一次第一人稱探索。本文沒有涉及復雜的數學計算,只用到了光線投射技術。你可能已經見識過這種技術了,比如《上古卷軸2 : 匕首雨》、《毀滅公爵3D》還有 Notch Persson 最近在 ludum dare 上的參賽作品。Notch 認為它夠好,我就認為它夠好!

 [Demo (arrow keys / touch)] [Source]

[[114219]]

用了光線投射就像開掛一樣,作為一名懶得出油的程序員,我表示非常喜歡。你可以舒暢地浸入到3D環境中而不受“真3D”復雜性的束縛。舉例來說,光線投射算法消耗線性時間,所以不用優化也可以加載一個巨大的世界,它執行的速度跟小型世界一樣快。水平面被定義成簡單的網格而不是多邊形網面樹,所以即使沒有 3D 建模基礎或數學博士學位也可以直接投入進去學習。

利用這些技巧很容易就可以做一些讓人嗨爆的事情。15分鐘之后,你會到處拍下你辦公室的墻壁,然后檢查你的 HR 文檔看有沒有規則禁止“工作場所槍戰建模”。

玩家

我們從何處投射光線?這就是玩家對象(Player)的作用,只需要三個屬性 x,y,direction。

  1. function Player(x, y, direction) {  
  2.   this.x = x;  
  3.   this.y = y;  
  4.   this.direction = direction;  
  5. }  

地圖

我們將地圖存作簡單的二維數組。數組中,0代表沒墻,1代表有墻。你還可以做得更復雜些,比如給墻設任意高度,或者將多個墻數據的“故事(stories)”打包進數組。但作為我們的第一次嘗試,用0-1就足夠了。

  1. function Map(size) {  
  2.   this.size = size;  
  3.   this.wallGrid = new Uint8Array(size * size);  
  4. }  

投射一束光線

這里就是竅門:光線投射引擎不會一次性繪制出整個場景。相反,它把場景分成獨立的列然后一條一條地渲染。每一列都代表從玩家特定角度投射出的一條光線。如果光線碰到墻壁,引擎會計算玩家到墻的距離然后在該列中畫出一個矩形。矩形的高度取決于光線的長度——越遠則越短。

[[114220]]

繪畫的光線越多,顯示效果就會越平滑。

 

1. 找到每條光線的角度

我們首先找出每條光線投射的角度。角度取決于三點:玩家面向的方向,攝像機的視野,還有正在繪畫的列。

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

2. 通過網格跟蹤每條光線

接下來,我們要檢查每條光線經過的墻。這里的目標是最終得出一個數組,列出了光線離開玩家后經過的每面墻。

[[114221]]

從玩家開始,我們找出最接近的橫向(stepX)和縱向(stepY)網格坐標線。移到最近的地方然后檢查是否有墻(inspect)。一直重復檢查直到跟蹤完每條線的所有長度。

  1. function ray(origin) {  
  2.   var stepX = step(sin, cos, origin.x, origin.y);  
  3.   var stepY = step(cos, sin, origin.y, origin.x, true);  
  4.   var nextStep = stepX.length2 < stepY.length2  
  5.     ? inspect(stepX, 1, 0, origin.distance, stepX.y)  
  6.     : inspect(stepY, 0, 1, origin.distance, stepY.x);  
  7.    
  8.   if (nextStep.distance > range) return [origin];  
  9.   return [origin].concat(ray(nextStep));  

尋找網格交點很簡單:只需要對 x 向下取整(1,2,3…),然后乘以光線的斜率(rise/run)得出 y。

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

現在看出了這個算法的亮點沒有?我們不用關心地圖有多大!只需要關注網格上特定的點——與每幀的點數大致相同。樣例中的地圖是32×32,而32,000×32,000的地圖一樣跑得這么快!

 

3. 繪制一列

跟蹤完一條光線后,我們就要畫出它在路徑上經過的所有墻。

  1. var z = distance * Math.cos(angle);  
  2. var wallHeight = this.height * height / z; 

我們通過墻高度的最大除以 z 來覺得它的高度。越遠的墻,就畫得越短。

 

額,這里用 cos 是怎么回事?如果直接使用原來的距離,就會產生一種超廣角的效果(魚眼鏡頭)。為什么?想象你正面向一面墻,墻的左右邊緣離你的距離比墻中心要遠。于是原本直的墻中心就會膨脹起來了!為了以我們真實所見的效果去渲染墻面,我們通過投射的每條光線一起構建了一個三角形,通過 cos 算出垂直距離。如圖:

[[114222]]

我向你保證,這里已經是本文最難的數學啦。

 

渲染出來

我們用攝像頭對象 Camera 從玩家視角畫出地圖的每一幀。當我們從左往右掃過屏幕時它會負責渲染每一列。

 
在繪制墻壁之前,我們先渲染一個天空盒(skybox)——就是一張大的背景圖,有星星和地平線,畫完墻后我們還會在前景放個武器。
  1. Camera.prototype.render = function(player, map) {  
  2.   this.drawSky(player.direction, map.skybox, map.light);  
  3.   this.drawColumns(player, map);  
  4.   this.drawWeapon(player.weapon, player.paces);  
  5. }; 

攝像機最重要的屬性是分辨率(resolution)、視野(fov)和射程(range)。

  • 分辨率決定了每幀要畫多少列,即要投射多少條光線。
  • 視野決定了我們能看的寬度,即光線的角度。
  • 射程決定了我們能看多遠,即光線長度的最大值

組合起來

使用控制對象 Controls 監聽方向鍵(和觸摸事件)。使用游戲循環對象 GameLoop 調用 requestAnimationFrame 請求渲染幀。這里的 gameloop 只有三行

  1. oop.start(function frame(seconds) {  
  2.   map.update(seconds);  
  3.   player.update(controls.states, map, seconds);  
  4.   camera.render(player, map);  
  5. });   
 

細節

雨滴

雨滴是用大量隨機放置的短墻模擬的。

  1. var rainDrops = Math.pow(Math.random(), 3) * s;  
  2. var rain = (rainDrops > 0) && this.project(0.1, angle, step.distance);  
  3.    
  4. ctx.fillStyle = '#ffffff';  
  5. ctx.globalAlpha = 0.15;  
  6. while (--rainDrops > 0) ctx.fillRect(left, Math.random() * rain.top, 1, rain.height); 

這里沒有畫出墻完全的寬度,而是畫了一個像素點的寬度。

 

照明和閃電

照明其實就是明暗處理。所有的墻都是以完全亮度畫出來,然后覆蓋一個帶有一定不透明度的黑色矩形。不透明度決定于距離與墻的方向(N/S/E/W)。

  1. ctx.fillStyle = '#000000';  
  2. ctx.globalAlpha = Math.max((step.distance + step.shading) / this.lightRange - map.light, 0);  
  3. ctx.fillRect(left, wall.top, width, wall.height); 

要模擬閃電,map.light 隨機達到2然后再快速地淡出。

 

碰撞檢測

要防止玩家穿墻,我們只要用他要到的位置跟地圖比較。分開檢查 x 和 y 玩家就可以靠著墻滑行。

  1. Player.prototype.walk = function(distance, map) {  
  2.   var dx = Math.cos(this.direction) * distance;  
  3.   var dy = Math.sin(this.direction) * distance;  
  4.   if (map.get(this.x + dx, this.y) <= 0) this.x += dx;  
  5.   if (map.get(this.x, this.y + dy) <= 0) this.y += dy;  
  6. }; 

墻壁貼圖

沒有貼圖(texture)的墻面看起來會比較無趣。但我們怎么把貼圖的某個部分對應到特定的列上?這其實很簡單:取交叉點坐標的小數部分。

  1. step.offset = offset - Math.floor(offset);  
  2. var textureX = Math.floor(texture.width * step.offset); 

舉例來說,一面墻上的交點為(10,8.2),于是取小數部分0.2。這意味著交點離墻左邊緣20%遠(8),離墻右邊緣80%遠(9)。所以我們用 0.2 * texture.width 得出貼圖的 x 坐標。

 

試一試

恐怖廢墟中逛一逛。
還有人擴展了社區版
 

接下來做什么?

因為光線投射器是如此地快速、簡單,你可以快速地實現許多想法。你可以做個地牢探索者(Dungeon Crawler)、第一人稱射手、或者俠盜飛車式沙盒。靠!常數級的時間消耗真讓我想做一個老式的大型多人在線角色扮演游戲,包含大量的、程序自動生成的世界。這里有一些帶你起步的難題:

  • 浸入式體驗。樣例在求你為它加上全屏、鼠標定位、下雨背景和閃電時同時出現雷響。
  • 室內級別。用對稱漸變取代天空盒。或者,你覺得自己很屌的話,嘗試用瓷片渲染地板和天花板。(可以這么想:所有墻面畫出來之后,畫面剩下的空隙就是地板和天花板了)
  • 照明對象。我們已經有了一個相當健壯的照明模型。為何不將光源放到地圖上,通過它們計算墻的照明?光源占了80%大氣層。
  • 良好的觸摸事件。我已經搞定了一些基本的觸摸操作,手機和平板的小伙伴們可以嘗試一樣 demo。但這里還有巨大的提升空間。
  • 攝像機特效。比如放大縮小、模糊、醉漢模式等等。有了光線投射器這些都顯得特別簡單。先從控制臺中修改 camera.fov 開始。

同往常一樣,如果你造了什么炫爆的東西或者有什么相關的研究要分享,發 email 給我或 tweet 我,我會分享給大家的。

 

討論

Hacker News 上的討論。

感謝

本來打算寫兩個鐘的文章結果寫了三周。沒有以下的幫助我不可能寫完這篇文章:

原文鏈接: A first-person engine in 265 lines   翻譯: 伯樂在線 - Jaward華仔

譯文鏈接: http://blog.jobbole.com/70956/

責任編輯:林師授 來源: 伯樂在線
相關推薦

2021-10-15 06:24:38

AIAR眼鏡人工智能

2012-12-24 09:21:45

iOSUnity3D

2012-12-24 09:13:23

iOSUnity3D

2013-10-18 09:29:53

編程開發

2013-01-04 13:14:25

筆記本

2013-05-24 14:02:42

2025-10-17 08:54:00

AI智能體模型

2021-10-15 15:05:32

AI 數據人工智能

2025-07-07 08:41:00

數據模型AI

2010-05-06 21:09:18

2025-06-25 09:02:05

2023-04-24 15:41:27

ChatGPT人工智能

2021-04-23 11:22:57

ThreadJava進階Runnable

2023-05-18 15:28:20

人工智能計算機科學

2021-06-02 16:19:14

技術研發指標

2025-10-03 02:00:00

視頻人體動作EgoTwin

2014-09-24 10:47:56

程序員
點贊
收藏

51CTO技術棧公眾號

国产精品视频你懂的| 黄色精品视频| 99re热视频精品| 日韩美女免费观看| 一本在线免费视频| 亚洲视频精选| 日本高清成人免费播放| 国产精品三区四区| 精品视频一二三区| 午夜精品久久久久99热蜜桃导演 | 性欧美高清come| 久久精品国产网站| 欧美精品久久久久久久久| 亚洲精品中文字幕乱码无线| 91九色porn在线资源| 日本一区二区三区四区在线视频| 78m国产成人精品视频| 国产精品理论在线| yy6080久久伦理一区二区| 久久精品亚洲麻豆av一区二区 | 一本综合久久| 日韩中文字幕国产精品| 欧类av怡春院| 国产亚洲观看| 欧美无砖专区一中文字| 国产www免费| 免费黄网站在线播放| 91浏览器在线视频| 日韩在线高清| 欧美亚洲国产一卡| 国产成人在线小视频| 波多野结衣家庭主妇| 欧美日本精品| 久久久精品国产网站| 最近中文字幕在线mv视频在线| 久草免费在线视频| 亚洲激情自拍视频| 亚洲欧美国产精品桃花| 国产日韩在线观看一区| 日韩国产精品大片| 69av在线播放| 国产一级一片免费播放放a| 欧美岛国激情| 夜夜嗨av一区二区三区四区 | 欧洲一区二区av| 丁香六月激情婷婷| 少女频道在线观看高清| 亚洲欧美综合色| 亚洲一区精品视频| av在线电影观看| 亚洲国产精品高清| 天天爽天天狠久久久| 黄色毛片在线看| 久久精品视频在线免费观看| 精品免费国产| 三级av在线| 久久久美女艺术照精彩视频福利播放| 国产免费成人av| aaa在线视频| 日韩黄色一级片| 国产成人极品视频| 波多野结衣黄色网址| 亚洲第一伊人| 97视频在线观看成人| 精品91久久久| 首页国产欧美日韩丝袜| 国产激情视频一区| 中文字幕在线播出| 韩国v欧美v日本v亚洲v| 日本成人激情视频| 免费一级全黄少妇性色生活片| 精品国产成人| 尤物九九久久国产精品的特点| 中文字幕在线观看91| 久久天堂av| 欧美日韩一区二区三区高清| 黄色一级片免费的| 日韩欧美久久| 亚洲黄色在线观看| 久久av无码精品人妻系列试探| 久久在线观看| 亚洲国产成人精品久久| 精品黑人一区二区三区观看时间| 国产欧美视频在线| 精品粉嫩超白一线天av| 日本少妇xxxx| 精品国产中文字幕第一页 | 欧美xxxx18性欧美| 久久免费在线观看视频| 国产欧美一区二区色老头| 国产成人精品亚洲精品| 一二三区在线播放| 成人午夜免费av| 欧美精品国产精品久久久| 成a人v在线播放| 一区二区视频在线| 国产淫片av片久久久久久| 成人在线免费| 欧美www视频| 97人妻人人揉人人躁人人| 91精品国产成人观看| 中文字幕成人精品久久不卡| 亚洲av综合一区二区| 亚洲精品国产setv| 久久艳片www.17c.com | 国产午夜精品一区理论片| 中文字幕在线不卡视频| 老太脱裤子让老头玩xxxxx| 国产超碰精品| 精品少妇一区二区三区在线播放| 亚洲国产午夜精品| 亚洲理论电影片| 色综合天天综合网国产成人网 | 中文字幕制服丝袜成人av| 精品国产福利在线| 日韩av电影中文字幕| 一级黄色片免费| 99久久精品国产网站| 污视频在线免费观看一区二区三区| 九色视频在线观看免费播放| 亚洲精选一二三| 别急慢慢来1978如如2| 欧美影院在线| 日韩中文在线观看| www.毛片.com| 男男成人高潮片免费网站| 高清不卡一区二区三区| 98在线视频| 色综合天天综合在线视频| 亚洲妇女无套内射精| 欧美三级美国一级| 97超碰色婷婷| 亚洲美女性生活| 亚洲欧美日本韩国| av日韩一区二区三区| 国产精品美女久久久久人| 精品少妇一区二区三区在线视频| 亚洲av无码一区二区三区网址| 午夜欧洲一区| 中文字幕在线成人| 波多野结衣视频观看| 91尤物视频在线观看| www插插插无码免费视频网站| 午夜影院在线播放| 欧美三级中文字| 国产美女免费网站| 老司机午夜精品视频在线观看| 成人两性免费视频| 男人的天堂在线视频免费观看| 亚洲综合在线视频| 中国男女全黄大片| 欧美一区二区三区另类 | 亚洲日韩成人| 国产高清精品一区| 国产对白在线播放| 手机在线理论片| 亚洲成人1234| 国产精品suv一区二区| 国产v日产∨综合v精品视频| 女同性恋一区二区| 亚洲一区欧美在线| 黄色免费在线观看网站| 欧美亚洲一区二区在线| 亚洲少妇中文字幕| 欧美激情综合色综合啪啪| 日韩av电影免费观看高清| 黄色在线小视频| 欧美中文一区二区三区| 成年人免费视频播放| 精品夜夜嗨av一区二区三区| 中文字幕av导航| 欧美日韩电影免费看| 亚洲一区二区久久久| 中文在线最新版天堂| 中文字幕永久在线不卡| 永久免费黄色片| 国内精品久久久久久久影视蜜臀| 国产www精品| 欧美视频久久久| 欧美日韩综合视频| 日本人亚洲人jjzzjjz| 黄色资源网久久资源365| 成人在线免费观看视频网站| 黄色欧美在线| 国产精品久久久久秋霞鲁丝| 成年人网站在线| 欧美精品一区二区不卡| 中文字幕av影院| 亚洲欧洲日韩在线| 免费看黄色一级大片| 亚洲精品二区三区| 国产精品免费一区二区三区| 久久精品一卡二卡| 久久99精品久久久野外观看| 高清欧美性猛交| 大片免费播放在线视频| 欧美一区二区三区四区五区 | 欧美三级日本三级| av在线不卡网| 亚洲熟妇无码另类久久久| 精品一区二区三| 国产成人中文字幕| a级网站在线播放| 亚洲欧美激情另类校园| 99久久精品无免国产免费| 欧美视频在线观看 亚洲欧| 在线免费观看a级片| 亚洲日本国产| 中文字幕av导航| 日本免费一区二区三区视频| 欧洲成人性视频| 性欧美ⅴideo另类hd| 国产亚洲欧美日韩美女| 亚洲高清在线观看视频| 欧美系列亚洲系列| 国产成人在线播放视频| 成人免费小视频| 中文字幕免费视频| 久久午夜av| 夜夜添无码一区二区三区| 日韩精品第一区| 久久久久久精| 国产色噜噜噜91在线精品| 91精品啪aⅴ在线观看国产| 亚洲欧洲自拍| 中文字幕亚洲欧美日韩2019| 五十路在线视频| 欧美不卡一区二区三区| 在线观看一二三区| 91久久久免费一区二区| 日韩大片免费在线观看| 91免费观看在线| 日韩大尺度视频| 国产精品69久久久久水密桃| 在线观看免费不卡av| 久久先锋影音| 日韩精品视频一区二区在线观看| 日韩av二区| 欧美在线日韩精品| 色婷婷综合久久久久久| 亚洲日本中文字幕| 三级a三级三级三级a十八发禁止| 九九热线有精品视频99| 国产有码在线一区二区视频| 亚洲a∨精品一区二区三区导航| 久色乳综合思思在线视频| 精品人妻一区二区三区日产乱码| 欧美日韩在线观看视频| 日本一级黄色大片| 亚洲午夜精品网| 黄色小说在线观看视频| 亚洲国产欧美一区二区三区丁香婷| 亚洲黄色在线网站| 91在线看国产| 天天干天天曰天天操| 国产一区福利在线| 杨幂一区二区国产精品| 国产伦理精品不卡| 999香蕉视频| 久久夜色精品| 免费特级黄色片| 亚洲高清资源| 国产精品裸体瑜伽视频| 在线视频精品| 青青草视频国产| 日韩中文在线电影| 亚洲午夜精品一区二区三区| 欧美一性一交| 欧美日韩国产一二| 成人在线视频免费观看| 色撸撸在线观看| 精品成人一区| www.中文字幕在线| 日韩福利视频导航| 亚洲五月激情网| 国产91丝袜在线播放九色| 欧美美女一级片| 国产河南妇女毛片精品久久久| mm1313亚洲国产精品无码试看| 日韩亚洲在线| 日日摸天天爽天天爽视频| 欧美a一区二区| 69久久精品无码一区二区| 成人av资源站| 欧美成人国产精品一区二区| 国产精品久久久久久亚洲毛片 | 亚洲视频国产| 久久五月天婷婷| 欧美第十八页| 国产精品无码一区二区在线| 日韩高清在线观看| 亚洲欧洲日韩综合| 久久久欧美精品sm网站| 日韩欧美综合视频| 色综合网色综合| 国产ts人妖调教重口男| 亚洲精品视频在线播放| 日本在线观看免费| 海角国产乱辈乱精品视频| 日本欧美韩国| 国产成人成网站在线播放青青| 欧美另类中文字幕| 麻豆精品视频| 欧美激情在线精品一区二区三区| 看高清中日韩色视频| 欧美hentaied在线观看| 奇米影视亚洲色图| 麻豆一区二区99久久久久| 精品人妻一区二区三区日产| 亚洲国产高清在线观看视频| 国产精品16p| 制服丝袜在线91| 欧洲免费在线视频| 欧美黑人性猛交| 97欧美成人| 精品日本一区二区| 欧美成人69av| 亚洲第一狼人区| 久久奇米777| 99在线视频免费| 国产精品大尺度| 久久青青草原亚洲av无码麻豆 | 国产精品福利电影| 精品一区二区电影| 美女91在线| 91在线观看免费观看| 99re6热只有精品免费观看| 午夜一区二区三区| 亚洲深夜激情| 污污免费在线观看| 一区二区三区免费网站| 国产又粗又猛视频| 在线视频亚洲欧美| 亚洲小说区图片区都市| 国产日韩在线播放| 国产精品亚洲二区| 国语对白做受xxxxx在线中国| 毛片基地黄久久久久久天堂| 波多野结衣片子| 日韩欧美在线第一页| 天天干天天色天天| 久久久噜噜噜久久久| 91精品国产乱码久久久竹菊| 7777在线视频| 国产一区日韩二区欧美三区| 夫妻性生活毛片| 88在线观看91蜜桃国自产| 男人在线资源站| 成人免费视频网| 一区二区三区午夜探花| 日本77777| 亚洲欧美视频在线观看| 国产免费黄色大片| 另类少妇人与禽zozz0性伦| 自拍偷拍亚洲| 日本丰满大乳奶| 国产精品123| 久草中文在线视频| 精品粉嫩超白一线天av| 九九精品调教| 国产日韩欧美一区二区| 亚洲激情女人| 亚洲精品成人无码熟妇在线| 欧美性生交xxxxx久久久| 国产原创av在线| 高清一区二区三区四区五区| 国产精品久久久久久久久久白浆| 懂色av一区二区三区蜜臀| www.17c.com喷水少妇| 久久精品日产第一区二区三区高清版 | 国产视频精品一区二区三区| 男人的天堂免费在线视频| 极品日韩久久| 日韩一区精品字幕| 成人信息集中地| 精品av久久707| 在线能看的av网址| 亚州欧美一区三区三区在线| 亚洲精品影院在线观看| 一区二区不卡免费视频| 欧美性一二三区| 久久久久久久影视| 国产精品日韩一区| 欧美大片一区| 少妇真人直播免费视频| 欧美日韩一卡二卡三卡 | 亚洲精品xxxx| 成人交换视频| www.国产二区| 久久精品视频网| 国产三级第一页| 欧美亚洲视频在线观看| 国偷自产av一区二区三区| 日日碰狠狠躁久久躁婷婷| 亚洲女同ⅹxx女同tv| 五月婷婷六月丁香| 91精品国产综合久久香蕉922| 日韩激情一区| 精品国产av色一区二区深夜久久 | 黄色av一级片|