class LevelPlay(tools._State): def __init__(self): super(LevelPlay, self).__init__() tmx_data = load_pygame(MAP['map0']) map_data = pyscroll.data.TiledMapData(tmx_data) self.map_rect = pg.Rect(0, 0, map_data.map_size[0] * map_data.tile_size[0], map_data.map_size[1] * map_data.tile_size[1]) self.map_layer = pyscroll.BufferedRenderer(map_data, SCREEN_SIZE) self.map_layer.zoom = 1 self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2) self.animations = pg.sprite.Group() self.labels = pg.sprite.Group() self.enemies = pg.sprite.Group() self.coins = pg.sprite.Group() self.pos_x = None self.pos_y = None self.pos_x_r = None self.pos_y_r = None self.upper_world = False self.time = 0 self.timer = TIME self.coin_num = 0 self.player_lives = 0 self.hud = Hud() self.walls = list() for object in tmx_data.objects: if object.name == 'collide': self.walls.append( pg.Rect(object.x, object.y, object.width, object.height)) elif object.name == 'playerpos': self.pos_x = object.x self.pos_y = object.y self.player = Player(self.pos_x, self.pos_y, False, self.group) elif object.name == 'playerpos_r': self.pos_x_r = object.x self.pos_y_r = object.y elif object.name == 'enemy': Enemy(object.x, object.y, self.enemies) elif object.name == 'fish': Fish(object.x, object.y, self.enemies) elif object.name == 'fly': Fly(object.x, object.y, self.enemies) elif object.name == 'coin': Coin(object.x, object.y, self.coins) elif object.name == 'bat': Bat(object.x, object.y, self.enemies) elif object.name == 'enimy': Enimy(object.x, object.y, self.enemies) elif object.name == 'f1sh': F1sh(object.x, object.y, self.enemies) elif object.name == 'over_event': self.over_rect = pg.Rect(object.x, object.y, object.width, object.height) elif object.name == 'over_event_r': self.over_rect_r = pg.Rect(object.x, object.y, object.width, object.height) self.player.platform = self.walls def get_event(self, event): self.player.get_event(event) if event.type == pg.QUIT: self.quit = True elif event.type == pg.KEYDOWN: if event.key == pg.K_SPACE: self.map_layer.zoom = 0.5 elif event.type == pg.KEYUP: if event.type == pg.K_ESCAPE: self.quit = True elif event.key == pg.K_SPACE: self.map_layer.zoom = 1 else: pass def startup(self, persist): pg.mixer.init() song = MUSIC['bg'] pg.mixer.music.load(song) pg.mixer.music.set_volume(0.1) pg.mixer.music.play() self.done = False self.persist = persist self.mask = self.persist['surface'] self.transition = Transition(self.mask) self.player_lives = self.persist['lives'] self.coin_num = self.persist['coins'] if self.player.reverse == True: self.fog = pg.Surface(SCREEN_RECT.size, pg.SRCALPHA) self.fog_color = (0, 0, 0, 200) self.fog.fill(self.fog_color) def player_dead(self): sound = SFX['dead0'] sound.play() self.player_lives -= 1 if self.player_lives < 1: self.done = True self.next = 'LOSE' buffer = pg.display.get_surface() self.switch_screen = Transition(buffer) if self.player.reverse == False: self.player.rect.x, self.player.rect.y = self.pos_x, self.pos_y elif self.player.reverse == True: self.player.rect.x, self.player.rect.y = self.pos_x_r, self.pos_y_r def update(self, dt): self.offset_x, self.offset_y = self.group._map_layer.get_center_offset( ) self.time += dt if self.time > self.timer: self.time -= self.timer self.player_dead() self.group.update(dt) self.enemies.update(dt) self.coins.update(dt) self.hud.update(self, dt) self.animations.update(dt) if self.player.rect.colliderect(self.over_rect_r): if self.player.reverse == True: self.done = True self.next = 'WIN' if self.player.rect.colliderect(self.over_rect): self.player.rect.x, self.player.rect.y = self.pos_x_r, self.pos_y_r if self.coin_num >= 30: self.player.kill() self.player = Player(self.pos_x_r, self.pos_y_r, True, self.group) self.player.platform = self.walls self.done = True self.next = 'UPPER' elif self.coin_num < 30: self.player.reverse = False self.done = True self.next = 'BOTUP' if pg.sprite.spritecollide(self.player, self.coins, True): self.coin_num += 1 sound = SFX['coin'] sound.play() self.labels.empty() self.animations.empty() coin_sprite = pg.sprite.Sprite(self.labels) coin_sprite.image = GFX['hud_coins'] x = self.offset_x + self.player.rect.x y = self.offset_y + self.player.rect.y coin_sprite.rect = pg.Rect((x, y), coin_sprite.image.get_size()) ani = Animation(x=50, y=10, duration=100, transition="out_bounce") ani.start(coin_sprite.rect) self.animations.add(ani) if not self.map_rect.contains(self.player.rect): self.player_dead() if pg.sprite.spritecollide(self.player, self.enemies, False): self.player_dead() self.labels.update(dt) def cleanup(self): pg.mixer.quit() self.persist = {} self.persist['coins'] = self.coin_num self.persist['lives'] = self.player_lives self.persist['surface'] = pg.display.get_surface() return self.persist def draw(self, surface): self.group.empty() if self.player.reverse == True: close = (enemy for enemy in self.enemies if get_distance( enemy.rect.center, self.player.rect.center) <= 100) close_enemies = pg.sprite.Group(close) self.group.add(self.player, self.coins, close_enemies) elif self.player.reverse == False: close = (enemy for enemy in self.enemies if get_distance( enemy.rect.center, self.player.rect.center) <= SCREEN_SIZE[0]) close_enemies = pg.sprite.Group(close) self.group.add(self.player, self.coins, close_enemies) self.group.draw(surface) self.group.center(self.player.rect.center) if hasattr(self, 'fog') and self.map_layer.zoom == 1: self.fog.fill(self.fog_color) for i in range(200): pg.draw.circle(self.fog, pg.Color(0, 0, 0, 200 - i), (self.player.rect.centerx + self.offset_x, self.player.rect.centery + self.offset_y), int(100 - i * 0.5)) surface.blit(self.fog, (0, 0)) elif hasattr(self, 'fog') and self.map_layer.zoom == 0.5: self.fog.fill(self.fog_color) surface.blit(self.fog, (0, 0)) self.hud.draw(surface) self.transition.draw(surface) self.labels.draw(surface) if hasattr(self, 'switch_screen'): self.switch_screen.draw(surface)
class QuestGame(object): """ This class is a basic game. This class will load data, create a pyscroll group, a hero object. It also reads input and moves the Hero around the map. Finally, it uses a pyscroll group to render the map and Hero. """ filename = get_map(MAP_FILENAME) counter = 1 counter2 = 1 def __init__(self, state): if state == False: self.fullscreen = False # true while running. self.running = False self.clock = pygame.time.Clock() # create all the directio variables self.direction = "still" self.EntityDirection = "still" self.EntityDirection1, self.EntityDirection2 = "still", "still" self.fps = 1000 self.bypass = False entityPos1, heroPos1 = False, False # load data from pytmx tmx_data = load_pygame(self.filename) self.tmx_data = tmx_data mapPlay = load_pygame(get_map(stats['map'])) # create new data source for pyscroll map_data = pyscroll.data.TiledMapData(mapPlay) # setup level geometry with simple pygame rects, loaded from pytmx. self.walls = list() for object in mapPlay.objects: self.walls.append(pygame.Rect( object.x, object.y, object.width, object.height)) # create new renderer (camera) self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size()) self.map_layer.zoom = 2 self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4) self.hero = Hero('Tiles/hero/character_still.png') self.entity = Entity('Tiles/hero/character_still.png') self.hero.position = stats['pos'] self.entity.position = stats['pos'] # add our hero to the group self.group.add(self.hero) #self.group.add(self.entity) self.entVel = (0, 0) def deep_thought(self): # The 'AI' function, needs work if self.counter2 % 75 == 0 or self.bypass == True: self.bypass = False if random.randint(0, 1) == 1: self.entity.velocity[0], self.entity.velocity[1] = 0, 0 movement = random.choice(["self.entity.velocity[0] = -45; self.EntityDirection = 'left'; self.EntityDirection2 = 'left'", "self.entity.velocity[0] = 45; self.EntityDirection = 'right'; self.EntityDirection2 = 'right'", "self.entity.velocity[1] = -45; self.EntityDirection = 'up'; self.EntityDirection1 = 'up'", "self.entity.velocity[1] = 45; self.EntityDirection = 'down'; self.EntityDirection1 = 'down'"]) exec(movement) def EntityAnimation(self, direction, number, character="hero"): self.entVel = self.entity.velocity self.counter += 1 if self.EntityDirection1 == "still" and self.EntityDirection2 == "still": if self.EntityDirection == "left": self.entity = Entity('Tiles/' +character +'/walking_left/walking_left1.png') if self.EntityDirection == "right": self.entity = Entity('Tiles/' +character +'/walking_right/walking_right1.png') if self.EntityDirection == "up": self.entity = Entity('Tiles/' +character +'/walking_up/walking_up1.png') if self.EntityDirection == "down": self.entity = Entity('Tiles/' +character +'/walking_down/walking_down1.png') else: self.entity = Entity('Tiles/' +character +'/walking_' +direction +'/walking_' +direction +str(number) +'.png') self.entity.velocity = self.entVel def EntMoveBack(self): #self.deep_thought(self, True) # Comment this to disable the 'AI' pass def map_change(self, map, target=False): # Does what it says on the tin mapfile = get_map(map) tmx_data = load_pygame(mapfile) self.tmx_data = tmx_data map_data = pyscroll.data.TiledMapData(tmx_data) self.walls = list() for object in tmx_data.objects: self.walls.append(pygame.Rect( object.x, object.y, object.width, object.height)) # creates new 'camera' self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size()) self.map_layer.zoom = 2 self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4) #creates a new Hero to go on our new camera self.hero = Hero('Tiles/hero/character_still.png') try: self.hero.position = (target) except TypeError: self.hero.position = self.map_layer.map_rect.center self.map = stats['map'][:-4].lower() self.map = self.map.lstrip("m") # Fix that stupid bug that changes "maze1" to "ze1" self.map = self.map.lstrip("aps/") def switcher(self): # Bunch of IF statements to decide if we're at a door or not, then changes the map. if len(objectX) == len(objectY) == len(targetPosX) == len(targetPosY) == len(currentMap) == \ len(targetMap) == len(animationDirection) == len(targetMapFile) == len(objectType): heroPos = [0, 0] heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1] for i in range(len(objectX)): if self.map == currentMap[i]: if self.hero.position[0] - 15 <= int(objectX[i]) <= self.hero.position[0] + 15: if self.hero.position[1] - 15 <= int(objectY[i]) <= self.hero.position[1] + 15: if objectType[i] == "door": used[i] = True self.map_change(targetMapFile[i]) self.map = targetMap[i] stats['map'] = targetMapFile[i] heroPos = (int(targetPosX[i]), int(targetPosY[i])) self.animation(animationDirection[i], 1) self.hero.position = heroPos return False elif objectType[i] == "chest": keyset, self.menu = "chest", "chest" if used[i] == False: if chestContents[i] == None and used[i] == False: used[i] = True pickle.dump(used, open(os.path.join("data", "saves", "used.dat"), "wb")) chestContents[i] = self.genchests() pickle.dump(chestContents, open(os.path.join("data", "saves", "chestContents.dat"), "wb")) self.chestNo = i return False def generate_surrounding_maps(self): heroPos = [0, 0] heroPos = self.hero.position if int(self.hero.position[0]) in range((self.tmx_data.width*32)-64, (self.tmx_data.width*32)): target = (32, heroPos[1]) self.grid[0] = self.grid[0]+1 try: self.map_change(str(self.grid[0]+1) +", "+ str(self.grid[1]) +".tmx", target) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" self.animation("right", 1) target = (32, heroPos[1]) #self.hero.position = target except FileNotFoundError: self.generate_new_map(4, 16, 2, self.grid, target) elif int(self.hero.position[1]) in range((self.tmx_data.height*32)-64, self.tmx_data.width*32): target = (heroPos[0], 32) self.grid[1] = self.grid[1]+1 try: self.map_change(str(self.grid[0]) +", "+ str(self.grid[1]+1) +".tmx", target) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1] self.animation("up", 1) except FileNotFoundError: self.generate_new_map(4, 16, 2, self.grid, target) elif int(self.hero.position[0]) in range(0, 64): target = (self.tmx_data.width*32 - 32, heroPos[1]) self.grid[0] = self.grid[0]-1 try: self.map_change(str(self.grid[0]-1) +", "+ str(self.grid[1]) +".tmx", target) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1] self.animation("left", 1) #self.hero.position = target except FileNotFoundError: self.generate_new_map(4, 16, 2, self.grid, target) elif int(self.hero.position[1]) in range(0, 64): target = (heroPos[0], self.tmx_data.height*32 - 32) self.grid[1] = self.grid[1]-1 try: self.map_change(str(self.grid[0]) +", "+ str(self.grid[1]-1) +".tmx", target) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1] self.animation("down", 1) #self.hero.position = target except FileNotFoundError: self.generate_new_map(4, 16, 2, self.grid, target) else: pass def generate_new_map(self, octaves, freq, area, target, position): command = "{}/lib/generate/__init__.py".format(os.getcwd()) if sys.platform.startswith('win32'): executeable = ("Python35\python.exe") elif sys.platform.startswith('linux'): executeable = ("python3.5") for y in range(self.grid[1] + eval("-"+ str(area)),self.grid[1] + area): for x in range(self.grid[0] + eval("-"+ str(area)),self.grid[0] + area): if os.path.isfile("data/maps/"+str(x)+", "+str(y)+".tmx"): pass else: p = subprocess.Popen([executeable, command, ("data/maps/"+ str(x)+", "+str(y)+".tmx"), str(octaves), str(freq), str(x), str(y)], close_fds=True) try: if p is not None: disp_width, disp_height = pygame.display.get_surface().get_size() #self.blit_inventory("speach", "Generating Map... Please Wait...") self.speach(disp_width, disp_height, "Generating Map... Please Wait...") pygame.display.update() p.wait() self.map_change((str(target[0])+", "+str(target[1])+".tmx"), position) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" except UnboundLocalError: pass def draw(self, surface): self.group.center(self.hero.rect.center) # draw the map and all sprites self.group.draw(surface) def speach(self, dispWidth, dispHeight, text): ## text = "Laudem bonorum salutandi pri te, tollit melius delicata mel cu,\ ## eu mea ullum legimus. Probo debitis te vel. Labores vulputate \ ## argumentum sea id. Cibo vitae vocent eos no, ne odio molestiae\ ## duo." screen.blit(pygame.transform.scale(load_image(os.path.join( "images", "gui", "speach.png")), (dispWidth, 150)), (0, dispHeight-150)) text = textwrap.wrap(text, width=95) for i, line in enumerate(text): text_blit = pixel_font.render(line, False, pygame.Color('white')) screen.blit(text_blit, (60, dispHeight-110 + 25*i)) def map_generate(self, output, octaves, freq, x, y): command = "{}/lib/generate/__init__.py".format(os.getcwd()) if sys.platform.startswith('win32'): executeable = ("Python35\python.exe") elif sys.platform.startswith('linux'): executeable = ("python3.5") subprocess.Popen([executeable, command, output, str(octaves), str(freq), str(x), str(y)],close_fds=True) def handle_input(self, keyset): """ Handle pygame input events """ poll = pygame.event.poll event = poll() while event: if event.type == QUIT: self.running = False pygame.quit() break elif event.type == KEYDOWN: if keyset == "game": if event.key == K_EQUALS: self.map_layer.zoom += .25 elif event.key == K_MINUS: value = self.map_layer.zoom - .25 if value > 0: self.map_layer.zoom = value else: self.map_layer.zoom = 0.1 elif event.key == K_KP0: try: if self.switcher() == True: self.generate_surrounding_maps() except FileNotFoundError: print("Exception Caught") pass elif event.key == K_e: self.menu = "inventory" pass if event.key == K_ESCAPE: for i in attack_stats_types: stats[i] = attack_stats[i] pickle.dump(stats, open(os.path.join("data", "saves", "save.dat"), "wb")) pickle.dump(inventory, open(os.path.join("data", "saves", "inventory.dat"), "wb")) self.running = False pygame.quit() print(" ") sleep(0.5) print("Shutdown... Complete") sys.exit() break if keyset != "game": if event.key == K_ESCAPE: self.menu = "game" pass if keyset == "inventory": if event.key == K_r: self.genchests() if keyset == "chest": if event.key == K_r: chestContents[self.chestNo] = self.genchests() if event.key == K_t: if taken[self.chestNo] != True: self.takeChest() taken[self.chestNo] = True pickle.dump(taken, open(os.path.join("data", "saves", "taken.dat"), "wb")) if keyset == "attack": pass #Basically just debug keys if event.key == K_KP1: self.menu = "game" pass elif event.key == K_KP2: self.map_change(FOREST) self.map = "forest" elif event.key == K_KP3: self.generate_new_map(4, 16, 3) pass elif event.key == K_KP4: self.map_generate(str(self.grid[0]) +", "+ str(self.grid[1]) +".tmx", 4, 16.0, self.grid[0], self.grid[1]) pass elif event.key == K_KP5: self.enemy_stats = self.gen_enemy(attack_stats, enemy_stats) self.menu = "attack" pass elif event.key == K_KP6: print("X :" +str(int(self.hero.position[0])) + ", Y: " +str(int(self.hero.position[1])) + ", Map: "+ self.map) pass elif event.key == K_KP7: print(str(pygame.mouse.get_pos())) pass elif event.key == K_KP8: sleep(0.5) elif event.key == K_KP9: editor = db_interface.Editor() conn = sqlite3.connect('data/saves/data.db') c = conn.cursor() for var in vars: exec("del "+var+"[:]") for data in c.execute("SELECT {} FROM csv".format(var)): data = str(data[0]) exec("{}.append(\"{}\")".format(var, data)) pass elif event.key == K_F11: for m in screeninfo.get_monitors(): displ = str(m) w, h, mx, c = displ.split(", ") if self.fullscreen: self.fullscreen = False screen = init_screen(1024, 700, pygame.HWSURFACE | pygame.FULLSCREEN ) else: self.fullscreen = True screen = init_screen(w, h, pygame.HWSURFACE | pygame.RESIZABLE ) pygame.display.toggle_fullscreen() elif event.type == VIDEORESIZE: self.map_layer.set_size((event.w, event.h)) dispHeight = event.h dispWidth = event.w event = poll() # using get_pressed is slightly less accurate than testing for events # but is much easier to use. if keyset == "game": pressed = pygame.key.get_pressed() if pressed[K_UP]: self.hero.velocity[1] = -HERO_MOVE_SPEED self.direction = "up" self.direction2 = "up" elif pressed[K_DOWN]: self.hero.velocity[1] = HERO_MOVE_SPEED self.direction = "down" self.direction2 = "down" elif pressed[K_w]: self.hero.velocity[1] = -HERO_SPRINT_SPEED self.direction = "up" self.direction2 = "up" elif pressed[K_s]: self.hero.velocity[1] = HERO_SPRINT_SPEED self.direction = "down" self.direction2 = "down" else: self.hero.velocity[1] = 0 self.direction2 = "still" if pressed[K_LEFT]: self.hero.velocity[0] = -HERO_MOVE_SPEED self.direction = "left" self.direction1 = "left" elif pressed[K_RIGHT]: self.hero.velocity[0] = HERO_MOVE_SPEED self.direction = "right" self.direction1 = "right" elif pressed[K_a]: self.hero.velocity[0] = -HERO_SPRINT_SPEED self.direction = "left" self.direction1 = "left" elif pressed[K_d]: self.hero.velocity[0] = HERO_SPRINT_SPEED self.direction = "right" self.direction1 = "right" else: self.hero.velocity[0] = 0 self.direction1 = "still" if self.direction1 == "still" and self.direction2 == "still": self.direction = "still" def update(self, dt): """ Tasks that occur over time should be handled here """ self.group.update(dt) # check if the sprite's feet are colliding with wall # sprite must have a rect called feet, and move_back method, # otherwise this will fail for sprite in self.group.sprites(): if sprite.feet.collidelist(self.walls) > -1: sprite.move_back(dt) def animation(self, direction, number): if self.direction1 == "still" and self.direction2 == "still": if self.direction == "left": self.hero = Hero('Tiles/hero/walking_left/walking_left1.png') if self.direction == "right": self.hero = Hero('Tiles/hero/walking_right/walking_right1.png') if self.direction == "up": self.hero = Hero('Tileshero/walking_up/walking_up1.png') if self.direction == "down": self.hero = Hero('Tiles/hero/walking_down/walking_down1.png') else: self.hero = Hero('Tiles/hero/walking_' +direction +'/walking_' +direction +str(number) +'.png') def genchests(self): wr = WeightedRandomizer(itemsProbability) self.taken = False chest.clear() numItems = random.randint(1, random.randint(2, 4)) if random.randint(0, 3) < 1: numItems += 1 elif random.randint(0, 9) < 2: numItems += 2 elif random.randint(0, 18) < 2: numItems += 5 for i in range(0, numItems): item = wr.random() while item in chest: item = wr.random() chest.append(item) return chest def gen_enemy(self, player_stats, enemy_stat): stats = attack_stats_types stat = player_stats for i in range(len(player_stats)): j = stats[i] try: enemy_stat[stats[i]] = int((stat[j]-(stat[j]*0.2)) + random.randint(0, int(stat[j]*0.4))) except TypeError: enemy_stat[j] = choice(attack_types) return enemy_stat pass def player_attack(): type = None while type not in attack_types: type = input("[ QUESTION ] Enter attack type. ") if type not in attack_types: print("[ ERROR ] Attack type {} not found. Must be {}".format(type, attack_types)) else: break return type pass def attack(self, attacker_stats, defender_stats, player_attack_type): fraction = attacker_stats['strength'] / defender_stats['blocking'] print("[ INFO ] Defender attack type: {}".format(defender_stats['attack'])) if player_attack_type != defender_stats['attack']: if fraction > (0.8 + (randint(0, 40)/100)): attacker_stats['health'] -= int(fraction*10) pass # Attacker Win else: defender_stats['health'] -= int(fraction*10) pass # Attacker Loss elif player_attack_type == attacker_stats['attack']: # Better odds here if fraction > (0.9 + (randint(0, 40)/100)): attacker_stats['health'] -= int(fraction*10) pass # Attacker Win else: defender_stats['health'] -= int(fraction*10) pass # Attacker Loss else: if fraction > (0.70 + (randint(0, 40)/100)): # Odds are worse here attacker_stats['health'] -= int(fraction*10) pass # Attacker Win else: defender_stats['health'] -= int(fraction*10) pass # Attacker Loss print("[ INFO ] Attacker: {} Defender: {}".format(attacker_stats['health'], defender_stats['health'])) print("[ INFO ] Health to be lost: {}".format(int(fraction*10))) return attacker_stats, defender_stats def blit_inventory(self, screenMode, speach=None): if screenMode != "game": xCounter, counter, OverCounter = 0, 0, 0 dispWidth, dispHeight = pygame.display.get_surface().get_size() guiX = (dispWidth / 2) - 175 guiY = (dispHeight / 2) - 165 screen.blit(load_image(os.path.join("images", "gui", "transparent.png")),( 0, 0)) screen.blit(load_image(os.path.join("images", "gui", screenMode +".png")),(guiX, guiY)) if screenMode == "inventory" or screenMode == "chest": dt = (clock.tick() / 500) clock.tick(self.fps) if len(inventory) > 0: for i in range(0, len(inventory)): OverCounter += 1 if xCounter >= 9: counter += 1 xCounter = 0 screen.blit(load_image(os.path.join("images", "items",\ str(items[inventory[i]])+".png")), (guiX + 16 + 36*xCounter, guiY + 168 + 36*counter)) xCounter += 1 if screenMode == "chest" and chestContents[self.chestNo] != None: itemNo = 0 for i in range(0, len(chestContents[self.chestNo])): screen.blit(load_image(os.path.join("images", "items",\ items[str(chestContents[self.chestNo][i])]\ +".png")), (guiX + 123 + 36*itemNo,\ guiY + 34 + int(35 * (i/3)) - int(35 * (i/3)) % 35)) if itemNo < 2: itemNo += 1 else: itemNo = 0 if screenMode == "speach": self.speach(dispWidth, dispHeight, speach) if screenMode == "attack": picture = load_image(os.path.join("Tiles", "hero", "walking_down", "walking_down1.png")) picture = pygame.transform.scale(picture, (100, 100)) rect = picture.get_rect() rect = rect.move((guiX + 50, guiY + 28)) screen.blit(picture, rect) text = font.render("Player : Enemy", True, pygame.Color('black')) screen.blit(text, (guiX + 172, guiY + 45)) text = "Health: "+str(attack_stats['health'])+" Skill: "+str(attack_stats['skill'])+" Attack: "+str(attack_stats['attack']) text_render = pixel_font.render(text, False, pygame.Color('gray27')) screen.blit(text_render, (guiX+20, guiY+290)) for i, attack in enumerate(attack_types): text = load_font(30, "data/PixelFont.ttf").render(attack, False, pygame.Color('black')) screen.blit(text, (guiX+172, guiY+25+28*(i+2))) # if pygame.mouse.get_pressed()[0] == 1: #print(pygame.mouse.get_pos()) mouse_pos = pygame.mouse.get_pos() if guiX+160 < mouse_pos[0] and guiX+330 > mouse_pos[0]: for i, attack in enumerate(attack_types): if guiY+25+28*(i+2) < mouse_pos[1] and (guiY+25+28*(i+2))+28 > mouse_pos[1]: print(attack) self.attack(attack_stats, enemy_stats, attack) else: pass pass def takeChest(self): if len(inventory) < 27: if chestContents[self.chestNo] != None: for i in range(0, (len(chestContents[self.chestNo]))): #print(i) inventory.append(chestContents[self.chestNo][i]) chestContents[self.chestNo][:] = [] pickle.dump(chestContents, open(os.path.join("data", "saves", "chestContents.dat"), "wb")) def run(self): screenMode = pygame.RESIZABLE oldPlay = stats['playTime'] clock = pygame.time.Clock() self.running = True self.grid = [0, 0] debug = True dispWidth, dispHeight = 1024, 768 self.menu = "game" game_time = pygame.time.get_ticks() playTime = font.render("Timer: ", False, pygame.Color('white')) minutes = 0 self.map = stats['map'][:-4].lower() self.map = self.map.lstrip("m") # Fix that stupid bug that changes "maze1" to "ze1" self.map = self.map.lstrip("aps/") try: while self.running: dt = (clock.tick() / 500) clock.tick(self.fps) if self.menu == "game": #self.deep_thought() if self.counter2 % 7 == 0: heroPos = self.hero.position self.animation(self.direction, self.counter) self.hero.position = heroPos #entityPos = self.entity.position #self.EntityAnimation(self.EntityDirection, self.counter, "princess") #self.entity.position = entityPos self.counter += 1 guiX = (dispWidth / 2) - 175 guiY = (dispHeight / 2) - 165 self.group.remove(self.hero) #self.group.remove(self.entity) self.group.empty() self.group.add(self.hero) #self.group.add(self.entity) self.counter2 += 1 if self.counter > 8: self.counter = 1 stats['pos'] = self.hero.position currentTime = systime() seconds = currentTime - gameStart + oldPlay dispWidth, dispHeight = pygame.display.get_surface().get_size() stats['playTime'] = seconds if debug == True and self.counter2 % 1 == 0: location = font.render("Position: " + str(round(round(self.hero.position[0], -1) / 10)) + ", " + str(round(round(self.hero.position[1], -1) / 10)), False, pygame.Color('white')) mapdebug = font.render("Map Name: " + str(self.map), False, pygame.Color('white')) minutes = seconds // 60 secondsDisp = seconds % 60 if minutes < 1: minutes = 0 if secondsDisp == 60: secondsDisp = 0 minutes += 1 fps = font.render("FPS:" + str(int(clock.get_fps())), False, pygame.Color('white')) screen.blit(fps, (50, 50)) screen.blit(playTime, (50,100)) screen.blit(location, (50,75)) screen.blit(mapdebug, (50, 125)) playTime = font.render("Timer: " + str(floor(minutes)) + " : " + str(round(secondsDisp)), True, pygame.Color('white')) screen.blit(playTime, (50,100)) self.blit_inventory(str(self.menu)) pygame.display.update() #pygame,display.flip() self.handle_input(self.menu) self.update(dt) self.draw(screen) except KeyboardInterrupt: self.running = False pygame.quit()
class QuestGame(object): """ This class is a basic game. This class will load data, create a pyscroll group, a hero object. It also reads input and moves the Hero around the map. Finally, it uses a pyscroll group to render the map and Hero. """ filename = get_map(MAP_FILENAME) def __init__(self, state): if state == False: screenMode = pygame.RESIZABLE # true while running. self.running = False self.clock = pygame.time.Clock() self.direction = "still" self.fps = 180 self.counter = 1 self.counter2 = 1 heroPos1 = False # load data from pytmx tmx_data = load_pygame(self.filename) mapPlay = load_pygame(get_map(stats['map'])) # create new data source for pyscroll map_data = pyscroll.data.TiledMapData(mapPlay) # setup level geometry with simple pygame rects, loaded from pytmx. self.walls = list() for object in mapPlay.objects: self.walls.append(pygame.Rect( object.x, object.y, object.width, object.height)) # create new renderer (camera) self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size()) self.map_layer.zoom = 2 self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4) self.hero = Hero('Tiles/character/character_still.png') self.hero.position = stats['pos'] # add our hero to the group self.group.add(self.hero) def map_change(self, map): mapfile = get_map(map) tmx_data = load_pygame(mapfile) print(tmx_data) map_data = pyscroll.data.TiledMapData(tmx_data) self.walls = list() for object in tmx_data.objects: self.walls.append(pygame.Rect( object.x, object.y, object.width, object.height)) self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size()) self.map_layer.zoom = 2 self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4) self.hero = Hero('Tiles/character/character_still.png') self.hero.position = self.map_layer.map_rect.center def switcher(self): if len(doorX) == len(doorY) == len(targetPosX) == len(targetPosY) == len(currentMap) == len(targetMap) == len(animationDirection) == len(targetMapFile): for i in range(len(doorX)): if self.map == currentMap[i]: if self.hero.position[0] - 15 <= doorX[i] <= self.hero.position[0] + 15: print("OK!") if self.hero.position[1] - 15 <= doorY[i] <= self.hero.position[1] + 15: self.map_change(targetMapFile[i]) self.map = targetMap[i] stats['map'] = targetMapFile[i] heroPos = (targetPosX[i], targetPosY[i]) self.animation(animationDirection[i], 1) self.hero.position = heroPos print("Yeah!") break else: print("Nope!") print(str(doorX[i]) +" " +str(self.hero.position[0])) print(str(doorY[i]) +" " +str(self.hero.position[1])) else: #print("Never!") pass else: print("Error: Invalid number of door entries.") ## elif self.map == "maze1": ## #HOUSE2 ## if self.hero.position[0] >= -20 and self.hero.position[0] <= 20 and self.hero.position[1] <= 20 and self.hero.position[1] >= -15: ## self.map_change(HOUSE1) ## stats['map'] = HOUSE1 ## self.map = "house1" ## heroPos = 206, 48 ## self.animation("down", 1) ## self.hero.position = heroPos ## self.group.remove(self) ## self.group.empty() ## self.group.add(self.hero) def draw(self, surface): self.group.center(self.hero.rect.center) # draw the map and all sprites self.group.draw(surface) def handle_input(self, keyset): """ Handle pygame input events """ poll = pygame.event.poll event = poll() while event: if event.type == QUIT: self.running = False pygame.quit() break elif event.type == KEYDOWN: if keyset == "game": if event.key == K_EQUALS: self.map_layer.zoom += .25 elif event.key == K_MINUS: value = self.map_layer.zoom - .25 if value > 0: self.map_layer.zoom = value elif event.key == K_KP0: self.switcher() pass elif event.key == K_e: self.menu = "inventory" print("Inventory") pass if event.key == K_ESCAPE: pickle.dump(stats, open(os.path.join("data", "saves", "save.dat"), "wb")) pickle.dump(inventory, open(os.path.join("data", "saves", "inventory.dat"), "wb")) self.running = False pygame.quit() print(" ") sleep(0.5) print("Shutdown... Complete") sys.exit() break if keyset == "inventory": if event.key == K_ESCAPE: self.menu = "game" print("Game") pass if event.key == K_r: self.genchests() elif event.key == K_KP1: self.menu = "game" print("Game") pass elif event.key == K_KP2: self.map_change(FOREST) self.map = "forest" elif event.key == K_KP3: self.menu = "inventory" print("Inventory") pass elif event.key == K_KP4: pass elif event.key == K_KP5: pass elif event.key == K_KP6: print("X :" +str(self.hero.position[0]) +", Y: " +str(self.hero.position[1])) pass elif event.key == K_KP7: print(str(pygame.mouse.get_pos())) pass elif event.key == K_KP8: sleep(0.5) elif event.key == K_KP9: self.genchests() pass elif event.key == K_F11: pygame.display.toggle_fullscreen() elif event.type == VIDEORESIZE: self.map_layer.set_size((event.w, event.h)) dispHeight = event.h dispWidth = event.w event = poll() # using get_pressed is slightly less accurate than testing for events # but is much easier to use. if keyset == "game": pressed = pygame.key.get_pressed() if pressed[K_UP]: self.hero.velocity[1] = -HERO_MOVE_SPEED self.direction = "up" self.direction2 = "up" elif pressed[K_DOWN]: self.hero.velocity[1] = HERO_MOVE_SPEED self.direction = "down" self.direction2 = "down" elif pressed[K_w]: self.hero.velocity[1] = -HERO_SPRINT_SPEED self.direction = "up" self.direction2 = "up" elif pressed[K_s]: self.hero.velocity[1] = HERO_SPRINT_SPEED self.direction = "down" self.direction2 = "down" else: self.hero.velocity[1] = 0 self.direction2 = "still" if pressed[K_LEFT]: self.hero.velocity[0] = -HERO_MOVE_SPEED self.direction = "left" self.direction2 = "left" elif pressed[K_RIGHT]: self.hero.velocity[0] = HERO_MOVE_SPEED self.direction = "right" self.direction2 = "right" elif pressed[K_a]: self.hero.velocity[0] = -HERO_SPRINT_SPEED self.direction = "left" self.direction2 = "left" elif pressed[K_d]: self.hero.velocity[0] = HERO_SPRINT_SPEED self.direction = "right" self.direction2 = "right" else: self.hero.velocity[0] = 0 self.direction1 = "still" if self.direction1 == "still" and self.direction2 == "still": self.direction = "still" def update(self, dt): """ Tasks that occur over time should be handled here """ self.group.update(dt) # check if the sprite's feet are colliding with wall # sprite must have a rect called feet, and move_back method, # otherwise this will fail for sprite in self.group.sprites(): if sprite.feet.collidelist(self.walls) > -1: sprite.move_back(dt) def animation(self, direction, number): self.counter += 1 if self.direction1 == "still" and self.direction2 == "still": if self.direction == "left": self.hero = Hero('Tiles/character/walking_left/walking_left1.png') if self.direction == "right": self.hero = Hero('Tiles/character/walking_right/walking_right1.png') if self.direction == "up": self.hero = Hero('Tiles/character/walking_up/walking_up1.png') if self.direction == "down": self.hero = Hero('Tiles/character/walking_down/walking_down1.png') else: self.hero = Hero('Tiles/character/walking_' +direction +'/walking_' +direction +str(number) +'.png') self.group.remove(self) self.group.empty() self.group.add(self.hero) def genchests(self): itm1, itm2, itm3, itm4, itm5, itm6 = "0", "0", "0", "0", "0", "0" numberItems = random.randint(1, 6) for i in range(0, numberItems): item = random.randint(1, 5) if i == 1: itm1 = item if i == 2: itm2 = item if i == 3: itm3 = item if i == 4: itm4 = item if i == 5: itm5 = item if i == 6: itm6 = item print("Found Chest With "+str(numberItems) +" Items: " +str(itm1) +" " +str(itm2) +" " +str(itm3) +" " +str(itm4) +" " +str(itm5) +" " +str(itm6) +" ") if 1 in(itm1, itm2, itm3, itm4, itm5, itm6): inventory['sword'] = True else: inventory['sword'] = False if 2 in(itm1, itm2, itm3, itm4, itm5, itm6): inventory['axe'] = True else: inventory['axe'] = False if 3 in(itm1, itm2, itm3, itm4, itm5, itm6): inventory['shovel'] = True else: inventory['shovel'] = False if 4 in(itm1, itm2, itm3, itm4, itm5, itm6): inventory['bow'] = True else: inventory['bow'] = False def run(self): screenMode = pygame.RESIZABLE self.map = stats['map'][:-4].lower() self.map = self.map.lstrip("maps/") oldPlay = stats['playTime'] clock = pygame.time.Clock() self.running = True debug = True dispWidth, dispHeight = 1024, 768 self.menu = "game" game_time = pygame.time.get_ticks() playTime = font.render("Timer: ", False, pygame.Color('white')) minutes = 0 try: while self.running: dt = (clock.tick() / 500) clock.tick(self.fps) if self.counter2 == 5: heroPos = self.hero.position self.animation(self.direction, self.counter) self.counter += 1 self.counter2 = 0 guiX = (dispWidth / 2) - 175 guiY = (dispHeight / 2) - 165 self.hero.position = heroPos self.counter2 += 1 if self.counter > 9: self.counter = 1 stats['pos'] = self.hero.position currentTime = systime() seconds = currentTime - gameStart + oldPlay dispWidth, dispHeight = pygame.display.get_surface().get_size() stats['playTime'] = seconds self.group.remove(self) self.group.add(self.hero) if debug == True: location = font.render("Position: " + str(round(round(self.hero.position[0], -1) / 10)) + ", " + str(round(round(self.hero.position[1], -1) / 10)), False, pygame.Color('white')) fps = font.render("FPS:" + str(int(clock.get_fps())), False, pygame.Color('white')) mapdebug = font.render("Map Name: " + str(self.map), False, pygame.Color('white')) minutes = seconds // 60 secondsDisp = seconds % 60 if minutes < 1: minutes = 0 if secondsDisp == 60: secondsDisp = 0 minutes += 1 playTime = font.render("Timer: " + str(floor(minutes)) + " : " + str(round(secondsDisp)), True, pygame.Color('white')) screen.blit(playTime, (50,100)) screen.blit(fps, (50, 50)) screen.blit(location, (50,75)) screen.blit(mapdebug, (50, 125)) if self.menu == "inventory": screen.blit(load_image(os.path.join("Images", "transparent.png")),( 0, 0)) screen.blit(load_image(os.path.join("Images", "inventory.png")),(guiX, guiY)) if inventory["sword"] == True: screen.blit(load_image(os.path.join("Images", "sword.png")),( guiX + 16, guiY + 168)) if inventory["axe"] == True: screen.blit(load_image(os.path.join("Images", "axe.png")),( guiX + 52, guiY + 168)) if inventory["bow"] == True: screen.blit(load_image(os.path.join("Images", "bow.png")),( guiX + 88, guiY + 168)) if inventory["shovel"] == True: screen.blit(load_image(os.path.join("Images", "shovel.png")),( guiX + 124, guiY + 168)) pygame.display.update() self.handle_input(self.menu) self.update(dt) self.draw(screen) except KeyboardInterrupt: self.running = False pygame.quit()
class QuestGame(object): """ This class is a basic game. This class will load data, create a pyscroll group, a hero object. It also reads input and moves the Hero around the map. Finally, it uses a pyscroll group to render the map and Hero. """ filename = get_map(MAP_FILENAME) counter = 1 counter2 = 1 def __init__(self, state): if state == False: self.fullscreen = False # true while running. self.running = False self.clock = pygame.time.Clock() # create all the directio variables self.direction = "still" self.EntityDirection = "still" self.EntityDirection1, self.EntityDirection2 = "still", "still" self.fps = 1000 self.bypass = False entityPos1, heroPos1 = False, False # load data from pytmx tmx_data = load_pygame(self.filename) self.tmx_data = tmx_data mapPlay = load_pygame(get_map(stats['map'])) # create new data source for pyscroll map_data = pyscroll.data.TiledMapData(mapPlay) # setup level geometry with simple pygame rects, loaded from pytmx. self.walls = list() for object in mapPlay.objects: self.walls.append( pygame.Rect(object.x, object.y, object.width, object.height)) # create new renderer (camera) self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size()) self.map_layer.zoom = 2 self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4) self.hero = Hero('Tiles/hero/character_still.png') self.entity = Entity('Tiles/hero/character_still.png') self.hero.position = stats['pos'] self.entity.position = stats['pos'] # add our hero to the group self.group.add(self.hero) #self.group.add(self.entity) self.entVel = (0, 0) def deep_thought(self): # The 'AI' function, needs work if self.counter2 % 75 == 0 or self.bypass == True: self.bypass = False if random.randint(0, 1) == 1: self.entity.velocity[0], self.entity.velocity[1] = 0, 0 movement = random.choice([ "self.entity.velocity[0] = -45; self.EntityDirection = 'left'; self.EntityDirection2 = 'left'", "self.entity.velocity[0] = 45; self.EntityDirection = 'right'; self.EntityDirection2 = 'right'", "self.entity.velocity[1] = -45; self.EntityDirection = 'up'; self.EntityDirection1 = 'up'", "self.entity.velocity[1] = 45; self.EntityDirection = 'down'; self.EntityDirection1 = 'down'" ]) exec(movement) def EntityAnimation(self, direction, number, character="hero"): self.entVel = self.entity.velocity self.counter += 1 if self.EntityDirection1 == "still" and self.EntityDirection2 == "still": if self.EntityDirection == "left": self.entity = Entity('Tiles/' + character + '/walking_left/walking_left1.png') if self.EntityDirection == "right": self.entity = Entity('Tiles/' + character + '/walking_right/walking_right1.png') if self.EntityDirection == "up": self.entity = Entity('Tiles/' + character + '/walking_up/walking_up1.png') if self.EntityDirection == "down": self.entity = Entity('Tiles/' + character + '/walking_down/walking_down1.png') else: self.entity = Entity('Tiles/' + character + '/walking_' + direction + '/walking_' + direction + str(number) + '.png') self.entity.velocity = self.entVel def EntMoveBack(self): #self.deep_thought(self, True) # Comment this to disable the 'AI' pass def map_change(self, map, target=False): # Does what it says on the tin mapfile = get_map(map) tmx_data = load_pygame(mapfile) self.tmx_data = tmx_data map_data = pyscroll.data.TiledMapData(tmx_data) self.walls = list() for object in tmx_data.objects: self.walls.append( pygame.Rect(object.x, object.y, object.width, object.height)) # creates new 'camera' self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size()) self.map_layer.zoom = 2 self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4) #creates a new Hero to go on our new camera self.hero = Hero('Tiles/hero/character_still.png') try: self.hero.position = (target) except TypeError: self.hero.position = self.map_layer.map_rect.center self.map = stats['map'][:-4].lower() self.map = self.map.lstrip( "m") # Fix that stupid bug that changes "maze1" to "ze1" self.map = self.map.lstrip("aps/") def switcher( self ): # Bunch of IF statements to decide if we're at a door or not, then changes the map. if len(objectX) == len(objectY) == len(targetPosX) == len(targetPosY) == len(currentMap) == \ len(targetMap) == len(animationDirection) == len(targetMapFile) == len(objectType): heroPos = [0, 0] heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[ 1] for i in range(len(objectX)): if self.map == currentMap[i]: if self.hero.position[0] - 15 <= int( objectX[i]) <= self.hero.position[0] + 15: if self.hero.position[1] - 15 <= int( objectY[i]) <= self.hero.position[1] + 15: if objectType[i] == "door": used[i] = True self.map_change(targetMapFile[i]) self.map = targetMap[i] stats['map'] = targetMapFile[i] heroPos = (int(targetPosX[i]), int(targetPosY[i])) self.animation(animationDirection[i], 1) self.hero.position = heroPos return False elif objectType[i] == "chest": keyset, self.menu = "chest", "chest" if used[i] == False: if chestContents[i] == None and used[ i] == False: used[i] = True pickle.dump( used, open( os.path.join( "data", "saves", "used.dat"), "wb")) chestContents[i] = self.genchests() pickle.dump( chestContents, open( os.path.join( "data", "saves", "chestContents.dat"), "wb")) self.chestNo = i return False def generate_surrounding_maps(self): heroPos = [0, 0] heroPos = self.hero.position if int(self.hero.position[0]) in range((self.tmx_data.width * 32) - 64, (self.tmx_data.width * 32)): target = (32, heroPos[1]) self.grid[0] = self.grid[0] + 1 try: self.map_change( str(self.grid[0] + 1) + ", " + str(self.grid[1]) + ".tmx", target) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" self.animation("right", 1) target = (32, heroPos[1]) #self.hero.position = target except FileNotFoundError: self.generate_new_map(4, 16, 2, self.grid, target) elif int(self.hero.position[1]) in range( (self.tmx_data.height * 32) - 64, self.tmx_data.width * 32): target = (heroPos[0], 32) self.grid[1] = self.grid[1] + 1 try: self.map_change( str(self.grid[0]) + ", " + str(self.grid[1] + 1) + ".tmx", target) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" heroPos[0], heroPos[1] = self.hero.position[ 0], self.hero.position[1] self.animation("up", 1) except FileNotFoundError: self.generate_new_map(4, 16, 2, self.grid, target) elif int(self.hero.position[0]) in range(0, 64): target = (self.tmx_data.width * 32 - 32, heroPos[1]) self.grid[0] = self.grid[0] - 1 try: self.map_change( str(self.grid[0] - 1) + ", " + str(self.grid[1]) + ".tmx", target) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" heroPos[0], heroPos[1] = self.hero.position[ 0], self.hero.position[1] self.animation("left", 1) #self.hero.position = target except FileNotFoundError: self.generate_new_map(4, 16, 2, self.grid, target) elif int(self.hero.position[1]) in range(0, 64): target = (heroPos[0], self.tmx_data.height * 32 - 32) self.grid[1] = self.grid[1] - 1 try: self.map_change( str(self.grid[0]) + ", " + str(self.grid[1] - 1) + ".tmx", target) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" heroPos[0], heroPos[1] = self.hero.position[ 0], self.hero.position[1] self.animation("down", 1) #self.hero.position = target except FileNotFoundError: self.generate_new_map(4, 16, 2, self.grid, target) else: pass def generate_new_map(self, octaves, freq, area, target, position): command = "{}/lib/generate/__init__.py".format(os.getcwd()) if sys.platform.startswith('win32'): executeable = ("Python35\python.exe") elif sys.platform.startswith('linux'): executeable = ("python3.5") for y in range(self.grid[1] + eval("-" + str(area)), self.grid[1] + area): for x in range(self.grid[0] + eval("-" + str(area)), self.grid[0] + area): if os.path.isfile("data/maps/" + str(x) + ", " + str(y) + ".tmx"): pass else: p = subprocess.Popen([ executeable, command, ("data/maps/" + str(x) + ", " + str(y) + ".tmx"), str(octaves), str(freq), str(x), str(y) ], close_fds=True) try: if p is not None: disp_width, disp_height = pygame.display.get_surface( ).get_size() #self.blit_inventory("speach", "Generating Map... Please Wait...") self.speach(disp_width, disp_height, "Generating Map... Please Wait...") pygame.display.update() p.wait() self.map_change( (str(target[0]) + ", " + str(target[1]) + ".tmx"), position) self.map = str(self.grid).lstrip("[").rstrip("]") stats['map'] = self.map + ".tmx" except UnboundLocalError: pass def draw(self, surface): self.group.center(self.hero.rect.center) # draw the map and all sprites self.group.draw(surface) def speach(self, dispWidth, dispHeight, text): ## text = "Laudem bonorum salutandi pri te, tollit melius delicata mel cu,\ ## eu mea ullum legimus. Probo debitis te vel. Labores vulputate \ ## argumentum sea id. Cibo vitae vocent eos no, ne odio molestiae\ ## duo." screen.blit( pygame.transform.scale( load_image(os.path.join("images", "gui", "speach.png")), (dispWidth, 150)), (0, dispHeight - 150)) text = textwrap.wrap(text, width=95) for i, line in enumerate(text): text_blit = pixel_font.render(line, False, pygame.Color('white')) screen.blit(text_blit, (60, dispHeight - 110 + 25 * i)) def map_generate(self, output, octaves, freq, x, y): command = "{}/lib/generate/__init__.py".format(os.getcwd()) if sys.platform.startswith('win32'): executeable = ("Python35\python.exe") elif sys.platform.startswith('linux'): executeable = ("python3.5") subprocess.Popen([ executeable, command, output, str(octaves), str(freq), str(x), str(y) ], close_fds=True) def handle_input(self, keyset): """ Handle pygame input events """ poll = pygame.event.poll event = poll() while event: if event.type == QUIT: self.running = False pygame.quit() break elif event.type == KEYDOWN: if keyset == "game": if event.key == K_EQUALS: self.map_layer.zoom += .25 elif event.key == K_MINUS: value = self.map_layer.zoom - .25 if value > 0: self.map_layer.zoom = value else: self.map_layer.zoom = 0.1 elif event.key == K_KP0: try: if self.switcher() == True: self.generate_surrounding_maps() except FileNotFoundError: print("Exception Caught") pass elif event.key == K_e: self.menu = "inventory" pass if event.key == K_ESCAPE: for i in attack_stats_types: stats[i] = attack_stats[i] pickle.dump( stats, open(os.path.join("data", "saves", "save.dat"), "wb")) pickle.dump( inventory, open( os.path.join("data", "saves", "inventory.dat"), "wb")) self.running = False pygame.quit() print(" ") sleep(0.5) print("Shutdown... Complete") sys.exit() break if keyset != "game": if event.key == K_ESCAPE: self.menu = "game" pass if keyset == "inventory": if event.key == K_r: self.genchests() if keyset == "chest": if event.key == K_r: chestContents[self.chestNo] = self.genchests() if event.key == K_t: if taken[self.chestNo] != True: self.takeChest() taken[self.chestNo] = True pickle.dump( taken, open( os.path.join("data", "saves", "taken.dat"), "wb")) if keyset == "attack": pass #Basically just debug keys if event.key == K_KP1: self.menu = "game" pass elif event.key == K_KP2: self.map_change(FOREST) self.map = "forest" elif event.key == K_KP3: self.generate_new_map(4, 16, 3) pass elif event.key == K_KP4: self.map_generate( str(self.grid[0]) + ", " + str(self.grid[1]) + ".tmx", 4, 16.0, self.grid[0], self.grid[1]) pass elif event.key == K_KP5: self.enemy_stats = self.gen_enemy(attack_stats, enemy_stats) self.menu = "attack" pass elif event.key == K_KP6: print("X :" + str(int(self.hero.position[0])) + ", Y: " + str(int(self.hero.position[1])) + ", Map: " + self.map) pass elif event.key == K_KP7: print(str(pygame.mouse.get_pos())) pass elif event.key == K_KP8: sleep(0.5) elif event.key == K_KP9: editor = db_interface.Editor() conn = sqlite3.connect('data/saves/data.db') c = conn.cursor() for var in vars: exec("del " + var + "[:]") for data in c.execute( "SELECT {} FROM csv".format(var)): data = str(data[0]) exec("{}.append(\"{}\")".format(var, data)) pass elif event.key == K_F11: for m in screeninfo.get_monitors(): displ = str(m) w, h, mx, c = displ.split(", ") if self.fullscreen: self.fullscreen = False screen = init_screen( 1024, 700, pygame.HWSURFACE | pygame.FULLSCREEN) else: self.fullscreen = True screen = init_screen( w, h, pygame.HWSURFACE | pygame.RESIZABLE) pygame.display.toggle_fullscreen() elif event.type == VIDEORESIZE: self.map_layer.set_size((event.w, event.h)) dispHeight = event.h dispWidth = event.w event = poll() # using get_pressed is slightly less accurate than testing for events # but is much easier to use. if keyset == "game": pressed = pygame.key.get_pressed() if pressed[K_UP]: self.hero.velocity[1] = -HERO_MOVE_SPEED self.direction = "up" self.direction2 = "up" elif pressed[K_DOWN]: self.hero.velocity[1] = HERO_MOVE_SPEED self.direction = "down" self.direction2 = "down" elif pressed[K_w]: self.hero.velocity[1] = -HERO_SPRINT_SPEED self.direction = "up" self.direction2 = "up" elif pressed[K_s]: self.hero.velocity[1] = HERO_SPRINT_SPEED self.direction = "down" self.direction2 = "down" else: self.hero.velocity[1] = 0 self.direction2 = "still" if pressed[K_LEFT]: self.hero.velocity[0] = -HERO_MOVE_SPEED self.direction = "left" self.direction1 = "left" elif pressed[K_RIGHT]: self.hero.velocity[0] = HERO_MOVE_SPEED self.direction = "right" self.direction1 = "right" elif pressed[K_a]: self.hero.velocity[0] = -HERO_SPRINT_SPEED self.direction = "left" self.direction1 = "left" elif pressed[K_d]: self.hero.velocity[0] = HERO_SPRINT_SPEED self.direction = "right" self.direction1 = "right" else: self.hero.velocity[0] = 0 self.direction1 = "still" if self.direction1 == "still" and self.direction2 == "still": self.direction = "still" def update(self, dt): """ Tasks that occur over time should be handled here """ self.group.update(dt) # check if the sprite's feet are colliding with wall # sprite must have a rect called feet, and move_back method, # otherwise this will fail for sprite in self.group.sprites(): if sprite.feet.collidelist(self.walls) > -1: sprite.move_back(dt) def animation(self, direction, number): if self.direction1 == "still" and self.direction2 == "still": if self.direction == "left": self.hero = Hero('Tiles/hero/walking_left/walking_left1.png') if self.direction == "right": self.hero = Hero('Tiles/hero/walking_right/walking_right1.png') if self.direction == "up": self.hero = Hero('Tileshero/walking_up/walking_up1.png') if self.direction == "down": self.hero = Hero('Tiles/hero/walking_down/walking_down1.png') else: self.hero = Hero('Tiles/hero/walking_' + direction + '/walking_' + direction + str(number) + '.png') def genchests(self): wr = WeightedRandomizer(itemsProbability) self.taken = False chest.clear() numItems = random.randint(1, random.randint(2, 4)) if random.randint(0, 3) < 1: numItems += 1 elif random.randint(0, 9) < 2: numItems += 2 elif random.randint(0, 18) < 2: numItems += 5 for i in range(0, numItems): item = wr.random() while item in chest: item = wr.random() chest.append(item) return chest def gen_enemy(self, player_stats, enemy_stat): stats = attack_stats_types stat = player_stats for i in range(len(player_stats)): j = stats[i] try: enemy_stat[ stats[i]] = int((stat[j] - (stat[j] * 0.2)) + random.randint(0, int(stat[j] * 0.4))) except TypeError: enemy_stat[j] = choice(attack_types) return enemy_stat pass def player_attack(): type = None while type not in attack_types: type = input("[ QUESTION ] Enter attack type. ") if type not in attack_types: print( "[ ERROR ] Attack type {} not found. Must be {}".format( type, attack_types)) else: break return type pass def attack(self, attacker_stats, defender_stats, player_attack_type): fraction = attacker_stats['strength'] / defender_stats['blocking'] print("[ INFO ] Defender attack type: {}".format( defender_stats['attack'])) if player_attack_type != defender_stats['attack']: if fraction > (0.8 + (randint(0, 40) / 100)): attacker_stats['health'] -= int(fraction * 10) pass # Attacker Win else: defender_stats['health'] -= int(fraction * 10) pass # Attacker Loss elif player_attack_type == attacker_stats[ 'attack']: # Better odds here if fraction > (0.9 + (randint(0, 40) / 100)): attacker_stats['health'] -= int(fraction * 10) pass # Attacker Win else: defender_stats['health'] -= int(fraction * 10) pass # Attacker Loss else: if fraction > (0.70 + (randint(0, 40) / 100)): # Odds are worse here attacker_stats['health'] -= int(fraction * 10) pass # Attacker Win else: defender_stats['health'] -= int(fraction * 10) pass # Attacker Loss print("[ INFO ] Attacker: {} Defender: {}".format( attacker_stats['health'], defender_stats['health'])) print("[ INFO ] Health to be lost: {}".format(int(fraction * 10))) return attacker_stats, defender_stats def blit_inventory(self, screenMode, speach=None): if screenMode != "game": xCounter, counter, OverCounter = 0, 0, 0 dispWidth, dispHeight = pygame.display.get_surface().get_size() guiX = (dispWidth / 2) - 175 guiY = (dispHeight / 2) - 165 screen.blit( load_image(os.path.join("images", "gui", "transparent.png")), (0, 0)) screen.blit( load_image(os.path.join("images", "gui", screenMode + ".png")), (guiX, guiY)) if screenMode == "inventory" or screenMode == "chest": dt = (clock.tick() / 500) clock.tick(self.fps) if len(inventory) > 0: for i in range(0, len(inventory)): OverCounter += 1 if xCounter >= 9: counter += 1 xCounter = 0 screen.blit(load_image(os.path.join("images", "items",\ str(items[inventory[i]])+".png")), (guiX + 16 + 36*xCounter, guiY + 168 + 36*counter)) xCounter += 1 if screenMode == "chest" and chestContents[self.chestNo] != None: itemNo = 0 for i in range(0, len(chestContents[self.chestNo])): screen.blit(load_image(os.path.join("images", "items",\ items[str(chestContents[self.chestNo][i])]\ +".png")), (guiX + 123 + 36*itemNo,\ guiY + 34 + int(35 * (i/3)) - int(35 * (i/3)) % 35)) if itemNo < 2: itemNo += 1 else: itemNo = 0 if screenMode == "speach": self.speach(dispWidth, dispHeight, speach) if screenMode == "attack": picture = load_image( os.path.join("Tiles", "hero", "walking_down", "walking_down1.png")) picture = pygame.transform.scale(picture, (100, 100)) rect = picture.get_rect() rect = rect.move((guiX + 50, guiY + 28)) screen.blit(picture, rect) text = font.render("Player : Enemy", True, pygame.Color('black')) screen.blit(text, (guiX + 172, guiY + 45)) text = "Health: " + str( attack_stats['health']) + " Skill: " + str( attack_stats['skill']) + " Attack: " + str( attack_stats['attack']) text_render = pixel_font.render(text, False, pygame.Color('gray27')) screen.blit(text_render, (guiX + 20, guiY + 290)) for i, attack in enumerate(attack_types): text = load_font(30, "data/PixelFont.ttf").render( attack, False, pygame.Color('black')) screen.blit(text, (guiX + 172, guiY + 25 + 28 * (i + 2))) # if pygame.mouse.get_pressed()[0] == 1: #print(pygame.mouse.get_pos()) mouse_pos = pygame.mouse.get_pos() if guiX + 160 < mouse_pos[0] and guiX + 330 > mouse_pos[0]: for i, attack in enumerate(attack_types): if guiY + 25 + 28 * (i + 2) < mouse_pos[1] and ( guiY + 25 + 28 * (i + 2)) + 28 > mouse_pos[1]: print(attack) self.attack(attack_stats, enemy_stats, attack) else: pass pass def takeChest(self): if len(inventory) < 27: if chestContents[self.chestNo] != None: for i in range(0, (len(chestContents[self.chestNo]))): #print(i) inventory.append(chestContents[self.chestNo][i]) chestContents[self.chestNo][:] = [] pickle.dump( chestContents, open(os.path.join("data", "saves", "chestContents.dat"), "wb")) def run(self): screenMode = pygame.RESIZABLE oldPlay = stats['playTime'] clock = pygame.time.Clock() self.running = True self.grid = [0, 0] debug = True dispWidth, dispHeight = 1024, 768 self.menu = "game" game_time = pygame.time.get_ticks() playTime = font.render("Timer: ", False, pygame.Color('white')) minutes = 0 self.map = stats['map'][:-4].lower() self.map = self.map.lstrip( "m") # Fix that stupid bug that changes "maze1" to "ze1" self.map = self.map.lstrip("aps/") try: while self.running: dt = (clock.tick() / 500) clock.tick(self.fps) if self.menu == "game": #self.deep_thought() if self.counter2 % 7 == 0: heroPos = self.hero.position self.animation(self.direction, self.counter) self.hero.position = heroPos #entityPos = self.entity.position #self.EntityAnimation(self.EntityDirection, self.counter, "princess") #self.entity.position = entityPos self.counter += 1 guiX = (dispWidth / 2) - 175 guiY = (dispHeight / 2) - 165 self.group.remove(self.hero) #self.group.remove(self.entity) self.group.empty() self.group.add(self.hero) #self.group.add(self.entity) self.counter2 += 1 if self.counter > 8: self.counter = 1 stats['pos'] = self.hero.position currentTime = systime() seconds = currentTime - gameStart + oldPlay dispWidth, dispHeight = pygame.display.get_surface().get_size() stats['playTime'] = seconds if debug == True and self.counter2 % 1 == 0: location = font.render( "Position: " + str(round(round(self.hero.position[0], -1) / 10)) + ", " + str(round(round(self.hero.position[1], -1) / 10)), False, pygame.Color('white')) mapdebug = font.render("Map Name: " + str(self.map), False, pygame.Color('white')) minutes = seconds // 60 secondsDisp = seconds % 60 if minutes < 1: minutes = 0 if secondsDisp == 60: secondsDisp = 0 minutes += 1 fps = font.render("FPS:" + str(int(clock.get_fps())), False, pygame.Color('white')) screen.blit(fps, (50, 50)) screen.blit(playTime, (50, 100)) screen.blit(location, (50, 75)) screen.blit(mapdebug, (50, 125)) playTime = font.render( "Timer: " + str(floor(minutes)) + " : " + str(round(secondsDisp)), True, pygame.Color('white')) screen.blit(playTime, (50, 100)) self.blit_inventory(str(self.menu)) pygame.display.update() #pygame,display.flip() self.handle_input(self.menu) self.update(dt) self.draw(screen) except KeyboardInterrupt: self.running = False pygame.quit()