Fake old 3d racing games

Hello everyone.
I would like to have a tip on performance issues.
I am going through a tutorial found on internet http://codeincomplete.com/posts/2012/6/22/javascript_racer/

I am now at the last part of the tutorial and I am at a loss.

the road is laminated into multiple segments, wel it is actually the other way around; the road is made of multiple segments.
on the sides of the road, there are trees, bilboards and stuffs. bref, bitmaps

And those bitmaps are set arbitrarily on the segments of the road.

as the player goes through the race track, there is a need to update and render the segments.
where I redraw the segments and all(segments scales…), but redrawing the segments also means re-adding some more bitmaps. which gets a bit out of hand here.

any idea on how to tackle this kind of problem so that it helps in future times too?

1 Like

Neat!

Well if you get to the end, where they say to use one spritesheet, then I’d recommend using Tilesheet.drawTiles to draw it, or perhaps a library that works over drawTiles (like “tilelayer” and others), you can use separate bitmaps, but currently, drawTiles will give you better performance for a spritesheet

Yes I had thought of using Tilesheet but the problem is I won’t be able to change the width and height of pictures.

Like while going through the race track, the further deep(in depth) is a tree, the smaller it is. and the closest it gets to the car the bigger it becomes.
so the height and width properties are always changing.
Using Tilesheet would have saved my day though.

You can change scaleX and scaleY with tilesheet when using Tilesheet.TILE_TRANS_2x2 flag. It looks like this:

var renderArray:Array<Float> = []; renderArray.push(0);//x renderArray.push(0);//y renderArray.push(0);//tileRect id var matrix:Matrix = new Matrix(); matrix.scale(2, 1.15); //scaleX, scaleY renderArray.push(matrix.a); renderArray.push(matrix.b); renderArray.push(matrix.c); renderArray.push(matrix.d); tilesheet.drawTiles(graphics, renderArray, true, Tilesheet.TILE_TRANS_2x2);

what if you just use a big animated sprite?

I.e:
a straight one
turn left
turn right

and make all of them looks like moving
this is the easiest way

it is the case for the player, but for the trees and stuffs on the sides of the road that’s another story.
so I am changing my codes a bit, I had totally forgot about Tilesheet.TILE_TRANS_2x2.
Thanks

Here’s how things went:
The use of Tilesheet was kinda cool but I had issues with uphills where the pictures needed to be shown partially.
-> so I thought hard then I came up with the idea of using "shape.graphics.beginBitmapFill()’ which did the trick perfectly
well, almost perfectly.

the problem that I am having right now is the following:

When the game starts, everything is drawn from back to front, from where the eye view ends to where the car is, so I can have the bilboards at the back covered by the trees in front of it and so forth until where the player is.
I have a while loop making wonders at start, everything is perfect.
well, almost perfect.

but When you are now driving on the track things seems cool untill there are billboards from the back appearing in the middle of a tree and the rest goes ugly.

I tried to put a addChildAt(myShape,0) in my while loop and it did the same but in reverse! the first pictures where ugly then it got pretty cool until the end. well almost. for some reasons near the end the games laggs a lot.

then I got fed up and thought why not adding all the shapes at the same time from back to front then the game crashed.
now I am out of ideas.

I figured something out!!!
I was too into the tutorial (which is in javascript) that I forgot I was in openfl.

Anyway, in the tutorial he is using a single canvas context variable that he was forced to use the painter algorithm, which says we need to draw from the back up to the front.

While in openfl, thanks to addChildAt and setChildIndex there’s no need for the painter algorithm.

so I got rid of that while loop and put a for loop in its stead.
And with the help of a if-statement and the combo addChildAt/setChildIndex
I got it fixed.
but now some part of my game is blinking…
quite annoying.

If you re-use graphics from frame to frame, are you recreating it, or are you keeping it, and simply updating the position/scale/rotation?

If it was simply updating position/scale/rotation, I would have sticked to tilesheets.
I recreate the graphics as the height of the next graphics is not the same,
I mean:
a rough illustration:

public static function peind(contenaire:Shape, largeur:Float, hauteur:Float, resolution:Float, largeur_de_la_route:Int, bitmapData:BitmapData, sprite: { x:Int, y:Int, w:Int, h:Int }, scale:Float, destX:Float, destY:Float, decalageX:Float = 0, decalageY:Float = 0, ?debordemenY:Float) {

var destW:Float = (sprite.w * scale * largeur / 2) * (Main.SPRITES.SCALES * largeur_de_la_route);
var destH:Float = (sprite.h * scale * largeur / 2) * (Main.SPRITES.SCALES * largeur_de_la_route);
destX = destX + (destW * decalageX);
destY = destY + (destH * decalageY);
var debordementH:Float = 0;
if (debordemenY != null) {
    debordementH = Math.max(0, destY + destH - debordemenY);
}

contenaire.graphics.clear();

if (debordementH < destH) {
//getting the image from the bitmapdata
contenaire.graphics.beginBitmapFill(bitmapData, new Matrix());
contenaire.graphics.drawRect(0, 0, sprite.w, sprite.h - (sprite.h * debordementH / destH));

  //placing the image
  contenaire.x = destX;
  contenaire.y = destY;
  contenaire.width = destW;
  contenaire.height = destH - debordementH;

}

}

this following line is the reason why I couldn’t use tilesheets contenaire.graphics.drawRect(0, 0, sprite.w, sprite.h - (sprite.h * debordementH / destH));
hence recreating the graphics was easier for me.

Oh, you need to clip the height? Perhaps a scrollRect might work

Yes I do need to clip the height!!!
my bad some of my variables are in french.
anyway, scrollRect???
ohhh that’s new for me. I now you are really busy, do you perhaps any links on how to use it?

Something like this:

var sprite = new Sprite ();
sprite.graphics.beginFill (0xFF0000);
sprite.graphics.drawRect (0, 0, 100, 100);
sprite.scrollRect = new Rectangle (0, 0, 100, 50);
addChild (sprite);

Have you tried adding:

 contenaire.graphics.endFill();

after the drawRect?

yep but nothing changed :frowning:

You only need to use endFill() after moveTo() and lineTo(). With drawCircle() and drawRect(), it makes no difference.

It sounds like scrollRect is going to be the easiest solution. Make a Bitmap object and set its scrollRect each frame. Oh, and for the record, something like bitmap.scrollRect.x = 5 will have no effect. You need to invoke the setter function:

myRect.x = 5;
bitmap.scrollRect = myRect;