Problem with drawing moving sprites.

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Problem with drawing moving sprites.

Post by davisdude »

Fruit[2] isn't touched here because when Fruit[1] is removed, Fruit[2] becomes Fruit[1], while the index is at 2. I hope that makes sense. It's a bit confusing. :P
As for your for-loop, I don't think it affects it, but I'm not sure. Since you're using pairs, I'm assuming you have a table that looks like this:

Code: Select all

Fruits = {
     Apple = { 'Whatever' }
}
?
In that case, I'm pretty sure it's not affected, since their index isn't based numerically. You may want to consult another, more experienced programmer for that, though.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Moonkis
Prole
Posts: 14
Joined: Thu Jan 09, 2014 4:37 pm

Re: Problem with drawing moving sprites.

Post by Moonkis »

davisdude wrote:Fruit[2] isn't touched here because when Fruit[1] is removed, Fruit[2] becomes Fruit[1], while the index is at 2. I hope that makes sense. It's a bit confusing. :P
As for your for-loop, I don't think it affects it, but I'm not sure. Since you're using pairs, I'm assuming you have a table that looks like this:

Code: Select all

Fruits = {
     Apple = { 'Whatever' }
}
?
In that case, I'm pretty sure it's not affected, since their index isn't based numerically. You may want to consult another, more experienced programmer for that, though.
Yeah, it resizes the table, right that makes sense! I tried iterating it backwards and it fixed the problem! I still have a few questions left.

My EntityManager.objects is indexed with an integer or "numerical" so I can use either pair or ipair, but they have exactly the same result. However if I have one generic "pairs"-loop that JUST updates and then add a new "pairs"-loop right after the update loop that checks if an Entity is alive and calls table.remove if it's dead dosen't cause this. But it should have the same impact? Should't it? I mean the table elements would be skipped this way as well, wouldn't it?

Like this:

Code: Select all

	for i, e in ipairs(EntityManager.objects) do
		if e.update then
			e:update(dt)
		end
	end

	for i, e in ipairs(EntityManager.objects) do
		if e:isAlive() == false then
			table.remove(EntityManager.objects, i)
		end
	end
This fixes the issue, by just moving the table.remove into it's own loop...
Note that this shouldn't be working, it still skips objects now and then, but it fixes the sprite movement...wat?

EDIT:

It might have to be with that other entities inside the array adds other entities (like Player adds Bullets) while doing the e:update(dt), however, removing from a table is not safe using pairs( or ipairs) whether I put it in a new loop or not, the correct way is to do a backwards iteration...

Combining wrongly deleting objects in tables whilst adding to it might be what causes this weird movement, seeing as not all objects gets updated correctly.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Problem with drawing moving sprites.

Post by davisdude »

One minor thing:
- Instead of if e:isAlive() == false then you can do if not e:isAlive() then. Not really important, but I think it looks better, and it takes less time to type. You can do whatever you want to do, though.

As for your solution, that's not the way I would do it, but I guess if it works...
Since your entities are numerically entered anyway, I would recommend the backwards-iterating loop, so you only have to have one loop, not two. I think this solution is not actually working, but I could be wrong. A .love would be nice, just to test.
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Moonkis
Prole
Posts: 14
Joined: Thu Jan 09, 2014 4:37 pm

Re: Problem with drawing moving sprites.

Post by Moonkis »

davisdude wrote:One minor thing:
- Instead of if e:isAlive() == false then you can do if not e:isAlive() then. Not really important, but I think it looks better, and it takes less time to type. You can do whatever you want to do, though.

As for your solution, that's not the way I would do it, but I guess if it works...
Since your entities are numerically entered anyway, I would recommend the backwards-iterating loop, so you only have to have one loop, not two. I think this solution is not actually working, but I could be wrong. A .love would be nice, just to test.
Please add a suggestion of how to do it, I'm still a newbie to Lua and I'm interessted in alternative solutions!

I do have 2 questions:

* How to correctly add item to table WHILE iterating over it?
* I know I can delete items from tables when iterating backwards, but rumors say you can "nil" an index also, how do you do that correctly?

I think those questions are the root and key to this problem of mine :)
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Problem with drawing moving sprites.

Post by davisdude »

Moonkis wrote:Please add a suggestion of how to do it, I'm still a newbie to Lua and I'm interessted in alternative solutions!
I'm assuming you're talking about backward iteration for your entities. If so, here's how you would do it:

Code: Select all

for a = #EntityManager.objects, 1, -1 do 
     local Entity = EntityManager.objects[a]
     if Entity.update then
          Entity:update(dt)
     end
     if not Entity:isAlive() then
          table.remove( EntityManager.objects, a )
     end
end
If you don't understand what's going on here, don't hesitate to ask! :)
Moonkis wrote:* How to correctly add item to table WHILE iterating over it?
It depends on the situation. If you want the newly added item to be updated immediately, that would be fairly complex. If you were alright with it being updated later, though, it would be easier.
Here's how you would do the easier one:

Code: Select all

for a = #EntityManager.objects, 1, -1 do 
     local Entity = EntityManager.objects[a]
     if Entity.update then
          Entity:update(dt)
     end
     if not Entity:isAlive() then
          table.remove( EntityManager.objects, a )
     end

     if ThingHappensHereThatMakesNewEntity then
          table.insert( EntityManager.objects, Thing ) -- Thing being what you want inserted.
     end
end
The first option is much more difficult. I'll give it a whirl (warning: code is untested).

Code: Select all

for a = #EntityManager.objects, 1, -1 do 
     local Entity = EntityManager.objects[a]
     if Entity.update then
          Entity:update(dt)
     end
     if not Entity:isAlive() then
          table.remove( EntityManager.objects, a )
     end

     if ThingHappensHereThatMakesNewEntity then
          ShiftTable( a, EntityManager.objects )
          Table[a - 1] = Thing -- Thing still being the added item. 
     end

     local function ShiftTable( Start, Table )
          for e = 1, #Table do
               Table[e + 1] = e
          end
     end
end
That should work, but don't hold me to it. I probably made a mistake somewhere.
Mookis wrote:* I know I can delete items from tables when iterating backwards, but rumors say you can "nil" an index also, how do you do that correctly?

Code: Select all

if not Entity:isAlive() then
     EntityManager.objects[a] = nil
end
Hope this helps! :)
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Problem with drawing moving sprites.

Post by Robin »

davisdude wrote:The first option is much more difficult. I'll give it a whirl (warning: code is untested).
That doesn't work (I see three reasons why not). And even if it worked, it would still be wrong, because then you update the current Entity twice (try to work it out in your head to see why).
Help us help you: attach a .love.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Problem with drawing moving sprites.

Post by davisdude »

Of course I made a mistake... :cry: How about this?

Code: Select all

function ShiftTable( Table, Index )
	for a = #Table, Index, -1 do
		Table[a + 1] = Table[a]
	end
end

-- Many lines of code later...

for a = #EntityManager.objects, 1, -1 do
	if ThingHappensHereThatMakesNewEntity then
		ShiftTable( EntityManager.objects, a )
		Table[a] = Thing -- Thing still being the added item. 
	end 
	local Entity = EntityManager.objects[a]
	if Entity.update then
		Entity:update(dt)
	end
	if not Entity:isAlive() then
		table.remove( EntityManager.objects, a )
	end
end
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
User avatar
Robin
The Omniscient
Posts: 6506
Joined: Fri Feb 20, 2009 4:29 pm
Location: The Netherlands
Contact:

Re: Problem with drawing moving sprites.

Post by Robin »

I didn't test it but it seems to fix almost everything I had a problem with (including one thing I had overlooked).

The one problem is this: suppose we have 3 entities ({"a", "b", "c"}), and after processing the first entity, we insert a new one (so when a = 2, ThingHappensHereThatMakesNewEntity is true, somehow).

Code: Select all

{"a", "b", "c"}, a = 3, EntityManager.objects[a] = "c"
-- new entity inserted here:
{"a", "x", "b", "c"}, a = 2, EntityManager.objects[a] = "x"
{"a", "x", "b", "c"}, a = 1, EntityManager.objects[a] = "a"
-- whoops! we've skipped "b"
And sorry to spoil the fun, but with your new implementation, this:

Code: Select all

		ShiftTable( EntityManager.objects, a )
		Table[a] = Thing -- Thing still being the added item. 
is (probably, I haven't checked it) equivalent to:

Code: Select all

		table.insert( EntityManager.objects, a, Thing )
Help us help you: attach a .love.
davisdude
Party member
Posts: 1154
Joined: Sun Apr 28, 2013 3:29 am
Location: North Carolina

Re: Problem with drawing moving sprites.

Post by davisdude »

Oh, I didn't know you could do that. That's good to know. :)
Just out of curiosity, how would you do it?
GitHub | MLib - Math and shape intersections library | Walt - Animation library | Brady - Camera library with parallax scrolling | Vim-love-docs - Help files and syntax coloring for Vim
Moonkis
Prole
Posts: 14
Joined: Thu Jan 09, 2014 4:37 pm

Re: Problem with drawing moving sprites.

Post by Moonkis »

If we are only iterating and adding in a loop (no removal) is it safe to use the iterator-loops like ipairs and pairs?
Post Reply

Who is online

Users browsing this forum: Google [Bot] and 2 guests