Quick Links: Download Gideros Studio | Gideros Documentation | Gideros Development Center | Gideros community chat | DONATE
onEnterFrame execution order? — Gideros Forum

onEnterFrame execution order?

dwilson08dwilson08 Member
edited September 2012 in General questions
Hey guys,

I'm just starting to learn Gideros and I'm trying to make a fairly simple overhead racing/obstacle-avoid game. Currently, I'm having some weird issues with the onEnterFrame event not working like I expect. Right now it seems the order that my sprites run their onEnterFrame function seems to be somewhat random. Unfortunately for me, if those functions aren't run in particular order I get weird seams in my road tiles (from speed changes). Here's are some relevant snippets to describe my code.

Game.lua
...
function game:init()
 
	local roads = Sprite.new()
 
	for i=0, 3 do
		local road = Road.new()
		road:setPosition(0, i*road:getHeight())
		roads:addChild(road)
	end
 
	self:addChild(roads)
 
	local smPothole = Pothole.new("assets/pothole-s.png", small)
	self:addChild(smPothole)
...
road.lua
Road = Core.class(Sprite)
 
function Road:init()
	local bitmap = Bitmap.new(Texture.new("assets/roadTile.png"))
	self:addChild(bitmap)
	self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
end
 
 
function Road:onEnterFrame(event)
	local x, y = self:getPosition()
	local tileHeight = self:getHeight()
 
	--[[Checks if tile is off the canvas and moves it to the top. Otherwise, move road tile down
		slightly to give illusion of car moving.]]
 
	if y >= tileHeight*3 then
		local overshoot = y - tileHeight*3
		self:setY(-tileHeight + overshoot + speed)
	else 
		self:setY(y + speed)
	end
end
pothole.lua
Pothole = Core.class(Sprite)
 
function Pothole:init(texture, size)
	--initialize pothole with texture passed as argument
	local bitmap = Bitmap.new(Texture.new(texture))
	self.size = size
	self:addChild(bitmap)
	self:setPosition(120, 955)
	self:addEventListener(Event.ENTER_FRAME, self.onEnterFrame, self)
end
 
function Pothole:onEnterFrame(event)
 
	local x, y = self:getPosition()
 
	-- moves pothole down screen with road, moves to top if off canvas.
	if y >= 954 then	
		self:setY(math.random(-950,-50))
		self:setX(math.random(70,330))
	else 
		self:setY(y + speed)
	end
 
	-- hit collision with car. See init.lua 
	if car:collision(self) then
		if speed > minSpeed then
			speed = speed - 0.2
			speedometerNeedle:setRotation(speedometerNeedle:getRotation()-4.8)
		end
	end
end
The problem is that if the pothole enterframe function is not run last, it changes the speed variable which makes the road tiles not line up properly (since it uses the speed variable to change position). I added a few print functions in that my code to figure out what order the functions were firing... and oddly enough it's different every time I reload in the player. (Are they all firing simultaneously and it's just my processor that's changing the order?)

What can I change so that all the road sprites run their onEnterFrame functions before the pothole sprites do?

Anyways, I'm just stumbling my way through this since I don't have a lot of programming experience. The code is probably pretty hackish, I'd love to hear how I can improve it.

Thanks in advance! :)

Likes: amaximov

Tagged:
+1 -1 (+1 / -0 )Share on Facebook

Comments

  • The order (I suspect) is probably determined by the order the items are stored in their respective tables.

    However what I would advise is to NOT have separate EnterFrame listeners but to assign a single EnterFrame listener to a master "control" object, it's then the job of this object to run the game. What you do then is call each objects EnterFrame (I prefer to rename it update) function in the order YOU specify - usually in a for loop or something like that.

    If you take the same approach and have a single touch listener function as well, it might also make your life a LOT easier as well.

    Hope this helps :)
    WhiteTree Games - Home, home on the web, where the bits and bytes they do play!
    #MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
  • Yeah, I designed a similar game, and I had separate onEnterFrame listeners for different objects as well (something I probably won't do again.)

    You could try a few things. I have no idea id they will work. First, rather that having the onEnterFrame listener for each road instance determine position, you could use the game onFrameListener to change the position of the roads sprite that you seem to have them stored in.

    Or, do the same thing only move each road object within the roads sprite under a single onEnterFrame even in the main game script. (which is I think what I did with my game.... but I can't remember. Something like that)

    @techdojo was probably right, using separate onEnterFrame instances will probably cause headaches for stuff like this.
  • @techdojo: Yup, had to do some rewriting but that seems like the solution that worked. I had separate listeners just to make my code a bit more mentally manageable but putting everything into one update function wasn't much harder. Now having separate classes seems pretty unnecessary. Thanks for your answer.

    @joel: I think I stole the concept from your early source code ;) . I ended up adding the roadtiles and potholes as children to sprites then looping through the children via indices in the main update function (called on onEnterFrame) to move them. Seems to work pretty good.
Sign In or Register to comment.