Hi,
I’m currently implementing a simple 2D-Side-Scroller game. I already read about tiling engines, but my requirements differ in a certain point.
The thing is that the foreground layer that the player is moving on has an irregular shape (actually its a height profile transmitted to the game via remoting). I’d like to texture this variable line.
So when i read about using BitmapData for speed purposes, i upgraded my project from flash mx to CS3 to be able to use this functionality. As i got it, the purpose of using BitmapData is to keep the number of mcs / sprites in the movie to a minimum. Still, i don’t quite get it (let the number of foreground track segments be i):
- I started with just one MC for the whole foreground line, which i drew in there using moveTo (i drew i polygons):
GraphicsUtil.createParaP(groundMC, 0x00FF00, 0x0000FF, 30, stPY(heightProfile*), stPY(heightProfile[i + 1]));
(where stPY is a screen coordinate translation function and createParaP is:
//create parallelogram with fill
public static function createParaP(clip : MovieClip,color1 : Number,color2 : Number,alpha : Number,p1 : Point,p2 : Point) : Void {
clip.beginFill(color1, alpha);
clip.moveTo(p1.x, p1.y);
clip.lineTo(p2.x, p2.y);
clip.lineTo(p2.x, p2.y + Stage.height);
clip.lineTo(p1.x, p1.y + Stage.width);
clip.lineTo(p1.x, p1.y);
clip.endFill();
}
That works OK, but no textures. As with the following examples, the foreground line clip is drawn entirely at startup, and then only moved in x and y space.
- I modified my code to use one mc per segment (basically the same code as before, but one segMC is created per segment:
for (var i : Number = 0;i < heightProfile.length - 1;i++) {
var segMC:MovieClip=groundMC.createEmptyMovieClip("segMC" + i, groundMC.getNextHighestDepth());
GraphicsUtil.createParaP(segMC, 0x00FF00, 0x0000FF, 30, stPY(heightProfile*), stPY(heightProfile[i + 1]));
drawSegment(segMC, stPY(heightProfile*), stPY(heightProfile[i + 1]));
}
Better modularity, and not too many MCs (the heightprofile typically has around 50 or 60 SEgments). Should also come in handy for texturing, as i could draw the segment as an rectangle, texture it and rotate it into place. but still. no Texturing.
-
When thinking about how to texture the individual segments (which have a variable length and a variable incline, the shapes drawn are Paralellograms), i first wanted to use a MC with the Texture. I would then attach this MC to every Segment as often as needed and place them in a tiling fashion. But this leads to a HUGE number of MCs (a segment can easily be 5000px in lenght, with a 128x128 TexMC… didnt bother doing the math).
-
Now i stumbled across the BitmapData. I first thought it was the solution. But then i realized that when attaching a BD to a MC, i cannot define any coordinates? (Seems i took a wrong turn along the road, i thought i could just put multiple BD instances into the MC and arrange them so they build a tiling whole). So if i wanted to texture with my 128x128 grass texture, i’d have to build a big BitmapData and attach it to the MC, probably using the drawn polygon as a mask? But then, i could only texture segments up to 2800px in length, and it would bog down system resources, as the tiling bitmap is held im memory over and over. And I would have to divide each segment into smaller parts not exceeding this limit, which in turn would increase the MC count. Isnt there a smarter way?
I could also break with the “draw all at init” approach mentioned in 1), but i’d like to keep it on a per-segment basis (so i could only texture the segments that are gonna be needed in the near future), and not splitting up the segments any further.
This is what i already did with the BitmapData (and no, its neither complete nor working correctly, i think i got the mask wrong or sth.)
public function drawSegment (mc:MovieClip, p1: Point, p2:Point) : Void {
var dist:Number = GraphicsUtil.distanceBetweenPoints(p1, p2);
var angleRad : Number = GraphicsUtil.inclineRAD(p1, p2);
var b:BitmapData = BitmapData.loadBitmap("GrassTexture");
var bmpMC : MovieClip = mc.createEmptyMovieClip("bmpMC", mc.getNextHighestDepth());
bmpMC.attachBitmap(b, 0, "auto", false);
bmpMC.setMask(mc);
}
As you know now, i am quite unsure how to handle the texturing problem. Just FYI, i use Flash CS3, and my animations are currently decoupled from the timeline using Interval-Updates - and some of them always will, as i do a server data update every second via remoting (in a update-method, where i set the foreground track x and y to the transmitted values, effectively syncing the mc with the server). Between these server updates, i extrapolate player position and speed from the last update (in a movePlayer method), which is also not working perfectly (i have 12 FPS and define 1/12 sec Intervals for the move method, but the number of actual calls varies from 8 to 14, and thus every second, i have a slight (and still ugly) resync that i have to do, especially at high speeds).
So in any case thank you for reading all this stuff!
I really hope you understand my problem and I am glad about any pointers you can give me.
Regards,
Paul