[pygame] Equiping inventory slots with invisible buttons - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: Game Development (https://python-forum.io/forum-11.html) +--- Thread: [pygame] Equiping inventory slots with invisible buttons (/thread-17840.html) |
[pygame] Equiping inventory slots with invisible buttons - SheeppOSU - Apr-25-2019 I have an inventory class with 3 functions. __init__, draw, and equipChange The job of each function - __init__ - to define x, y, slots, and a few more predefined variables draw - draw inventory based on the amount of slots and x and y. Also checks if a slot is pressed on and turns it red if so (I currently have not added the unequip feature. I am working on the equip feature first) equipChange - the function for changing the tuple of equip which in turn changes what is drawn. I'm sorry if I made a simple mistake - that would be embarrassing - TIA for your help. inventory class - the full code is here - https://github.com/Sheepposu/Destination - on github class inventoryGUI(): def __init__(self, x, y, slots): self.x = x self.y = y self.i = 0 self.n = 0 self.slots = slots self.equips = None def draw(self, equips): SD.message_display(gD, 'Inventory', 50, black, self.x + 100, self.y - 50) self.equips = equips for n in range(1, self.slots + 1): p = equips self.n += 1 if n in p: SlotBtn = IBT((self.x + self.i, self.y, self.x + self.i + 20, self.y + 20)) if self.equips == None: SlotBtn.optClick(partial(self.equipChange, (False, n))) else: self.equips += (n,) SlotBtn.optClick(partial(self.equipChange, (False, self.equips))) pygame.draw.line(gD, red, (self.x + self.i, self.y), (self.x + self.i + 20, self.y)) #Top pygame.draw.line(gD, red, (self.x + self.i + 20, self.y), (self.x + 20 + self.i, self.y + 20)) # Right pygame.draw.line(gD, red, (self.x + self.i, self.y), (self.x + self.i, self.y + 20)) #Left pygame.draw.line(gD, red, (self.x + self.i, self.y + 20), (self.x + self.i + 20, self.y + 20)) #Bottom else: SlotBtn = IBT((self.x + self.i, self.y, self.x + self.i + 20, self.y + 20)) if self.equips == None: SlotBtn.optClick(partial(self.equipChange, (False, n))) else: self.equips += (n,) SlotBtn.optClick(partial(self.equipChange, (False, self.equips))) pygame.draw.line(gD, black, (self.x + self.i, self.y), (self.x + self.i + 20, self.y)) #Top pygame.draw.line(gD, black, (self.x + self.i + 20, self.y), (self.x + 20 + self.i, self.y + 20)) # Right pygame.draw.line(gD, black, (self.x + self.i, self.y), (self.x + self.i, self.y + 20)) #Left pygame.draw.line(gD, black, (self.x + self.i, self.y + 20), (self.x + self.i + 20, self.y + 20)) #Bottom if self.n < 6: self.i += 30 else: self.n = 0 self.i = 0 self.y += 30 def equipChange(self, receive, equips=None): if receive: return self.equips elif not receive: self.equips = equips print('self.equip now equals ' + self.equips) RE: [pygame] Equiping inventory slots with invisible buttons - Windspar - Apr-26-2019 Example import pygame # Simple Scene Interface class Scene: def draw(self, surface, game): pass def event(self, event, game): pass def update(self, game): pass class Game: def __init__(self, caption, width, height): # Basic pygame setup pygame.display.set_caption(caption) self.rect = pygame.Rect(0, 0, width, height) self.surface = pygame.display.set_mode(self.rect.size) self.clock = pygame.time.Clock() self.running = False self.fps = 30 self.delta = 0 # Scene Interface self.scene = Scene() Game.info = self def mainloop(self): self.running = True while self.running: for event in pygame.event.get(): self.scene.event(event, self) self.keys = pygame.key.get_pressed() self.scene.update(self) self.scene.draw(self.surface, self) pygame.display.flip() self.delta = self.clock.tick(self.fps) class Inventory: def __init__(self, position, slots): self.slots = slots self.equip = [False] * slots self.hover = False if isinstance(position, pygame.math.Vector2): self.position = position else: self.position = pygame.math.Vector2(position) self.create_rects() def create_rects(self): self.rects = [] for n in range(self.slots): offset = ((n % 6) * 30, n // 6 * 30) self.rects.append(pygame.Rect(self.position + offset, (20, 20))) def draw(self, surface): for enum, rect in enumerate(self.rects): if self.equip[enum]: pygame.draw.rect(surface, pygame.Color('red'), rect, 1) elif self.hover == enum: pygame.draw.rect(surface, pygame.Color('dodgerblue'), rect, 1) else: pygame.draw.rect(surface, pygame.Color('black'), rect, 1) def on_click(self): if self.hover > -1: self.equip[self.hover] = not self.equip[self.hover] def on_mousemotion(self, event): self.hover = -1 for enum, rect in enumerate(self.rects): if rect.collidepoint(event.pos): self.hover = enum break class Example(Scene): def __init__(self): self.inventory = Inventory((50, 20), 18) def draw(self, surface, game): surface.fill(pygame.Color('gray25')) self.inventory.draw(surface) def event(self, event, game): if event.type == pygame.MOUSEMOTION: self.inventory.on_mousemotion(event) elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: self.inventory.on_click() elif event.type == pygame.QUIT: game.running = False def main(): pygame.init() game = Game("Example", 400, 300) game.scene = Example() game.mainloop() pygame.quit() main() RE: [pygame] Equiping inventory slots with invisible buttons - SheeppOSU - Apr-26-2019 I'm sorry if my code is hard to navigate through. When making this game I found it easy and organized to define all my variables at the top including width, height, fps, and colors, class the player, class the enemy, define non-categorized functions outside of classes and def different function for different levels. I then put everything together in a main loop. RE: [pygame] Equiping inventory slots with invisible buttons - Windspar - Apr-26-2019 1. I'm just going to give examples. You can take what you want from my code and inject it into yours. 2. Personal I believe beginners should avoid global at all cost. 3. Classes can use local variables. All variables do not need to be part of the object. Example class inventoryGUI(): def __init__(self, x, y, slots): self.x = x self.y = y self.i = 0 # this is not going to be use through out object. Need to be remove self.n = 0 # this is not going to be use through out object. Need to be remove def draw(self, equips): n = 0 # local variable, one of your n would have to be rename. i = 0 # local variablepygame.Vector2 and pygame.Rect are your friends. Learn to use them. This can be done with a simple rect. pygame.draw.line(gD, red, (self.x + self.i, self.y), (self.x + self.i + 20, self.y)) #Top pygame.draw.line(gD, red, (self.x + self.i + 20, self.y), (self.x + 20 + self.i, self.y + 20)) # Right pygame.draw.line(gD, red, (self.x + self.i, self.y), (self.x + self.i, self.y + 20)) #Left pygame.draw.line(gD, red, (self.x + self.i, self.y + 20), (self.x + self.i + 20, self.y + 20)) #Bottomexample position = pygame.Vector2(self.x, self.y) # position should been a variable. It hold x and y # position.x and position.y can be use. rect = pygame.Rect(position + (self.i, 0), (20, 20)) # create a rect. pygame.draw.rect(surface, color, rect, 1) # 1 is outline thickness. If 1 is omitted. Then if would fill rect. RE: [pygame] Equiping inventory slots with invisible buttons - SheeppOSU - Apr-26-2019 I try to avoid local variables but I global specific variables that will make them more easily accessible but not interfering with other stuff. I will implement your suggestions when I get home. i am at school right now and we're watching "Matilda". RE: [pygame] Equiping inventory slots with invisible buttons - Windspar - Apr-26-2019 Why would you avoid local variables ? They help keep memory usage down. In classes it helps keep object memory smaller. My Color Handler import pygame class Color: def __getitem__(self, key): return self.__getattr__(key) def __getattr__(self, key): if key == "keys": return pygame.color.THECOLORS.keys() return pygame.Color(key) def group(self, color_name): group = [] for name in pygame.color.THECOLORS.keys(): if color_name in name: group.append(name) return group def main(): color = Color() # Quickly call print("orange", color.orange) print("darkred", color.darkred) print() # Find all colors that include name for c in color.group('blue'): print(c, color[c]) main()Example. My color handler in action import pygame class Color: def __getitem__(self, key): return self.__getattr__(key) def __getattr__(self, key): if key == "keys": return pygame.color.THECOLORS.keys() return pygame.Color(key) def group(self, color_name): group = [] for name in pygame.color.THECOLORS.keys(): if color_name in name: group.append(name) group.sort() return group # Simple Scene Interface class Scene: def draw(self, surface, game): pass def event(self, event, game): pass def update(self, game): pass class Game: color = Color() def __init__(self, caption, width, height): # Basic pygame setup pygame.display.set_caption(caption) self.rect = pygame.Rect(0, 0, width, height) self.surface = pygame.display.set_mode(self.rect.size) self.clock = pygame.time.Clock() self.running = False self.fps = 30 self.delta = 0 # Scene Interface self.scene = Scene() Game.info = self def mainloop(self): self.running = True while self.running: for event in pygame.event.get(): self.scene.event(event, self) self.keys = pygame.key.get_pressed() self.scene.update(self) self.scene.draw(self.surface, self) pygame.display.flip() self.delta = self.clock.tick(self.fps) class ColorShow(Scene): def __init__(self): self.colors = 'red', 'blue', 'green' self.color_position = 0 self.color_group = Game.color.group('red') self.cg_position = 0 # timer self.interval = 900 self.next_tick = pygame.time.get_ticks() self.font = pygame.font.Font(None, 32) self.render_text(Game.info) def draw(self, surface, game): surface.fill(pygame.Color(self.color_group[self.cg_position])) surface.blit(self.text, self.text_rect) def event(self, event, game): if event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: self.color_position = (self.color_position + 1) % len(self.colors) self.color_group = Game.color.group(self.colors[self.color_position]) self.cg_position = 0 self.render_text(game) elif event.key == pygame.K_ESCAPE: game.running = False elif event.type == pygame.QUIT: game.running = False def render_text(self, game): self.text = self.font.render(self.color_group[self.cg_position], 1, pygame.Color('black')) self.text_rect = self.text.get_rect() self.text_rect.y = 10 self.text_rect.centerx = game.rect.centerx def update(self, game): ticks = pygame.time.get_ticks() if ticks > self.next_tick: self.next_tick += self.interval self.cg_position = (self.cg_position + 1) % len(self.color_group) self.render_text(game) def main(): pygame.init() game = Game("Color Show", 400, 300) game.scene = ColorShow() game.mainloop() pygame.quit() main() RE: [pygame] Equiping inventory slots with invisible buttons - SheeppOSU - Apr-26-2019 I'm sorry - I meant avoid global variables |