diff --git a/src/item.py b/src/item.py new file mode 100644 index 0000000..e0cec9e --- /dev/null +++ b/src/item.py @@ -0,0 +1,133 @@ +import pygame +import random +from src.settings import ( + ITEM_SPAWN_INTERVAL, ITEM_SHOPPING_TIMER, ITEM_SIZE, + COLOR_HP_BAR_YELLOW, COLOR_HP_BAR_BG +) + + +class Item: + def __init__(self, x, y, item_type): + self.x = x + self.y = y + self.item_type = item_type + + # collision rect for player (2 times item size for width and height) + self.rect = pygame.Rect(self.x, self.y, ITEM_SIZE, ITEM_SIZE) + + # timer to store time when item appeared + self.spawn_time = pygame.time.get_ticks() + + # try to load sprite with item type + try: + path = f"assets/items/{item_type}.png" + self.image = pygame.image.load(path).convert_alpha() + self.image = pygame.transform.scale(self.image, (ITEM_SIZE, ITEM_SIZE)) + except Exception as e: + print(f"Error loading item sprite {item_type}: {e}") + self.image = None + + # to check if the time ran out to buy the item + def is_expired(self): + return pygame.time.get_ticks() - self.spawn_time >= ITEM_SHOPPING_TIMER + + # cam offset to convert world coordinates to screen coordinates + def draw(self, screen, cam_x, cam_y): + draw_x = self.x - cam_x + draw_y = self.y - cam_y + + if self.image is not None: + screen.blit(self.image, (draw_x, draw_y)) + else: + # fallback using settings colors + # coffee brown, beer yellow + if self.item_type == "coffee": + color = (120, 70, 30) + else: + color = COLOR_HP_BAR_YELLOW + + draw_rect = (draw_x, draw_y, ITEM_SIZE, ITEM_SIZE) + pygame.draw.rect(screen, color, draw_rect) + pygame.draw.rect(screen, COLOR_HP_BAR_BG, draw_rect, 2) + + +# try 50 times to find a free position to spawn item +def _random_position(room_rect, blocked_rects): + attempts = 0 + max_attempts = 50 + + while attempts < max_attempts: + # generate random x/y coordinates with room boundaries + # * 2 to have a margin to walls + x = random.randint(room_rect.left + ITEM_SIZE, room_rect.right - ITEM_SIZE * 2) + y = random.randint(room_rect.top + ITEM_SIZE, room_rect.bottom - ITEM_SIZE * 2) + + # create a rect at this position for testing collision + test_rect = pygame.Rect(x, y, ITEM_SIZE, ITEM_SIZE) + blocked = False + for b in blocked_rects: + if test_rect.colliderect(b): + blocked = True + break + + # if position is not blocked, return the position + if not blocked: + return x, y + + attempts += 1 + + # no spot after 50 attempts -> return + return None + + +class ItemManager: + def __init__(self): + self.items = [] + self.last_spawn_time = pygame.time.get_ticks() + + # remove expired items and spawn new ones + def update(self, room_rect, blocked_rects): + now = pygame.time.get_ticks() + + remaining_items = [] + + for item in self.items: + if item.is_expired() == False: + remaining_items.append(item) + + # replace the old list with the new temp_list + self.items = remaining_items + + # spawn logic for new items + if room_rect is not None: + if now - self.last_spawn_time >= ITEM_SPAWN_INTERVAL: + pos = _random_position(room_rect, blocked_rects) + if pos is not None: + x, y = pos + item_type = random.choice(["coffee", "beer"]) + self.items.append(Item(x, y, item_type)) + + self.last_spawn_time = now + + # check if player press "e" to buy + def check_collect(self, player_rect, keys): + if keys[pygame.K_e]: + for item in self.items: + if player_rect.colliderect(item.rect): + return item + return None + + # delete item from list after buying it + def remove_item(self, item): + if item in self.items: + self.items.remove(item) + + # draw all active items + def draw(self, screen, cam_x, cam_y): + for item in self.items: + item.draw(screen, cam_x, cam_y) + + # clear items when changing room + def clear(self): + self.items = [] + self.last_spawn_time = pygame.time.get_ticks() \ No newline at end of file diff --git a/src/settings.py b/src/settings.py index 3d4328a..fb68e0a 100644 --- a/src/settings.py +++ b/src/settings.py @@ -38,7 +38,7 @@ DEFAULT_FRAME_TIME: float = 0.16 # --- ECTS --- START_ECTS_VALUE = 1 # how many ECTS are generated at the beginning -ECTS_UPDATE_INTERVAL = 1000 # time in ms = 1 sec +ECTS_UPDATE_INTERVAL = 1000 # time in ms (1000 = 1 sec) BEER_BOTTLE_ECTS_VALUE = 2 BEER_COST = 50 @@ -76,11 +76,13 @@ COLOR_PROJECTILE = (200, 200, 0) TOWER_TIMER = 30000 # how long the tower stays and attack before it disappears -# --- SHOPPING TIMER --- -ITEM_SHOPPING_TIMER = 10000 # for items like coffee, beer, tower - how long u have time to buy it +# --- ITEM SPAWN TIMER --- +ITEM_SPAWN_INTERVAL = 5000 # ms until a new item spawns +ITEM_SHOPPING_TIMER = 10000 # how long you have time to buy items before they despawn +ITEM_SIZE = 30 -# -- ZOMBIE --- +# --- ZOMBIE --- ZOMBIE_EASY_HP = 30 ZOMBIE_EASY_DMG = 3