Hello there, i've been searching the web and a few books for the last days with this (simple?) problem and only ended up fairly confused.

the scenario: me and my friends are learning python while/by writing a little game together.
My current problem is conserning getting the items (from classes) blittet on the screen at predefined positions, BUT only the items that has a: item.count > 0.
The way i figured i could do this was to, at the beginning of the loop, to add every item with item.count > 0 to a dictionary with its name and count.
Then a len(item_dictionary) determines how many of the predefined item slots should be filled, and thats where i get stuck.

It would be great if i could somehow extract the key (in this example "item") from the dictionary in use for assigning the coords: "item"([pre_def_x,pre_def_y]) and blitting of "item".image at "item".rect

I hope you understand my problem and are able to help, even though our code probably is like babytalk ;-)

Example of our item class:

class red_key(pygame.sprite.Sprite):
    image = None
    count = 0

    def __init__(self, location):
        pygame.sprite.Sprite.__init__(self)

        if red_key.image is None:
            red_key.image = pygame.image.load("red_key.png").convert_alpha()
            
        self.image = red_key.image

        if red_key.count > 0:
            red_key.rect = self.image.get_rect()
            red_key.rect.topleft = location

the adding to dictionary at beginning of loop:

item_dictionary.clear()
    if red_key.count > 0:
        item_dictionary["red_key"]=red_key.count

Have so far tried this (down), in order to get the dictionary key out for use at the class operations, but the " " is keeping me from doing it because obviously: 'str' is not callable

item_sum = len(item_dictionary)
    item_list = item_dictionary.keys()
    if item_sum == 1:
        item_list[0]([570,70])
        screen.blit(item_list[0].image,item_list[0].rect)

It is okay for me at the moment to add every item to the dictionary "manually" (item by item), and having to define assignments for every possible item_sum.

Thanks in advance
Nezbo

Edited 6 Years Ago by nezbo: n/a

I'm little confused on what you are trying to do, but it seems that if a item has a count of 0 then it should not even be active and just have pygame kill() it. If count is enumerating the number of classes on the screen then it is easier to have a dict or list of positions when rendering the sprites. Also is there a reason that you are blitting the sprites to the screen instead of using draw()? If you are using a sprite group to render then it is easy to set the beginning positions of sprites when rendering.

Also how long is your game, if you can post more of the code it might help with diagnosing the problem.

Edited 6 Years Ago by tbone2sk: n/a

I'm little confused on what you are trying to do, but it seems that if a item has a count of 0 then it should not even be active and just have pygame kill() it. If count is enumerating the number of classes on the screen then it is easier to have a dict or list of positions when rendering the sprites. Also is there a reason that you are blitting the sprites to the screen instead of using draw()? If you are using a sprite group to render then it is easy to set the beginning positions of sprites when rendering.

Also how long is your game, if you can post more of the code it might help with diagnosing the problem.

Yea i know its a little complex. The item.count is actually the number of that item in possession, thats why the item shouldn't be assigned a position if the item.count == 0. The reason why im using blit instead of draw is solely because i've gotten accustomed to it during learning python (and pygame) through a book.
the sprites are saved as individual files (as seen in the class).

I'll try to describe better what im trying to do:
I have a limited number of item spots on a "inventory" part of the screen. The items should only be visible here if they have a item.count > 0 (items which the player has none of should not be displayed). Also I do not want to assign a specific spot for each items because it would look bad when some were missing at specific spots. I would like them to "move up" when an item gets used/removed. The way i had imagined it (the code) all items with a item.count > 0 is added to a dictionary and that dictionary is used to determine the number of different items in possession (len(dictionary)) and following assigning specific coords for dictionary[0], dictionary[1], dictionary[2] ... up to len(dictionary). But the problem with that approach is just how i can let the assignment script know the class of the item (code 3).

Hope this helps a bit, if you have any questions please ask some more, would really like to get this problem solved :)

I'm not sure on how you are storing the items that are active, but one way to do it is store them in a list. When you render a sprite then add it to this list, and if the item is used pop it from the list. Then you can have a dict with the open position that item can go on the screen. This way you don't need to use count as the active items on the screen will be the item in this list.

class red_key(pygame.sprite.Sprite):
    image = None
    count = 0

    def __init__(self):
        pygame.sprite.Sprite.__init__(self)

        if red_key.image is None:
            red_key.image = pygame.image.load("red_key.png").convert_alpha()
            
        self.image = red_key.image
        
    def moveToPos(self,location):
        self.rect = self.image.get_rect()
        self.rect.topleft = location


listOfItems = []
positionsDict = {1:(570,400), 2:(575,400), 3:(580,400)}

#Adding item to list
redKey = red_key()
listOfItems.append(redKey)

for pos in positionsDict:
    if len(listOfItems) == pos:
        listOfItems[len(listOfItems)-1].moveToPos(positionsDict[pos])
        break

This is just a start, also when an item is removed you will have to change the cords of the active items by comparing the dict key with their position in the list.

Edited 6 Years Ago by tbone2sk: n/a

You can use the class instance as key:

class RedKey(pygame.sprite.Sprite):
    image = None
    count = 0

    def __init__(self, location):
        pygame.sprite.Sprite.__init__(self)

        if self.image is None:
            self.image = pygame.image.load("red_key.png").convert_alpha()
            
        if self.count > 0:
            self.rect = self.image.get_rect()
            self.rect.topleft = location


# more of your code here
...

location = ...  # pick your location

# create instance of class
red_key = RedKey(location)

# more of your code here
...

item_dictionary.clear()
if red_key.count > 0:
    item_dictionary[red_key] = red_key.count

Edited 6 Years Ago by bumsfeld: n/a

Thanks alot guys. I used a variation of tbone2sk's solution. I thought it would be nice to show you a photo of how it ended up, so here it is:

And yes, everything is drawn in ms paint ;)

Edited 6 Years Ago by nezbo: n/a

Attachments qm.jpg 66.26 KB

Love the artwork, great for just using paint! You going to post the game to pygame.org when finished?

We probably will, even though the code is as simple as cave art ;-)

Edited 6 Years Ago by nezbo: n/a

hey again tbone2sk and everyone else! We've come a long way since i posted the above question, and have both learned a bunch. So we thought it would be about time to show some of it.
The project has been created at pygame.org (http://pygame.org/project-Quantum+Man-1513-2692.html)
And a source code is avalable and can run if you have the right versions of pygame and python (we don't have a compiled version yet)

Here's a few new pictures from the game if you just want a quick look

Comments
nice
Attachments qman.jpg 70.31 KB qman2.jpg 79.11 KB

Nice project!
Are you hooked on Python yet?

Well we started the project as a mean to learning python, since we need it for a course at the university. But since we started learning it's just kept growing, so i guess you could say we're hooked :)
If you have time (and the needed versions of python/pygame), please take a look. I'm sure you can find a bug somewhere :D
There are currently a total of 4 monsters in the game, but unfortunately 3 of them are down for maintenance, won't be able to fix that until another day.

Looks really cool I have not played much yet, but that will change. It might just be my computer but the game is running at 100% cpu, if you are not capping the max frame rate it might be a good idea. It can be done by using the built in clock in pygame, initialize the clock before the game loop with:

clock = pygame.time.Clock()

Then in the beginning of the game loop add:

clock.tick(40)

This example caps the max frame rate at 40 fps you could even drop it to 20 with a game if yours.

Also when I try and run version 0.0.2 I get error at line 1708 in game.py:

screen.blit(fontsize(16).render("Hint: "+hint_text,True,(0,0,0)),(7,578))
NameError: name 'hint_text' is not defined

Version 0.0.1 works fine, when I have some more time I will look over the code some more.

I do really like the simple paint artwork and the code may be messy, but coding is a learning experience. I hope you guys continue the project and this really makes me want to finish some of the games that I have started in pygame.

I am already using a clock.tick(30) in the combat module, and it's still slowing down. We arent using any dirtysprites or threading atm though. The bug you mentioned in 0.0.2 should be fixed now.

This article has been dead for over six months. Start a new discussion instead.