def new_game(self, player1_is_ai, player2_is_ai): ffr = self.frames.factory_frame.inner[0].rect frect = (ffr[0], ffr[1]+20, ffr[2] - self.spawn_width, ffr[3]-20) self.factory1 = Factory(1, self.on_put_unit, self.on_module_changed, frect) self.factory2 = Factory(2, self.on_put_unit, self.on_module_changed, frect) self.ai1 = None self.ai2 = None if player1_is_ai: self.ai1 = ai.AI(self.factory1) if player2_is_ai: self.ai2 = ai.AI(self.factory2) self.battlefield = Battlefield( rect = self.frames.battlefield_frame.outer.rect) self.dropping_units = DroppingUnits( battlefield = self.battlefield)
class App(Duct): def __init__(self): self.drag_start = None self.selected_module = None self.mouse_down = False self.dragging_minimap = False def update_everything(self): dt = 0.016 # TODO self.factory1.update(dt) self.factory2.update(dt) self.dropping_units.update(dt) self.battlefield.update(dt) if self.ai1: self.ai1.update(dt) if self.ai2: self.ai2.update(dt) def draw_everything(self): surface = self.display_surface a = pygame.time.get_ticks() self.draw_ui() b = pygame.time.get_ticks() self.factory1.draw(surface) c = pygame.time.get_ticks() if self.selected_module: pygame.draw.rect(surface, (255, 255, 255), self.selected_module.screen_rect, 1) d = pygame.time.get_ticks() self.dropping_units.draw(surface) self.battlefield.draw(surface) e = pygame.time.get_ticks() #print(b-a, c-b, d-c, e-d) def run_main_loop(self): while True: # main game loop for event in pygame.event.get(): if event.type == KEYDOWN: if event.key == pygame.K_d: self.toggle_dir(0) if event.key == pygame.K_w: self.toggle_dir(1) if event.key == pygame.K_a: self.toggle_dir(2) if event.key == pygame.K_s: self.toggle_dir(3) if event.type == MOUSEBUTTONDOWN and event.button == 1: self.on_mouse_down(pygame.mouse.get_pos()) if event.type == MOUSEBUTTONUP and event.button == 1: self.on_mouse_up(pygame.mouse.get_pos()) if event.type == MOUSEMOTION and self.mouse_down: self.on_mouse_drag(pygame.mouse.get_pos()) if event.type == QUIT or (event.type == KEYUP and event.key == K_ESCAPE): pygame.quit() sys.exit() self.update_everything() self.draw_everything() pygame.display.update() def choose_fontname(self): fonts = pygame.font.get_fonts() wants = "freesansbold liberationmono".split() for font in wants: if font in fonts: return font return None def setup_ui(self): fontname = self.choose_fontname() self.main_font = pygame.font.SysFont(fontname, 24) w = self.size[0] h = self.size[1] mh = 100 ih = 200 fw = 400 bw = w - fw flh = 50 sph = 50 mfh = flh * mh / (h-mh-ih) self.frames = Duct() self.minimap_height = mh self.minimap_border = 4 self.factory_width = fw self.battlefield_width = bw self.info_height = ih self.floor_height = flh self.minimap_floor_height = mfh self.spawn_width = sph self.frames.minimap_frame = Frame(Colors.black, None, (0, 0, w, mh)) self.frames.minimap_frame.add_rect((0, 0, w, mh-mfh), None, (0, 127, 155)) self.frames.minimap_frame.add_rect((0, mh-mfh, w, mfh), None, (110, 100, 70)) self.frames.factory_frame = Frame(Colors.black, None, (0, mh, fw, h-mh-ih)) self.frames.factory_frame.add_rect((0, mh, fw, h-mh-ih-flh), None, (0, 127, 155)) self.frames.factory_frame.add_rect((0, h-ih-flh, fw, flh), None, (110, 100, 70)) self.frames.buttons_frame = Frame(Colors.black, (50,50,50), (0, h-ih, fw, ih)) self.frames.battlefield_frame = Frame(Colors.black, None, (fw, mh, bw, h-mh-ih)) self.frames.battlefield_frame.add_rect((fw, mh, bw, h-mh-ih-flh), None, (0, 127, 155)) self.frames.battlefield_frame.add_rect((fw, h-ih-flh, bw, flh), None, (110, 100, 70)) self.frames.info_frame = Frame(Colors.black, (100,100,100), (fw, h-ih, bw, ih)) bh = 20 n = 5 sh = (ih - n * bh) / (n + 1) self.build_buttons = [] self.buttons = Duct() def getrektl(i): return (sh, h - ih + sh + (i - 1) * (bh + sh), fw / 2 - 3/2*sh, bh) def getrektr(i): return ((fw+sh) / 2, h - ih + sh + (i - 1) * (bh + sh), fw / 2 - 3/2*sh, bh) for t in range(1, n+1): text = "Build: " + Module.names[t] + " ( " + str(Module.build_costs[t]) + " energy )" btn = SFButton( getrektr(t), None, text, None, self.on_build_press, t) self.buttons[text] = btn self.build_buttons.append(btn) self.buttons.upgrade = SFButton(getrektl(n), None, "Upgrade", None, self.on_upgrade_press, None) self.buttons.sell = SFButton(getrektl(n-1), None, "Sell", None, self.on_sell_press, None) self.selected_module = None self.update_buttons() # add button.sprites to .buttons_group self.buttons_group = pygame.sprite.LayeredUpdates() for btn in self.buttons.values(): self.buttons_group.add(btn.sprites()) self.labels = [] #self.labels.append(self.main_font.render("Modul 1", 1, Colors.white)) def new_game(self, player1_is_ai, player2_is_ai): ffr = self.frames.factory_frame.inner[0].rect frect = (ffr[0], ffr[1]+20, ffr[2] - self.spawn_width, ffr[3]-20) self.factory1 = Factory(1, self.on_put_unit, self.on_module_changed, frect) self.factory2 = Factory(2, self.on_put_unit, self.on_module_changed, frect) self.ai1 = None self.ai2 = None if player1_is_ai: self.ai1 = ai.AI(self.factory1) if player2_is_ai: self.ai2 = ai.AI(self.factory2) self.battlefield = Battlefield( rect = self.frames.battlefield_frame.outer.rect) self.dropping_units = DroppingUnits( battlefield = self.battlefield) def draw_minimap_rect(self, surface): b = self.minimap_border sw = self.size[0] - 2 * b x = self.battlefield.get_offset_percentage() * sw + b w = self.battlefield.get_width_percentage() * sw r = (x, b, w, self.minimap_height - 2 * b) pygame.draw.rect(surface, (200, 200, 220), r, 1) def draw_ui(self): surface = self.display_surface a = pygame.time.get_ticks() for frame in self.frames.values(): frame.draw(surface) self.draw_minimap_rect(surface) b = pygame.time.get_ticks() self.buttons_group.draw(surface) c = pygame.time.get_ticks() for label in self.labels: surface.blit(label, (170, 500)) d = pygame.time.get_ticks() #print(b-a, c-b, d-c) # draw_mouse_pos() def on_module_changed(self, module): if module is self.selected_module: self.update_buttons() def update_buttons(self): if self.selected_module: for b in self.build_buttons: if self.selected_module.can_build_new(): b.set_available() else: b.set_unavailable() if self.selected_module.can_upgrade(): self.buttons.upgrade.set_available() else: self.buttons.upgrade.set_unavailable() if self.selected_module.can_sell(): self.buttons.sell.set_available() else: self.buttons.sell.set_unavailable() else: for b in self.build_buttons: b.set_deactivated() self.buttons.upgrade.set_deactivated() self.buttons.sell.set_deactivated() def toggle_dir(self, dir): if self.selected_module: self.selected_module.toggle_target_dir(dir) def on_minimap_touch(self, x): b = self.minimap_border x = (x - b) / (self.size[0] - 2 * b) * self.battlefield.size self.battlefield.set_window_center(x) def on_mouse_drag(self, pos): if self.dragging_minimap: self.on_minimap_touch(pos[0]) def on_mouse_down(self, pos): self.mouse_down = True # hit a module? if yes, select it and start drag module = None for m in self.factory1.modules: if is_point_in_rect(pos, m.screen_rect): module = m break if module: self.selected_module = module self.update_buttons() self.drag_start = pos return # no module clicked. maybe a button? button = None for b in self.buttons.values(): if b.is_inside(pos): button = b break if button: button.press() return # clicked on minimap? if is_point_in_rect(pos, self.frames.minimap_frame.outer.rect): self.dragging_minimap = True self.on_minimap_touch(pos[0]) return # nothing to press? deselect self.selected_module = None self.update_buttons def on_mouse_up(self, pos): self.mouse_down = False self.dragging_minimap = False if self.drag_start and self.selected_module: dx = pos[0] - self.drag_start[0] dy = pos[1] - self.drag_start[1] min = 10 if dx*dx + dy*dy > min*min: dir = -1 if abs(dx) > abs(dy): if dx > 0: dir = 0 else: dir = 2 else: if dy > 0: dir = 3 else: dir = 1 self.toggle_dir(dir) self.drag_start = None def on_build_press(self, type): if self.selected_module: self.selected_module.build_new(type) def on_upgrade_press(self, object): if self.selected_module: self.selected_module.upgrade() def on_sell_press(self, object): if self.selected_module: self.selected_module.sell() def on_put_unit(self, unit): import images # TODO: insert unit unit.kill() if unit.team == 1: self.dropping_units.add_unit(unit) else: self.battlefield.add_unit(unit) unit.set_anim(images.blubb_anim())