Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import library.List;
- import library.display.Screen;
- import library.display.Pixmap;
- import library.display.Pixie;
- import library.display.Sprodel;
- import library.system.Controls;
- import library.display.Context;
- import flash.display.BitmapData;
- import flash.geom.Rectangle;
- import flash.geom.Point;
- import flash.display.Bitmap;
- import flash.Vector;
- class Game implements library.system.Scene {
- public var raycaster:Raycaster;
- public function new() {}
- public function startScene():Void {
- raycaster = new Raycaster();
- raycaster.x = 200;
- raycaster.y = 200;
- raycaster.z = 64;
- raycaster.angle = 0;
- raycaster.roll = 60;
- }
- public function closeScene():Void {
- }
- public function update():Void {
- if(Keyboard.keyDown[87]) {
- raycaster.x += Math.cos( raycaster.angle ) * 6;
- raycaster.y += Math.sin( raycaster.angle ) * 6;
- }
- if(Keyboard.keyDown[65]) {
- raycaster.x += Math.cos( raycaster.angle-(Math.PI/2) ) * 6;
- raycaster.y += Math.sin( raycaster.angle-(Math.PI/2) ) * 6;
- }
- if(Keyboard.keyDown[68]) {
- raycaster.x += Math.cos( raycaster.angle+(Math.PI/2) ) * 6;
- raycaster.y += Math.sin( raycaster.angle+(Math.PI/2) ) * 6;
- }
- if(Keyboard.keyDown[83]) {
- raycaster.x += Math.cos( raycaster.angle+(Math.PI) ) * 6;
- raycaster.y += Math.sin( raycaster.angle+(Math.PI) ) * 6;
- }
- if(Keyboard.keyDown[81]) {
- raycaster.angle -= 0.05;
- }
- if(Keyboard.keyDown[69]) {
- raycaster.angle += 0.05;
- }
- if(Keyboard.keyDown[32]) {
- raycaster.z++;
- }
- }
- public function render():Void {
- raycaster.render();
- }
- }
- class Raycaster {
- private var map: Array<Int>;
- //-- WORLD COORDINATES --//
- public var x: Float;
- public var y: Float;
- public var z: Float;
- public var angle: Float;
- public var roll: Float;
- private var iceil: BitmapData;
- private var ifloor: BitmapData;
- private var iwall: BitmapData;
- //-- PRE COMPUTE --//
- public var fov: Float;
- private var eyeDistance: Float;
- private var subRayAngle: Float;
- private var p_center: Float;
- private var sin: Array<Float>;
- private var cos: Array<Float>;
- private var tan: Array<Float>;
- private var myvector:Vector<UInt>;
- public function new() {
- ifloor = new BitmapData( 64, 64, false, 0xffcc00 );
- iceil = new BitmapData( 64, 64, false, 0xff0000 );
- iwall = new BitmapData( 64, 96, false, 0xcccccc );
- myvector = new Vector<UInt>(Core.width*Core.height,true);
- ifloor.copyPixels( Asset.pixmap.textures.bitmapdata, new Rectangle( 0, 0, 64, 64 ), new Point( 0, 0 ) );
- iceil.copyPixels( Asset.pixmap.textures.bitmapdata, new Rectangle( 64, 0, 64, 64 ), new Point( 0, 0 ) );
- iwall.copyPixels( Asset.pixmap.textures.bitmapdata, new Rectangle( 128, 0, 64, 96 ), new Point( 0, 0 ) );
- map = [
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
- ];
- angle = 0;
- roll = 0;
- fov = 60 * Math.PI / 180;
- //-- fill lookup table
- sin = new Array<Float>();
- cos = new Array<Float>();
- tan = new Array<Float>();
- var i:Int = 0;
- while(i < 7200) {
- sin[i] = Math.sin( i / 3600 * Math.PI );
- cos[i] = Math.cos( i / 3600 * Math.PI );
- tan[i] = Math.tan( i / 3600 * Math.PI );
- i++;
- }
- init();
- }
- public function init():Void {
- eyeDistance = ( Core.width / 2 ) / Math.tan( fov / 2 );
- subRayAngle = fov / Core.width;
- }
- public function render():Void {
- //-- LOCAL VARIABLES --//
- var rx:Int = Std.int(x) >> 6;
- var ry:Int = Std.int(y) >> 6;
- var tx:Int = rx;
- var ty:Int = ry;
- var ax:Float;
- var ay:Float;
- var dx:Float;
- var dy:Float;
- var distance:Float = 0;
- var offset:Float = 0;
- var nearest:Float;
- var beta:Float;
- var ht:Float;
- var tn:Float;
- var cs:Float;
- var sn:Float;
- var distort:Float;
- var cf:Float;
- var ff:Float;
- var c0:Int;
- var c1:Int;
- var dg:Int;
- var color:Int;
- //-- clamp angle for lookup tables
- if( angle < 0 ) angle += Math.PI * 2;
- if( angle > Math.PI * 2 ) angle -= Math.PI * 2;
- var a: Float = angle + fov * .5;
- if( a > Math.PI * 2 ) a -= Math.PI * 2;
- var pixelColumn: Int = Core.width - 1;
- var pixelRow: Int = 0;
- //-- PRECOMPUTE --//
- p_center = Core.height / 2 - roll;
- var oz: Float = 96 - z;
- var ang: Int = Std.int( angle * ( 3600 / Math.PI ) ) | 0;
- while( --pixelColumn > -1 ) {
- nearest = Math.POSITIVE_INFINITY;
- dg = Std.int( a * ( 3600 / Math.PI ) );
- tn = tan[ dg ];
- sn = sin[ dg ];
- cs = cos[ dg ];
- rx = tx;
- ry = ty;
- if ( sn < 0 ) {
- while( ry > -1 && rx > -1 && rx < 20 ) {
- ay = ry << 6;
- ax = x + ( ay - y ) / tn;
- rx = Std.int(ax) >> 6;
- ry--;
- if ( getmap( rx, ry ) != 0 ) {
- dx = ax - x;
- dy = ay - y;
- nearest = dx * dx + dy * dy;
- offset = Std.int(ax) & 63;
- break;
- }
- }
- } else {
- while( ry < 20 && rx > -1 && rx < 20) {
- ++ry;
- ay = ry << 6;
- ax = x + ( ay - y ) / tn;
- rx = Std.int(ax) >> 6;
- if ( getmap( rx, ry ) != 0) {
- dx = ax - x;
- dy = ay - y;
- nearest = dx * dx + dy * dy;
- offset = 64 - Std.int(ax) & 63;
- break;
- }
- }
- }
- rx = tx;
- ry = ty;
- if ( cs < 0 ) {
- while( rx > -1 && ry > -1 && ry < 20 ) {
- ax = rx << 6;
- ay = y + ( ax - x ) * tn;
- ry = Std.int(ay) >> 6;
- rx--;
- if(getmap( rx, ry ) != 0) {
- dx = ax - x;
- dy = ay - y;
- distance = dx * dx + dy * dy;
- if(distance < nearest) {
- nearest = distance;
- offset = 64 - Std.int(ay) & 63;
- }
- break;
- }
- }
- } else {
- while( rx < 128 && ry > -1 && ry < 128 ) {
- ++rx;
- ax = rx << 6;
- ay = y + ( ax - x ) * tn;
- ry = Std.int(ay) >> 6;
- if(getmap( rx, ry ) != 0) {
- dx = ax - x;
- dy = ay - y;
- distance = dx * dx + dy * dy;
- if ( distance < nearest ) {
- nearest = distance;
- offset = Std.int(ay) & 63;
- }
- break;
- }
- }
- }
- if( dg < ang ) {
- distort = eyeDistance / cos[ 7200 + dg - ang ];
- } else {
- distort = eyeDistance / cos[ dg - ang ];
- }
- ht = distort / Math.sqrt( nearest );
- cf = oz * distort;
- ff = z * distort;
- c0 = Std.int( p_center - ht * oz );
- c1 = Std.int( p_center + ht * z );
- pixelRow = Core.height;
- while( --pixelRow > c1-1 ) {
- if( pixelRow < 0 ) break;
- //-- FLOOR TILES --//
- distance = ff / ( pixelRow+1 - p_center );
- color = iceil.getPixel( Std.int( x + cs * distance ) & 63, Std.int( y + sn * distance ) & 63 );
- var dark:Int = 255-(Std.int(distance)>>2);
- if(dark<0) {dark=0;}
- myvector[pixelColumn+pixelRow*Core.width] = color+(dark<<24);
- }
- pixelRow++;
- while( --pixelRow > c0 ) {
- if( pixelRow < 0 ) {break;}
- //-- BLOCKS --//
- color = iwall.getPixel( Std.int(offset), Std.int(( pixelRow - c0 ) / ht) );
- var dark:Int = 255-(Std.int(distance)>>2);
- if(dark<0) {dark=0;}
- myvector[pixelColumn+pixelRow*Core.width] = color+(dark<<24);
- }
- pixelRow++;
- while( --pixelRow > -1 ) {
- if( pixelRow < 0 ) break;
- //-- CEILING --//
- distance = cf / ( p_center - pixelRow );
- color = iceil.getPixel( Std.int( x + cs * distance ) & 63, Std.int( y + sn * distance ) & 63 );
- var dark:Int = 255-(Std.int(distance)>>2);
- if(dark<0) {dark=0;}
- myvector[pixelColumn+pixelRow*Core.width] = color+(dark<<24);
- }
- a -= subRayAngle;
- if( a < 0) a += (Math.PI * 2)-0.001;
- }
- Screen.buffer.bitmapdata.setVector(Screen.buffer.bitmapdata.rect,myvector);
- }
- public inline function getmap(_x:Int,_y:Int):Int {
- return if(_x>20||_y>20) {0;} else {map[_x+_y*20];}
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement