Python Forum

Full Version: Easy equipment system for simple game and problems with it
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello, I want to make simple game with equipment system, shop and fights.
All will play around our character. If you want to be stronger, level up and try to buy better items, which will give you better stats.
I have one problem that I didn't expected. I have used first time __init__ ... Here is my code (full is here: https://pastebin.com/uXTgqcYC):
class item:
    def __init__(self):
        self.name = ""
        self.type = ""
        self.image = ""
        self.stats = [0] * 5



class character:
    def __init__(self):
        self.name = ""
        self.stats = [0] * 5
        self.weapon = item()
        self.equipment = {
            "helmet": blank,
            "armor": blank
            "weapon": blank
        }
        self.backpack = [blank, blank, blank, blank, blank]
        self.available_points = 5

class Game:
    def __init__(self, parent):
        self.myParent = parent
        self.myGame = tk.Frame(parent)
        self.myGame.grid()

        self.statsFrame = tk.Frame(self.myGame)
        self.statsFrame.grid()

        self.make_stat("Strength:", 0, 1, 1)
        self.make_stat("Agility", 1, 1, 2)
        self.make_stat("Intelligence", 2, 1, 3)
        self.make_stat("Vitality", 3, 1, 4)

        self.make_equipment("helmet", 4, 5)
        self.make_backpack(0, 5, 6)

    def make_stat(self, text, idx, column, row):
        label = tk.Label(self.statsFrame, text=text)
        label.grid(column=column, row=row)

        amount = tk.Label(self.statsFrame, text=my_character.stats[idx])
        amount.grid(column=column+1, row=row)

        def add_stat():
            if my_character.available_points >= 1:
                my_character.stats[idx] += 1
                my_character.available_points -= 1
            else:
                pass
            amount["text"] = my_character.stats[idx]

        button = tk.Button(self.statsFrame, text="+", command=add_stat)
        button.grid(column=column+2, row=row)

    def make_equipment(self, item_type, column, row): #item-type = "helmet" etc

        def update():
            button.update_idletasks()

        def take_off():
            if my_character.equipment[item_type] != blank:
                if my_character.backpack[0] ==  blank:
                    my_character.equipment[item_type], my_character.backpack[0] = my_character.backpack[0], my_character.equipment[item_type]
                elif my_character.backpack[1] == blank:
                    my_character.equipment[item_type], my_character.backpack[1] = my_character.backpack[1], my_character.equipment[item_type]



        photo = tk.PhotoImage(file=my_character.equipment[item_type].image)
        button = tk.Button(self.statsFrame, image=photo, command=take_off)
        button.image = photo
        button.grid(column=column, row=row)

But first question is: Should I make method (like add_stat) inside character or it won't matter anyway?(I made function for adding stats inside button)
Second: I don't know how to acces things made this method (for example:
 self.make_equipment("helmet", 4, 5)
and I don't know how to acces it and
update_idletasks()
it
Third: Is there easier way to make equipment system? I have used here dicts and lists for eq and backpack.
It's my second attemp to made it. Please help me.
It makes sense to include as methods within the character class everything you need to manipulate and extract information from it. This allows you to change things more easily later on without having to change the code exploiting the classes.

So, for example, you might start with stats stored as a list and later decide to make it a more complex structure. With a method, def add_stat(self, statistic, value):, you would hide the implementation detail.

How you access information is entirely up to you. On the one hand, you can simple reference directly: player_one.stats.strength but using, for example, @property you can define a method that you reference like an attribute but which actually invokes the method thus allowing you to provide different responses dependent on some other criteria (type of character perhaps).

Looking at your code, it strikes me that weapons, equipment and backpack might all have similar characteristics to items so could be based on items or subclasses of items. Remember DRY.
I noticed in class Item, you have: self.type = ""
type is a reserved Python keyword (function that returns type of a variable). You would be better off renaming that class attribute, even if just slightly.
(Sep-01-2018, 08:40 AM)j.crater Wrote: [ -> ]type is a reserved Python keyword
Technically speaking, type is not a keyword and it is perfectly legal to use it, however it is a well known builtin function, like list, dict, open, and nobody expects a different meaning for this variable when reading a python program. It is indeed better to rename it.

For a list of keywords (which you cannot use as variable names) see
>>> import keyword
>>> keyword.kwlist
['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif', 'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or', 'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
For a list of builtin names to avoid
>>> sorted(vars(__builtins__))
['ArithmeticError', 'AssertionError', ..., 'type', 'vars', 'zip']