Hello Everybody!
I’m using Haxe for a sort while now and for the most part i’m enjoying it!. I wish to use it to make some 2D games. I am experiencing some problems though On Neko and Cpp target - Cpp is my primary target, Neko is for testing. I’m experiencing a lot of lag. It seems that things are not buffered correctly on SDL backend targets. I’ve posted this example code to proof my point. Hopefully someone has a solution for this. This is otherwise a breakpoint for me.
I would ratter use Haxe then something else, but this kind of lag is unacceptable for me. (sorry, I really like haxe though)
Does anyone have a solution? Sometimes it takes a while for the lag to show, but if you keep restarting the program eventually you will have a version that lags.
This code should work out of the box on any new generated OpenFL project of any version. Only Flash does not like me and gives a blank window? :S Obviously I want to know what to do with this code to make it not lag!
package;
/*
OpenFL program to show lag. It runs great in HTML5 but Neko And CPP targets are laggy.
You can use any version of OpenFL + Lime, but Flash only shows a empty window :S ?
If you start the program either lag is already showing or it may take a while.
Keep restarting the program, eventually lag will show. Also dragging the window in
MS Windows can introduce lag. HTML5 does not show any of this behaviour.!, So i'm
guessing that SDL - implementation or SDL itself - is the culprit!
Please note that, resizing the stage is not implemented in this code, and
don't build with -debug! Debug targets can/may allocate new objects for debugging!
*/
import openfl.display.Sprite;
import openfl.geom.Rectangle;
import openfl.display.DisplayObjectContainer;
class Main extends Sprite {
// you can play around with these, but 200, 300 is heavily tested
// For windowed mode I use 1280x720
public static inline var kSize:Int = 200;
public static inline var kSpeed:Int = cast kSize*1.5;
var amount:Int;
var yoff:Float;
var instances:Array<Sprite>;
var colors:Array<UInt> = [0xFF0000, 0x00FF00];
var col:Int=0;
var current:Int=-1;
var world:DisplayObjectContainer;
public function new () {
super ();
world = new DisplayObjectContainer();
addChild(world);
amount = Std.int(stage.stageWidth / kSize)+2;
instances = new Array<Sprite>();
yoff = stage.stageHeight-kSize; // No subpixels, both are int.
for (i in 0...amount) {
newInstance(++current);
}
stage.addEventListener(openfl.events.Event.ENTER_FRAME, onUpdate);
}
function createSprite(color:UInt):Sprite {
var s = new Sprite();
s.graphics.beginFill(color);
s.graphics.drawRect(0, 0, kSize, kSize);
s.graphics.endFill();
return s;
}
function newInstance(column:Int) {
var s = createSprite(colors[col]);
s.x = column * kSize; // no subpixels, both are int.
s.y = yoff;
if (++col==colors.length) col=0;
instances[column]=s;
world.addChild(s);
}
function onUpdate(e:openfl.events.Event) {
moveWorldByDelta(1.0/60);
validateBuild();
}
function validateBuild() {
// Just math, no new Garbage() or "bad" + "string" + "concats"
var c:Int = Std.int((-world.x+(stage.stageWidth))/kSize);
var s:Sprite;
if (c>current) {
s = instances[0];
for (i in 1...amount) { // no iterator!
instances[i-1] = instances[i];
}
// No subpixels (both are int)
s.x = ++current * kSize;
instances[amount-1]=s;
}
}
function moveWorldByDelta(delta:Float) {
// Delta is open for discussion. But i've tried any sane value for it.
// Dynamic delta's, smoothing deltas, but Fixed Deltas (like this one)
// Give nice results. Also when in VSync (assuming 60hz), fixed delta's
// 1/60 should give best results. (don't forget that the caller/drivers can/will also
// adept their syncs when it fall behind, there no reason to do this yourself.)
// some much refered reading: https://gafferongames.com/post/fix_your_timestep/
// a suggested variable delta 0.01 or 0.02 makes the rendering really shakky.
// After applying that he interpolates the alpha, technically he's is just doing a
// complexed dynamic delta: (current_frame_time-_previous_frame_time), with
// overhead of potentially calling the physics multiple times instead of once.
// also in vsync this kind of methods should not be necessary, just use 1/refreshrate.
// Lets just say that even if 1/60 is inaccurate, then still the only real effect should
// be speed, and this should not result in lag!. Lag is created by not being synced correctly
// with the hardware. HTML5 syncs perfectly, CPP/Neko do not! Double Buffering is probably
// not well implemented!
world.x -= Math.round(kSpeed * delta); // No subpixels!
}
}
Many thanks in advanced for any help on this matter!
Best regards!