def initialize(self): pygame.init() self.screen = pygame.display.set_mode(window_size) self.screen_width=self.screen.get_rect().width self.screen_height=self.screen.get_rect().height preload() self.map = Map(self,'media/map.txt', images['tiles'],self.screen) temp_width = 150 temp_height = 150 self.minimap = MiniMap(self.engine,self,self.map,Rect([self.screen.get_rect().width-temp_width,0,temp_width,temp_height])) #self.clock = pygame.time.Clock() pygame.time.set_timer(USEREVENT, 1000) self.font = pygame.font.Font('media/freesansbold.ttf', 40) self.timer = pygame.time.Clock() self.engine.screen_width = self.screen.get_rect().width self.engine.screen_height = self.screen.get_rect().height self.engine.world_width = self.map.world_width self.engine.world_height = self.map.world_height self.engine.tile_width = self.map.tile_width self.engine.tile_height = self.map.tile_height for l in self.engine._lifes: l.sprite = get_sprite(l.sprite_name) (l)
def initialize(self): pygame.init() self.screen = pygame.display.set_mode(window_size) self.screen_width = self.screen.get_rect().width self.screen_height = self.screen.get_rect().height preload() self.map = Map(self, 'media/map.txt', images['tiles'], self.screen) temp_width = 150 temp_height = 150 self.minimap = MiniMap( self.engine, self, self.map, Rect([ self.screen.get_rect().width - temp_width, 0, temp_width, temp_height ])) #self.clock = pygame.time.Clock() pygame.time.set_timer(USEREVENT, 1000) self.font = pygame.font.Font('media/freesansbold.ttf', 40) self.timer = pygame.time.Clock() self.engine.screen_width = self.screen.get_rect().width self.engine.screen_height = self.screen.get_rect().height self.engine.world_width = self.map.world_width self.engine.world_height = self.map.world_height self.engine.tile_width = self.map.tile_width self.engine.tile_height = self.map.tile_height for l in self.engine._lifes: l.sprite = get_sprite(l.sprite_name)(l)
def new(self): self.dragging_camera = False self.all_sprites = pg.sprite.LayeredUpdates() self.items = pg.sprite.Group() self.imps = pg.sprite.Group() self.woods = pg.sprite.Group() self.map = Map(self) self.map.generate(200, 200) self.map.light(vec(10, 10), 20, 1) self.camera = Camera(self) self.game_speed = 200 self.pause = False self.mode = None self.dragging = 0 # 0: False, 1: add, -1:remove pg.mixer.music.load(path.join(self.snd_dir, 'ObservingTheStar.ogg')) Imp(self, vec(10, 10)) self.camera.focus(vec(10 * config.TILESIZE, 10 * config.TILESIZE)) self.resource = { 'woods': 0, 'iron': 0, }
class Game: def __init__(self, resources: Resources) -> None: self.camera = Vector2d(0, 0) self.stopwatch = Stopwatch(resources) # Objective 4: Create a Player self.player = Player(resources) # Objective 5: Create a Map self.map = Map(resources) def update(self, controller: Controller) -> None: if controller.has_input(Input.RESTART): self.stopwatch.reset() # Objective 4: Put the player back at the start self.player.restart() # Objective 6: Call the player update method self.player.update(controller, self.map) # Objective 7: Call the move_camera function with a focus on the player position #move_camera(self.camera, self.player.pos) # Objective 8: Update the stopwatch according to the player tile # YOUR CODE HERE... def render(self, renderer: Renderer) -> None: # Objective 4: Render the player self.player.render(renderer, self.camera) # Objective 5: Render the tilemap self.map.render(renderer, self.camera) self.stopwatch.render(renderer)
def __init__(self, resources: Resources) -> None: self.camera = Vector2d(0, 0) self.stopwatch = Stopwatch(resources) # Objective 4: Create a Player self.player = Player(resources) # Objective 5: Create a Map self.map = Map(resources)
def update(self, dt): # print("update", dt) if self.current_key != "" and self.can_walk_again: self.can_walk_again = False Clock.schedule_once(self.update_can_walk_again, 0.3) # print(self.current_key) self.next_move = self.move(self.current_key) # print(self.tile, self.next_move) possible = [x + y for x, y in zip(self.tile, self.next_move)] self.tile = possible print(self.tile) # collisions: for widget in self.parent.children: if widget is self: continue if self.tile == widget.tile: # print(widget) if isinstance(widget, Grass): print("grass") if isinstance(widget, Door): print("door", self.parent.map.filename, widget.map) self.parent.clean_widgets() self.parent.map = Map(widget.map, GAME.get("tilesize")) self.parent.new() # camera: self.parent.camera.update(self.parent.player) for sprite in self.parent.children: self.parent.camera.apply(sprite)
def __init__(self, **kwargs): super().__init__(**kwargs) print("Town") self.player = Player() self.add_widget(self.player) self.map = Map(GAME.get("first_map"), GAME.get("tilesize")) self.new()
def update(self, controller: Controller, tilemap: Map) -> None: ground = tilemap.on_ground(self.pos, PLAYER_SIZE) new_vel = copy(self.vel) # new y velocity... if controller.has_input(Input.JUMP): if ground: new_vel.y = -15 new_vel.y += 0.5 # gravity # new x velocity... direction = float(controller.direction) if ground: new_vel.x = 0.5 * new_vel.x + 4.0 * direction else: new_vel.x = 0.95 * new_vel.x + 2.0 * direction new_vel.x = min(max(new_vel.x, -2), 2) # Objective 6: Use the tilemap to shift the player position by velocity # YOUR CODE HERE... self.pos, self.vel = tilemap.move_box(self.pos, new_vel, PLAYER_SIZE) self.pos.x = int(self.pos.x) self.pos.y = int(self.pos.y)
def update(self, controller: Controller, tilemap: Map) -> None: ground = tilemap.on_ground(self.pos, PLAYER_SIZE) new_vel = copy(self.vel) # new y velocity... if controller.has_input(Input.JUMP): if ground: new_vel.y = -21 new_vel.y += 0.75 # gravity # new x velocity... direction = float(controller.direction) if ground: new_vel.x = 0.5 * new_vel.x + 4.0 * direction else: new_vel.x = 0.95 * new_vel.x + 2.0 * direction new_vel.x = min(max(new_vel.x, -8), 8)
def make_map(self): tileset_path = os.path.join(self.game.map_folder, 'RPGpack_sheet.png') tileset = TileSet(tileset_path, tilesize=32) grass_tile_ids = [41, 42, 43, 44, 81, 82, 83, 84] grass_tiles = [tileset[id] for id in grass_tile_ids] wall_tile_ids = [267, 268, 269, 270] wall_tiles = [tileset[id] for id in wall_tile_ids] W = 10 H = 10 map_data = generate_maze(H, W) map_data = convert_to_thick_walls(map_data) H = len(map_data) W = len(map_data[0]) self.map = Map(W, H) self.game.map = self.map empty_cells = [] wall_cells = [] map_img = pg.Surface((self.map.width, self.map.height)) for r in range(H): for c in range(W): if map_data[r][c] == 0: tile = random.choice(grass_tiles) empty_cells.append((r, c)) else: tile = random.choice(wall_tiles) wall_cells.append((r, c)) map_img.blit(tile, (c * TILESIZE, r * TILESIZE)) self.player_init_pos = random.choice(empty_cells) self.goal_pos = random.choice(empty_cells) self.game.map_img = map_img self.game.map_rect = map_img.get_rect() self.wall_cells = wall_cells
def load_data(self): """ Loads the necessary assets for the game. :return: None """ # Game map self.map = Map(path.join(self.game_folder, 'map3.txt')) self.pause_screen_effect = pg.Surface(self.screen.get_size()).convert() self.pause_screen_effect.fill((0, 0, 0, 225)) # Fog of war self.fog = pg.Surface(self.screen.get_size()).convert() self.fog.fill(NIGHT_COLOR) # Light on the player self.light_mask = pg.image.load(path.join(self.img_folder, LIGHT_MASK)).convert_alpha() self.light_mask = pg.transform.smoothscale(self.light_mask, (LIGHT_RADIUS, LIGHT_RADIUS)) self.light_rect = self.light_mask.get_rect() # HUD Elements self.mag_img = pg.transform.smoothscale(pg.image.load(path.join(self.img_folder, CLIP_IMG)), (40, 40)).convert_alpha() # Crosshairs self.crosshairs = [ pg.transform.smoothscale(pg.image.load(path.join(self.crosshair_folder, crosshair)), (32, 32)).convert_alpha() for crosshair in CROSSHAIRS] # todo - have a menu decide the player's crosshair self.crosshair = choice(self.crosshairs) # Item pickups self.pickup_items = {} for item in ITEM_IMAGES: self.pickup_items[item] = [] self.pickup_items[item] = pg.image.load(path.join(self.item_folder, ITEM_IMAGES[item])).convert_alpha() # Fonts self.hud_font = path.join(self.img_folder, 'Fonts\Impacted2.0.ttf') # Sound loading self.music_tracks = {"main menu": MAIN_MENU_MUSIC, 'Game over': GAME_OVER_MUSIC, 'background music': BG_MUSIC} pg.mixer.music.load(path.join(self.music_folder, self.music_tracks['background music'])) pg.mixer.music.set_volume(.5) self.swing_noises = {} for weapon in PLAYER_SWING_NOISES: noise = pg.mixer.Sound(path.join(self.snd_folder, PLAYER_SWING_NOISES[weapon])) noise.set_volume(.25) self.swing_noises[weapon] = noise self.player_hit_sounds = [] for snd in PLAYER_HIT_SOUNDS: self.player_hit_sounds.append(pg.mixer.Sound(path.join(self.snd_folder, snd))) self.weapon_sounds = {} for weapon in WEAPONS['sound']: self.weapon_sounds[weapon] = {} sound_list = {} for snd in WEAPONS['sound'][weapon]: noise = pg.mixer.Sound(path.join(self.snd_folder, WEAPONS['sound'][weapon][snd])) noise.set_volume(.9) sound_list[snd] = noise self.weapon_sounds[weapon] = sound_list self.zombie_moan_sounds = [] for snd in ZOMBIE_MOAN_SOUNDS: noise = pg.mixer.Sound(path.join(self.snd_folder, snd)) noise.set_volume(.25) self.zombie_moan_sounds.append(noise) self.zombie_hit_sounds = {} for type in ENEMY_HIT_SOUNDS: self.zombie_hit_sounds[type] = [] for snd in ENEMY_HIT_SOUNDS[type]: snd = pg.mixer.Sound(path.join(self.snd_folder, snd)) snd.set_volume(.75) self.zombie_hit_sounds[type].append(snd) self.player_foot_steps = {} for terrain in PLAYER_FOOTSTEPS: self.player_foot_steps[terrain] = [] for snd in PLAYER_FOOTSTEPS[terrain]: snd = pg.mixer.Sound(path.join(self.snd_folder, snd)) snd.set_volume(.5) self.player_foot_steps[terrain].append(snd) # Bullets self.bullet_images = {} self.bullet_images['lg'] = pg.transform.smoothscale(pg.image.load(path.join(self.img_folder, RIFLE_BULLET_IMG)), (10, 3)).convert_alpha() self.bullet_images['med'] = pg.transform.smoothscale( pg.image.load(path.join(self.img_folder, HANDGUN_BULLET_IMG)), (5, 3)).convert_alpha() self.bullet_images['sm'] = pg.transform.smoothscale(pg.image.load( path.join(self.img_folder, SHOTGUN_BULLET_IMG)).convert_alpha(), (7, 7)) # Effects self.gun_flashes = [pg.image.load(path.join(self.img_folder, flash)).convert_alpha() for flash in MUZZLE_FLASHES] # Load enemy animations self.enemy_imgs = [pg.transform.smoothscale(pg.image.load(path.join(self.game_folder, name)), (96, 96)).convert_alpha() for name in ENEMY_IMGS] # Load player animations self.default_player_weapon = 'knife' self.default_player_action = 'idle' self.player_animations = {'handgun': {}, 'knife': {}, 'rifle': {}, 'shotgun': {}} # Create all hand gun animations self.player_animations['handgun']['idle'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in HANDGUN_ANIMATIONS['idle']] self.player_animations['handgun']['melee'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in HANDGUN_ANIMATIONS['melee']] self.player_animations['handgun']['move'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in HANDGUN_ANIMATIONS['move']] self.player_animations['handgun']['reload'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in HANDGUN_ANIMATIONS['reload']] self.player_animations['handgun']['shoot'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in HANDGUN_ANIMATIONS['shoot']] # Create all knife animations self.player_animations['knife']['idle'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in KNIFE_ANIMATIONS['idle']] self.player_animations['knife']['melee'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in KNIFE_ANIMATIONS['melee']] self.player_animations['knife']['move'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in KNIFE_ANIMATIONS['move']] # Create all rifle animations self.player_animations['rifle']['idle'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in RIFLE_ANIMATIONS['idle']] self.player_animations['rifle']['melee'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in RIFLE_ANIMATIONS['melee']] self.player_animations['rifle']['move'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in RIFLE_ANIMATIONS['move']] self.player_animations['rifle']['reload'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in RIFLE_ANIMATIONS['reload']] self.player_animations['rifle']['shoot'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in RIFLE_ANIMATIONS['shoot']] # Create all shotgun animations self.player_animations['shotgun']['idle'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in SHOTGUN_ANIMATIONS['idle']] self.player_animations['shotgun']['melee'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in SHOTGUN_ANIMATIONS['melee']] self.player_animations['shotgun']['move'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in SHOTGUN_ANIMATIONS['move']] self.player_animations['shotgun']['reload'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in SHOTGUN_ANIMATIONS['reload']] self.player_animations['shotgun']['shoot'] = [pg.image.load(path.join(self.game_folder, name)).convert_alpha() for name in SHOTGUN_ANIMATIONS['shoot']]
class Render: def __init__(self, engine): self.engine = engine def initialize(self): pygame.init() self.screen = pygame.display.set_mode(window_size) self.screen_width = self.screen.get_rect().width self.screen_height = self.screen.get_rect().height preload() self.map = Map(self, 'media/map.txt', images['tiles'], self.screen) temp_width = 150 temp_height = 150 self.minimap = MiniMap( self.engine, self, self.map, Rect([ self.screen.get_rect().width - temp_width, 0, temp_width, temp_height ])) #self.clock = pygame.time.Clock() pygame.time.set_timer(USEREVENT, 1000) self.font = pygame.font.Font('media/freesansbold.ttf', 40) self.timer = pygame.time.Clock() self.engine.screen_width = self.screen.get_rect().width self.engine.screen_height = self.screen.get_rect().height self.engine.world_width = self.map.world_width self.engine.world_height = self.map.world_height self.engine.tile_width = self.map.tile_width self.engine.tile_height = self.map.tile_height for l in self.engine._lifes: l.sprite = get_sprite(l.sprite_name)(l) def loop(self): fps = 0 message = None viewpos = (0, 0) sx, sy = self.screen.get_size() mapsurf = pygame.Surface(self.screen.get_size()) fresh = True group = pygame.sprite.RenderUpdates() while True: self.timer.tick() mousex, mousey = pygame.mouse.get_pos() mouse_in_minimap = self.minimap.contain((mousex, mousey)) border = 100 cond1 = mousex < border cond2 = mousey < border and not mouse_in_minimap cond3 = mousex > self.screen.get_rect( ).width - border and not mouse_in_minimap cond4 = mousey > self.screen.get_rect().height - border moveunit = 20 x, y = self.map.get_viewpos() if cond1: x -= moveunit elif cond2: y -= moveunit elif cond3: x += moveunit elif cond4: y += moveunit self.map.set_viewpos(self.map.limit((x, y))) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == KEYDOWN and event.key == K_ESCAPE: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: if mouse_in_minimap: self.minimap.mouse(event.pos) else: x, y = self.map.get_viewpos() dx, dy = event.pos x += dx - sx / 2 y += dy - sy / 2 viewpos = self.map.limit((x, y)) self.map.set_viewpos(viewpos) elif event.type == USEREVENT: fps = self.timer.get_fps() s = " fps: %.2f pos: %s" % (fps, str(self.map.get_viewpos())) message = self.font.render(s, 0, (255, 255, 255)).convert() self.map.draw() for pos in self.map.get_range(): if self.engine._tile_lifes.has_key(pos): for life in self.engine._tile_lifes[pos]: sprite = life.sprite img = sprite.image temp = img.get_rect().move( life.position[0] - self.map.viewpos[0], life.position[1] - self.map.viewpos[1]) if math.cos(life.direction) < 0: img = pygame.transform.flip(img, 1, 0) self.screen.blit(img, temp) self.screen.blit(message, (0, 0)) self.minimap.draw(self.screen) pygame.display.update() stackless.schedule()
class Game(object): def __init__(self): pg.mixer.pre_init(44100, -16, 1, 512) pg.init() pg.mixer.init() pg.display.set_caption(TITLE) pg.mouse.set_visible(False) self.screen = pg.display.set_mode((WIDTH, HEIGHT)) self.clock = pg.time.Clock() # game self.running = True self.playing = False self.game_speed = 0 self.last_update = 0 self.dt = 0 self.cursor_pos = vec() self.last_mouse_pos = vec() self.dragging_camera = False self.dragging_camera = False # Groups self.all_sprites = [] self.items = [] self.imps = [] self.woods = [] # Switcher self.map = None self.camera = None self.pause = False self.mode = None self.modes = [ None, 'dig&cut', 'resource', 'imp', 'ladder', 'torch', 'shelf', 'bed' ] self.dragging = 0 # 0: False, 1: add, -1:remove # ----- load data ----- self.dir = path.dirname(__file__) self.img_dir = path.join(self.dir, 'img') self.snd_dir = path.join(self.dir, 'snd') self.map_dir = path.join(self.dir, 'map') # load font self.font_name = path.join(self.dir, 'old_evils.ttf') # load images self.img = { 'sky': pg.image.load(path.join(self.img_dir, 'Other/skybox_sideHills.png')).convert(), 'sky_top': pg.image.load(path.join(self.img_dir, 'Other/skybox_top.png')).convert(), 'sky_bottom': pg.image.load(path.join(self.img_dir, 'Other/skybox_bottom.png')).convert(), 'dig_mark': pg.image.load(path.join(self.img_dir, 'dig_mark.png')).convert_alpha(), 'dig_mark_hammer': pg.image.load(path.join(self.img_dir, 'dig_mark_hammer.png')).convert_alpha(), 'imp': pg.image.load(path.join(self.img_dir, 'imp.png')).convert_alpha(), 'wood': pg.image.load(path.join(self.img_dir, 'wood.png')).convert_alpha(), 'cursor': pg.image.load(path.join(self.img_dir, 'cursor.png')).convert_alpha(), 'axe_iron': pg.image.load(path.join(self.img_dir, 'Items/axe_iron.png')).convert_alpha(), } self.img['wood'].set_colorkey(BLACK) # load musics and sounds self.snd = { 'mark': pg.mixer.Sound(path.join(self.snd_dir, 'mark1.ogg')), 'unmark': pg.mixer.Sound(path.join(self.snd_dir, 'unmark1.ogg')), 'digging': list(), 'cut_tree': pg.mixer.Sound(path.join(self.snd_dir, 'qubodupImpactWood.ogg')), # 'dig_stone': [pg.mixer.Sound(path.join(self.snd_dir, 'qubodupImpactStone.ogg')), # pg.mixer.Sound(path.join(self.snd_dir, 'qubodupImpactMetal.ogg'))], 'shift': pg.mixer.Sound(path.join(self.snd_dir, 'UI_Click_Organic_mono.ogg')), 'tree_down': pg.mixer.Sound(path.join(self.snd_dir, 'crack01.mp3.flac')), 'build': [ pg.mixer.Sound( path.join(self.snd_dir, 'qubodupImpactMeat01.ogg')), pg.mixer.Sound( path.join(self.snd_dir, 'qubodupImpactMeat02.ogg')) ] } for i in range(1, 9): self.snd['digging'].append( pg.mixer.Sound(path.join(self.snd_dir, 'tool{}.ogg'.format(i)))) def new(self): self.dragging_camera = False self.all_sprites = pg.sprite.LayeredUpdates() self.items = pg.sprite.Group() self.imps = pg.sprite.Group() self.woods = pg.sprite.Group() self.map = Map(self) self.map.generate(200, 200) self.map.light(vec(10, 10), 20, 1) self.camera = Camera(self) self.game_speed = 200 self.pause = False self.mode = None self.dragging = 0 # 0: False, 1: add, -1:remove pg.mixer.music.load(path.join(self.snd_dir, 'ObservingTheStar.ogg')) Imp(self, vec(10, 10)) self.camera.focus(vec(10 * config.TILESIZE, 10 * config.TILESIZE)) self.resource = { 'woods': 0, 'iron': 0, } def run(self): pg.mixer.music.play(loops=-1) pg.mixer.music.set_volume(0.4) self.playing = True self.last_update = pg.time.get_ticks() while self.playing: self.dt = self.clock.tick(config.FPS) / 1000 self.events() self.update() self.draw() def update(self): if not self.pause: now = pg.time.get_ticks() if now - self.last_update > self.game_speed: self.last_update = now self.next_turn() for sprite in self.all_sprites: sprite.float_pos += sprite.v / ( (self.game_speed - 14) / 1000) / config.FPS sprite.rect.topleft = sprite.float_pos mouse_pos = vec(pg.mouse.get_pos()) self.cursor_pos = vec( vec2int((mouse_pos - self.camera.offset) / config.TILESIZE)) tile = self.map.data[vec2int(self.cursor_pos)] # drag camera if self.dragging_camera: mouse_vector = mouse_pos - self.last_mouse_pos self.camera.update(mouse_vector) # game stuff if self.map.in_bounds(self.cursor_pos) and self.map.in_view( self.cursor_pos): if self.mode == 'dig&cut' and tile and ( tile.in_group('destroyable') or tile.in_group('diggable') or tile.in_group('cuttable')): if self.dragging == 1: if not tile.in_group('dig&cut_mark'): tile.add_to_group('dig&cut_mark') self.snd['mark'].play() elif self.dragging == -1: if tile.in_group('dig&cut_mark'): tile.remove_from_group('dig&cut_mark') elif self.mode == 'ladder': if self.dragging == 1: if tile is None or isinstance(tile, BgTile): # Ladder(self.map, self.cursor_pos) BuildMark(self.map, self.cursor_pos, 'ladder') elif self.dragging == -1: if isinstance(tile, BuildMark) and tile.image_name == 'ladder': tile.kill() elif self.mode == 'shelf': if self.dragging == 1: if tile is None or isinstance(tile, BgTile): BuildMark(self.map, self.cursor_pos, 'shelf') elif self.dragging == -1: if isinstance(tile, BuildMark) and tile.image_name == 'shelf': tile.kill() elif self.mode == 'bed': if self.dragging == 1: if tile is None or isinstance(tile, BgTile): BuildMark(self.map, self.cursor_pos, 'bed') elif self.dragging == -1: if isinstance(tile, BuildMark) and tile.image_name == 'bed': tile.kill() elif self.mode == 'resource' and tile and tile.in_group('earth'): if self.dragging == 1: if not tile.in_group('resource_mark') and \ self.map.can_stand(tile.pos + (0, -1)): tile.add_to_group('resource_mark') self.snd['mark'].play() elif self.dragging == -1: if tile.in_group('resource_mark'): tile.remove_from_group('resource_mark') self.snd['unmark'].play() self.last_mouse_pos = mouse_pos def next_turn(self): # ----- 遍历标记,为标记雇佣 imp ----- for mark in union_dicts(self.map.groups['dig&cut_mark'], self.map.groups['build_mark_noworker']): tile = self.map.data[mark] neighbors = self.map.find_neighbors(tile.pos, (self.map.can_stand, )) found = False for dest in neighbors: if not found: path = self.map.path_finding(dest) for imp in self.imps: if not found: if imp.task is None and vec2int(imp.pos) in path: if tile and (tile.in_group('diggable') or tile.in_group('destroyable')): imp.task = Dig(self.map, tile.pos, dest) found = True elif tile and tile.in_group('cuttable'): imp.task = Cut(self.map, tile.pos, dest) found = True elif isinstance(tile, BuildMark): if (tile.image_name == 'torch') or \ (tile.image_name == 'ladder' and self.resource['woods'] >= 1) or \ (tile.image_name == 'shelf' and self.resource['woods'] >= 3) or \ (tile.image_name == 'bed' and self.resource['woods'] >= 4): imp.task = Build( self.map, tile.pos, dest) tile.worker = imp tile.remove_from_group( 'build_mark_noworker') found = True # # ----- 更新小弟目的地 ----- # for imp in self.imps: # if isinstance(imp.task, Dig) or isinstance(imp.task, Cut): # imp.task.path = {} # neighbors = self.map.find_neighbors(imp.task.target, (self.map.can_stand,)) # found = False # for dest in neighbors: # if not found: # path = self.map.path_finding(dest) # if vec2int(imp.pos) in path: # imp.task.path = path # found = True for wood in self.woods: tile_below = self.map.data[vec2int(wood.pos + (0, 1))] if not wood.owner and tile_below and not tile_below.in_group( 'resource_mark'): path = self.map.path_finding(wood.pos) found = False for imp in self.imps: if not found: if imp.task is None and vec2int(imp.pos) in path and \ len([i for i in imp.inventories if isinstance(i, Wood)]) < 1: imp.task = Carry(self.map, wood.pos, wood.pos, item_to_find=wood) for mark in self.map.groups['resource_mark']: path = self.map.path_finding(vec(mark) + (0, -1)) for wood in self.woods: if wood.owner and vec2int(wood.owner.pos) in path: wood.owner.task = Carry(self.map, vec(mark) + (0, -1), vec(mark) + (0, -1), item_to_find=None) self.all_sprites.update() self.map.groups['visible'] = {} for imp in self.imps: self.map.light(imp.pos) self.map.light_torch() def consume_woods(self, n): for i, wood_in_res in enumerate([ wood for wood in self.woods if vec2int(wood.pos + vec(0, 1)) in self.map.groups['resource_mark'] ]): if i < n: wood_in_res.kill() def events(self): tile = self.map.data[vec2int(self.cursor_pos)] for e in pg.event.get(): # ----- 退出事件 ----- if e.type == pg.QUIT: if self.playing: self.playing = False self.running = False # ----- 退出事件 ----- # ----- 鼠标按下事件 ----- if e.type == pg.MOUSEBUTTONDOWN: # e.button 1左键 2中键 3右键 4滚轮上 5滚轮下 if e.button == 1: if self.map.in_bounds( self.cursor_pos) and self.map.in_view( self.cursor_pos): if self.mode == 'imp': if self.map.can_stand(self.cursor_pos): Imp(self, self.cursor_pos) elif self.mode == 'shelf': if tile is None or isinstance(tile, BgTile): self.dragging = 1 elif isinstance( tile, BuildMark) and tile.image_name == 'ladder': self.dragging = -1 elif self.mode == 'bed': if tile is None or isinstance(tile, BgTile): self.dragging = 1 elif isinstance( tile, BuildMark) and tile.image_name == 'bed': self.dragging = -1 elif self.mode == 'ladder': if tile is None or isinstance(tile, BgTile): self.dragging = 1 elif isinstance( tile, BuildMark) and tile.image_name == 'ladder': self.dragging = -1 elif self.mode == 'dig&cut' and tile: if tile.in_group('dig&cut_mark'): self.dragging = -1 else: self.dragging = 1 elif self.mode == 'resource' and tile and tile.in_group( 'earth'): if tile.in_group('resource_mark'): self.dragging = -1 else: self.dragging = 1 elif self.mode == 'torch': if isinstance(tile, BgTile): BuildMark(self.map, tile.pos, 'torch') elif isinstance(tile, Torch): tile.kill() elif self.mode == 'remove' and tile is not None: tile.kill() if e.button == 3: self.dragging_camera = True if e.button == 4: self.mode = self.modes[(self.modes.index(self.mode) - 1) % len(self.modes)] self.snd['shift'].play() if e.button == 5: self.mode = self.modes[(self.modes.index(self.mode) + 1) % len(self.modes)] self.snd['shift'].play() # ----- 鼠标按下事件 ----- # ----- 鼠标放开事件 ----- if e.type == pg.MOUSEBUTTONUP: if e.button == 1: if self.dragging: self.dragging = False if e.button == 2: # debug pass if e.button == 3: self.dragging_camera = False # ----- 鼠标放开事件 ----- # ----- 键盘按下事件 ----- if e.type == pg.KEYDOWN: if e.key == pg.K_SPACE: self.pause = False if self.pause else True if e.key == pg.K_1: self.game_speed = 800 if e.key == pg.K_2: self.game_speed = 600 if e.key == pg.K_3: self.game_speed = 400 if e.key == pg.K_4: self.game_speed = 200 if e.key == pg.K_z: if config.TILESIZE == 48: config.TILESIZE = 32 self.camera.offset += (self.cursor_pos.x * 16, self.cursor_pos.y * 16) else: config.TILESIZE = 48 self.camera.offset -= (self.cursor_pos.x * 16, self.cursor_pos.y * 16) self.camera.repair() if e.key == pg.K_d: self.mode = 'dig&cut' if e.key == pg.K_i: self.mode = 'imp' if e.key == pg.K_l: self.mode = 'ladder' if e.key == pg.K_r: self.mode = 'resource' if e.key == pg.K_c: self.mode = 'torch' # ----- 键盘按下事件 ----- def draw(self): # draw debug HUD pg.display.set_caption("{:.2f}".format(self.clock.get_fps())) # pg.display.set_caption("camera({}, {})".format(self.camera.offset.x, self.camera.offset.y)) # pg.display.set_caption( # "({},{},{})".format(self.cursor_pos.x, self.cursor_pos.y, # (type(self.map.data[vec2int(self.cursor_pos)])))) self.screen.blit(pg.transform.scale(self.img['sky_top'], (WIDTH, 100)), (0, 0)) self.screen.blit(self.img['sky'], (0, 100)) self.screen.blit(self.img['sky'], (512, 100)) self.screen.blit( pg.transform.scale(self.img['sky_bottom'], (WIDTH, 512)), (0, 612)) tiles = self.map.draw(self.camera) # pg.display.set_caption(str(tiles)) # self.all_sprites.draw(self.screen) for sprite in self.all_sprites: if isinstance(sprite, Wood) and sprite.owner: # 隐藏被捡起来的木头 continue self.screen.blit(sprite.image, self.camera.apply(sprite)) # draw target box and mouse cursor target = pg.Rect( self.cursor_pos.x * config.TILESIZE + self.camera.offset.x, self.cursor_pos.y * config.TILESIZE + self.camera.offset.y, config.TILESIZE, config.TILESIZE) pg.draw.rect(self.screen, WHITE, target, 2) self.draw_mode_icon(self.mode) # draw game speed if self.pause: self.draw_text('PAUSE', 32, RED, vec(WIDTH / 2, 16), align='mid') else: self.draw_text('SPEED:', 32, WHITE, vec(WIDTH / 2 - 130, 16), align='mid') for i in range(1, 5): if 1000 - (200 * i) == self.game_speed: self.draw_text('x' + str(i), 38, BROWN, vec(WIDTH / 2 - 100 + 56 * i, 16), align='mid') else: self.draw_text('x' + str(i), 32, WHITE, vec(WIDTH / 2 - 100 + 56 * i, 16), align='mid') # draw resource # count woods self.resource['woods'] = 0 for wood in self.woods: if vec2int(wood.pos + vec(0, 1)) in self.map.groups['resource_mark']: self.resource['woods'] += 1 count_woods = self.resource['woods'] for bm in self.map.groups['build_mark']: bm = self.map.data[bm] if bm.image_name == 'ladder': count_woods -= 1 elif bm.image_name == 'shelf': count_woods -= 3 elif bm.image_name == 'bed': count_woods -= 4 self.screen.blit(pg.transform.scale(self.img['wood'], (24, 24)), (16, HEIGHT - 30)) if count_woods >= 0: self.draw_text('x' + str(count_woods), 24, WHITE, (40, HEIGHT - 24)) else: self.draw_text('x' + str(count_woods), 24, RED, (40, HEIGHT - 24)) self.screen.blit(self.img['cursor'], self.last_mouse_pos - (15, 10)) pg.display.flip() def draw_mode_icon(self, mode): if mode == 'dig&cut': image = self.img['axe_iron'] mode_name = 'Dig&Cut' elif mode == 'resource': image = self.map.image['greystone_sand'] mode_name = 'Set Resource Area' elif mode == 'imp': image = self.img['imp'] mode_name = 'Minion' elif mode == 'ladder': image = self.map.image['ladder'].copy() mode_name = 'Ladder' elif mode == 'torch': image = self.map.image['torch'] mode_name = 'Torch' elif mode == 'shelf': image = self.map.image['shelf'] mode_name = 'Library' elif mode == 'bed': image = self.map.image['bed'] mode_name = 'Bed' else: image = self.map.image['table'] mode_name = 'Nothing' self.screen.blit(pg.transform.scale(image, (64, 64)), vec(WIDTH - 96, HEIGHT - 96)) self.draw_text(mode_name, 46, WHITE, vec(WIDTH - 104, HEIGHT - 90), align='right') def draw_text(self, text, font_size, color, pos, align='left'): font = pg.font.Font(self.font_name, font_size) text_surface = font.render(text, True, color) text_rect = text_surface.get_rect() if align == 'left': text_rect.topleft = pos elif align == 'mid': text_rect.midtop = pos elif align == 'right': text_rect.topright = pos self.screen.blit(text_surface, text_rect) def zoom(self, n): config.TILESIZE += n if 32 <= config.TILESIZE <= 96: self.camera.offset -= (self.cursor_pos.x * n, self.cursor_pos.y * n) config.TILESIZE = max(32, config.TILESIZE) config.TILESIZE = min(96, config.TILESIZE) self.camera.repair()
class Render: def __init__(self,engine): self.engine = engine def initialize(self): pygame.init() self.screen = pygame.display.set_mode(window_size) self.screen_width=self.screen.get_rect().width self.screen_height=self.screen.get_rect().height preload() self.map = Map(self,'media/map.txt', images['tiles'],self.screen) temp_width = 150 temp_height = 150 self.minimap = MiniMap(self.engine,self,self.map,Rect([self.screen.get_rect().width-temp_width,0,temp_width,temp_height])) #self.clock = pygame.time.Clock() pygame.time.set_timer(USEREVENT, 1000) self.font = pygame.font.Font('media/freesansbold.ttf', 40) self.timer = pygame.time.Clock() self.engine.screen_width = self.screen.get_rect().width self.engine.screen_height = self.screen.get_rect().height self.engine.world_width = self.map.world_width self.engine.world_height = self.map.world_height self.engine.tile_width = self.map.tile_width self.engine.tile_height = self.map.tile_height for l in self.engine._lifes: l.sprite = get_sprite(l.sprite_name) (l) def loop(self): fps = 0 message = None viewpos = (0,0) sx, sy = self.screen.get_size() mapsurf = pygame.Surface(self.screen.get_size()) fresh = True group = pygame.sprite.RenderUpdates() while True: self.timer.tick() mousex,mousey = pygame.mouse.get_pos() mouse_in_minimap = self.minimap.contain((mousex,mousey)) border = 100 cond1 = mousex<border cond2 = mousey<border and not mouse_in_minimap cond3 = mousex>self.screen.get_rect().width-border and not mouse_in_minimap cond4 = mousey>self.screen.get_rect().height-border moveunit = 20 x,y = self.map.get_viewpos() if cond1: x-=moveunit elif cond2: y-=moveunit elif cond3: x+=moveunit elif cond4: y+=moveunit self.map.set_viewpos(self.map.limit((x,y))) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == KEYDOWN and event.key==K_ESCAPE: pygame.quit() sys.exit() elif event.type == MOUSEBUTTONDOWN: if mouse_in_minimap: self.minimap.mouse(event.pos) else: x, y = self.map.get_viewpos() dx, dy = event.pos x += dx - sx/2 y += dy - sy/2 viewpos = self.map.limit((x,y)) self.map.set_viewpos(viewpos) elif event.type == USEREVENT: fps = self.timer.get_fps() s = " fps: %.2f pos: %s" % (fps,str(self.map.get_viewpos())) message = self.font.render(s, 0, (255,255,255)).convert() self.map.draw() for pos in self.map.get_range(): if self.engine._tile_lifes.has_key(pos): for life in self.engine._tile_lifes[pos]: sprite = life.sprite img = sprite.image temp = img.get_rect().move(life.position[0]-self.map.viewpos[0],life.position[1]-self.map.viewpos[1]) if math.cos(life.direction) < 0: img = pygame.transform.flip(img, 1, 0) self.screen.blit(img,temp) self.screen.blit(message,(0,0)) self.minimap.draw(self.screen) pygame.display.update() stackless.schedule()