Iterating through a dictionary on Micro Python question

bkumanchik

  • Full Member
  • ***
    • Posts: 28
    • View Profile
I have created a table in Lua for Pico-8 in order to draw a row of invaders every frame (see attached images - code/result)

I'm trying to do the same thing with a dictionary (as it seems to be the closest data type to a table in Lua) in Micro Python and I'm having trouble understanding/figuring out the syntax to do this, I think I've created the dictionary properly but need to create the for loop to iterate through it and display my sprites.

Here's my code so far:


--------------------------------------------------------------------------
inv = {}
# sprite number, x, y
inv = {'s':'invader_a', 'x':40, 'y':28}
inv = {'s':1, 'x':50, 'y':28}
inv = {'s':1, 'x':60, 'y':28}
inv = {'s':1, 'x':70, 'y':28}
inv = {'s':1, 'x':80, 'y':28}

while(1):
   thumby.display.fill(0)
   for ?: 
      thumby.display.blit(sprite number?, x?, y?, 8, 8, 0)
--------------------------------------------------------------------------


As you can see, I need help to fill in the for loop and the sprite number?, x?, y?   I have a pretty good python book and have read many samples online of how this should work but I haven't been able to come up with a solution that works, any help would be appreciated.

Thanks,

Brian



rli

  • Jr. Member
  • **
    • Posts: 8
    • View Profile
Hi Brian,

There are a few changes I think you need to make. Here's my interpretation of what you want as well as a few other options:
Code: [Select]
sprite_1 = (...) # Some 8x8 sprite data

sprite_invader_a = (...) # Some other 8x8 sprite data

inv = [] # A Python list
# sprite number, x, y
inv.append({'s':sprite_invader_a, 'x':40, 'y':28})
inv.append({'s':sprite_1, 'x':50, 'y':28})
inv.append({'s':sprite_1, 'x':60, 'y':28})
inv.append({'s':sprite_1, 'x':70, 'y':28})
inv.append({'s':sprite_1, 'x':80, 'y':28})

while(1):
   thumby.display.fill(0)
   for invader in inv:
      thumby.display.blit(invader['s'],invader['x'], invader['y'], 8, 8, 0)

To remove an element from inv:
Code: [Select]
# By index:
del inv[0] # removes invader_a
del inv[0] # removes {'s':sprite_1, 'x':50, 'y':28}

# By value:
inv.remove({'s':sprite_invader_a, 'x':40, 'y':28}) # the whole dict needs to be passed in, which might not make sense for you

# This probably won't do what you expect (deleting all elements) because the indices change as you delete elements:
for invader_i in range(len(inv)):
    del inv[invader_i]


Other methods:
I'm not sure what the rest of your game code will look like, but for a space invaders style game, I would consider a pre-allocated list or using a dict to store information about game objects.

If you're unsure of the index of any particular object and you want to remove an element a little more efficiently than searching through the list and removing by index, I would recommend using a Python dict like this:
Code: [Select]
sprite_1 = (...) # Some 8x8 sprite data

sprite_invader_a = (...) # Some other 8x8 sprite data

inv = {} # A Python dict
# sprite number, x, y
inv[0] = {'s':sprite_invader_a, 'x':40, 'y':28} # The key/id (0) can be any immutable object. Usually it's an integer as shown here or a string like 'a', 'b', 'c'
inv[1] = {'s':sprite_1, 'x':50, 'y':28}
inv[2] = {'s':sprite_1, 'x':60, 'y':28}
inv[3] = {'s':sprite_1, 'x':70, 'y':28}
inv[4] = {'s':sprite_1, 'x':80, 'y':28}

while(1):
   thumby.display.fill(0)
   for inv_id in inv:
      invader = inv[inv_id]
      thumby.display.blit(invader['s'],invader['x'], invader['y'], 8, 8, 0)

# Removing an object:
del inv[3] # Removes {'s':sprite_1, 'x':70, 'y':28}
del inv[4] # Removes {'s':sprite_1, 'x':80, 'y':28}
del inv[0] # Removes {'s':sprite_invader_a, 'x':40, 'y':28}
Note the difference in what's removed compared to removal by index in the list version above.

If you pre-allocate a list instead, you can use the value None to mark an object as deleted:
Code: [Select]
inv = [None] * 5 # a List
inv[0] = {'s':sprite_invader_a, 'x':40, 'y':28}
inv[1] = {'s':sprite_1, 'x':50, 'y':28}
inv[2] = {'s':sprite_1, 'x':60, 'y':28}
inv[3] = {'s':sprite_1, 'x':70, 'y':28}
inv[4] = {'s':sprite_1, 'x':80, 'y':28}

# Removal:
inv[3] = None

Same thing:
Code: [Select]
inv = [ # List
    {'s':sprite_invader_a, 'x':40, 'y':28},
    {'s':sprite_1, 'x':50, 'y':28},
    {'s':sprite_1, 'x':60, 'y':28},
    {'s':sprite_1, 'x':70, 'y':28},
    {'s':sprite_1, 'x':80, 'y':28}
]

# Removal:
inv[3] = None

Good luck!

Edit: left an incorrect comment in there. Good catch
« Last Edit: October 31, 2021, 01:59:59 PM by rli »


bkumanchik

  • Full Member
  • ***
    • Posts: 28
    • View Profile
Thanks so much for the help, I will give this a try ASAP and let you know how it goes.

Brian


bkumanchik

  • Full Member
  • ***
    • Posts: 28
    • View Profile
Thanks so much for the very detailed help and explanation, I have a row of invaders animating and marching across the screen (see attached file) I still have a lot to

Take a look (if/when ) you have time and check out the forum post called Invader Test to see my first attempt at all the mechanics needed to get a Space Invader game up and running on the Thumby in Micro Python.

I have one question about your reply' in your reply under Other methods: - that is a Dictionary (not a list) right? your comments say "# A Python list" so I was just checking to make sure I understand.

Thanks again,

Brian



rli

  • Jr. Member
  • **
    • Posts: 8
    • View Profile
It looks good!

You're right about the comment, thanks for catching that. It is a dict.



 

SMF spam blocked by CleanTalk