def __init__(self): """ Initialisation """ # Matrice de collision onvention : True = libre; False = bloqué self.mat_collide = None # Matrice de vision True = VIsible. False = invisible self.mat_view = None # Matrice d'affichage du village self.mat_render = None # Entités self.player = Player() self.door = None self.bullets = None self.monsters = None self.treasure = None self.swords = None # COmpteur de update # TODO : Compteur dans les classes respectives self.cpt_bullet = None self.cpt_strike = None self.cpt_monster = None # Tableau d'affichage final self.buffer_window = [[None for _ in range(500)] for _ in range(500)] # Start ! self.generate() self.game_state = self.GAME_STATE_RUN self.timer_state = 0
def __init__(self, mapFile, enemies=[Enemy(10, 10, 1), Enemy(11, 10, 1)]): self.player = Player() self.enemies = enemies self.prevLoc = (self.player.getX(), self.player.getY()) self.map = [[]] self.items = [Weapon(WeaponType.SWORD, 3, 3)] with open(mapFile, "r") as mapTxt: for line in mapTxt.readlines(): self.map.append(self.split(line.rstrip())) self.updatePlayer()
class Game(object): def __init__(self): self.player = Player() self.station = Station() def play(self): while True: self.station.levels[self.player.floor].rooms[ self.player.room].describe() for enemy in self.station.levels[self.player.floor].rooms[ self.player.room].entities: if isinstance(enemy, Enemy): while self.player.health > 0 and enemy.health > 0: self.player.attack(enemy) if enemy.health > 0: enemy.attack(self.player) self.station.levels[self.player.floor].rooms[ self.player.room].entities.remove(enemy) # Lose condition if self.player.health <= 0: print "Oh no, you've died!" break self.take_turn() # Win condition if self.player.floor >= len(self.station.levels): print "You've escaped!" break def take_turn(self): # move # item # map? self.move() def move(self): input = raw_input("Which door would you like to enter?") visible_doors = self.station.levels[self.player.floor].rooms[ self.player.room].doors door = next((door for door in visible_doors if door.label == input), None) if door is None: print "There is no door labeled {0} here!".format(input) else: self.player.room = door.enter(self.player.room) if self.player.room == -1: self.player.floor += 1 self.player.room = 0
def populate_world(self): # Skeleton Sprites for i in range(50): self._entities.add( Skeleton([ random.randint(50, self._width - 50), random.randint(80, self._height - 80) ], random.randint(0, 360), 0, random.randint(50, 80))) # Player self._player = Player([settings.WIDTH, settings.HEIGHT]) self._entities.add(self._player)
def __init__(self, size): Template.__init__(self, size) check_dir("saveload.py") self.size = size self.background = pg.Surface((40*64, 40*64)) self.bgpos = (0,0) #self.floors, self.walls = self.make_level(32) self.walls = pg.sprite.LayeredDirty() self.world = self.make_world() self.clip = pg.Rect(0,0,size[0],size[1]) self.player = Player(self.size, self.walls, tuple_div(size, 2)) self.characters = pg.sprite.LayeredDirty() self.characters.add(self.player) self.mob = Npc(self.size, 1) self.characters.add(self.mob)
def __init__(self, playerstate, level, scale=1.0, L=10, item=None): self.level = level self.scale = scale L *= scale self.L = L # self.stardust = StarDust(scale) self.wireframe = WireFrame(scale) self.sky = Sky() self.player = Player(self, playerstate, Vector4D(0, 0, 0, L)) self.enemies = Enemies(self) types = [randint(0, level.types - 1)for i in xrange(level.enemy_num-1)] types += [level.types-1] for t in types: x = 6*L*(2.0*random()-1.0) y = 6*L*(2.0*random()-1.0) z = 6*L*(1.0*random()-2.0) self.enemies.add(Vector4D(0, x, y, z), t) self.stars = Stars(self, Vector4D(0.0, 0.0, -0.5*scale, L-3*scale), scale) if item is not None and item == playerstate.gun_num: self.item = Item(item, self.player.P.X+Vector4D(0, 0, 0.5*scale, -5*scale), scale) else: self.item = None self.score = 0
def place_entities(self, spec_dict, monster_dict, player_dict, entities): """Place monsters and player on the map.""" for monster_type in monster_dict.keys(): for n in range(spec_dict.get(monster_type, 0)): while True: unfilled_rooms = [ room for room in self.rooms if room.num_monsters != room.max_monsters ] room = choice(unfilled_rooms) x, y = room.get_point() if self.tiles[x][y].has_entity or self.tiles[x][y].blocked: continue else: monster = Monster(monster_type, monster_dict[monster_type], x, y) entities.append(monster) room.num_monsters += 1 self.tiles[x][y].has_entity = 1 break flag = True while flag: room = self.rooms[randint(0, len(self.rooms) - 1)] x, y = room.get_point() if self.tiles[x][y].has_entity or self.tiles[x][y].blocked: continue else: flag = False player = Player(spec_dict.get('player', 'Player'), player_dict, x, y) entities.append(player) self.player = player
def appStarted(app): # map generation app.mapRows = app.mapCols = 70 app.map = generateMap(app.mapRows, app.mapCols) # player (born at a random room.) birthRoom = random.choice(app.map.rooms) cx = birthRoom.cx cy = birthRoom.cy print(cx, cy) app.player = Player(cx, cy) app.playerSpriteCount = 0 # others app.margin = 20 app.currRow = app.mapRows // 2 app.currCol = app.mapCols // 2 app.viewDepth = 5 app.drawMiniMap = False app.timerDelay = 100 app.time_groundEffect = time.time() app.time_moveCtrl = time.time() app.lightEffect = 0 app.moveAllowed = True app.sendMissMsg = False app.time_missMsg = time.time()
class Game(Scene): def __init__(self): self.c = Constants() self.player = Player(self.c.screen_width / 2, self.c.screen_height / 2, 300) def draw(self, sm, screen): screen.fill(self.c.black) utils.draw_text(screen, "Game: [M] to Menu") self.player.draw(screen) def input(self, sm): for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit(0) if event.type == pygame.KEYDOWN: if event.key == pygame.K_m: sm.pop() sm.push( FadeTransitionScene(self, None) ) # We pass none as we are not transitiong to a *new* scene. if event.key == pygame.K_w: self.player.moving_up = True if event.key == pygame.K_s: self.player.moving_down = True if event.key == pygame.K_a: self.player.moving_left = True if event.key == pygame.K_d: self.player.moving_right = True if event.type == pygame.KEYUP: if event.key == pygame.K_w: self.player.moving_up = False if event.key == pygame.K_s: self.player.moving_down = False if event.key == pygame.K_a: self.player.moving_left = False if event.key == pygame.K_d: self.player.moving_right = False def update(self, sm, dt): self.player.update(dt) def exit(self): print("Leaving Game.") def enter(self): print("Entering Game.")
def new(self): self.unused_keys = [] self.rooms = {} self.enemies = [] self.objects = [] self.base = [] self.entities = [] self.buttons = [] self.user_name = '' self.first = True self.background, self.top_panel, self.bottom_panel = None, None, None self.player = Player((1, 1), 5, 5, 1, 1, 3, 3, 0, 255) self.current_room = 1 self.turn = 1 self.change_room(1)
def __init__(self, screen): """Create the screen, player, assets.""" # Some technical items, first self.screen = screen self.gameScreen = curses.newpad(Constants.SCREENHEIGHT, Constants.SCREENWIDTH) self.running = True # Collections of various objects self.player = Player(self) self.walls = dict() self.doors = dict() self.decorations = dict() self.fences = dict() self.npcs = [] self.villagers = [] self.police = [] self.squares = [] # Camera self.cameraX = 0 self.cameraY = 0 # The current contents of the status line # TODO: Maybe rename this self.statusLine = "" # The bottom line contains the clock and other stuff self.bottomLine = "" # The current time and time-related variables self.hour = 7 self.minute = 59 self.turnsToNextMinute = 0 ### The actual game creation logic # Random decoration for _ in range(500): (y, x) = (random.randint(1, Constants.MAPHEIGHT - 1), random.randint(1, Constants.MAPWIDTH - 1)) self.decorations[(y, x)] = Decoration() # Create tiles for visibility and FoV self.tiles = dict() for x in range(Constants.MAPWIDTH): for y in range(Constants.MAPHEIGHT): self.tiles[(y,x)] = Tile() # Town creation self.town = Town(self, 5, 5, 3, 3) self.town2 = Town(self, 5, 88, 3, 3) # Setup the murder.. self.victim = None self.killer = None self.murderSetup() # Put together the NPC schedules self.generatePlans()
def sim(self, name: str, level: int = None, player: Player = None, target: Monster = None): if player is None: player = Player(level=level, stats=STATBLOCKS[level]) if target is None: target = MONSTERS[level] def sim_decorator(f: ty.Callable[[], float]): self.damage_sims[name] = player, target, f return f return sim_decorator
def __init__(self): super().__init__() self.unused_keys = [] self.first = True self.rooms = {} self.enemies = [] self.objects = [] self.base = [] self.entities = [] self.buttons = [] self.user_name = '' self.con = sqlite3.connect(DATABASE) self.background, self.top_panel, self.bottom_panel = None, None, None self.player = Player((1, 1), 5, 5, 1, 1, 3, 3, 0, 255) self.current_room = 1 self.turn = 1 self.change_room(1)
def run_game(): pygame.init() clock = pygame.time.Clock() screen = pygame.display.set_mode((globals['SCREEN_WIDTH'], globals['SCREEN_HEIGHT']), 0, 32) currently_held_keys = [] #debug stuff lvl = Level("testlevel.txt", screen) playerCam = Camera((85,85), globals['SCREEN_WIDTH'], globals['SCREEN_HEIGHT']) originCam = Camera((0,0), globals['SCREEN_WIDTH'], globals['SCREEN_HEIGHT']) player = Player("resources/robodude.png", screen, (85,85), playerCam) currentCam = player.camera entities = [] entities.append(player) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: exit_game() if event.type == pygame.KEYDOWN: currently_held_keys.append(event.key) if event.type == pygame.KEYUP: currently_held_keys.remove(event.key) currentCam = player.camera do_render_light = True for keydown in currently_held_keys: if keydown in globals['WASD_KEYS']: player.movement_handler(keydown) #debug stuff if keydown == pygame.K_1: currentCam = originCam if keydown == pygame.K_2: do_render_light = False time_passed = clock.tick(50) screen.fill(globals['BG_COLOR']) # debug stuff pygame.display.set_caption('Lightgame : %d fps' % clock.get_fps()) corners = currentCam.get_corners() lvl.draw_visible_level(corners[0], corners[1]) player.update(time_passed, lvl, currentCam) player.draw(currentCam) lights_per_entity = [entity.lights for entity in entities] all_lights = [light for lights in lights_per_entity for light in lights] if do_render_light: currentCam.render_light(screen, all_lights) pygame.display.flip()
def __init__(self, level, scale, playerstate, item=None): self.level = level self.scale = scale self.playerstate = playerstate self.L = self.level.L * scale self.wireframe = WireFrame(scale=self.scale) self.sky = Sky() self.player = Player(world=self, level=level, state=playerstate, pos=Vector4D(0, 0, 0, self.L)) self.solar = SolarSystem(self, self.player.P.X, self.scale) self.enemies = Enemies(world=self) self.item = None if not level.is_travel(): self.init_set_enemy() self.init_set_item(item) self.init_set_worldline() self.score = 0
def load_map_file(self): ''' Maps are specified by a json file. Load the map into the physics engine ''' self.dynamics = [] self.goals = [] self.statics = [] with open(self.args.map_file, mode='r') as f: top = json.loads(f.read()) width_m = top['width'] self._pixels_per_meter = SCREEN_WIDTH / width_m self._meters_per_pixel = 1.0 / self._pixels_per_meter dynamics = top['dynamics'] for dynamic in dynamics: name = dynamic['name'] t = dynamic['type'] if t == "player": x = dynamic['x_center'] y = dynamic['y_center'] w = dynamic['w_half'] h = dynamic['h_half'] p = Player(self, name, x, y, w, h) self.player = p self.dynamics.append(p) else: raise Exception("Unexpected dynamic type {}".format(t)) statics = top['statics'] for static in statics: name = static['name'] t = static['type'] if t == "wall": x = static['x_center'] y = static['y_center'] w = static['w_half'] h = static['h_half'] if name == "goal": wall = Goal(self, name, x, y, w, h) self.goals.append(wall) else: wall = Wall(self, name, x, y, w, h) self.statics.append(wall) else: raise Exception("Unexpected static type {}".format(t))
def load_room(self, name, passage=None): name = 'Data/Rooms/' + name with open(name, mode='r') as file: room_map = [line.strip() for line in file] width = len(room_map[0]) height = len(room_map) room_map = [list(row) for row in room_map] if passage is not None: row = None if passage == 1: row = 0 elif passage == 2: row = height - 1 if row is not None: room_map[row][width // 2 - 1] = '|' room_map[row][width // 2] = '|' room_map[row][width // 2 + 1] = '|' for row in range(height): for col in range(width): obj = None if room_map[row][col] == 'W': obj = Object((self.room_sprites, self.wall_sprites), 'wall', col, row, BLOCK_SIZE, offset=self.offset) elif room_map[row][col] == '.': obj = Object((self.room_sprites,), 'empty', col, row, BLOCK_SIZE, offset=self.offset) elif room_map[row][col] == '|': obj = Object((self.room_sprites,), 'empty', col, row, BLOCK_SIZE, offset=self.offset) block_wall = Object((self.block_walls,), 'wall', col, row, BLOCK_SIZE, offset=self.offset) self.block_walls.add(block_wall) elif room_map[row][col] == 'S': obj = Object((self.room_sprites,), 'empty', col, row, BLOCK_SIZE, offset=self.offset) script = Object((self.room_sprites,), 'empty', col, row, BLOCK_SIZE, offset=self.offset) self.scripts.add(script) self.room_sprites.add(script) elif room_map[row][col] == 'P': obj = Object((self.room_sprites,), 'empty', col, row, BLOCK_SIZE, offset=self.offset) self.player = Player(col, row, offset=self.offset) elif room_map[row][col] == 'T': obj = Object((self.room_sprites,), 'empty', col, row, BLOCK_SIZE, offset=self.offset) self.teleport = Object((self.room_sprites,), 'teleport', col - 2, row - 4, BLOCK_SIZE, offset=self.offset) if obj is not None: self.room_sprites.add(obj) return width, height
def __init__(self): States.__init__(self) self.next = "menu" self.all_sprites = pygame.sprite.Group() self.wall_list = pygame.sprite.Group() self.countHorBlock = 8 self.countVertBlock = 10 self.walls = setup.makeouterwalls(BLOCK, SCREEN_SIZE) self.blocks = setup.makeinnerblocks(BLOCK, SCREEN_SIZE, self.countHorBlock, self.countVertBlock) self.player = Player(PLAYER, 20, 20) self.wall_list.add(self.walls, self.blocks) self.all_sprites.add(self.wall_list, self.player) self.player.walls = self.wall_list
def get_game_variables(constants): """ Cette fonction retourne un dictionnaire qui contient les variables principales (joueur, entites presentes, carte, messages à afficher, état du jeu) du jeu. Elle est appelée dans la fonction principale (main) du jeu. :param constants: constantes de jeu :return: """ fighter_component = Fighter(hp=30, defense=2, power=5) inventory_component = Inventory(26) player = Player(0, 0, '@', libtcod.black, 'Player', render_order=RenderOrder.ACTOR, blocks=True, fighter=fighter_component, inventory=inventory_component) entities = [player] game_map = GameMap(constants.get('map_width'), constants.get('map_height')) game_map.make_map(constants.get('max_rooms'), constants.get('room_min_size'), constants.get('room_max_size'), constants.get('map_width'), constants.get('map_height'), player, entities, constants.get('max_monsters_per_room'), constants.get('max_items_per_room')) message_log = MessageLog(constants.get('message_x'), constants.get('message_width'), constants.get('message_height')) game_state = GameStates.PLAYERS_TURN return player, entities, game_map, message_log, game_state
def init_game(): w = World('assets/level.lvl') w.addEntitiy(Player(pos=[3, 3], image='assets/pika.png')) c = Camera(w) return w, c
def draw_menu(): window.blit(menu_bg.image, (menu_bg.x, menu_bg.y)) window.blit(start_button.image, (start_button.x, start_button.y)) window.blit(exit_button.image, (exit_button.x, exit_button.y)) pygame.display.update() # Generate inital cave cave = Cave(screen_height // 15, screen_width // 15) bg = Background(0, 0, screen_height, screen_width) # Character Creation # Class definition in entity.py entities = [] user = Player(450, 350, 13, 30, 100, 5, 3) entities += [user] # Main Draw function def redraw(): cells_to_redraw = [] for entity in entities: cells_to_redraw += entity.get_cells(cave) for cell in cells_to_redraw: window.blit(pygame.image.load(cell.sprite), (cell.x * 15, cell.y * 15)) window.blit(user.still_sprite, (user.x, user.y)) pygame.display.update()
class Main(Template): def __init__(self, size): Template.__init__(self, size) check_dir("saveload.py") self.size = size self.background = pg.Surface((40*64, 40*64)) self.bgpos = (0,0) #self.floors, self.walls = self.make_level(32) self.walls = pg.sprite.LayeredDirty() self.world = self.make_world() self.clip = pg.Rect(0,0,size[0],size[1]) self.player = Player(self.size, self.walls, tuple_div(size, 2)) self.characters = pg.sprite.LayeredDirty() self.characters.add(self.player) self.mob = Npc(self.size, 1) self.characters.add(self.mob) def make_world(self): load = LoadMap(os.path.join("save", "savemap1.sav")) return load.bg_group def move_world(self): playercenter = tuple_sub(self.player.rect.center, self.bgpos) screencenter = tuple_div(self.size, 2) difference = tuple_sub(playercenter, screencenter) if difference != 0: coords = tuple_sub(playercenter, self.player.rect.center) self.bgpos = tuple_sub(coords, difference) self.clip.center = self.player.rect.center def make_level(self, block): bsize = (int(round(self.size[0] / block)), int(round(self.size[1] / block))) wall = "./img/wall1_medium.png" floor = "./img/floor1_medium.png" room = Room(bsize, wall, floor, block) room.make_door("north") return room.floors_group, room.walls_group def update(self, dt): self.characters.update(dt) self.mob.follow(self.player.pos) self.move_world() def draw(self): self.screen.fill((0,0,0)) # Background #self.floors.draw(self.background) #self.walls.draw(self.background) self.world.set_clip(self.clip) self.world.draw(self.background) # Characters self.characters.draw(self.background) self.screen.blit(self.background, self.bgpos) # pg.draw.rect(self.screen, (255, 255, 255), self.player.rect, 1) # GUI # Mouse pointer def key_down(self, key): # Escape to quit if key == K_ESCAPE: self.game_on = False # wasd and arrows to move if key in (K_w, K_UP): # Up self.player.direction["up"] = True if key in (K_a, K_LEFT): # Left self.player.direction["left"] = True if key in (K_s, K_DOWN): # Down self.player.direction["down"] = True if key in (K_d, K_RIGHT): # Right self.player.direction["right"] = True # Shift key to run. if key == K_LSHIFT: self.player.l_shift(True) def key_up(self, key): if key in (K_w, K_UP): # Up self.player.direction["up"] = False if key in (K_a, K_LEFT): # Left self.player.direction["left"] = False if key in (K_s, K_DOWN): # Down self.player.direction["down"] = False if key in (K_d, K_RIGHT): # Right self.player.direction["right"] = False if key == K_LSHIFT: self.player.l_shift(False) def mouse_down(self, button, pos): pass def mouse_up(self, button, pos): pass def mouse_motion(self, button, pos, rel): pass
def main(): bg_x = bg.get_width() bg_y = bg.get_height() font = pygame.font.SysFont('helvetica', 20) player = Player(bg_x // 2, bg_y // 2) enemies = [Minion(random.randrange(0, bg_x), random.randrange(0, bg_y)) for _ in range(10)] + \ [Runner(random.randrange(0, bg_x), random.randrange(0, bg_y)) for _ in range(3)] + \ [Tank(random.randrange(0, bg_x), random.randrange(0, bg_y))] projectiles = [] projectile_tick = 0 score = 0 run = True while run: clock.tick(27) for event in pygame.event.get(): if event.type == pygame.QUIT: run = False pygame.quit() player.move(bg_x, bg_y, width, height) if projectile_tick == 0: if pygame.mouse.get_pressed()[0]: projectiles.extend(player.shoot(w2, h2)) projectile_tick = 1 elif projectile_tick < player.gun.cooldown: projectile_tick += 1 else: projectile_tick = 0 win.fill((0, 0, 0)) win.blit(bg, (w2 - player.x, h2 - player.y)) player.draw(win, player, w2, h2) for projectile in projectiles: projectile.draw(win, player, w2, h2) projectile.move() if projectile.is_offscreen(player, width, height): projectiles.remove(projectile) for enemy in enemies: if enemy.is_hit(projectile): projectiles.remove(projectile) enemy.hit(projectile) if enemy.is_dead(): score += enemy.points enemies.remove(enemy) break for enemy in enemies: if not enemy.is_offscreen(player, width, height): if player.is_hit(enemy) and not player.was_hit: player.was_hit = True player.curr_health -= 1 if player.curr_health == 0: run = False pygame.quit() enemy.move(bg_x, bg_y, player) enemy.draw(win, player, w2, h2) text = font.render(f'Score: {score}', True, (255, 255, 255)) win.blit(text, (0, 0)) pygame.display.update()
import os from entity import Player, Monster from dungeon import Dungeon from actions import Moves player = Player() monster = Monster() dungeon = Dungeon() moves = Moves() dungeon.generate() player.set_location(0, 0) monster.set_location(2, 2) all_entities = [player, monster] while True: if player.location == monster.location: print "The monster ate you!" break dungeon.get(all_entities) moves.invalid_moves(player, dungeon) direction = raw_input(">> Where would you like to move?\n").upper() if direction == "QUIT": break moves.move(player, direction) moves.reset() os.system('cls' if os.name == 'nt' else 'clear')
class DirtWorld(BaseWorld): def __init__(self, width=500, height=500, pos=[0, 0]): self._seed = "PyGaMe" super().__init__(width, height, pos) def init_background(self): gen = random.Random() gen.seed(self._seed) sprite_map = SpriteLoader.load_sheet( settings.TEXTURE_DIR + "basictiles.png", 16, 16, 0, 0, 8, 13) grass = sprite_map[11] flowers = sprite_map[12] tree = sprite_map[30] stone = sprite_map[58] for x in range(0, self._width, sprite_map[0].get_width()): for y in range(0, self._height, sprite_map[0].get_height()): self._background_surface.blit(grass, (x, y)) rand = gen.randint(0, 100) # TODO: Make a dictionary that will handle spawn percentages # [{icon: surface, pct: 10}, ...] if rand in [0, 1, 2, 3, 4, 5]: self._background_surface.blit(flowers, (x, y)) elif rand in [6]: self._background_surface.blit(tree, (x, y)) elif rand in [7]: self._background_surface.blit(stone, (x, y)) def populate_world(self): # Skeleton Sprites for i in range(50): self._entities.add( Skeleton([ random.randint(50, self._width - 50), random.randint(80, self._height - 80) ], random.randint(0, 360), 0, random.randint(50, 80))) # Player self._player = Player([settings.WIDTH, settings.HEIGHT]) self._entities.add(self._player) def handle_events(self, events): super().handle_events(events) for e in events: if e.type == pygame.MOUSEBUTTONDOWN: # TODO: Add rock sprite click_world = self.to_world_pos(e.pos) dx = int(click_world[0] - self._player.get_x() - (self._player.get_width() / 2)) dy = int(click_world[1] - self._player.get_y() - (self._player.get_height() / 2)) angle = math.degrees(math.atan2(dy, dx)) # if dy > 0: # if dx > 0: # angle = math.atan2(dy, d) self._entities.add( Rock([ i + (self._player.get_width() / 2) for i in self._player.get_pos() ], angle, 300)) def update(self, micro): super().update(micro) p_pos = self.get_screen_pos(self._player) if p_pos[0] < 250: self._pos[0] = self._pos[0] + (250 - p_pos[0]) elif p_pos[0] + self._player.get_width() > settings.WIDTH - 250: self._pos[0] = self._pos[0] - ( (p_pos[0] + self._player.get_width()) - (settings.WIDTH - 250)) if p_pos[1] < 150: self._pos[1] = self._pos[1] + (150 - p_pos[1]) elif p_pos[1] + self._player.get_height() > settings.HEIGHT - 150: self._pos[1] = self._pos[1] - ( (p_pos[1] + self._player.get_height()) - (settings.HEIGHT - 150))
def __init__(self): self.player = Player() self.station = Station()
class Dungeon(Element): """класс подземелья""" def __init__(self): super().__init__() self.unused_keys = [] self.first = True self.rooms = {} self.enemies = [] self.objects = [] self.base = [] self.entities = [] self.buttons = [] self.user_name = '' self.con = sqlite3.connect(DATABASE) self.background, self.top_panel, self.bottom_panel = None, None, None self.player = Player((1, 1), 5, 5, 1, 1, 3, 3, 0, 255) self.current_room = 1 self.turn = 1 self.change_room(1) def new(self): self.unused_keys = [] self.rooms = {} self.enemies = [] self.objects = [] self.base = [] self.entities = [] self.buttons = [] self.user_name = '' self.first = True self.background, self.top_panel, self.bottom_panel = None, None, None self.player = Player((1, 1), 5, 5, 1, 1, 3, 3, 0, 255) self.current_room = 1 self.turn = 1 self.change_room(1) def change_room(self, num): # смена комнаты, в которой находится игрок self.enemies = [] self.objects = [] self.base = [] if num not in self.rooms.keys(): # если следующей комнаты не существует self.generate_level(num) else: self.enemies = self.rooms[num].enemies self.objects = self.rooms[num].objects if self.first: # если запустили первый раз self.player.position = (1, 1) self.first = False elif num > self.current_room: # смотрим, откуда пришел игрок self.player.position = self.rooms[num].enter[1], \ self.rooms[num].enter[0] else: self.player.position = self.rooms[num].exit_[1], \ self.rooms[num].exit_[0] self.current_room = num self.entities = [self.player, *self.enemies] self.load_room(self.current_room) def load_room(self, num_of_room): # загрузка комнаты на экран self.base = [] level = self.rooms[num_of_room].structure() empty = Image.open('Sprites/ground/idle/00.png') wall = Image.open('Sprites/wall/idle/00.png') background = Image.new('RGB', (len(level[0]) * TILE, len(level) * TILE), (255, 255, 255)) # собираем из маленьких изображений пустых клетов и стен # одно большое изображение поля чтобы потом отображать только его for i in range(len(level)): for k in range(len(level[i])): if level[i][k] == 'W': self.base.append(Wall((k, i))) background.paste(wall, (k * TILE, i * TILE)) else: self.base.append(Empty((k, i))) background.paste(empty, (k * TILE, i * TILE)) self.background = pygame.image.fromstring(background.tobytes(), background.size, background.mode) self.top_panel = Panel(self.player, 0) # создаем верхнюю self.bottom_panel = Panel(None, 550) # и нижнюю панели self.buttons = [ # создаем кнопки Button('game/panel/exit', (550, 10), 'menu'), Button('game/panel/inventory', (450, 10), 'inventory'), Button('game/panel/save', (500, 10), 'save'), ] def generate_enemies(self, room): patterns = [ ['blue', 2, 2, 1, 1, 2, 2], ['green', 3, 3, 1, 2, 2, 2], ['red', 3, 3, 2, 2, 2, 2], ['purple', 4, 4, 2, 3, 3, 3], ] enemy_number = [0, 0, 0, 0] if room == 1: a = random.randint(2, 4) enemy_number = [a, 4 - a, 0, 0] elif 2 <= room <= 5: a = random.randint(3, 4) enemy_number = [4 - a, a, 0, 0] elif 6 <= room <= 9: a = random.randint(2, 3) enemy_number = [1, a, 3 - a, 0] elif 10 <= room <= 14: a = random.randint(3, 5) enemy_number = [0, 5 - a, a, 0] elif 15 <= room <= 20: a = random.randint(3, 4) enemy_number = [0, 4 - a, a, 1] elif room > 20: a = random.randint(4, 5) enemy_number = [0, 0, 6 - a, a] return [ patterns[i] for i in range(len(patterns)) for _ in range(enemy_number[i]) ] def generate_level(self, num): # генерация уровня игры (карты) closed_cells = [self.player.position] enter = (0, 0) if num != 1: enter = self.rooms[num - 1].enter_from_exit() enemies_options = self.generate_enemies(num) for i in range(len(enemies_options)): # генерация врагов x, y = random.randint(2, 9), random.randint(2, 8) while (x, y) in closed_cells: x, y = random.randint(2, 9), random.randint(2, 8) self.enemies.append(Enemy((x, y), *enemies_options[i])) closed_cells.append((x, y)) for i in range(random.randint(6, 7)): # генерация коробок x, y = random.randint(2, 8), random.randint(2, 7) while (x, y) in closed_cells: x, y = random.randint(2, 8), random.randint(2, 7) self.objects.append(Box((x, y))) closed_cells.append((x, y)) a, b = (0, 2) for i in range(random.randint(a, b)): # генерация зельев для здоровья x, y = random.randint(1, 9), random.randint(2, 8) while (x, y) in closed_cells: x, y = random.randint(1, 9), random.randint(2, 8) self.objects.append(Chest((x, y), 'potion', 'green')) closed_cells.append((x, y)) exit_ = random.choice([(random.randint(2, 8), 11), (9, random.randint(2, 9))]) if num > 6: # генерация зельев для повышения силы или количества ходов if not random.randint(0, 2): x, y = random.randint(1, 9), random.randint(2, 8) while (x, y) in closed_cells: x, y = random.randint(1, 9), random.randint(2, 8) self.objects.append( Chest((x, y), 'potion', random.choice(['red', 'blue']))) closed_cells.append((x, y)) if not random.randint(0, 2) and len(self.unused_keys) < 6: # генерация двери, если неиспользованных ключей меньше 6 door_color = random.choice(['red', 'blue', 'green']) x, y = random.randint(1, 9), random.randint(1, 8) while (x, y) in closed_cells: x, y = random.randint(2, 9), random.randint(2, 8) self.objects.append(Chest((x, y), 'key', door_color)) self.unused_keys.append(door_color) if not random.randint(0, 2) and self.unused_keys: # добавится ли дверь в текущую комнату self.objects.append( Door((exit_[1], exit_[0]), self.unused_keys.pop( random.randint(0, len(self.unused_keys) - 1)))) self.rooms[num] = Room(exit_, self.enemies, self.objects, num, enter) def load(self, user_name): # загрузка игры с базы cur = self.con.cursor() self.user_name = user_name player = cur.execute(f"""SELECT room_num, hit_points, max_hit_points, damage, max_damage, action_points, max_action_points, posX, posY, experience, max_experience FROM users WHERE user_name = '{user_name}'""").fetchone() # все харастеристикик игрока self.unused_keys = list( map( lambda i: i[0], cur.execute(f"""SELECT type FROM inventory WHERE user = '******' AND used = 'False'"""))) self.player = Player((player[-4], player[-3]), *player[1:-4], *player[-2:]) # игрок self.player.inventory = list( map( lambda i: i[0], cur.execute(f"""SELECT type FROM inventory WHERE user = '******' AND used = 'True'"""))) self.current_room = player[0] rooms = cur.execute(f"""SELECT id, number, enter_posX, enter_posY, exit_posX, exit_posY FROM rooms WHERE user = '******'""").fetchall() self.rooms = {} for room_id, number, *positions in rooms: # все комнаты подземелья enemies = cur.execute(f"""SELECT color, hit_points, max_hit_points, action_points, max_action_points, damage, max_damage, posX, posY FROM entities WHERE room_id = {room_id}""").fetchall() list_of_enemies = [] list_of_objects = [] # все враги на карте for color, hit, m_hit, act, m_act, dam, m_dam, x, y in enemies: list_of_enemies.append( Enemy((x, y), color, hit, m_hit, dam, m_dam, act, m_act)) objects = cur.execute(f"""SELECT type, posX, posY, inside, color, stage FROM objects WHERE room_id = {room_id}""").fetchall() for type_, x, y, inside, color, stage in objects: # все объекты на карте if type_ == 1: # коробки list_of_objects.append(Box((x, y))) elif type_ == 2: # сундуки list_of_objects.append( Chest((x, y), *reversed(inside.split('_')))) if stage: list_of_objects[-1].touch() else: # двери list_of_objects.append(Door((x, y), color)) self.rooms[number] = Room(positions[-2:], list_of_enemies, list_of_objects, number, positions[:2]) self.enemies = self.rooms[self.current_room].enemies self.entities = [self.player, *self.enemies] self.objects = self.rooms[self.current_room].objects self.load_room(player[0]) def save_room(self, n): # сохранение 1 комнаты в базе cur = self.con.cursor() room_id = cur.execute(f"""SELECT id FROM rooms WHERE number = {n} and user = '******'""").fetchone()[0] room = self.rooms[n] for enemy in room.enemies: if enemy.alive: cur.execute(f"""INSERT INTO entities(hit_points, max_hit_points, action_points, max_action_points, damage, max_damage, posX, posY, room_id, color) values({enemy.hit_points[0]}, {enemy.hit_points[1]}, {enemy.action_points[0]}, {enemy.action_points[1]}, {enemy.damage[0]}, {enemy.damage[1]}, {enemy.position[0]}, {enemy.position[1]}, {room_id}, '{enemy.color}')""") for obj in room.objects: # объекты комнаты if obj.name == 'box': cur.execute(f"""INSERT INTO objects(type, posX, posY, room_id) values(1, {obj.position[0]}, {obj.position[1]}, {room_id})""") elif obj.stage == 0: # если объект активен if obj.name == 'chest': cur.execute(f"""INSERT INTO objects(type, posX, posY, room_id, inside) values(2, {obj.position[0]}, {obj.position[1]}, {room_id}, '{obj.inside.name}')""") elif obj.name == 'door': cur.execute(f"""INSERT INTO objects(type, posX, posY, room_id, color) values(3, {obj.position[0]}, {obj.position[1]}, {room_id}, '{obj.color}')""") elif obj.stage == 1 and obj.name == 'chest': if obj.name == 'chest': cur.execute(f"""INSERT INTO objects(type, posX, posY, room_id, inside, stage) values(2, {obj.position[0]}, {obj.position[1]}, {room_id}, '{obj.inside.name}', 1)""") self.con.commit() def update_base(self): # обновление базы (если имя пользователя уже вводилось) cur = self.con.cursor() cur.execute(f"""UPDATE users SET room_num = {self.current_room}, hit_points = {self.player.hit_points[0]}, max_hit_points = {self.player.hit_points[1]}, action_points = {self.player.action_points[0]}, max_action_points = {self.player.action_points[1]}, damage = {self.player.damage[0]}, max_damage = {self.player.damage[1]}, posX = {self.player.position[0]}, posY = {self.player.position[1]}, experience = '{self.player.experience[0]}', max_experience = '{self.player.experience[1]}' WHERE user_name = '{self.user_name}'""") self.con.commit() cur.execute("""DELETE FROM inventory WHERE user = '******'""") # удаление старого инвентаря for obj in self.player.inventory: cur.execute(f"""INSERT INTO inventory(user, type, used) values('{self.user_name}', '{obj}', 'True')""") for obj in self.unused_keys: cur.execute(f"""INSERT INTO inventory(user, type, used) values('{self.user_name}', '{obj}', 'False')""") self.con.commit() for n, room in self.rooms.items(): # если в комнату заходили, то есть могли изменяться # положения врагов, объектов и тд room_id = cur.execute(f"""SELECT id FROM rooms WHERE number = {n} and user = '******'""").fetchone()[0] cur.execute(f"""DELETE FROM entities WHERE room_id = {room_id}""") self.con.commit() cur.execute(f"""DELETE FROM objects WHERE room_id = {room_id}""") self.con.commit() self.save_room(n) def save(self, user_name): # функция сохранения базы cur = self.con.cursor() self.user_name = user_name if not self.user_name else self.user_name cur.execute(f"""INSERT INTO users(user_name, room_num, hit_points, max_hit_points, action_points, max_action_points, damage, max_damage, posX, posY, experience, max_experience) values('{self.user_name}', {self.current_room}, {self.player.hit_points[0]}, {self.player.hit_points[1]}, {self.player.action_points[0]}, {self.player.action_points[1]}, {self.player.damage[0]},{self.player.damage[1]}, {self.player.position[0]}, {self.player.position[1]}, '{self.player.experience[0]}', '{self.player.experience[1]}')""") # добавление нового пользователя со всеми характеристиками self.con.commit() for obj in self.player.inventory: # добавление инвентаря игрока cur.execute(f"""INSERT INTO inventory(user, type, used) values('{self.user_name}', '{obj}', 'True')""") for obj in self.unused_keys: # добавляются неиспользованные ключи cur.execute(f"""INSERT INTO inventory(user, type, used) values('{self.user_name}', '{obj}', 'False')""") for n, room in self.rooms.items(): cur.execute(f"""INSERT INTO rooms(number, enter_posX, enter_posY, exit_posX, exit_posY, user) values({n}, {room.enter[0]}, {room.enter[1]}, {room.exit_[0]}, {room.exit_[1]}, '{self.user_name}')""") self.con.commit() self.save_room(n) # добавление каждой комнаты в базу def get(self, coordinates, diff=(0, 0)): """Возвращает объект по координатам""" for obj in [*self.entities, *self.objects, *self.base]: if obj.position == (coordinates[0] + diff[1], coordinates[1] + diff[0]): if getattr(obj, 'alive', True): return obj def player_move(self, button): """Движение игрока""" # словарь вида {кнопка: (смещение на X и Y)} buttons_keys = { pygame.K_LEFT: (0, -1), pygame.K_RIGHT: (0, 1), pygame.K_UP: (-1, 0), pygame.K_DOWN: (1, 0) } if any([ i.animator.animation not in ['idle', 'die'] for i in self.enemies ]): # если враги еще совершают какие-то действия, то игрок стоит return if self.player.animator.animation != 'idle': # если игрок совершает какое-то действие, то # мы не начинаем новое действие return if button not in buttons_keys.keys(): return # если нажали на неизвестную кнопку # проверяем на нахождение в телепорте self.player.interaction_teleport(self) # взаимодействуем с объектом obj = self.get(self.player.position, buttons_keys[button]) obj_name = obj.name if hasattr(obj, 'name') else None self.player.interaction(self, buttons_keys[button]) if obj_name == 'enemy' and not obj.alive: self.player.experience[0] += 2 if self.player.experience[0] > self.player.experience[1]: config.NEXT_WINDOW = 'win' def enemies_move(self): """Движение врагов""" if self.player.animator.animation != 'idle': return # если игрок что-то делает, то враги не начинают новых действий options = [(-1, 0), (1, 0), (0, -1), (0, 1)] res = [] blocked_cells = [] for enemy in self.enemies: if not enemy.alive: # текущий враг метрв, то переходим к следущему врагу continue if enemy.animator.animation != 'idle': res.append(True) # если враг уже совершает действие, # то переходим к следущему врагу continue checking = [] for i in options: checking.append( self.get(enemy.position, i).name in ('player', 'empty')) if not any(checking): # если врагу некуда идти res.append(False) continue player_pos = self.player.position enemy_pos = enemy.position diff = (0, 0) if random.randint(0, 1): # генерация ходов врага # враг пытается приблизиться к игроку if enemy_pos[0] != player_pos[0]: diff = (0, -1) if enemy_pos[0] > player_pos[0] else (0, 1) elif enemy_pos[1] != player_pos[1]: diff = (-1, 0) if enemy_pos[1] > player_pos[1] else (1, 0) else: if enemy_pos[1] != player_pos[1]: diff = (-1, 0) if enemy_pos[1] > player_pos[1] else (1, 0) elif enemy_pos[0] != player_pos[0]: diff = (0, -1) if enemy_pos[0] > player_pos[0] else (0, 1) while (enemy_pos[0] + diff[0], enemy_pos[1] + diff[1]) in blocked_cells or \ self.get(enemy_pos, diff).name not in ('empty', 'player'): diff = options[random.randint(0, len(options) - 1)] blocked_cells.append( (enemy_pos[0] + diff[0], enemy_pos[1] + diff[1])) # добавляем результат взаимодействия с список res.append(enemy.interaction(self, diff)) if not any(res): # если у всех врагов закончились очки действий self.turn = 1 # передаем ход игроку for enemy in self.enemies: # обновляем очки действий у врагов enemy.action_points[0] = enemy.action_points[1] def show(self, surf): """Отображение на поверхность""" if self.turn == 2: self.enemies_move() surf.blit(self.background, apply((0, 0))) # отображаем поле for entity in self.entities: # отображаем существ entity.show(surf) for obj in self.objects: # отображаем объекты obj.show(surf) self.top_panel.show(surf) # отображаем верхнюю self.bottom_panel.show(surf) # и нижнюю панели for elem in self.buttons: # отображаем кнопки elem.show(surf) def button_down(self, mouse_pos): """Нажатие мыши""" # получаем объект, на который нажали obj = self.get( (mouse_pos[0] // TILE, (mouse_pos[1] - PANEL_HEIGHT) // TILE)) if isinstance(obj, Enemy) and obj.alive: # если нажали на врага self.bottom_panel.change_target(obj) # меняем цель нижней панели else: self.bottom_panel.change_target(None) for elem in self.buttons: # проверяем нажатие на кнопки elem.button_down(mouse_pos) def key_down(self, key): """Нажатие на клавиатуру""" for elem in self.buttons: elem.key_down(key) if self.turn == 1: # если ход игрока self.player_move(key) # то вызываем функцию движения игрока
class World(object): def __init__(self, playerstate, level, scale=1.0, L=10, item=None): self.level = level self.scale = scale L *= scale self.L = L # self.stardust = StarDust(scale) self.wireframe = WireFrame(scale) self.sky = Sky() self.player = Player(self, playerstate, Vector4D(0, 0, 0, L)) self.enemies = Enemies(self) types = [randint(0, level.types - 1)for i in xrange(level.enemy_num-1)] types += [level.types-1] for t in types: x = 6*L*(2.0*random()-1.0) y = 6*L*(2.0*random()-1.0) z = 6*L*(1.0*random()-2.0) self.enemies.add(Vector4D(0, x, y, z), t) self.stars = Stars(self, Vector4D(0.0, 0.0, -0.5*scale, L-3*scale), scale) if item is not None and item == playerstate.gun_num: self.item = Item(item, self.player.P.X+Vector4D(0, 0, 0.5*scale, -5*scale), scale) else: self.item = None self.score = 0 def action(self, keys, ds): # self.player.worldline.reset() # for enemy in self.enemies: # enemy.worldline.reset() n = int(ds * 10.0) + 1 ds /= n count = 0 while count < n: self.player.action(keys, ds) self.score += self.enemies.action(ds) self.stars.hit_check(self.player.P.X) if (self.item is not None and self.player.P.X.distance_to_squared(self.item.X) < self.player.collision_radius2*4): self.player.state.gun_get() self.player.gun_get_time = self.player.time self.item = None elif self.item is not None: self.item.action(ds) count += 1 # self.player.worldline.cut() # for enemy in self.enemies: # enemy.worldline.cut() def draw(self, keys): L = Lorentz(self.player.P.U) Xp = self.player.P.X matrix = self.player.quaternion.get_RotMat() if keys.k_look_behind: matrix *= Matrix44.y_rotation(pi) matrix_i = matrix.get_inverse_rot() glDisable(GL_DEPTH_TEST) glLoadMatrixd(matrix_i.to_opengl()) self.sky.draw(matrix_i, Lorentz(-self.player.P.U)) if keys.k_map: # self.stardust.draw(Xp, L) self.wireframe.draw(Xp, L) glEnable(GL_DEPTH_TEST) self.stars.draw(Xp, L) self.enemies.draw(Xp, L) if self.item is not None: self.item.draw(Xp, L) for gun in self.player.guns: gun.bullets.draw(Xp, L) self.enemies.bullets.draw(Xp, L) glDisable(GL_DEPTH_TEST) self.player.draw_window(L) glEnable(GL_DEPTH_TEST) if keys.k_map: self.player.draw_hp() self.player.draw_gun_name() self.player.draw_booster(keys)
class Core: """ Cette classe contient tout le coeur du jeu * les données * l' update """ # définition du mat_collide _XMAX = 200 _YMAX = 150 _NB_ROOMS = 20 RULE_VISION = False GAME_STATE_RUN = True GAME_STATE_MENU = False def __init__(self): """ Initialisation """ # Matrice de collision onvention : True = libre; False = bloqué self.mat_collide = None # Matrice de vision True = VIsible. False = invisible self.mat_view = None # Matrice d'affichage du village self.mat_render = None # Entités self.player = Player() self.door = None self.bullets = None self.monsters = None self.treasure = None self.swords = None # COmpteur de update # TODO : Compteur dans les classes respectives self.cpt_bullet = None self.cpt_strike = None self.cpt_monster = None # Tableau d'affichage final self.buffer_window = [[None for _ in range(500)] for _ in range(500)] # Start ! self.generate() self.game_state = self.GAME_STATE_RUN self.timer_state = 0 def generate(self): """ Genere les salles du jeu <=> initialise tab """ # Generation du village village = Village(self._XMAX, self._YMAX, self._NB_ROOMS) village.generate() # Player dans la premiere salle self.player.level_up(village.rooms[0].center) self.door = Door(village.rooms[-1].center) # ======================== MATRICES ========================= # Matrice de collision onvention : True = libre; False = bloqué self.mat_collide = [[False for _ in range(self._YMAX)] for _ in range(self._XMAX)] # Matrice de vision True = VIsible. False = invisible self.mat_view = [[False for _ in range(self._YMAX)] for _ in range(self._XMAX)] # Matrice d'affichage du village self.mat_render = [[' ' for _ in range(self._YMAX)] for _ in range(self._XMAX)] # COLLIDES for pos in village.g_xyCollide(): self.mat_collide[pos.x][pos.y] = True # RENDER for pos, char in village.g_xyRender(): self.mat_render[pos.x][pos.y] = char # ======================== ENTITEES ========================= # Ajout de coffres (2 max par room) | Monsters self.bullets = [] self.monsters = [] self.treasure = [] self.swords = [] for i, room in enumerate(village.rooms): if i != 0: self.monsters.append( Monster(room.newRandomPointInRoom(), 1 + self.player.level // 3, 1 + self.player.level)) for _ in range(randint(0, 2)): self.treasure.append( Treasure(room.newRandomPointInRoom(), randint(1, 3))) # Cpt self.cpt_bullet = 0 self.cpt_strike = 0 self.cpt_monster = 0 self.monster_life = self.monsters[0].health def update(self, events): """ Met le jeu à jour fc(tous les events) """ self.cpt_monster += 1 self.cpt_bullet += 1 self.cpt_strike += 1 def get_user_depl(events): """ retourne le vecteur de deplacement """ # position desire (componsation des fleches opposées) return Vect( int(Key.right in events) - int(Key.left in events), int(Key.up in events) - int(Key.down in events)) def update_player(): """ Mise a jour du personnage """ self.player.update(self.mat_collide, get_user_depl(events)) # Shoot ? et assez de balles ? if Key.space in events and self.cpt_bullet >= 3 \ and self.player.bullet: self.cpt_bullet = 0 self.bullets.append(self.player.shoot()) # Strike if Key.shift in events and self.cpt_strike >= 4: self.cpt_strike = 0 self.swords.append(self.player.strike(self.mat_collide)) # Mise a jour de la cartograpgie for pos in self.player.g_case_visible(self.mat_collide): self.mat_view[pos.x][pos.y] = True def update_bullets(): """ Mise à jour des balles """ for i in range(len(self.bullets) - 1, -1, -1): if not self.bullets[i].update(self.mat_collide): self.bullets.pop(i) else: for i_monster in range(len(self.monsters) - 1, -1, -1): if self.bullets[i].pos \ == self.monsters[i_monster].pos \ or self.bullets[i].pos + self.bullets[i].direction \ == self.monsters[i_monster].pos: self.monsters[i_monster].health -= \ self.bullets[i].dammage self.monsters[i_monster].kill() self.bullets.pop(i) break def update_sword(): """² Mise à jour de l'épée """ for i in range(len(self.swords) - 1, -1, -1): if self.swords[i].update(self.mat_collide, self.player.pos): self.swords.pop(i) else: for i_monster in range(len(self.monsters) - 1, -1, -1): if self.swords[i].pos == self.monsters[i_monster].pos: self.monsters[i_monster].health -= \ self.swords[i].dammage self.monsters[i_monster].kill() break def update_monsters(): """ Mise à jour des monstres """ if self.cpt_monster % 3 == 0: for i in range(len(self.monsters) - 1, -1, -1): if self.monsters[i].update(self.mat_collide, self.player.pos): # Mort self.monsters.pop(i) else: # Vivant, le monstre fait des dégats au joueur if self.monsters[i].pos == self.player.pos \ and self.monsters[i].state != Monster.DECOMPOSITION: self.player.hp -= 1 def update_treasures(): """ Mise a jour des coffres """ for i in range(len(self.treasure) - 1, -1, -1): if self.treasure[i].pos == self.player.pos: if self.treasure[i].object == Treasure.HEART: if self.player.add_hp(self.treasure[i].value): self.treasure.pop(i) elif self.treasure[i].object == Treasure.BULLET: if self.player.add_bullets(self.treasure[i].value): self.treasure.pop(i) elif self.treasure[i].object == Treasure.GOLD: self.player.add_money(self.treasure[i].value) self.treasure.pop(i) elif self.treasure[i].object == Treasure.STRENGH: self.player.sword_damage += 1 self.treasure.pop(i) elif self.treasure[i].object == Treasure.POWER: self.player.gun_damage += 1 self.treasure.pop(i) self.timer_state += 1 if Key.esc in events and self.timer_state >= 4: self.timer_state = 0 self.game_state = not self.game_state if self.game_state == self.GAME_STATE_RUN: update_player() # Actualise le depl / tirs / vision update_monsters() # Actualise les monstres : enleve HP update_bullets() # Actualise toutes les balles : kill monsters update_sword() # Actualise le coup d'épee update_treasures() # Actualise les coffres : <3 / Balles / $ if self.player.pos == self.door.pos: self.generate() return self.player.hp >= 0 # Condition d'arret if self.game_state == self.GAME_STATE_MENU: return True def render(self, scr_size, g_scr_pos, os_info): """ retoure un tableau des caractères à affiche suivant l'ordre d'affichage fc(vision, rendu, objets) """ def render_run(): """ Render state = run """ def scr2mat(scr_pos): return scr_pos + self.player.pos - scr_size // 2 def mat2scr(mat_pos): return mat_pos - self.player.pos + scr_size // 2 def isScrPosInScr(scr_pos): return Vect(0, 0) <= scr_pos < scr_size # Rendu du fond for scr in g_scr_pos: mat_pos = scr2mat(scr) # Dans matrice et Visible if Vect(0, 0) <= mat_pos < Vect(self._XMAX, self._YMAX) and \ (self.mat_view[mat_pos.x][mat_pos.y] or self.RULE_VISION): self.buffer_window[scr.x][scr.y] = \ self.mat_render[mat_pos.x][mat_pos.y] else: self.buffer_window[scr.x][scr.y] = ' ' # Rendu des entitées for entity in chain(self.bullets, self.swords, self.monsters, self.treasure, [self.player], [self.door]): scr_pos = mat2scr(entity.pos) if isScrPosInScr(scr_pos) \ and self.mat_view[entity.pos.x][entity.pos.y] \ or self.RULE_VISION: self.buffer_window[scr_pos.x][scr_pos.y] = entity.render() # Rendu du joueur scr_pos = mat2scr(self.player.pos) self.buffer_window[scr_pos.x][scr_pos.y] = self.player.render() # Text top_bar = "Town : Koku <> ./ [***] " + os_info bot_bat1 = str(self.player) + " \ | Monsters : " + str(len(self.monsters)) bot_bat2 = ("[" + str(chars.C_BAR_DECORATIONS[self.cpt_monster % 4]) + "]" + "| Level : " + str(self.player.level) + "| Gold : " + str(self.player.money) + "| Sword : " + str(self.player.sword_damage) + "| Gun : " + str(self.player.gun_damage) + "| Monster lvl : " + str(self.monster_life)) for i, ch in enumerate( zip_longest(top_bar, bot_bat1, bot_bat2, range(scr_size.x), fillvalue=' ')): self.buffer_window[i][scr_size.y - 1] = (ch[0]) self.buffer_window[i][1] = (ch[1]) self.buffer_window[i][2] = (ch[2]) # Bousolle for y, string in enumerate( [" N ", " ^ ", "W<-o->E", " v ", " S "]): for x, char in enumerate(string): self.buffer_window[scr_size.x - 7 + x][5 - y] = (char) def render_menu(): """ Render state = menu """ # for scr in g_scr_pos: # self.buffer_window[scr.x][scr.y] = ' ' scr_center = scr_size // 2 box_cote = Vect(scr_size.x // 4, scr_size.y // 8) for pos in scr_center.g_rect(box_cote): self.buffer_window[pos.x][pos.y] = chars.C_PAUSE_BORDER for pos in scr_center.g_rect_fill_no_border(box_cote): self.buffer_window[pos.x][pos.y] = chars.C_PAUSE_FILL for i, char in enumerate("texte"): self.buffer_window[scr_center.x - 3 + i][scr_center.y] = char if self.game_state == self.GAME_STATE_RUN: render_run() if self.game_state == self.GAME_STATE_MENU: render_run() render_menu() return self.buffer_window
HALF_SCREEN_HEIGHT = SCREEN_HEIGHT // 2 if __name__ == "__main__": logging.basicConfig(format="[%(levelname)s @ %(name)s.%(funcName)s:%(lineno)s] %(message)s") window = pyglet.window.Window(SCREEN_WIDTH, SCREEN_HEIGHT) # create thread pool to allow async pathfinding pool = ThreadPoolExecutor(max_workers=2) generator = WorldGenerator(15, Vector2(100, 100), Vector2(300, 300), 50) # generate default world and dummy enemy world = generator.generate() camera = Camera(SCREEN_WIDTH, SCREEN_HEIGHT, 2) world.entities.append(EnemyEntity(world, Vector2(25, 25))) # enable player and give it the default Arrow Attack player = Player(world) player.skill = BowAttack() # add player, initialize labels world.entities.append(player) fps_display = FPSDisplay(window) fps_display.label.x += 200 support_display = Label("No Active Supports", font_size=12, x=window.width//2, y=12, anchor_x="center", anchor_y="center") score_display = Label("Score: ", font_size=12, x=window.width//2, y=24, anchor_x="center", anchor_y="center") @window.event def on_draw(): window.clear() # translate to isometric view camera.initialize_ortho()
class World(object): def __init__(self, level, scale, playerstate, item=None): self.level = level self.scale = scale self.playerstate = playerstate self.L = self.level.L * scale self.wireframe = WireFrame(scale=self.scale) self.sky = Sky() self.player = Player(world=self, level=level, state=playerstate, pos=Vector4D(0, 0, 0, self.L)) self.solar = SolarSystem(self, self.player.P.X, self.scale) self.enemies = Enemies(world=self) self.item = None if not level.is_travel(): self.init_set_enemy() self.init_set_item(item) self.init_set_worldline() self.score = 0 def init_set_enemy(self): types = [randint(0, self.level.types - 1)for i in xrange(self.level.enemy_num-1)] types += [self.level.types-1] for typ in types: x = 6.0 * self.L * (2.0*random()-1.0) y = 6.0 * self.L * (2.0*random()-1.0) z = 6.0 * self.L * (1.0*random()-2.0) self.enemies.add(Vector4D(0, x, y, z), typ=typ, level=self.level) def init_set_item(self, item): if item is not None and item == self.playerstate.gun_num: pos = self.player.P.X + Vector4D(0, 0, 0.5, -5.0) * self.scale self.item = Item(item, pos, self.scale) def init_set_worldline(self): self.worldline_ref = {} lis = list(self.enemies) + [self.player] for a in lis: self.worldline_ref[id(a)] = a.worldline for b in lis: if a is b: continue a.worldline.set_id(id(b.P.X)) def action(self, keys, ds): n = int(ds * 10.0) + 1 ds /= n count = 0 while count < n: self.player.action(keys, ds) self.score += self.enemies.action(ds) self.solar.hit_check(self.player.P.X) self.item_action(ds) count += 1 for wl in self.worldline_ref.itervalues(): wl.cut() def item_action(self, ds): if self.item is not None: self.item.action(ds) if self.item.check_collision(self.player.P.X, self.player.collision_radius2*4): self.player.state.gun_get() self.player.gun_get_time = self.player.time self.item = None def draw(self, keys): L = Lorentz(self.player.P.U) LL = Lorentz(-self.player.P.U) Xp = self.player.P.X matrix = self.player.quaternion.get_RotMat() if keys.k_look_behind: matrix *= Matrix44.y_rotation(pi) matrix_i = matrix.get_inverse_rot() glDisable(GL_DEPTH_TEST) glLoadMatrixd(matrix_i.to_opengl()) self.sky.draw(matrix_i, LL) if keys.k_map: self.wireframe.draw(Xp, L) glEnable(GL_DEPTH_TEST) self.solar.draw(Xp, L, LL) self.enemies.draw(Xp, L, LL, self.worldline_ref) if self.item is not None: self.item.draw(Xp, L, LL) for gun in self.player.guns: gun.bullets.draw(Xp, L) self.enemies.bullets.draw(Xp, L) if keys.k_map: glDisable(GL_DEPTH_TEST) self.player.draw_window(L) glEnable(GL_DEPTH_TEST) self.player.draw_hp() self.player.draw_gun_name() self.player.draw_booster(keys)
def __init__(self): self.c = Constants() self.player = Player(self.c.screen_width / 2, self.c.screen_height / 2, 300)
class Game: """The game logic itself. The loop and input handling are here.""" def __init__(self, screen): """Create the screen, player, assets.""" # Some technical items, first self.screen = screen self.gameScreen = curses.newpad(Constants.SCREENHEIGHT, Constants.SCREENWIDTH) self.running = True # Collections of various objects self.player = Player(self) self.walls = dict() self.doors = dict() self.decorations = dict() self.fences = dict() self.npcs = [] self.villagers = [] self.police = [] self.squares = [] # Camera self.cameraX = 0 self.cameraY = 0 # The current contents of the status line # TODO: Maybe rename this self.statusLine = "" # The bottom line contains the clock and other stuff self.bottomLine = "" # The current time and time-related variables self.hour = 7 self.minute = 59 self.turnsToNextMinute = 0 ### The actual game creation logic # Random decoration for _ in range(500): (y, x) = (random.randint(1, Constants.MAPHEIGHT - 1), random.randint(1, Constants.MAPWIDTH - 1)) self.decorations[(y, x)] = Decoration() # Create tiles for visibility and FoV self.tiles = dict() for x in range(Constants.MAPWIDTH): for y in range(Constants.MAPHEIGHT): self.tiles[(y,x)] = Tile() # Town creation self.town = Town(self, 5, 5, 3, 3) self.town2 = Town(self, 5, 88, 3, 3) # Setup the murder.. self.victim = None self.killer = None self.murderSetup() # Put together the NPC schedules self.generatePlans() def initialiseWalls(self): """Builds the correct wall graphics""" # This is one of the ugliest things I've ever written. # Don't judge me! for (y, x) in self.walls: wall = self.walls[(y, x)] if wall.character.isdigit(): continue wallUp = wallDown = wallLeft = wallRight = False # Check for walls via worst method possible try: self.walls[(y-1, x)] wallUp = True except Exception as e: pass try: self.walls[(y+1, x)] wallDown = True except Exception as e: pass try: self.walls[(y, x-1)] wallLeft = True except Exception as e: pass try: self.walls[(y, x+1)] wallRight = True except Exception as e: pass # Check for doors using the same awful method try: self.doors[(y-1, x)] wallUp = True except Exception as e: pass try: self.doors[(y+1, x)] wallDown = True except Exception as e: pass try: self.doors[(y, x-1)] wallLeft = True except Exception as e: pass try: self.doors[(y, x+1)] wallRight = True except Exception as e: pass system = platform.system() UpDown = '|' LeftRight = '-' UpLeft = '-' UpRight = '-' DownLeft = '-' DownRight = '-' DownLeftRight = '-' UpLeftRight = '-' LeftUpDown = '|' RightUpDown = '|' UpDownLeftRight = '|' # Terrible attempt at getting nice walls in Linux # UpDown = '|' # LeftRight = '-' # UpLeft = chr(0x6a) # UpRight = chr(0x6d) # DownLeft = chr(0x06b) # DownRight = chr(0x6c) # DownLeftRight = chr(0x77) # UpLeftRight = chr(0x76) # LeftUpDown = chr(0x75) # RightUpDown = chr(0x74) # UpDownLeftRight = chr(0x6e) # Smells bad, huh. if (system == 'Windows'): LeftRight = chr(0xC4) UpDown = chr(0xB3) UpLeft = chr(0xD9) UpRight = chr(0xC0) DownLeft = chr(0xBF) DownRight = chr(0xDA) DownLeftRight = chr(0xC2) UpLeftRight = chr(0xC1) LeftUpDown = chr(0xB4) RightUpDown = chr(0xC3) UpDownLeftRight = chr(0xC5) if (wallLeft or wallRight): wall.character = LeftRight else: wall.character = UpDown # Yeah.. This just happened. Next time consider bitstates if (wallUp and wallLeft): wall.character = UpLeft if (wallUp and wallRight): wall.character = UpRight if (wallDown and wallLeft): wall.character = DownLeft if (wallDown and wallRight): wall.character = DownRight if (wallDown and wallLeft and wallRight): wall.character = DownLeftRight if (wallUp and wallLeft and wallRight): wall.character = UpLeftRight if (wallLeft and wallUp and wallDown): wall.character = LeftUpDown if (wallRight and wallUp and wallDown): wall.character = RightUpDown if (wallRight and wallUp and wallDown and wallLeft): wall.character = UpDownLeftRight def mainLoop(self): """Run the game while a flag is set.""" # Initialise walls to correct characters self.initialiseWalls() # Start the main loop while (self.running): self.logic() self.draw() self.handleInput() def isInCamera(self, entityY, entityX): """ Shouldn't be a class method. Determines if we should draw a character or not.""" return (entityY >= self.cameraY and entityY < self.cameraY + Constants.GAMEHEIGHT and entityX >= self.cameraX and entityX < self.cameraX + Constants.GAMEWIDTH) def draw(self): """ Draw it all, but only the stuff that would be on the screen""" # Wipe out the screen. self.screen.erase() self.gameScreen.erase() # Sort out the camera self.cameraX = max(0, self.player.x - Constants.GAMEWIDTH // 2) self.cameraX = min(self.cameraX, Constants.MAPWIDTH - Constants.GAMEWIDTH) self.cameraY = max(0, self.player.y - Constants.GAMEHEIGHT // 2) self.cameraY = min(self.cameraY, Constants.MAPHEIGHT - Constants.GAMEHEIGHT) alwaysSeeWalls = False # Draw the floors, walls, etc. # Floors first, then we'll override them for x in range(0, Constants.MAPWIDTH): for y in range(0, Constants.MAPHEIGHT): if not self.isInCamera(y, x): continue if self.tiles[(y, x)].visible or not Constants.FOV_ENABLED: self.gameScreen.addstr( y, x, '.', Constants.COLOUR_GREEN) if (y, x) in self.decorations: decoration = self.decorations[(y, x)] self.gameScreen.addstr(y, x, decoration.character, decoration.colour) # Fences if (y, x) in self.fences: fence = self.fences[(y, x)] self.gameScreen.addstr(y, x, fence.character, fence.colour) # Doors if (y, x) in self.doors: door = self.doors[(y, x)] self.gameScreen.addstr(y, x, door.character, door.colour) if (self.tiles[(y,x)].seen and (alwaysSeeWalls or self.tiles[(y,x)].visible) or not Constants.FOV_ENABLED): if (y, x) in self.walls: wall = self.walls[(y,x)] self.gameScreen.addstr(y, x, wall.character, wall.colour) # Draw the entities like players, NPCs for npc in self.npcs: npcPos = (npc.y, npc.x) if npcPos in self.tiles: tile = self.tiles[npcPos] if (self.isInCamera(npc.y, npc.x) and tile.visible or not Constants.FOV_ENABLED): if (npc in self.villagers and self.player.notebook.isNpcKnown(npc) and npc.alive): character = str(npc.square.house.number) else: character = npc.character self.gameScreen.addstr(npc.y, npc.x, character, npc.colour) player = self.player self.gameScreen.addstr(player.y, player.x, player.character, player.colour) # Status line printing self.screen.addstr(0, 0, self.statusLine) self.statusLine = "" # Debug and bottom status stuff self.screen.addstr(Constants.GAMEHEIGHT +1, 0, self.bottomLine) if self.npcs: npc = self.npcs[0] if npc.path: path = npc.path[0] self.screen.addstr(Constants.GAMEHEIGHT+2, 1, str(path)) self.screen.noutrefresh() self.gameScreen.noutrefresh(self.cameraY, self.cameraX, 1, 1, Constants.GAMEHEIGHT, Constants.GAMEWIDTH) screen.moveCursorToPlayer(self.screen, self.player) # Blit the screen curses.doupdate() def getAnyKey(self): """Utility funciton that waits until a ANY input has been entered, does not return anything.""" self.screen.getch() def getKey(self, acceptedInputs = Constants.KEYMAP.values()): """Utility funciton that waits until a valid input has been entered.""" gotKey = False while not gotKey: got = self.screen.getch() if (got in Constants.KEYMAP and Constants.KEYMAP[got] in acceptedInputs): key = Constants.KEYMAP[got] return key def getDialogueChoice(self, numberOfChoices): """Utility funciton that waits until a valid dialogue choice has been entered.""" gotKey = False while not gotKey: got = self.screen.getch() if (got >= ord('1') and got <= ord(str(numberOfChoices))): return int(chr(got)) def printStatus(self, status, moveCursor = True): """Prints the status line. Also sets it so it doesn't get wiped until next frame""" self.statusLine = status self.screen.addstr(0, 0, " " * Constants.XRES) self.screen.addstr(0, 0, status) if moveCursor: screen.moveCursorToPlayer(self.screen, self.player) def printDescription(self, text, header = None, showAnyKeyPrompt = True): """Prints the description in a nice box before re-drawing the game on closure""" # Print the text if header: underline = '-' * Constants.DESC_BOX_WIDTH screen.printBox(self.screen, [header, underline, text], showAnyKeyPrompt) else: screen.printBox(self.screen, [text], showAnyKeyPrompt) # Wait for an input screen.moveCursorToPlayer(self.screen, self.player) self.getAnyKey() self.printStatus("") self.draw() def getYesNo(self, message = None): """Utility function for getting 'yes/no' responses.""" gotYesNo = False key = None if message: self.printStatus(message) while not gotYesNo: key = self.screen.getch() if key is ord('y') or key is ord('n'): gotYesNo = True self.printStatus("") return key is ord('y') def kickDoor(self): """Prompts for direction and attempts to kick down the door there if present.""" actionTaken = True self.printStatus("Which direction?") direction = self.screen.getch() success = random.randrange(100) > 80 playerPos = [self.player.y, self.player.x] try: direction = Constants.KEYMAP[direction] if direction == InputActions.MOVE_LEFT: playerPos[1] -= 1 elif direction == InputActions.MOVE_DOWN: playerPos[0] += 1 elif direction == InputActions.MOVE_UP: playerPos[0] -= 1 elif direction == InputActions.MOVE_RIGHT: playerPos[1] += 1 if playerPos != [self.player.y, self.player.x]: try: door = self.doors[tuple(playerPos)] if not door.closed: self.printStatus("It's open, champ.") elif success: door.locked= False door.playerOpen() self.printStatus("The door slams open!") else: self.printStatus("The door holds fast.") except: self.printStatus("No door there!") actionTaken = False else: self.printStatus("Nevermind.") actionTaken = False except: self.printStatus("Nevermind.") actionTaken = False return actionTaken def talk(self): """Prompts for direction and talks to NPC in that direction if present.""" promptText = "Navigate with left and right, cancel with Quit, select with Talk" (npc, error) = self.selectVisibleNPC(promptText, InputActions.TALK) if not npc: self.printStatus(error) return False elif not npc.alive: self.printStatus("I don't think they're in a talkative mood.") return False else: npc.beginConversation() return True def openDoor(self): self.printStatus("Which direction?") direction = self.screen.getch() playerPos = [self.player.y, self.player.x] actionTaken = True try: direction = Constants.KEYMAP[direction] if direction == InputActions.MOVE_LEFT: playerPos[1] -= 1 elif direction == InputActions.MOVE_DOWN: playerPos[0] += 1 elif direction == InputActions.MOVE_UP: playerPos[0] -= 1 elif direction == InputActions.MOVE_RIGHT: playerPos[1] += 1 if playerPos != [self.player.y, self.player.x]: try: door = self.doors[tuple(playerPos)] door.playerOpen() except: self.printStatus("No door there!") actionTaken = False else: self.printStatus("Nevermind.") actionTaken = False except: self.printStatus("Nevermind.") actionTaken = False return actionTaken def selectVisibleNPC(self, promptText, selectionAction): visibleNpcs = [npc for npc in self.npcs if self.tiles[npc.y, npc.x].visible and self.isInCamera(npc.y, npc.x)] error = "No-one in sight!" npcSelected = None if visibleNpcs: npcIdx = 0 while not npcSelected: self.printStatus(promptText, False) screen.moveCursorToEntity(self.screen, self.player, visibleNpcs[npcIdx]) key = self.getKey([InputActions.MOVE_LEFT, InputActions.MOVE_RIGHT, selectionAction, InputActions.QUIT]) if key == InputActions.MOVE_LEFT: npcIdx += 1 if npcIdx >= len(visibleNpcs): npcIdx = 0 elif key == InputActions.MOVE_RIGHT: npcIdx -= 1 if npcIdx < 0: npcIdx = len(visibleNpcs) - 1 elif key == selectionAction: npcSelected = visibleNpcs[npcIdx] elif key == InputActions.QUIT: break if not npcSelected and visibleNpcs: error = "Cancelled." return (npcSelected, error) def look(self): promptText = "Navigate with left and right, cancel with Quit, select with Look" (npc, error) = self.selectVisibleNPC(promptText, InputActions.LOOK) if not npc: self.printStatus(error) else: status = "" if self.player.notebook.isNpcKnown(npc): thatWord = "That's " if npc.alive else "That was " status = (thatWord + npc.firstName + " " + npc.lastName + "." + " " + npc.getDescription()) else: status = "You don't know who that is. " + npc.getDescription() self.printDescription(status) return False def handleInput(self): """ Wait for the player to press a key, then handle input appropriately.""" actionTaken = False while not actionTaken: key = self.getKey() # Clear the status line self.printStatus("") # Assume guilty until proven innocent. actionTaken = True # Quit? if key == InputActions.QUIT: quit = self.getYesNo("Are you sure you want to quit?") if quit: self.running = False else: actionTaken = False # Move? elif key == InputActions.MOVE_LEFT: actionTaken = self.player.attemptMove(Direction.LEFT) elif key == InputActions.MOVE_DOWN: actionTaken = self.player.attemptMove(Direction.DOWN) elif key == InputActions.MOVE_UP: actionTaken = self.player.attemptMove(Direction.UP) elif key == InputActions.MOVE_RIGHT: actionTaken = self.player.attemptMove(Direction.RIGHT) elif key == InputActions.OPEN_DOOR: actionTaken = self.openDoor() elif key == InputActions.KICK_DOOR: actionTaken = self.kickDoor() elif key == InputActions.LOOK: actionTaken = self.look() elif key == InputActions.TALK: actionTaken = self.talk() elif key == InputActions.WAIT: actionTaken = True # Do nothing. def murderSetup(self): """Picks the victim and murderer, and kills the victim""" victim = random.choice(self.villagers) self.victim = victim killer = None while True: killer = random.choice(self.villagers) if killer is not victim: self.killer = killer killer.killer = True break victim.die() house = victim.square.house # Unlock the front door doorY = house.absoluteY + house.frontDoorPos[0] doorX = house.absoluteX + house.frontDoorPos[1] self.doors[doorY, doorX].locked = False # Put the player outside the dead guy's house self.player.y = house.absoluteY + house.frontDoorPos[0] + 1 self.player.x = house.absoluteX + house.frontDoorPos[1] # Spawn some cops around the dead guy and next to our character copSpawnLocations = [(self.player.y, self.player.x + 1)] for _ in range(0, random.randint(4, 5)): y = random.randint(house.absoluteY + 1, house.absoluteY + house.height - 1) x = random.randint(house.absoluteX + 1, house.absoluteX + house.width - 1) copSpawnLocations.append((y,x)) for location in copSpawnLocations: (y, x) = location police = Police(self, y, x) self.npcs.append(police) self.police.append(police) self.player.notebook.addToKnownNpcs(police) self.printStatus("\"It's a messy one today, boss.\"") def generatePlans(self): """Generate the initial Plans for all NPCs""" # It should be pretty consistent. Like, if an NPC is visiting # another NPC's house, the vistee shouldn't make a plan to go out. for npc in self.villagers: if npc.alive: for x in range(5): randomSquareIndex = None while True: # Don't visit the dead guy, that's morbid randomSquare = random.choice(self.squares) if randomSquare.npc.alive: break visitNeighbour = Plan.VisitNeighbour(npc, randomSquare) randomHour = random.randint(0, 8) + 8 npc.plan.addPlanEntry(randomHour, 0, visitNeighbour) def logic(self): """Run all the assorted logic for all entities and advance the clock""" if self.turnsToNextMinute <= 0: self.minute += 1 if self.minute == 60: self.minute = 0 self.hour += 1 if self.hour == 24: self.hour = 0 self.turnsToNextMinute = Constants.TURNS_BETWEEN_MINUTES else: self.turnsToNextMinute -= 1 for npc in self.npcs: npc.update() for door in self.doors: self.doors[door].update() self.player.generateFov() # Update the bottom line self.bottomLine = "(" + str(self.player.x) + ", " + str(self.player.y) + ")" time = str(self.hour).zfill(2) + ":" + str(self.minute).zfill(2) self.bottomLine += " " + time
def game(): screen.fill(black) running = True keyboard = Keyboard() world = World(32, 32) off = ((WIDTH - world.get_render_width()) / 2, (HEIGHT - world.get_render_height()) / 2) world.offX = off[0] world.offY = off[1] ply = Player(0, 0, world) ply.x = random.randint(0, WIDTH - ply.w) ply.y = random.randint(0, HEIGHT - ply.h) while world.entity_hitpos(ply): ply.x = random.randint(0, WIDTH - ply.w) ply.y = random.randint(0, HEIGHT - ply.h) physics = Physics(world, (WIDTH, HEIGHT)) physics.watch(ply) clock = pygame.time.Clock() last = pygame.time.get_ticks() ticks = 0 plydeathtimer = 0 lastrect = pygame.Rect(0, 0, 0, 0) while running: ticks += 1 clock.tick(0) for ev in pygame.event.get(): if ev.type == QUIT: running = False break elif ev.type == FRAMECOUNTER: print clock.get_fps() elif ev.type == WORLDREGEN: world.regen_once() elif ev.type == ENTITYGEN: x = random.randint(0, WIDTH) y = random.randint(0, HEIGHT) physics.watch(Enemy(x, y, world, physics)) elif ev.type == MOUSEBUTTONDOWN: if ev.button == 0 and plydeathtimer == 0: mpos = ev.pos center = ply.get_center() a = mpos[0] - center[0] b = mpos[1] - center[1] # tan(ang) = b / a ang = math.atan2(b, a) # Calculate bullet pos pos = [math.cos(ang) * ply.w + center[0], math.sin(ang) * ply.h + center[1]] bull = Bullet(pos[0], pos[1], world) speed = 2 bull.vx = speed * math.cos(ang) bull.vy = speed * math.sin(ang) physics.watch(bull) shootsound.play() elif ev.type == KEYDOWN: keyboard.keydown(ev.key) elif ev.type == KEYUP: keyboard.keyup(ev.key) # Handle movement if plydeathtimer == 0: if keyboard.is_down(K_w): ply.vy = -1 elif keyboard.is_down(K_s): ply.vy = 1 else: ply.vy = 0 if keyboard.is_down(K_a): ply.vx = -1 elif keyboard.is_down(K_d): ply.vx = 1 else: ply.vx = 0 # Shooting repeat if ticks % 10 == 0 and pygame.mouse.get_pressed()[0]: mpos = pygame.mouse.get_pos() center = ply.get_center() a = mpos[0] - center[0] b = mpos[1] - center[1] # tan(ang) = b / a ang = math.atan2(b, a) # Calculate bullet pos pos = [math.cos(ang) * ply.w + center[0], math.sin(ang) * ply.h + center[1]] bull = Bullet(pos[0], pos[1], world) speed = 2 bull.vx = speed * math.cos(ang) bull.vy = speed * math.sin(ang) physics.watch(bull) shootsound.play() for ent in physics.entities: if isinstance(ent, Enemy): ent.think(ply) if world.win(): win() running = False if ply.lives == 0: lose() running = False elif ply.removeme: ply.removeme = False plydeathtimer = 180 if plydeathtimer > 0: if plydeathtimer == 1: ply.x = random.randint(0, WIDTH - ply.w) ply.y = random.randint(0, HEIGHT - ply.h) while world.entity_hitpos(ply): ply.x = random.randint(0, WIDTH - ply.w) ply.y = random.randint(0, HEIGHT - ply.h) physics.watch(ply) plydeathtimer -= 1 # Clear previous font screen.fill(black, lastrect) # Render physics.renderclear(screen) world.render(screen) physics.tick() physics.render(screen) # Display health msg = "Lives: %d | Health: %d" % (ply.lives, ply.health) text = bigfont.render(msg, 1, white) lastrect = pygame.Rect(0, 0, text.get_width(), text.get_height()) screen.blit(text, (0, 0)) pygame.display.flip() dt = pygame.time.get_ticks() - last if dt < (1000 / 60): pygame.time.delay((1000 / 60) - dt) last = pygame.time.get_ticks()
def main(): # Define the console and map's size console_width = 80 console_height = 60 map_width = 80 map_height = 45 # UI component sizes, partially based off of the sizes above bar_width = 20 message_x = bar_width + 2 message_width = console_width - bar_width - 2 message_height = console_height-map_height -2 # The colors passed into the rendering functions map_colors = { 'tree' :tcod.Color(102,51,0), 'dark tree':tcod.Color(51,25,0), 'grass':tcod.Color(0,102,0), 'dark grass':tcod.Color(0,51,0), 'burning out':tcod.orange, 'dim':tcod.yellow, 'bright':tcod.yellow, 'too bright':tcod.white } # Random generation variables tree_density = 30 clearing_min = 5 clearing_max = 10 max_clearings = 25 max_entities_per_room = 4 # Init player player_x = randint(0, map_width) player_y = randint(0, map_height) fighter_module=Fighter(hp=30, defense=2, power=5) eater_module=Eater(50,30) player = Player(player_x,player_y,'G', tcod.white, 'Player', blocks=True, render_order=RenderOrder.ACTOR,fighter=fighter_module, eater=eater_module) fov_radius = 8 # Entities list will keep track of all humans,corpses, and the player entities = [player] # Create a console using a provided tileset image to contain the game tileset = tcod.console_set_custom_font('dejavu10x10_gs_tc.png', tcod.FONT_TYPE_GREYSCALE | tcod.FONT_LAYOUT_TCOD) console = tcod.Console(console_width, console_height) # Initialize map forestMap = ForestMap(map_width,map_height) forestMap.gen_forest(tree_density,clearing_min,clearing_max,max_clearings, player, entities, max_entities_per_room) # Player's field of view fov_map = initialize_fov(forestMap) fov_recompute = True # Message log that prints game Messages message_log = MessageLog(message_x,message_width, message_height) # Initialize mouse location for mouse hover hints feature mouse_hover_loc=(0,0) with tcod.context.new_terminal(console.width, console.height,title='Grue 2', tileset=tileset,) as root_console: # Intro text intro = ["Welcome to Grue 2!", "The humans are trying to hunt you down, and you're hungry!", "1. Avoid the light! it burns and its hard to see in it.", "2. Win the game by filling your hunger bar! Lose by starving.", "Controls:", "Up,Down,Left,Right: J,K,H,L", "Up-Left,Up-Right: Y,U", "Down-Left,Down-Right: B,N", "Wait: Space Bar", "Eat: E when available", "Rest: R when alone" ] for text in intro: # Print intro to message log message = Message(text,tcod.white) message_log.add_message(message) for entity in entities: if entity.torch: entity.torch.updateFov() # Starts the game with the player moving first game_state = GameStates.PLAYER_TURN while True: # Main game loop #Clear console before redrawing if fov_recompute: recompute_fov(fov_map, player.x, player.y, fov_radius) console.clear(fg=(255,127,0)) # Render player in their current position, and the message log render(console,entities,player,forestMap,fov_map, fov_recompute,console_width,console_height,bar_width,map_colors, message_log, mouse_hover_loc) fov_recompute = False # Display the console root_console.present(console) # Process events for event in tcod.event.wait(): # Events are sent to input_handler.py for processing action = handle_input(event) move = action.get('move') eat = action.get('eat') rest = action.get('rest') if event.type == 'MOUSEMOTION': # Converts event's pixel coordinates into tile coordinates root_console.convert_event(event) mouse_hover_loc = event.tile player_turn_results = [] # Messages and flags are gathered into a list to process all at once if game_state == GameStates.PLAYER_TURN: # Update player's position if they have moved if move: dx, dy = move dest_x = player.x + dx dest_y = player.y + dy # Check for a valid move if dest_x >= 0 and dest_x < map_width and dest_y >= 0 and dest_y < map_height: if not forestMap.is_blocked(dest_x, dest_y): target = get_blocking_entity(entities, dest_x, dest_y) if target and target is not player: # Attack enemy if in destination tile attack_results = player.fighter.attack(target) player_turn_results.extend(attack_results) else: # Otherwise, just move to the new empty tile player.move(dest_x, dest_y) starve_results = player.eater.starve() player_turn_results.extend(starve_results) game_state = GameStates.ENEMY_TURN # Note: Nothing is printed to the message log if the player walks into a tree, to avoid excessive messages else: # Print an error if the player reaches the edges of the map message = Message("You can't leave the dark forest!",tcod.yellow) message_log.add_message(message) fov_recompute = True # Set flag to render player's new field of view due to changed coordinates elif eat: # If the player tries to eat, check if a food entity is available target = get_consumable_entity(entities, player.x, player.y) if target: # If so, eat it, and add items to player_turn_results. Healing is processed later. amount_eaten, consume_result = target.food.consume() eat_results = player.eater.eat(amount_eaten) player_turn_results.extend(consume_result) player_turn_results.extend(eat_results) fov_recompute = True # Rerender field of view because of possible removed entity game_state = GameStates.ENEMY_TURN elif rest: being_chased = False for entity in entities: # Check if an Entity is currently chasing the player if entity.ai: if entity.ai.chasing: being_chased = True message = None if being_chased: # If so, print an error in the Message Log, and keep it as the player's turn message = Message("You cannot rest while there are enemies nearby",tcod.orange) message_log.add_message(message) elif player.fighter.hp < player.fighter.max_hp and player.eater.hunger > 0: # If it's safe to rest, they heal, lose hunger value, and end the player's turn message = Message("You rest briefly...",tcod.light_grey) message_log.add_message(message) heal_results = player.fighter.heal(1) player_turn_results.extend(heal_results) starve_results = player.eater.starve() player_turn_results.extend(starve_results) fov_recompute = True # Rerender field of view because of changed HP/Hunger bars game_state = GameStates.ENEMY_TURN for player_turn_result in player_turn_results: # Parse results from player moves message = player_turn_result.get('message') dead_entity = player_turn_result.get('dead') recovery = player_turn_result.get('recovery') consumed = player_turn_result.get('consumed') starving = player_turn_result.get('starving') # Print messages to message log if message: message_log.add_message(message) # Heal the player, check if their hunger bar reaches max hunger, which is the winning condition if recovery: heal_results = player.fighter.heal(recovery) eating_results = player.eater.eat(recovery) for result in heal_results: message = result.get('message') if message: message_log.add_message(message) for result in eating_results: message = result.get('message') stuffed = result.get('stuffed') if message: message_log.add_message(message) if stuffed: message = Message("Your stomach is fit to burst, and does! You win!", tcod.yellow) message_log.add_message(message) game_state = GameStates.PLAYER_WINS break if game_state == GameStates.PLAYER_WINS: break if game_state == GameStates.PLAYER_WINS: # When the player wins, no further input is possible break # Except for Esc which closes the game if consumed: # If an entity's food module has been consumed, remove the entity from existence message = Message("{0} has been eaten whole!".format(consumed.name.capitalize()), tcod.grey) message_log.add_message(message) entities.remove(consumed) if starving: # If the player is starving, take damage each turn starved = player.fighter.take_damage(1) if starved: # If the starved flag is returned, the player has died of starvation dead_entity = player if dead_entity: # Handle all entity deaths if dead_entity == player: # The player's death results in a game over, in death_functions.py message, game_state = kill_player(player) fov_recompute = True else: # Other entities are killed and turned into corpses/food message = kill_enemy(dead_entity) message_log.add_message(message) # Message about who died is passed into the message log # Process all of the enemy's turns if game_state == GameStates.ENEMY_TURN: enemy_turn_results = [] player_lightLevel = 0 for entity in entities: if entity.ai: # If the entity has an ai module attached, they get a turn (non ai Entities are just items, like corpses) enemy_turn_results.extend(entity.ai.take_turn(player, fov_map, forestMap, entities)) if entity.torch: # If the entity has a torch, check the field of view and if it touches the player entity.torch.updateFov() if entity.torch.brightness > 0: # Check and get the highest brightness on the player's tile lit = tcod.map_is_in_fov(entity.torch.fov,player.x,player.y) if lit == True: # Keep track of the brightest value touching the player, if any if entity.torch.brightness > player_lightLevel: player_lightLevel = entity.torch.brightness burn_results = entity.torch.burn(fov_map) enemy_turn_results.extend(burn_results) if game_state == GameStates.PLAYER_DEAD: break if player_lightLevel: # If the player was caught in torchlight, add message about damage, and take damage basedon the light level message = [{'message':Message("You are burning from the light and take {0} damage!".format(player_lightLevel),tcod.red)}] enemy_turn_results.extend(message) burning_result = player.fighter.take_damage(player_lightLevel) enemy_turn_results.extend(burning_result) for enemy_turn_result in enemy_turn_results: # Process all enemy turn results at once message = enemy_turn_result.get('message') dead_entity = enemy_turn_result.get('dead') torch_out = enemy_turn_result.get('torch_out') if message: # Print any messages to the message log message_log.add_message(message) if torch_out: # If an entity's torch has gone out, remove their torch module torch_out.torch = None if dead_entity: # If an entity died, process based on who if dead_entity == player: # Player death = game over message, game_state = kill_player(dead_entity) else: # Entity death results in losing ai/fighter/torch modules, gaining food module and becoming a corpse message = kill_enemy(dead_entity) message_log.add_message(message) # Add message about who died to the message log if game_state is not GameStates.PLAYER_DEAD: # So long as the player is not dead, it becomes the player's turn again game_state = GameStates.PLAYER_TURN # First, however, the map will be rendered again.
class Game: def __init__(self, mapFile, enemies=[Enemy(10, 10, 1), Enemy(11, 10, 1)]): self.player = Player() self.enemies = enemies self.prevLoc = (self.player.getX(), self.player.getY()) self.map = [[]] self.items = [Weapon(WeaponType.SWORD, 3, 3)] with open(mapFile, "r") as mapTxt: for line in mapTxt.readlines(): self.map.append(self.split(line.rstrip())) self.updatePlayer() def updatePlayer(self, direction=Direction.UP, isTick=True): self.map[self.prevLoc[1]][self.prevLoc[0]] = " " self.map[self.player.getY()][self.player.getX()] = direction.value self.player.setDirection(direction) self.prevLoc = (self.player.getX(), self.player.getY()) self.updateMap(isTick) def updateMap(self, isTick=True): os.system('cls' if os.name == 'nt' else 'clear') # 🛡 if isTick: self.updateEntities() self.updateItems() print("Tick") else: print("Not tick") printMap = f"\n{TermColors.OKGREEN}{self.player}{TermColors.ENDC}\n" for arr in self.map: printMap += self.convert(arr) print(printMap) def move(self, direction): if self.player.entityCanMove(direction, self.map): if direction == Direction.UP: self.player.moveUp() elif direction == Direction.LEFT: self.player.moveLeft() elif direction == Direction.RIGHT: self.player.moveRight() elif direction == Direction.DOWN: self.player.moveDown() self.updatePlayer(direction) else: self.updatePlayer(direction, False) def performAction(self): direction = self.player.getDirection() location = (self.player.getX(), self.player.getY()) if direction == Direction.UP: location = (location[0], location[1] - 1) elif direction == Direction.DOWN: location = (location[0], location[1] + 1) elif direction == Direction.LEFT: location = (location[0] - 2, location[1]) elif direction == Direction.RIGHT: location = (location[0] + 2, location[1]) for item in self.items: itemLocation = item.getLocation() print( f"item x: {itemLocation[0]}, item y: {itemLocation[1]}, statement evaluates to {itemLocation[0] == location[0]//2 + 1 and itemLocation[1] == location[1]}" ) if itemLocation[0] == location[0] and itemLocation[1] == location[ 1]: print("We did it") self.getItem(item) for index, enemy in enumerate(self.enemies): enemyLocation = enemy.getCurrentLocation() print( f"Enemy health: {enemy.getHealth()}, enemy location: {enemyLocation}, location in front of player: ({location[0]//2 + 1}, {location[1]})" ) if enemyLocation[0] == location[0] // 2 + 1 and enemyLocation[ 1] == location[1]: enemy.removeHealth(self.player.getDamage()) print(enemy.checkIfDead()) if enemy.checkIfDead(): print("Dead") del (self.enemies[index]) self.items.append(enemy.dropItem()) self.updatePlayer(self.player.getDirection(), True) def switchWeapon(self, index): self.player.setSelectedWeapon(index) def getItem(self, item): self.map[item.getX() // 2 + 1][item.getY()] = " " self.player.addItemToInv(item) self.items.remove(item) self.updatePlayer(self.player.getDirection(), True) def updateEntities(self): for enemy in self.enemies: enemy.updateEntity(self.map, self.player) def updateItems(self): for item in self.items: self.map[item.getY()][item.getX()] = "+" def split(self, str): return [char for char in str] def convert(self, arr): string = "" for char in arr: string += char return string
from graphics.colors import * from graphics.graphicshandler import * DONE = False all_sprites = pygame.sprite.Group() wall_list = pygame.sprite.Group() countHorBlock = 8 countVertBlock = 10 walls = setup.makeouterwalls(BLOCK, SCREEN_SIZE) blocks = setup.makeinnerblocks(BLOCK, SCREEN_SIZE, countHorBlock, countVertBlock) player = Player(PLAYER, 20, 20) wall_list.add(walls, blocks) all_sprites.add(wall_list, player) player.walls = wall_list vidinfo = pygame.display.Info() while not DONE: CLOCK.tick(60) for event in pygame.event.get(): if event.type == pygame.QUIT: DONE = True elif event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: player.changespeed(-3, 0) elif event.key == pygame.K_RIGHT:
def load(self, user_name): # загрузка игры с базы cur = self.con.cursor() self.user_name = user_name player = cur.execute(f"""SELECT room_num, hit_points, max_hit_points, damage, max_damage, action_points, max_action_points, posX, posY, experience, max_experience FROM users WHERE user_name = '{user_name}'""").fetchone() # все харастеристикик игрока self.unused_keys = list( map( lambda i: i[0], cur.execute(f"""SELECT type FROM inventory WHERE user = '******' AND used = 'False'"""))) self.player = Player((player[-4], player[-3]), *player[1:-4], *player[-2:]) # игрок self.player.inventory = list( map( lambda i: i[0], cur.execute(f"""SELECT type FROM inventory WHERE user = '******' AND used = 'True'"""))) self.current_room = player[0] rooms = cur.execute(f"""SELECT id, number, enter_posX, enter_posY, exit_posX, exit_posY FROM rooms WHERE user = '******'""").fetchall() self.rooms = {} for room_id, number, *positions in rooms: # все комнаты подземелья enemies = cur.execute(f"""SELECT color, hit_points, max_hit_points, action_points, max_action_points, damage, max_damage, posX, posY FROM entities WHERE room_id = {room_id}""").fetchall() list_of_enemies = [] list_of_objects = [] # все враги на карте for color, hit, m_hit, act, m_act, dam, m_dam, x, y in enemies: list_of_enemies.append( Enemy((x, y), color, hit, m_hit, dam, m_dam, act, m_act)) objects = cur.execute(f"""SELECT type, posX, posY, inside, color, stage FROM objects WHERE room_id = {room_id}""").fetchall() for type_, x, y, inside, color, stage in objects: # все объекты на карте if type_ == 1: # коробки list_of_objects.append(Box((x, y))) elif type_ == 2: # сундуки list_of_objects.append( Chest((x, y), *reversed(inside.split('_')))) if stage: list_of_objects[-1].touch() else: # двери list_of_objects.append(Door((x, y), color)) self.rooms[number] = Room(positions[-2:], list_of_enemies, list_of_objects, number, positions[:2]) self.enemies = self.rooms[self.current_room].enemies self.entities = [self.player, *self.enemies] self.objects = self.rooms[self.current_room].objects self.load_room(player[0])
from constants import * from entity import Player from graphics.colors import * from graphics.handler import * #SCREEN = pygame.display.set_mode(SCREEN_SIZE) #CLOCK = pygame.time.Clock() DONE = False all_sprites = pygame.sprite.Group() wall_list = pygame.sprite.Group() walls = setup.makeouterwalls(BLOCK, SCREEN_SIZE) blocks = setup.makeinnerblocks(BLOCK, SCREEN_SIZE, 5) player = Player(PLAYER, 20, 20) wall_list.add(walls, blocks) all_sprites.add(wall_list, player) player.walls = wall_list while not DONE: for event in pygame.event.get(): if event.type == pygame.QUIT: DONE = True elif event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: player.changespeed(-3, 0) elif event.key == pygame.K_RIGHT: player.changespeed(3, 0)
class Game(States): def __init__(self): States.__init__(self) self.next = "menu" self.all_sprites = pygame.sprite.Group() self.wall_list = pygame.sprite.Group() self.countHorBlock = 8 self.countVertBlock = 10 self.walls = setup.makeouterwalls(BLOCK, SCREEN_SIZE) self.blocks = setup.makeinnerblocks(BLOCK, SCREEN_SIZE, self.countHorBlock, self.countVertBlock) self.player = Player(PLAYER, 20, 20) self.wall_list.add(self.walls, self.blocks) self.all_sprites.add(self.wall_list, self.player) self.player.walls = self.wall_list def cleanup(self): self.all_sprites = None self.wall_list = None self.walls = None self.blocks = None self.player = None def startup(self): self.__init__() def get_event(self, event): if event.type == pygame.QUIT: self.done = True elif event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: self.player.changespeed(-3, 0) elif event.key == pygame.K_RIGHT: self.player.changespeed(3, 0) elif event.key == pygame.K_UP: self.player.changespeed(0, -3) elif event.key == pygame.K_DOWN: self.player.changespeed(0, 3) if event.key == pygame.K_SPACE: self.all_sprites.add(self.player.putbomb()) if event.key == pygame.K_ESCAPE: self.done = True elif event.type == pygame.KEYUP: if event.key == pygame.K_LEFT: self.player.changespeed(3, 0) elif event.key == pygame.K_RIGHT: self.player.changespeed(-3, 0) elif event.key == pygame.K_UP: self.player.changespeed(0, 3) elif event.key == pygame.K_DOWN: self.player.changespeed(0, -3) def update(self, screen, dt): self.draw(screen) self.all_sprites.update() def draw(self, screen): screen.fill(GAMEBACKGROUND) self.all_sprites.draw(SCREEN)
def instanceLoader(entityType, entityName): if entityType == "item": # check if item exists if itemCheck(entityName, "ITEMFOUND"): # open file where item is located with open(itemCheck(entityName, "ITEMLOCATION"), "r") as file: reader = csv.reader(file, delimiter=',') # search each row to find item for row in reader: if row[0] == entityName: # create, initialize, and return the item found item = Item(entityName, row[1], row[2], row[3], row[4], row[5], row[6]) return item else: print("{} does not exist".format(entityName)) sys.exit(2) # ensure csv file exists if os.path.isfile("entity_data/" + entityType + ".csv" == False): print( "{} data does not exist. Please restart and create a new {} data file." .format(entityType.capitalize(), entityType.capitalize())) sys.exit(3) with open("entity_data/" + entityType + ".csv", "r") as file: reader = csv.reader(file, delimiter=',') # search every first value until name is found for name in reader: if entityName == name[0]: # create a new entity with values found in csv file if entityType == "player": # intialize a player with default values # Class: Human, Weight: 100lbs Strength: 10, Endurance: 20, Agility: 20 player = Player(entityName, "Human", 100, 10, 20, 20) # open up class types file and search for player's class with open("entity_data/class_types.csv", "r") as classTypeFile: classReader = csv.reader(classTypeFile, delimiter=',') for row in classReader: # if class type (row[0]) is equal to player's class type (name[1]) if row[0] == name[1]: player.classType = row[0] # add items to players inventory for item in row: if item != name[1] and itemCheck( item, "ITEMFOUND"): player.addItem(item) # find item and apply it's stats to player for item in range(player.inventorySize()): print("Item: {}".format(player.getItem(item))) # make sure item stored in inventory still exists if itemCheck(player.getItem(item), "ITEMFOUND") == False: return False itemDirectory = itemCheck(player.getItem(item), "ITEMLOCATION") # open file where item is stored with open(itemDirectory, "r") as itemFile: itemReader = csv.reader(itemFile, delimiter=',') # search for item name in the first string of every row for row in itemReader: if row[0] == player.getItem(item): # apply the rest of items stats that can be applied to player (weight, strength, endurance etc...) player.applyStats(row[3], row[4], row[5], row[6]) break break # return initialized player return player elif entityType == "enemy": with open("entity_data/enemy.csv") as file: reader = csv.reader(file, delimiter=',') for row in reader: if row[0] == entityName: # intialize an enemy with values found in row enemy = Enemy(entityName, row[1], row[2]) # return initialized enemy return enemy else: print("Entity type does not exist.") return False
def play(): keys = defaultdict(lambda: False) clock = pygame.time.Clock() paused = False world = World((50, 50), default=Tile.GRASS) px, py = world.random_position() player = Player((px, py), loadimage("player.png")) world.add_entity(player) MOVE_SPEED = 3 for i in range(1): world.spawn_clock() for i in range(3): world.spawn_fastenemy() for i in range(5): world.spawn_slowenemy() ticks = 0 started = False while True: for ev in pygame.event.get(): if ev.type == QUIT: pygame.quit() sys.exit(0) elif ev.type == KEYDOWN: keys[ev.key] = True if ev.key == K_SPACE: if not started: started = True else: paused = not paused if ev.key in [K_UP, K_LEFT, K_DOWN, K_RIGHT]: slash.play() if ev.key == K_e and player.bombs > 0: world.bomb((player.x, player.y)) player.bombs -= 1 elif ev.type == KEYUP: keys[ev.key] = False if keys[K_ESCAPE]: pygame.quit() sys.exit(0) if started and not paused: if keys[K_w]: player.move((player.x, player.y - MOVE_SPEED)) if keys[K_s]: player.move((player.x, player.y + MOVE_SPEED)) if keys[K_a]: player.move((player.x - MOVE_SPEED, player.y)) if keys[K_d]: player.move((player.x + MOVE_SPEED, player.y)) if keys[K_UP]: player.attack("UP") elif keys[K_LEFT]: player.attack("LEFT") elif keys[K_DOWN]: player.attack("DOWN") elif keys[K_RIGHT]: player.attack("RIGHT") world.tick() if player.health <= 0 or world.timer <= 0: return player.score, ticks px, py = player.x, player.y xo = SWIDTH / 2 - player.x yo = SHEIGHT / 2 - player.y #screen.fill(BLACK) screen.blit(bg, (0, 0)) # Draw world world.render(screen, (xo, yo), (TWIDTH, THEIGHT)) # Draw HUD for e in world.entities: if isinstance(e, Clock): ex = e.x + xo ey = e.y + yo if (ex < 0 or ex > SWIDTH or ey < 0 or ey > SHEIGHT): ang = math.atan2(ey - SHEIGHT / 2, ex - SWIDTH / 2) icon = pygame.transform.rotate(arrow, -ang * 180 / math.pi) w = icon.get_width() / 2 h = icon.get_height() / 2 dx = math.cos(ang) * 50 - h dy = math.sin(ang) * 50 - w screen.blit(icon, (SWIDTH / 2 + dx, SHEIGHT / 2 + dy)) msg = regfont.render("{} fps".format(int(clock.get_fps())), 1, WHITE, BLACK) blitfont(screen, msg, (0, 0)) msg = regfont.render("{:.1f} seconds".format(world.timer / 60.0), 1, WHITE, BLACK) blitfont(screen, msg, (SWIDTH - 1, 0), align="RIGHT") msg = regfont.render("Bombs: {}".format(player.bombs), 1, WHITE, BLACK) blitfont(screen, msg, (0, 1 * msg.get_height())) healthcol = GREEN if player.health < 3: healthcol = RED elif player.health < 6: healthcol = YELLOW msg = regfont.render("Health: {}".format(player.health), 1, healthcol, BLACK) blitfont(screen, msg, (0, 2 * msg.get_height())) msg = regfont.render("Score: {}".format(player.score), 1, WHITE, BLACK) blitfont(screen, msg, (0, 3 * msg.get_height())) if world.timer < 180 and ticks % 40 == 0: timewarn.play() if world.timer < 180 and (ticks / 20) % 2 == 0: msg = regfont.render("Time's running out!", 1, WHITE, BLACK) blitfont(screen, msg, (SWIDTH / 2, msg.get_height() / 2), align="CENTER") if not started: show_intro(screen, regfont) elif paused: msg = regfont.render("Paused", 1, WHITE, BLACK) blitfont(screen, msg, (SWIDTH / 2, SHEIGHT / 2), align="CENTER") pygame.display.flip() ticks += 1 clock.tick(60)
def play(): keys = defaultdict(lambda: False) clock = pygame.time.Clock() paused = False world = World((50, 50), default=Tile.GRASS) px, py = world.random_position() player = Player((px, py), loadimage("player.png")) world.add_entity(player) MOVE_SPEED = 3 for i in range(1): world.spawn_clock() for i in range(3): world.spawn_fastenemy() for i in range(5): world.spawn_slowenemy() ticks = 0 started = False while True: for ev in pygame.event.get(): if ev.type == QUIT: pygame.quit() sys.exit(0) elif ev.type == KEYDOWN: keys[ev.key] = True if ev.key == K_SPACE: if not started: started = True else: paused = not paused if ev.key in [K_UP, K_LEFT, K_DOWN, K_RIGHT]: slash.play() if ev.key == K_e and player.bombs > 0: world.bomb((player.x, player.y)) player.bombs -= 1 elif ev.type == KEYUP: keys[ev.key] = False if keys[K_ESCAPE]: pygame.quit() sys.exit(0) if started and not paused: if keys[K_w]: player.move((player.x , player.y-MOVE_SPEED)) if keys[K_s]: player.move((player.x , player.y+MOVE_SPEED)) if keys[K_a]: player.move((player.x-MOVE_SPEED, player.y )) if keys[K_d]: player.move((player.x+MOVE_SPEED, player.y )) if keys[K_UP]: player.attack("UP") elif keys[K_LEFT]: player.attack("LEFT") elif keys[K_DOWN]: player.attack("DOWN") elif keys[K_RIGHT]: player.attack("RIGHT") world.tick() if player.health <= 0 or world.timer <= 0: return player.score, ticks px, py = player.x, player.y xo = SWIDTH/2 - player.x yo = SHEIGHT/2 - player.y #screen.fill(BLACK) screen.blit(bg, (0, 0)) # Draw world world.render(screen, (xo, yo), (TWIDTH, THEIGHT)) # Draw HUD for e in world.entities: if isinstance(e, Clock): ex = e.x + xo ey = e.y + yo if (ex < 0 or ex > SWIDTH or ey < 0 or ey > SHEIGHT): ang = math.atan2(ey - SHEIGHT/2, ex - SWIDTH/2) icon = pygame.transform.rotate(arrow, -ang*180/math.pi) w = icon.get_width()/2 h = icon.get_height()/2 dx = math.cos(ang) * 50 - h dy = math.sin(ang) * 50 - w screen.blit(icon, (SWIDTH/2 + dx, SHEIGHT/2 + dy)) msg = regfont.render("{} fps".format(int(clock.get_fps())), 1, WHITE, BLACK) blitfont(screen, msg, (0, 0)) msg = regfont.render("{:.1f} seconds".format(world.timer / 60.0), 1, WHITE, BLACK) blitfont(screen, msg, (SWIDTH-1, 0), align="RIGHT") msg = regfont.render("Bombs: {}".format(player.bombs), 1, WHITE, BLACK) blitfont(screen, msg, (0, 1*msg.get_height())) healthcol = GREEN if player.health < 3: healthcol = RED elif player.health < 6: healthcol = YELLOW msg = regfont.render("Health: {}".format(player.health), 1, healthcol, BLACK) blitfont(screen, msg, (0, 2*msg.get_height())) msg = regfont.render("Score: {}".format(player.score), 1, WHITE, BLACK) blitfont(screen, msg, (0, 3*msg.get_height())) if world.timer < 180 and ticks % 40 == 0: timewarn.play() if world.timer < 180 and (ticks / 20) % 2 == 0: msg = regfont.render("Time's running out!", 1, WHITE, BLACK) blitfont(screen, msg, (SWIDTH/2, msg.get_height()/2), align="CENTER") if not started: show_intro(screen, regfont) elif paused: msg = regfont.render("Paused", 1, WHITE, BLACK) blitfont(screen, msg, (SWIDTH/2, SHEIGHT/2), align="CENTER") pygame.display.flip() ticks += 1 clock.tick(60)