A Flash Developer Resource Site

Results 1 to 5 of 5

Thread: [F8] Help with mode7 and displaying 2d objects

  1. #1
    FK founder & general loiterer Flashkit's Avatar
    Join Date
    Feb 2000
    Location
    Sydney
    Posts
    1,149

    [F8] Help with mode7 and displaying 2d objects

    Hey,
    I'm hoping for some advice from some of the guns here, I have a tight project to get out the door, and it is in flash 8 (otherwise Id have a hack in papervision!)

    I'ts a race around a map game using a mode7 Engine (The fast one from Fred Heintz) I'm attaching 2d objects on top of it, but my perspective when I turn goes all screwey, and it's making my head explode!

    The files are at http://www.markfennell.com/mode7.zip for anyone that can help. And I'm happy to bribe for the solution!
    Regards Mark Fennell - Flash Kit Founder, general loiterer
    -------------------------------
    I Hate Zombies - iPhone Game | markfennell.com

  2. #2
    FK founder & general loiterer Flashkit's Avatar
    Join Date
    Feb 2000
    Location
    Sydney
    Posts
    1,149
    resolved thanks to a little help from the legendary PercyPea (mode7 grandmaster!)

    Code:
    import flash.geom.Matrix;
    import flash.display.BitmapData;
    
    class PeaGame extends MovieClip
    {
    	public var focalLength = 600
    	
    	private var	_nbMs:Number;
    	private var	_oldTime:Number;
    	private var	_time:Number;
    	private var	_resoDx:Number = 200 // width
    	private var	_resoDy:Number = 400 // width
    	private var _worldScale:Number = 55000
    	private var _horizon:Number = 160 // sets alpha in distance
    	private var _horizonScale:Number = 20 // 	
    	
    	private var	_xcam:Number;
    	private var	_ycam:Number = 50
    	private var	_zcam:Number;
    	private var	_angleX:Number = 20 // viewing angle up / down
    	private var	_angleY:Number = 180 // viewing angle rotate left / right
    	
    	private var	_nbScans:Number;
    	private var	_scanSteps:Number;	
    	
    	private var	_mapWidth:Number = 2880
    	private var	_mapHeight:Number = 2880
    	
    	private var _bmpd:BitmapData
    	
    	private var _angleIncrement:Number = 0.06
    	private var _velocity:Number = 0.1
    	
    	private var offsetX:Number = 0
    	private var offsetY:Number = 80
    
    	private var minimap:MovieClip
    	private var dot:MovieClip
    	private var minimapWidth:Number = 250
    	private var minimapHeight:Number = 250
    	private var minimapOffsetX:Number = 00
    	private var minimapOffsetY:Number = 00
    	
    	private var ringsArray:Array = []
    	private var ringsClipArray:Array = []
    	private var ringsArrayLength:Number
    	
    	private var btnUp:MovieClip
    	private var btnDown:MovieClip
    	private var offsetArrow:Number = 70
    	
    	private var container:MovieClip
    	
    	public function PeaGame()
    	{		
    	
    		var myThis = this
    		
    		container = this.createEmptyMovieClip("container", this.getNextHighestDepth());
    
    		_xcam = -_mapWidth * 0.5
    		_zcam = -_mapHeight * 0.5;
    		
    		// Init bitmap // Note image needs to be flibbed on verticle axis in image editor
    		_bmpd = BitmapData.loadBitmap("map");
    		
    		_nbScans = 0;
    		
    		minimapInit()
    		mode7init(1);
    		
    		_oldTime = getTimer();
    		
    		onEnterFrame = render
    		
    	}
    
    	// Loop ----------------------------
    	function render()
    	{
    		synchroniseTime();
    		keyManager();
    		mode7manager();
    		minimapRender()
    		peaRenderRings()
    	}
    
    	// Timer
    	function synchroniseTime()
    	{
    		// keeps movement consistent across different framerates
    		_time = getTimer();
    		_nbMs = _time - _oldTime;
    		_oldTime = _time;
    		if(_nbMs < 1) _nbMs = 1;
    		else if(_nbMs > 120) _nbMs = 120;
    	}	
    	
    	// Manage moves
    	function keyManager()
    	{
    		var	dx:Number;
    		var	dy:Number;
    		var	rayX:Number;
    		var	rayZ:Number;
    		
    		if(Key.isDown(Key.RIGHT)) _angleY += _nbMs * _angleIncrement;
    		if(Key.isDown(Key.LEFT)) _angleY -= _nbMs * _angleIncrement;
    					
    		_angleX = _angleX % 360.0;
    		_angleY = _angleY % 360.0;
    	
    		// demo purposes floats camera up or down
    		if(Key.isDown(107))	_ycam += _nbMs * 0.2;
    		if(Key.isDown(109))	_ycam -= _nbMs * 0.2;	
    		
    		rayX = Math.sin(_angleY * Math.PI / 180.0);
    		rayZ = Math.cos(_angleY * Math.PI / 180.0);
    		
    		if(Key.isDown(Key.UP))
    		{			
    			_xcam -= (rayX * _nbMs * _velocity);
    			_zcam -= (rayZ * _nbMs * _velocity);
    		}
    		
    		if(Key.isDown(Key.DOWN))
    		{			
    			_xcam += (rayX * _nbMs * _velocity);
    			_zcam += (rayZ * _nbMs * _velocity);
    		}
    		
    		//_xcam = _xcam % 2880;
    		//_zcam = _zcam % 2880;
    		
    		//if(_ycam < 30.0)					_ycam = 30.0;
    		//else if(_ycam >= 2000.0)		_ycam = 2000.0;
    		
    		// Display Do
    		
    		//trace(_root.minimap.dot._x+" :"+(_xcam))
    	}
    
    	function minimapInit()
    	{
    		
    		minimap = this.attachMovie("minimap", "minimap", this.getNextHighestDepth());
    		minimap._x = minimapOffsetX
    		minimap._y = minimapOffsetY
    		minimap._width = minimapWidth
    		minimap._height = minimapHeight
    		minimap._alpha = 50
    		
    		//trace(minimap._width+" : "+minimap._height)
    		dot = this.attachMovie("dot", "dot", this.getNextHighestDepth());
    		
    		// Initialise Rings, positions are stored in a layer on the minimap
    		for (var i in minimap.rings)
    		{
    			//trace(i+" : " +minimap.rings[i]+" : "+minimap.rings[i]._x)
    			ringsArray.push(new Array(_mapWidth-minimap.rings[i]._x, minimap.rings[i]._y))
    			var ring = this.attachMovie("ring", "ring"+this.getNextHighestDepth(), this.getNextHighestDepth() );
    			//ring._visible = false
    			ringsClipArray.push(ring)
    		}
    		
    		ringsArrayLength = ringsArray.length		
    	}
    	
    	function minimapRender()
    	{
    		dot._x = minimapOffsetX + minimapWidth + _xcam/_mapWidth * minimapWidth
    		dot._y = minimapOffsetY - _zcam/_mapHeight * minimapHeight
    		dot._rotation = _angleY
    	}
    	function peaRenderRings()
    	{
    		var tx, ty;
    		var sin = Math.sin;
    		var cos = Math.cos;		
    		var angle = -_angleY*Math.PI/180;
    		
    		//my guess as to how much horizon you have
    		var horizonHeight=80
    		
    		for(var j=0;j<ringsArray.length;j++)
    		{
    			var ob=ringsClipArray[j]			
    			
    			var vx = _xcam+ringsArray[j][0]
    			var vy = _zcam+ringsArray[j][1]			
    			
    			tx = vy*sin(angle)+vx*cos(angle);
    			ty = vy*cos(angle)-vx*sin(angle) + offsetArrow
    			
    			// clipping (if the ring  will be off screen, make it invisible, other wise calculate its position
    			if (ty<0) 
    			{
    				ob._visible = 0;				
    			} else {				
    				ob._visible = 1;				
    				//use your buttons to make focal length around 550 - 600, seems to work best
    				ob._y = focalLength*(_ycam/(ty))+horizonHeight
    				//dont ask me why it's -10/ty, I couldnt tell you  :)
    				var s = ob._y-(focalLength*(-5/(ty))+horizonHeight);		
    				ob._xscale = ob._yscale=(s);
    				ob._x = focalLength*(tx/(ty))+_resoDx * 0.5
    				
    			}
    		}
    	}
    		
    	// Mode7 Init
    	function mode7init(laDef)
    	{
    		var	i;
    	
    		// remove previous scanlines
    		for(i = 0; i < _nbScans; i++)
    		{
    			container[i].removeMovieClip();
    		}
    		// create new scanlines
    		if(laDef == 0)
    		{
    			// low def
    			_scanSteps = 2;
    			_nbScans = (_resoDy >> 1);
    		}
    		else
    		{
    			// high def
    			_scanSteps = 1;
    			_nbScans = _resoDy;
    		}
    		// create and place scan lines
    		for(i = 0; i < _nbScans; i++)
    		{
    			container.createEmptyMovieClip(i, 100 + i);
    			container[i]._x = offsetX + (_resoDx * 0.5);
    			container[i]._y = offsetY + (i * _scanSteps);
    		}
    	}
    	
    	// Mode7 Main. Draw a scan line after another (horizontal rectangles)
    	function mode7manager()
    	{		
    		var	i;
    		var	x2;
    		var	x2b;
    		var	colX;
    		var	colZ;
    		var	rayX;
    		var	rayY;
    		var	rayZ;
    		var	cfX;
    		var	angleX;
    		var	dist;
    		var	alpha;
    		var	leCos;
    		var	sinus;	
    		var	cosinus;
    		var	matrix:Matrix;
    		var	bmp:BitmapData;
    		
    		sinus = Math.sin;
    		cosinus = Math.cos;
    
    		matrix = new Matrix(); 
    		matrix.rotate(_angleY * Math.PI / 180.0);
    
    		x2 =  (_resoDx * 0.5) / 250.0;
    		
    		cfX = (40.0 / _nbScans)  * Math.PI / 180.0;
    
    		angleX = (_angleX  * Math.PI / 180.0) - (cfX * _nbScans * 0.5);
    
    		rayX = sinus(_angleY * Math.PI / 180.0);
    		rayZ = cosinus(_angleY * Math.PI / 180.0);
    		
    		bmp = _bmpd
    		
    		i = -1;
    		while(++i < _nbScans)
    		{
    			container[i].clear();
    			angleX += cfX;
    			rayY = sinus(angleX);	// dot prod ray (rayX, rayY, rayZ) with plane (0.0, 1.0, 0.0)
    			if(rayY < 0.0)
    			{
    				// over horizon
    				continue;
    			}
    			dist = (_ycam / rayY);				// distance to hit point on plane
    			
    			alpha = _horizon - (dist / _horizonScale);
    			
    			if(alpha < 1.0)
    			{
    				// too far
    				continue;
    			}
    			container[i]._alpha = alpha;
    			
    			leCos = cosinus(angleX) * dist;
    			colX = _xcam - (rayX * leCos);		// x of hit point on plane
    			colZ = _zcam - (rayZ * leCos);		// z of hit point on plane
    			
    			matrix.tx = (colX * matrix.a) + (colZ * matrix.c);
    		
    			matrix.ty = (colX * matrix.b) + (colZ * matrix.d) + offsetArrow
    			
    			x2b = (x2 * dist); 			
    		
    			// scale src
    			container[i]._xscale = (_worldScale / dist);	// scale tgt
    			
    			container[i].beginBitmapFill(bmp, matrix, false, true);
    			container[i].moveTo(-x2b, 0);
    			container[i].lineTo(x2b, 0);
    			container[i].lineTo(x2b, 1);
    			container[i].lineTo(-x2b, _scanSteps);
    			container[i].endFill();
    		}
    	}
    }
    Regards Mark Fennell - Flash Kit Founder, general loiterer
    -------------------------------
    I Hate Zombies - iPhone Game | markfennell.com

  3. #3
    Zombie Coder EvilKris's Avatar
    Join Date
    Jun 2006
    Location
    Fukuoka, Japan.
    Posts
    796
    Wow a free Mode 7 routine/engine, it must be my birthday.
    Why don't you try throwing in a few Papervision models instead of 2d sprites bud? I'm dying to see if that technique would work.

  4. #4
    FK founder & general loiterer Flashkit's Avatar
    Join Date
    Feb 2000
    Location
    Sydney
    Posts
    1,149
    If I was allowed to make it in as3 Id probably make a papervision tile engine and do it that way...

    anyways the engine is available from fredheintz.com and there is some code in my version that can help you put 2d objects on top of it, it will still mess with your head and cause you a headache (guaranteed!)
    Regards Mark Fennell - Flash Kit Founder, general loiterer
    -------------------------------
    I Hate Zombies - iPhone Game | markfennell.com

  5. #5
    Student
    Join Date
    Apr 2001
    Location
    -
    Posts
    4,756
    it´s not like papervision is only available for AS3- as2 is downloadable as well. So does it apply for Sandy booth AS2 and AS3 support.

    If you dont have to throw that many triangles AS2 might do the job as well.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  




Click Here to Expand Forum to Full Width

HTML5 Development Center