diff --git a/cowyeet.py b/cowyeet.py index 1900e17..5aff000 100644 --- a/cowyeet.py +++ b/cowyeet.py @@ -14,386 +14,341 @@ FPS = 60 SAVE_SETTINGS_ON_EXIT = True -pygame.init() # pygame initialization -screen = pygame.display.set_mode(DEFAULT_WINDOW_SIZE) -pygame.display.set_caption("Cowyeet 2.0") +class Cowyeet: + def __init__(self): + self.DEFAULT_WINDOW_SIZE = DEFAULT_WINDOW_SIZE + self.FPS = FPS + self.SAVE_SETTINGS_ON_EXIT = SAVE_SETTINGS_ON_EXIT -if os.path.isfile("settings.txt"): # If the settings exist, load them into a dict. Else create the settings with the default values. - settings = FileDict("settings.txt") + pygame.init() # pygame initialization + self.screen = pygame.display.set_mode(DEFAULT_WINDOW_SIZE) + pygame.display.set_caption("Cowyeet 2.0") -else: - settings = FileDict() - settings.path = "settings.txt" - settings["win_size"] = DEFAULT_WINDOW_SIZE - settings["level_size_multiplier"] = 1 - settings.save() + self.settings = self.load_settings() -# loading screen -default_font = pygame.font.SysFont("ubuntu", 16) -loading_text = default_font.render("Loading...", True, (240, 240, 240)) + self.draw_loading_screen() -screen.fill((40, 40, 40)) -screen.blit(loading_text, (400 - loading_text.get_width() / 2, 300 - loading_text.get_height() / 2)) -pygame.display.update() -# /loading screen + # variables + self.nero = (40, 40, 40) # colors (color names by https://www.color-blindness.com/color-name-hue/) + self.dim_gray = (100, 100, 100) + self.summer_sky = (50, 200, 220) + self.white_smoke = (240, 240, 240) + self.buttons = [] # misc + self.text_buttons = [] + self.active_buttons = [] + self.last_frame_mouse_pressed = False + self.page = "main_menu" + self.level = None + self.level_data = None + self.lvl_width = None + self.level_surface = None + self.cow_throwable = False + self.cow_flying = False + self.cow_position = (0, 0) + self.cow_flight_path = [] + self.cow_flight_step = 0 + self.pressed_keys = [] + self.pressed_special_keys = pygame.key.get_mods() -# functions + # pygame objects + self.clock = pygame.time.Clock() # misc + self.mouse = pygame.mouse + self.keyboard = pygame.key -# images -def load_texture(path: str): - if os.path.isfile(path): - return pygame.image.load(path) + self.bigger_default_font = pygame.font.SysFont("ubuntu", 32) # fonts - else: - return texture_not_found + self.choose_level_text = self.bigger_default_font.render("Choose a level:", True, self.white_smoke) # texts + self.texture_not_found = pygame.image.load("textures/texture_not_found.png") + self.texture_not_found = pygame.transform.scale(self.texture_not_found, (40 * self.settings["level_size_multiplier"], 40 * self.settings["level_size_multiplier"])) -def load_block_texture(path: str): - texture = load_texture(path) + self.icon_texture = self.load_texture("textures/icon.png") + self.full_icon_texture = self.load_texture("textures/icon_full.png") + self.full_icon_texture = pygame.transform.scale(self.full_icon_texture, (260, 90)) + self.catapult_frame_texture = self.load_texture("textures/catapult/frame.png") + self.catapult_frame_texture = pygame.transform.scale(self.catapult_frame_texture, (66 * 5 * self.settings["level_size_multiplier"], 31 * 5 * self.settings["level_size_multiplier"])) + self.catapult_arm_texture = self.load_texture("textures/catapult/arm.png") + self.catapult_arm_texture = pygame.transform.scale(self.catapult_arm_texture, (25 * 5 * self.settings["level_size_multiplier"], 53 * 5 * self.settings["level_size_multiplier"])) + self.cow = self.load_texture("textures/cow/head.png") + self.cow = pygame.transform.scale(self.cow, (64 * 5 * self.settings["level_size_multiplier"], 64 * 5 * self.settings["level_size_multiplier"])) + self.stone_block_texture = self.load_block_texture("textures/terrain/stone_01.png") + self.dirt_block_texture = self.load_block_texture("textures/terrain/dirt_01.png") + self.grass_block_texture = self.load_block_texture("textures/terrain/grass_01.png") + self.rock_block_texture = self.load_block_texture("textures/terrain/rock_01.png") - return pygame.transform.scale(texture, (40 * settings["level_size_multiplier"], 40 * settings["level_size_multiplier"])) -# /images + # buttons + self.buttons.append( + pg.TextButton("Start", self.center, self.screen, lambda: self.page_switch("level_selector"), text_color=self.white_smoke, bg_color=self.dim_gray, font=self.bigger_default_font)) + self.start_button = len(self.buttons) - 1 + self.text_buttons.append(self.start_button) + self.buttons.append( + pg.TextButton("1", (128, 128), self.screen, lambda: self.start_level(1), text_color=self.white_smoke, bg_color=self.dim_gray, font=self.bigger_default_font, padding=(17, 8))) + self.lvl_one_button = len(self.buttons) - 1 + self.text_buttons.append(self.lvl_one_button) + # /buttons -# coordinate calculations -def center_x(width: int): - return screen.get_width() / 2 - width / 2 + # /variables + # loading completed -def center_y(height: int): - return screen.get_height() / 2 - height / 2 + self.screen = pygame.display.set_mode(self.settings["win_size"], flags=pygame.RESIZABLE, vsync=1) + self.window_size_reload(self.settings["win_size"]) + pygame.display.set_icon(self.icon_texture) + self.screen.fill(self.nero) + pygame.display.update() + self.page_switch("main_menu") -def center(size): - width, height = size + self.running = True - return center_x(width), center_y(height) -# /coordinate calculations - - -# image calculations -def set_rot_point(img, pos): - w, h = img.get_size() - w, h = w * 2, h * 2 - - img2 = pygame.Surface((w, h), pygame.SRCALPHA) - img2.blit(img, (w / 2 - pos[0], h / 2 - pos[1])) - return img2, (w, h) -# / image calculations - - -# game logic -def start_level(lvl: int): - global level - global cow_throwable - - page_switch("ingame") - level = lvl - - load_level(lvl) - - cow_throwable = True - - -def load_level(lvl): - global level_data - global lvl_width - global level_surface - - level_data = __import__("data.levels." + str(lvl), fromlist="data.levels") - - lvl_width, lvl_height = level_data.level_size - - level_surface = pygame.Surface((lvl_width * 40 * settings["level_size_multiplier"], lvl_height * 40 * settings["level_size_multiplier"]), pygame.SRCALPHA, 32) - - x = 0 - y = 0 - - for row in level_data.data_array: - x = 0 - - for block in row: - rx = x * 40 * settings["level_size_multiplier"] - ry = y * 40 * settings["level_size_multiplier"] - - blit_block(block, (rx, ry)) - x += 1 - - y += 1 - - -def blit_block(block, position: tuple): - if not block == 0: - if block == 1: - level_surface.blit(stone_block_texture, position) - - elif block == 2: - level_surface.blit(dirt_block_texture, position) - - elif block == 3: - level_surface.blit(grass_block_texture, position) - - elif block == 4: - level_surface.blit(rock_block_texture, position) + def load_settings(self): + if os.path.isfile("settings.txt"): # If the settings exist, load them into a dict. Else create the settings with the default values. + settings = FileDict("settings.txt") else: - level_surface.blit(texture_not_found, position) + settings = FileDict() + settings.path = "settings.txt" + settings["win_size"] = DEFAULT_WINDOW_SIZE + settings["level_size_multiplier"] = 1 + settings.save() + return settings -def yeet_cow(): - global cow_throwable - global cow_flying - global cow_flight_path - global cow_flight_step + def draw_loading_screen(self): + default_font = pygame.font.SysFont("ubuntu", 16) + loading_text = default_font.render("Loading...", True, (240, 240, 240)) - if cow_throwable: - cow_throwable = False + self.screen.fill((40, 40, 40)) + self.screen.blit(loading_text, (400 - loading_text.get_width() / 2, 300 - loading_text.get_height() / 2)) + pygame.display.update() - lvl_x, lvl_y = level_data.level_size - lvl_x *= 40 - lvl_x *= settings["level_size_multiplier"] - lvl_y *= 40 - lvl_y *= settings["level_size_multiplier"] + def load_texture(self, path: str): + if os.path.isfile(path): + return pygame.image.load(path) - cow_flight_path = berechneflugbahn(lvl_x, lvl_y, lvl_x + 100, 34, 128, xstep=10) + else: + return self.texture_not_found - cow_flying = True - cow_flight_step = 0 -# /game logic + def load_block_texture(self, path: str): + texture = self.load_texture(path) + return pygame.transform.scale(texture, (40 * self.settings["level_size_multiplier"], 40 * self.settings["level_size_multiplier"])) -# page system -def main_menu_page(): - screen.blit(full_icon_texture, (center_x(full_icon_texture.get_width()), 128)) - buttons[start_button].blit() + def center_x(self, width: int): + return self.screen.get_width() / 2 - width / 2 + def center_y(self, height: int): + return self.screen.get_height() / 2 - height / 2 -def level_selector_page(): - buttons[lvl_one_button].blit() + def center(self, size): + width, height = size - screen.blit(choose_level_text, (screen.get_width() / 2 - choose_level_text.get_width() / 2, 16)) + return self.center_x(width), self.center_y(height) + def set_rot_point(self, img, pos): + w, h = img.get_size() + w, h = w * 2, h * 2 -def ingame_page(): - global cow_flight_step - global cow_position - global cow_flying - global cow_throwable + img2 = pygame.Surface((w, h), pygame.SRCALPHA) + img2.blit(img, (w / 2 - pos[0], h / 2 - pos[1])) + return img2, (w, h) - screen.fill(summer_sky) - screen.blit(level_surface, (0, screen.get_height() - level_surface.get_height())) + def start_level(self, lvl: int): + self.page_switch("ingame") + self.level = lvl - lvl_size = settings["level_size_multiplier"] + self.load_level(lvl) - cx, cy = level_data.catapult_pos - cx = cx * 40 * lvl_size - cy = screen.get_height() - level_surface.get_height() + cy * 40 * lvl_size - catapult_frame_texture.get_height() + self.cow_throwable = True - screen.blit(catapult_frame_texture, (cx, cy)) - screen.blit(catapult_arm_texture, (cx + 27 * 5 * lvl_size, cy - 35 * 5 * lvl_size)) + def load_level(self, lvl): + self.level_data = __import__("data.levels." + str(lvl), fromlist="data.levels") - if cow_flying: - cow_flight_step += 1 + self.lvl_width, lvl_height = self.level_data.level_size - x = cow_flight_path[cow_flight_step * 2] - y = cow_flight_path[cow_flight_step * 2 + 1] - cow_position = (x, screen.get_height() - y - 64 * 5 * settings["level_size_multiplier"]) + self.level_surface = pygame.Surface((self.lvl_width * 40 * self.settings["level_size_multiplier"], lvl_height * 40 * self.settings["level_size_multiplier"]), pygame.SRCALPHA, 32) - if cow_flight_step * 2 == len(cow_flight_path) - 2: - cow_flying = False - cow_throwable = True + x = 0 + y = 0 - screen.blit(cow, cow_position) + for row in self.level_data.data_array: + x = 0 + for block in row: + rx = x * 40 * self.settings["level_size_multiplier"] + ry = y * 40 * self.settings["level_size_multiplier"] -def page_selector(): - if page == "main_menu": - main_menu_page() + self.blit_block(block, (rx, ry)) + x += 1 - elif page == "level_selector": - level_selector_page() + y += 1 - elif page == "ingame": - ingame_page() + def blit_block(self, block, position: tuple): + if not block == 0: + if block == 1: + self.level_surface.blit(self.stone_block_texture, position) + elif block == 2: + self.level_surface.blit(self.dirt_block_texture, position) -def page_switch(new_page: str=None): - global active_buttons - global page + elif block == 3: + self.level_surface.blit(self.grass_block_texture, position) - if not new_page is None: - page = new_page + elif block == 4: + self.level_surface.blit(self.rock_block_texture, position) - if page == "main_menu": - active_buttons = [start_button] + else: + self.level_surface.blit(self.texture_not_found, position) - elif page == "level_selector": - active_buttons = [lvl_one_button] + def yeet_cow(self): + if self.cow_throwable: + self.cow_throwable = False - elif page == "ingame": - active_buttons = [] + lvl_x, lvl_y = self.level_data.level_size + lvl_x *= 40 + lvl_x *= self.settings["level_size_multiplier"] + lvl_y *= 40 + lvl_y *= self.settings["level_size_multiplier"] - # for button in buttons: - # button.active = False - # - # for button in active_buttons: - # button.active = True -# /page system + self.cow_flight_path = berechneflugbahn(lvl_x, lvl_y, lvl_x + 100, 34, 128, xstep=10) + self.cow_flying = True + self.cow_flight_step = 0 -def close(): - global running - running = False + def main_menu_page(self): + self.screen.blit(self.full_icon_texture, (self.center_x(self.full_icon_texture.get_width()), 128)) + self.buttons[self.start_button].blit() + def level_selector_page(self): + self.buttons[self.lvl_one_button].blit() -def window_size_reload(new_size): - for button in text_buttons: - buttons[button].update() + self.screen.blit(self.choose_level_text, (self.screen.get_width() / 2 - self.choose_level_text.get_width() / 2, 16)) - settings["win_size"] = new_size + def ingame_page(self): + self.screen.fill(self.summer_sky) + self.screen.blit(self.level_surface, (0, self.screen.get_height() - self.level_surface.get_height())) + lvl_size = self.settings["level_size_multiplier"] -def get_events(): - global last_frame_mouse_pressed + cx, cy = self.level_data.catapult_pos + cx = cx * 40 * lvl_size + cy = self.screen.get_height() - self.level_surface.get_height() + cy * 40 * lvl_size - self.catapult_frame_texture.get_height() - for event in pygame.event.get(): - if event.type == pygame.QUIT: - close() + self.screen.blit(self.catapult_frame_texture, (cx, cy)) + self.screen.blit(self.catapult_arm_texture, (cx + 27 * 5 * lvl_size, cy - 35 * 5 * lvl_size)) + + if self.cow_flying: + self.cow_flight_step += 1 + + x = self.cow_flight_path[self.cow_flight_step * 2] + y = self.cow_flight_path[self.cow_flight_step * 2 + 1] + self.cow_position = (x, self.screen.get_height() - y - 64 * 5 * self.settings["level_size_multiplier"]) + + if self.cow_flight_step * 2 == len(self.cow_flight_path) - 2: + self.cow_flying = False + self.cow_throwable = True + + self.screen.blit(self.cow, self.cow_position) + + def page_selector(self): + if self.page == "main_menu": + self.main_menu_page() + + elif self.page == "level_selector": + self.level_selector_page() + + elif self.page == "ingame": + self.ingame_page() + + def page_switch(self, new_page: str=None): + if not new_page is None: + self.page = new_page + + if self.page == "main_menu": + self.active_buttons = [self.start_button] + + elif self.page == "level_selector": + self.active_buttons = [self.lvl_one_button] + + elif self.page == "ingame": + self.active_buttons = [] + + # for button in buttons: + # button.active = False + # + # for button in active_buttons: + # button.active = True + + def close(self): + self.running = False + + def window_size_reload(self, new_size): + for button in self.text_buttons: + self.buttons[button].update() + + self.settings["win_size"] = new_size + + def get_events(self): + for event in pygame.event.get(): + if event.type == pygame.QUIT: + self.close() + return + + if event.type == pygame.MOUSEBUTTONDOWN: + pressed = self.mouse.get_pressed() + pos = self.mouse.get_pos() + + for button in self.active_buttons: + self.buttons[button].check(pos, pressed) + + self.last_frame_mouse_pressed = True + + elif event.type == pygame.VIDEORESIZE: + + self.window_size_reload(event.size) + + elif event.type == pygame.KEYDOWN: + key = event.key + + if key == pygame.K_c and self.pressed_special_keys & pygame.KMOD_CTRL: + self.close() + + elif key == pygame.K_SPACE: + if self.page == "ingame": + self.yeet_cow() + + def loop(self): + global last_frame_mouse_pressed + global pressed_keys + global pressed_special_keys + + self.screen.fill(self.nero) + + self.pressed_keys = self.keyboard.get_pressed() + self.pressed_special_keys = self.keyboard.get_mods() + self.get_events() + + if not self.running: return - if event.type == pygame.MOUSEBUTTONDOWN: - pressed = mouse.get_pressed() - pos = mouse.get_pos() + self.page_selector() - if not last_frame_mouse_pressed: - for button in active_buttons: - buttons[button].check(pos, pressed) + pygame.display.update() - last_frame_mouse_pressed = True - - elif event.type == pygame.VIDEORESIZE: - - window_size_reload(event.size) - - elif event.type == pygame.KEYDOWN: - key = event.key - - if key == pygame.K_c and pressed_special_keys & pygame.KMOD_CTRL: - close() - - elif key == pygame.K_SPACE: - if page == "ingame": - yeet_cow() + self.clock.tick(self.FPS) -def loop(): - global last_frame_mouse_pressed - global pressed_keys - global pressed_special_keys +if __name__ == "__main__": + game = Cowyeet() - screen.fill(nero) + while game.running: + game.loop() - pressed_keys = keyboard.get_pressed() - pressed_special_keys = keyboard.get_mods() - get_events() + pygame.quit() - if not running: - return + if game.SAVE_SETTINGS_ON_EXIT: + game.settings.save() - pressed = mouse.get_pressed() - if not pressed[0] and not pressed[1] and not pressed[2]: - last_frame_mouse_pressed = False - - page_selector() - - pygame.display.update() - - clock.tick(FPS) - - -# variables -nero = (40, 40, 40) # colors (color names by https://www.color-blindness.com/color-name-hue/) -dim_gray = (100, 100, 100) -summer_sky = (50, 200, 220) -white_smoke = (240, 240, 240) - -buttons = [] # misc -text_buttons = [] -active_buttons = [] -last_frame_mouse_pressed = False -page = "main_menu" -level = None -level_data = None -lvl_width = None -level_surface = None -cow_throwable = False -cow_flying = False -cow_position = (0, 0) -cow_flight_path = [] -cow_flight_step = 0 -pressed_keys = [] -pressed_special_keys = pygame.key.get_mods() - - -# pygame objects -clock = pygame.time.Clock() # misc -mouse = pygame.mouse -keyboard = pygame.key - -bigger_default_font = pygame.font.SysFont("ubuntu", 32) # fonts - -choose_level_text = bigger_default_font.render("Choose a level:", True, white_smoke) # texts - -texture_not_found = pygame.image.load("textures/texture_not_found.png") -texture_not_found = pygame.transform.scale(texture_not_found, (40 * settings["level_size_multiplier"], 40 * settings["level_size_multiplier"])) - -icon_texture = load_texture("textures/icon.png") -full_icon_texture = load_texture("textures/icon_full.png") -full_icon_texture = pygame.transform.scale(full_icon_texture, (260, 90)) -catapult_frame_texture = load_texture("textures/catapult/frame.png") -catapult_frame_texture = pygame.transform.scale(catapult_frame_texture, (66 * 5 * settings["level_size_multiplier"], 31 * 5 * settings["level_size_multiplier"])) -catapult_arm_texture = load_texture("textures/catapult/arm.png") -catapult_arm_texture = pygame.transform.scale(catapult_arm_texture, (25 * 5 * settings["level_size_multiplier"], 53 * 5 * settings["level_size_multiplier"])) -cow = load_texture("textures/cow/head.png") -cow = pygame.transform.scale(cow, (64 * 5 * settings["level_size_multiplier"], 64 * 5 * settings["level_size_multiplier"])) -stone_block_texture = load_block_texture("textures/terrain/stone_01.png") -dirt_block_texture = load_block_texture("textures/terrain/dirt_01.png") -grass_block_texture = load_block_texture("textures/terrain/grass_01.png") -rock_block_texture = load_block_texture("textures/terrain/rock_01.png") - - - -# buttons -buttons.append(pg.TextButton("Start", center, screen, lambda: page_switch("level_selector"), text_color=white_smoke, bg_color=dim_gray, font=bigger_default_font)) -start_button = len(buttons) - 1 -text_buttons.append(start_button) -buttons.append(pg.TextButton("1", (128, 128), screen, lambda: start_level(1), text_color=white_smoke, bg_color=dim_gray, font=bigger_default_font, padding=(17, 8))) -lvl_one_button = len(buttons) - 1 -text_buttons.append(lvl_one_button) -# /buttons - -# /variables - - -# loading completed - -screen = pygame.display.set_mode(settings["win_size"], flags=pygame.RESIZABLE, vsync=1) -window_size_reload(settings["win_size"]) -pygame.display.set_icon(icon_texture) -screen.fill(nero) -pygame.display.update() - -page_switch("main_menu") - -running = True - -while running: - loop() - -pygame.quit() - -if SAVE_SETTINGS_ON_EXIT: - settings.save() - -print("Bye!") + print("Bye!")