|
-
FK founder & general loiterer
[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!
-
FK founder & general loiterer
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();
}
}
}
-
Zombie Coder
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.
-
FK founder & general loiterer
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!)
-
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|