Prosty RayCaster
z Mozilla Developer Center, polskiego centrum programistów Mozilli.
UWAGA: Tłumaczenie tej strony nie zostało zakończone.
Może być ona niekompletna lub wymagać korekty.
Chcesz pomóc? | Dokończ tłumaczenie | Sprawdź ortografię | Więcej takich stron...
Spis treści |
[edytuj] Dlaczego?
After realizing, to my delight, that the nifty <canvas> element I'd been czytając o was not only soon to be supported in Firefox, but was already supported in the current version of Safari, I had to try a little experiment.
Ogólny przegląd i przewodnik Canvas, które możemy znaleźć tu na MDC są bardzo dobre, lecz nikt jeszcze nie napisał o animacjach, więc I thought I'd try a port of a basic raycaster I'd worked on a while ago, and see what sort of performance we can expect from a javascript controlled pixel buffer.
[edytuj] Jak?
The basic idea is to use setInterval at some arbitrary delay that corresponds to a desired frame rate. After every interval an update function will repaint the canvas showing the current view. I know I could have started with a simpler example, but I'm sure the canvas tutorial will get to that, and I wanted to see if I could do this.
So every update, the raycaster looks to see if you've pressed any keys lately, to conserve calculations by not casting if you're idle. If you have, then the canvas is cleared, the ground and sky are drawn, the camera position and / or orientation are updated and the rays are cast out. As the rays intersect walls, then they render a vertical sliver of canvas in the color of the wall they've hit, blended with a darker version of the color according to the distance to the wall. The height of the sliver is also modulated by the distance from the camera to the wall, and is drawn centered over the horizon line.
The code I ended up with is a regurgitated amalgam of the raycaster chapters from an old André LaMothe Tricks of the Game Programming Gurus book (ISBN: 0672305070), i java raycaster I found online, filtered through my compulsion to rename everything so it makes sense to me, and all the tinkering that had to be done to make things work well.
[edytuj] Rezultat
The canvas in Safari 2.0.1 performed suprisingly well. With the blockiness factor cranked up to render slivers 8 pixels wide, I can run a 320 x 240 window at 24 fps on my Apple mini. Firefox 1.5 Beta 1 is even faster; I can run 320 x 240 at 24 fps with 4 pixel slivers. Not exactly a new member of the ID software family, but pretty decent considering it's a fully interpreted environment, and I didn't have to worry about memory allocation or video modes or coding inner routines in assembler or anything. The code does attempt to be very efficient, using array look-ups of pre-computed values, but I'm no optimization guru, so things could probably be written faster.
Also, it leaves a lot to be desired in terms of trying to be any sort of game engine—there are no wall textures, no sprites, no doors, not even any teleporters to get to another level. But I'm pretty confident all those things could be added given enough time. The canvas API supports pixel copying of images, so textures seem feasible. I'll leave that for another article, probably from another person. =)
[edytuj] RayCaster
Dla osób, których przyjemnością jest przerabianie skryptów zamieszczone zostały kopie plików, które możesz pobrać i zobaczyć. Zamieszczone zostały poszczególne pliki wraz z listningiem kodu (zobacz poniżej).
Używaj tych plików w przeglądarce Safari 1.3+ lub Firefox 1.5+ lub jakieś innej, która wspiera element <canvas>. Życzymy dobrej zabawy!
input.js |
Level.js |
Player.js |
RayCaster.html |
RayCaster.js |
trace.css |
trace.js