class BackgroundLayer(object): "Creates a background from an image, making a mosaic" def __init__(self, image): self.image = image self.batch = BatchNode() self.create_background() def create_background(self): x_size, y_size = director.get_window_size() self.sprite = Sprite(self.image) # self.sprite.anchor_x = self.sprite.width / 2 # self.sprite.anchor_y = self.sprite.height / 2 for x in xrange(0, x_size, self.sprite.width): for y in xrange(0, y_size, self.sprite.height): sprite = Sprite(self.image) sprite.x = x sprite.y = y self.batch.add(sprite) # print "sprite agregado", self.batch def back_batch(self): return self.batch
def __init__(self, game_layer): super(DudeDamageLayer, self).__init__() self.game_layer = game_layer self.red_bp = BatchNode() self.normal_bp = BatchNode() self.armored_bp = BatchNode() self.ui_body = {'back': {}, 'front': {}, 'armored': {}} self._init_body_parts('back') self._init_body_parts('front') self._init_body_parts('armored') # the layer now listens to on_take_damage event from hero self.game_layer.hero.push_handlers(self.on_take_damage) armored_bp = self._get_armored_body_parts() for body_part in self.ui_body['back']: self.red_bp.add(self.ui_body['back'][body_part]) for body_part in self.ui_body['front']: self.normal_bp.add(self.ui_body['front'][body_part]) for body_part in self.ui_body['armored']: if body_part in armored_bp: self.armored_bp.add(self.ui_body['armored'][body_part]) self.add(self.red_bp, z=-1) self.add(self.normal_bp, z=0) self.add(self.armored_bp, z=1)
def init_node_sprites(self, wipe=False): if wipe: #wipe old sprites #for n in self.G.nodes_iter(): # self.map.node[n]['sprite'] = None self.remove("nodes") #make node sprites nodes = BatchNode() raw_positions = self.map.get_positions() rotate_effect = Repeat(RotateBy(-360, 2)) for n in raw_positions: #get node position x, y = raw_positions[n] pos = (x * settings.LVL_W, y * settings.LVL_H) #get type of node type = self.map.get_type(n) #make sprite node_spr = Sprite( image=settings.IMAGE_DATA[type], position=pos, ) type != "factory" or node_spr.do(rotate_effect) self.nodesprites[n] = node_spr nodes.add(node_spr) #add nodes to map_layer self.add(nodes, z=1, name="nodes") self.update_node_sprites()
def reset(self): self.client.cancelCalibration() for c in self.get_children(): c.stop() self.remove(c) self.batch1 = BatchNode() self.batch2 = BatchNode() self.init()
def __init__( self, director, dificuldade ): super( GameLayer, self ).__init__() self.director = director self.tabuleiro = [] self.offsetX = director.get_window_size()[0]/3 self.offsetY = director.get_window_size()[1]/8 lado = 45 self.lado = lado self.dificuldade = dificuldade self.cpu = False self.prolog = Prolog() self.prolog.consult("reversi.pl") self.tabMatriz = list(self.prolog.query("novotab(X)"))[0]['X'] self.matriz = deepcopy(self.tabMatriz) pyglet.font.add_directory('.') self.jogadorAtivo = Label("Jogador: Player1", font_name = 'Blood Of Dracula', font_size = 22, x = 20, y = 350) self.add(self.jogadorAtivo) self.dif = Label("Dificuldade: " + self.dificuldade, font_name = 'Blood Of Dracula', font_size = 16, x = 20, y = 300) self.add(self.dif) self.p = list(self.prolog.query("winner(" + str(self.tabMatriz) + ", P0, P1, P2)"))[0] self.p1 = Label("P1: " + str(self.p['P1']) + self.dificuldade, font_name = 'Bloodsuckers', font_size = 26, x = 20, y = 200) self.p2 = Label("P1: " + str(self.p['P2']) + self.dificuldade, font_name = 'Bloodsuckers', font_size = 26, x = 20, y = 150) self.add(self.p1) self.add(self.p2) #Batch que vai segurar todos os pecas self.spriteBatch = BatchNode() self.add(self.spriteBatch) size = 8*self.lado for i in range(8): l = [] for j in range(8): peca = Peca(self.tabMatriz[i][j], (j*lado + lado/2, size - (i*lado + lado/2))) l.append(peca) self.spriteBatch.add(peca) self.tabuleiro.append(l) self.spriteBatch.add(Sprite("tabuleiro.png", (self.tabuleiro[4][4].position[0] - lado/2, self.tabuleiro[4][4].position[1] + lado/2) , 0, 1, 32), 0) self.spriteBatch.position = (self.offsetX, self.offsetY) self.spriteBatch.scale = 1.0 self.hud = GameHud() self.add(self.hud) self.schedule(self.gameLoop)
def create_cliff(self): self.cliffs = BatchNode() self.add(self.cliffs) for i, _ in enumerate(self.obstacle_map.cells): if not self.obstacle_map.cells[i][0].tile: self.cliffs.add( Cliff(self.obstacle_map.cells[i][0].center, self.obstacle_map))
def __init__(self, director): super(Tabuleiro, self).__init__() self.director = director self.tabuleiro = [] self.offsetX = 100 self.offsetY = 100 lado = 32 #montagem da matriz inicial self.tabMatriz = [] for i in range(8): linha = [] for j in range(8): linha.append(0) self.tabMatriz.append(linha) self.tabMatriz[3][3] = 1 self.tabMatriz[3][4] = 2 self.tabMatriz[4][3] = 2 self.tabMatriz[4][4] = 1 ################################### #Batch que vai segurar todos os pecas self.spriteBatch = BatchNode() self.add(self.spriteBatch) for i in range(8): l = [] for j in range(8): if (self.tabMatriz[i][j] == 0): peca = Peca("vazio.png", (i * lado + lado / 2, j * lado + lado / 2)) elif (self.tabMatriz[i][j] == 1): peca = Peca("preto.png", (i * lado + lado / 2, j * lado + lado / 2)) elif (self.tabMatriz[i][j] == 2): peca = Peca("branco.png", (i * lado + lado / 2, j * lado + lado / 2)) l.append(peca) self.spriteBatch.add(peca) self.tabuleiro.append(l) self.spriteBatch.position = (self.offsetX, self.offsetY) self.teste = Sprite("grossini.png", (300, 200)) self.spriteBatch.add(self.teste) self.hud = GameHud() self.add(self.hud) for i in self.tabMatriz: print(i)
def clear_shapes(self): self.circles = [] self.cm.clear() for c in self.get_children(): if c != self.gaze and c != self.attention: self.remove(c) self.batch = BatchNode() self.id_batch = BatchNode()
def __init__(self): super(BackgroundLayer, self).__init__() self.screen = director.get_window_size() self.batch = BatchNode() self.add(self.batch) self.shapes = {"circle":"E", "square":"K", "oval":"F", "diamond":"T", "crescent":"Q", "cross":"Y", "star":"C", "triangle":"A"} self.font = font.load('Cut Outs for 3D FX', 128) self.glyphs = self.font.get_glyphs("".join(self.shapes.values())) ratio = 1 - self.screen[1] / self.screen[0] n = int(750 * ratio) for _ in range(0, n): img = choice(self.glyphs).get_texture(True) img.anchor_x = 'center' img.anchor_y = 'center' max_o = 96 o = choice([0, max_o]) speed = uniform(1, 10) sprite = Shape(img, rotation=randrange(0, 365), scale=uniform(ratio, 3 * ratio), position=(randrange(0, self.screen[0]), randrange(0, self.screen[1])), opacity=o, color=(randrange(0, 256), randrange(0, 256), randrange(0, 256))) if o == max_o: sprite.do(Repeat(FadeTo(0, speed) + FadeTo(max_o, speed))) else: sprite.do(Repeat(FadeTo(max_o, speed) + FadeTo(0, speed))) self.batch.add(sprite)
def updatePlayerUnitStats(self, battle_unit): if self.unit_display is not None: self.unit_display.kill() self.unit_display_bg.kill() if battle_unit is None: # Hide player unit stats at bottom left self.unit_display = None self.unit_display_bg = None return from board import Board # size = director.get_window_size() # width = size[0] # height = size[1] self.unit_display = UnitCard(battle_unit) self.unit_display.position = Board.TILE_SIZE // 2, Board.TILE_SIZE self.add(self.unit_display) self.unit_display_bg = BatchNode() bg_sprite = Sprite(Resources.unit_card_bg_left_img) self.unit_display_bg.add(bg_sprite) bg_position = self.unit_display.sprite.get_rect().topleft self.unit_display_bg.position = bg_position[0] + bg_sprite.width // 2, bg_position[1] self.add(self.unit_display_bg, z=-1)
def updateTargetUnitStats(self, target_unit, is_friendly=False): if self.target_display is not None: self.target_display.kill() self.target_display_bg.kill() if target_unit is None: # Hide target unit stats at top right self.target_display = None self.target_display_bg = None return from board import Board size = director.get_window_size() width = size[0] height = size[1] self.target_display = UnitCard(target_unit, is_friendly=is_friendly, reverse=True) self.target_display.position = width - self.target_display.width - Board.TILE_SIZE // 2, \ height - self.target_display.height - Board.TILE_SIZE // 2 self.add(self.target_display) self.target_display_bg = BatchNode() bg_sprite = Sprite(Resources.unit_card_bg_right_img) self.target_display_bg.add(bg_sprite) self.target_display_bg.position = width - bg_sprite.width // 2, \ height - bg_sprite.height // 2 - Board.TILE_SIZE // 2 self.add(self.target_display_bg, z=-1)
def __init__(self, minimap, w, h, size=10): super().__init__(0, 0, 0, 100, w * size, h * size) self.batch = BatchNode() for (i, j) in minimap: tmp = minimap[(i, j)] if tmp is not -1: img = 'grid/' + str(tmp) + '.png' pos = i * size, j * size spr = Sprite(image=img, position=pos) spr.scale_x, spr.scale_y = size / spr.width, size / spr.height spr.image_anchor = (0, 0) self.batch.add(spr) self.add(self.batch) self.frame = ColorLayer(0, 0, 100, 100, min(w * 10, 160), min(h * 10, 90)) self.add(self.frame)
class DudeStatusLayer(ResizableLayer): is_event_handler = True def __init__(self, game_layer): super(DudeStatusLayer, self).__init__() self.game_layer = game_layer self.batch = BatchNode() self.ui_status_icons = {'health_icon': Sprite(con.status['health_icon'], position=(110, self.cur_y-50))} self.bar_orig_x = 140 self.hb_len = 100 # health bar length self.ui_health_bar = Line((self.bar_orig_x, self.cur_y-50), (self.bar_orig_x + self.hb_len, self.cur_y-50), (255, 0, 0, 255), 15) # the layer now listens to on_take_damage and on_death event from hero self.game_layer.hero.push_handlers(self.on_take_damage) self.game_layer.hero.push_handlers(self.on_death) for icon in self.ui_status_icons: self.batch.add(self.ui_status_icons[icon]) self.add(self.batch) self.add(self.ui_health_bar) def on_hud_shift_needed(self): for icon in self.ui_status_icons: self.ui_status_icons[icon].y += self.dy self.ui_health_bar.start = (self.ui_health_bar.start[0], self.ui_health_bar.start[1] + self.dy) self.ui_health_bar.end = (self.ui_health_bar.end[0], self.ui_health_bar.end[1] + self.dy) def on_take_damage(self, body_part): hb = self.ui_health_bar hb.end = (self.bar_orig_x + self.hb_len * body_part.master.health / float(body_part.master.max_health), self.cur_y-50) def on_death(self, hero): self.ui_health_bar.end = (self.bar_orig_x, self.cur_y-50) # zero length bar
def init_link_sprites(self, wipe=False): if wipe: #wipe old sprites for start, end in self.map.edges_iter(): self.linksprites[start][end] = None self.remove("links") #make links links = BatchNode() for start, end in self.map.edges_iter(): #get start and end nodes start_node = self.nodesprites[start] end_node = self.nodesprites[end] #get centre of line pos = ((start_node.x + end_node.x) / 2, (start_node.y + end_node.y) / 2) #get type of link type = self.map.get_type(start, end) link_spr = Sprite( image=settings.IMAGE_DATA[type], position=pos, rotation=-degrees(atan2( (end_node.y - start_node.y), (end_node.x - start_node.x), )) ) #add link to lists self.linksprites[start][end] = link_spr links.add(link_spr) #add sprites to map_layer self.add(links, z=0, name="links") self.update_link_sprites()
def __init__(self, battle): super(Board, self).__init__() Board.BOARD = self self.scroller = None self.battle = battle self.map = battle.map self.cellMap = {} # add basic ground cell tiles ground_img = Resources.ground_img node = BatchNode() self.add(node, z=0) for row in range(self.map.numRows): for col in range(self.map.numCols): tile = self.map.getTileAt(col, row) cell = Cell(tile, ground_img) rect = cell.get_rect() rect.bottomleft = col * 32, row * 32 cell.position = rect.center node.add(cell, z=0) self.cellMap[(col, row)] = cell # add terrain feature/building cell tiles for col, row in self.map.boardMap: loc = (col, row) cell_data = self.map.boardMap[loc] cell_images = cell_data.images if cell_images is not None: cell_level = cell_data.level cell_z = (self.map.numCols - row - cell_level) * 10 cell_batch = BatchNode() cell_batch.position = col * self.TILE_SIZE, row * self.TILE_SIZE self.add(cell_batch, z=cell_z) cell_cols = cell_data.cols cell_rows = cell_data.rows for this_row in range(cell_rows + cell_level): for this_col in range(cell_cols): cell_index = this_col + (this_row * cell_cols) cell_sprite = Sprite(cell_images[cell_index]) cell_rect = cell_sprite.get_rect() cell_rect.bottomleft = this_col * self.TILE_SIZE, this_row * self.TILE_SIZE cell_sprite.position = cell_rect.center cell_batch.add(cell_sprite)
def __init__(self, main_scene): self.bullets = BatchNode() self.walls = BatchNode() self.objects = BatchNode() self.backgrounds = BatchNode() self.tanks = BatchNode() # self.decorations = BatchNode() #main_scene = get_main_scene_layer() self.main_scene = main_scene self.main_scene.add(self.backgrounds, z=0) self.main_scene.add(self.bullets, z=1) # self.main_scene.add(self.decorations) self.main_scene.add(self.walls) self.main_scene.add(self.objects) self.main_scene.add(self.tanks) self.globalPanel = cocos.layer.Layer() self.main_scene.add(self.globalPanel, z=1)
def __init__(self, *args): super().__init__() self.hud = args[0] self.obstacle_map = args[1] self.objects_map = args[2] self.tileset = args[3] self.create_mario() self.create_cliff() self.create_flag() self.enemies = BatchNode() self.add(self.enemies) self.enemy_objs = self.objects_map.match(label="enemy") self.exist_enemy_index = [] width, height = director.get_window_size() self.cm = CollisionManagerGrid(0, width, 0, height, 20, 20) stats.reset_current_game() Sound.play("mario")
def __init__(self, R): super(GameScene, self).__init__() self.R = R self.batch = BatchNode() self.collisionManager = CollisionModel.CollisionManagerBruteForce() #Main Background mainBack = Sprite(R._BACKGROUND[4]) mainBack.position = (director._window_virtual_width / 2, director._window_virtual_height / 2) self.add(mainBack) #Parallax-BackGround self.add( ParallaxBackground((0, 0, 800, 600), [R._BACKGROUND[1], R._BACKGROUND[1]], 16, 10)) self.add( ParallaxBackground((0, 0, 800, 600), [R._BACKGROUND[2], R._BACKGROUND[2]], 4, 10)) self.add( ParallaxBackground((0, 0, 800, 600), [R._BACKGROUND[3], R._BACKGROUND[3]], 2, 10)) #Add Player self.PLAYER = Player() self.ENEMY = Enemy() self.HUD = HUD() #set Data self.PLAYER.set(self) self.ENEMY.set(self) self.HUD.set(self) #Add layers self.add(self.PLAYER) self.add(self.ENEMY) self.add(self.HUD) #Adding Batch to Layer self.add(self.batch)
def __init__(self, game_layer): super(DudeStatusLayer, self).__init__() self.game_layer = game_layer self.batch = BatchNode() self.ui_status_icons = {'health_icon': Sprite(con.status['health_icon'], position=(110, self.cur_y-50))} self.bar_orig_x = 140 self.hb_len = 100 # health bar length self.ui_health_bar = Line((self.bar_orig_x, self.cur_y-50), (self.bar_orig_x + self.hb_len, self.cur_y-50), (255, 0, 0, 255), 15) # the layer now listens to on_take_damage and on_death event from hero self.game_layer.hero.push_handlers(self.on_take_damage) self.game_layer.hero.push_handlers(self.on_death) for icon in self.ui_status_icons: self.batch.add(self.ui_status_icons[icon]) self.add(self.batch) self.add(self.ui_health_bar)
class MechSprite(cocos.layer.Layer): shadow_img = pyglet.resource.image("images/ui/shadows.png") shadow_img_grid = pyglet.image.ImageGrid(shadow_img, 1, 4) def __init__(self, battle_mech): super(MechSprite, self).__init__() self.battle_mech = battle_mech mech_img = pyglet.resource.image(self.battle_mech.getImagePath()) mech_img_grid = pyglet.image.ImageGrid(mech_img, 1, 6) self.static = True img_static = Sprite(mech_img_grid[0]) self.width = img_static.width self.height = img_static.height # TODO: setup the non square friendly/enemy indicators based on team of current player's turn if battle_mech.player.is_bot: indicator = Sprite(Resources.enemy_indicator_img) else: indicator = Sprite(Resources.friendly_indicator_img) indicator.visible = False indicator.position = 0, -img_static.height // 2 + indicator.height // 2 + 1 self.indicator = indicator self.add(indicator, z=0) shadow = Sprite(MechSprite.shadow_img_grid[battle_mech.getSize() - 1]) shadow_rect = shadow.get_rect() shadow_rect.bottomleft = (self.battle_mech.col * Board.TILE_SIZE), \ (self.battle_mech.row * Board.TILE_SIZE) shadow.position = shadow_rect.center self.shadow = shadow rect = img_static.get_rect() rect.bottomleft = (self.battle_mech.col * Board.TILE_SIZE) - (img_static.width//2 - shadow.width//2), \ (self.battle_mech.row * Board.TILE_SIZE) self.position = rect.center self.node = BatchNode() self.add(self.node, z=2) img_static.y = Board.TILE_SIZE//4 self.node.add(img_static) self.img_static = img_static img_ct = Sprite(mech_img_grid[1]) img_ct.y = Board.TILE_SIZE//4 self.img_ct = img_ct img_ll = Sprite(mech_img_grid[4]) img_ll.y = Board.TILE_SIZE//4 self.img_ll = img_ll img_rl = Sprite(mech_img_grid[5]) img_rl.y = Board.TILE_SIZE//4 self.img_rl = img_rl img_la = Sprite(mech_img_grid[2]) img_la.y = Board.TILE_SIZE//4 self.img_la = img_la img_ra = Sprite(mech_img_grid[3]) img_ra.y = Board.TILE_SIZE//4 self.img_ra = img_ra # testing the stats stuff self.stats = BatchNode() self.updateStatsIndicators() def get_width(self): return self.img_static.width def get_height(self): return self.img_static.height + int(self.img_static.y) def showIndicator(self, visible=True): self.indicator.visible = visible def showStats(self, visible=True): self.stats.visible = visible def timeBySize(self): times = { 4: 0.25, 3: 0.21, 2: 0.17, 1: 0.13 } return times.get(self.battle_mech.getSize(), times[4]) def destroy(self): # TODO: animate the destruction and show a wreckage self.node.kill() self.shadow.kill() self.indicator.kill() self.kill() def strut(self, reverse=False): self.reset() # make smaller mechs move faster time = self.timeBySize() shift = MoveBy((0, 3), duration=time) move = MoveBy((0, -4), duration=time) if reverse: # start with raising the left leg/right arm first self.img_ra.do(Repeat(shift + Reverse(shift) + Reverse(shift) + shift)) self.img_la.do(Repeat(Reverse(shift) + shift + shift + Reverse(shift))) self.img_rl.do(Repeat(Delay(time * 2) + Reverse(move) + move)) self.img_ll.do(Repeat(Reverse(move) + move + Delay(time * 2))) else: # start with raising the right leg/left arm first self.img_la.do(Repeat(shift + Reverse(shift) + Reverse(shift) + shift)) self.img_ra.do(Repeat(Reverse(shift) + shift + shift + Reverse(shift))) self.img_ll.do(Repeat(Delay(time * 2) + Reverse(move) + move)) self.img_rl.do(Repeat(Reverse(move) + move + Delay(time * 2))) rise = MoveBy((0, 2), duration=time) self.img_ct.do(Repeat(rise + Reverse(rise) + rise + Reverse(rise))) def sulk(self): if not self.static: self.stop() if self.static: self.static = False for section in self.node.get_children(): section.kill() z = 1 self.node.add(self.img_ct, z=z) z += 1 self.node.add(self.img_ll, z=z) z += 1 self.node.add(self.img_rl, z=z) z += 1 self.node.add(self.img_la, z=z) z += 1 self.node.add(self.img_ra, z=z) # TODO: adjust Z order only AFTER a Y position move # TODO: Z order should be based on the number of rows in the board new_z = (Map.numRows - self.battle_mech.row) * 10 parent = self.parent parent.remove(self.shadow) parent.remove(self) parent.add(self.shadow, z=new_z) parent.add(self, z=new_z+2) # make smaller mechs move faster time = self.timeBySize() shift = MoveBy((0, 2), duration=time) self.img_la.do(Repeat(shift + Reverse(shift) + Reverse(shift) + shift)) self.img_ra.do(Repeat(shift + Reverse(shift) + Reverse(shift) + shift)) sink = MoveBy((0, -2), duration=time) self.img_ct.do(Repeat(Delay(time * 2) + sink + Reverse(sink))) def shutdown(self): if not self.static: self.stop() if self.static: self.static = False for section in self.node.get_children(): section.kill() z = 1 self.node.add(self.img_ct, z=z) z += 1 self.node.add(self.img_ll, z=z) z += 1 self.node.add(self.img_rl, z=z) z += 1 self.node.add(self.img_la, z=z) z += 1 self.node.add(self.img_ra, z=z) # TODO: adjust Z order only AFTER a Y position move # TODO: Z order should be based on the number of rows in the board new_z = (Map.numRows - self.battle_mech.row) * 10 parent = self.parent parent.remove(self.shadow) parent.remove(self) parent.add(self.shadow, z=new_z) parent.add(self, z=new_z+2) # make smaller mechs move faster time = 1.0 shift = MoveBy((0, -8), duration=time) # lower the arms self.img_la.do(shift) self.img_ra.do(shift) # lower the torso lower = MoveBy((0, -4), duration=time/2) self.img_ct.do(lower) def reset(self): for section in self.node.get_children(): section.stop() section.position = 0, Board.TILE_SIZE//4 if self.battle_mech.isShutdown(): # lower the arms self.img_la.y -= 8 self.img_ra.y -= 8 # lower the torso self.img_ct.y -= 4 def stop(self): self.shadow.stop() for section in self.node.get_children(): section.stop() section.position = 0, Board.TILE_SIZE//4 if self.battle_mech.isShutdown(): # lower the arms self.img_la.y -= 8 self.img_ra.y -= 8 # lower the torso self.img_ct.y -= 4 elif not self.static: self.static = True for section in self.node.get_children(): section.kill() self.node.add(self.img_static) def pause(self): self.shadow.pause() for section in self.node.get_children(): section.pause() def resume(self): self.shadow.resume() for section in self.node.get_children(): section.resume() def moveToCell(self, to_col, to_row, reverse=False, func=None): if to_col == self.battle_mech.col and to_row == self.battle_mech.row: return 0.5 # determine the route and the points along the way to_cell = (to_col, to_row) cell_route = self._get_cell_move_route(to_cell) total_time = 0 actions = Delay(0) shadow_actions = Delay(0) stomp_actions = Delay(0) for cell in cell_route: col = cell[0] row = cell[1] num_steps = 2 time = self.timeBySize() * (num_steps * 2) shadow_rect = self.shadow.get_rect() shadow_rect.bottomleft = (col * 32), (row * 32) rect = self.img_static.get_rect() rect.bottomleft = (col * Board.TILE_SIZE) - (self.img_static.width // 2 - self.shadow.width // 2), \ (row * Board.TILE_SIZE) actions += MoveTo(rect.center, duration=time) shadow_actions += MoveTo(shadow_rect.center, duration=time) # play movement sounds sound_index = self.battle_mech.getSize() - 1 stomp_sound = Resources.stomp_sounds[sound_index] for i in range(num_steps): # use channel 0 and 1 for alternating steps stomp_channel = pygame.mixer.Channel(i % 2) stomp_channel.set_volume(Settings.get_volume_fx()) stomp_reverse = True if i % 2 == (1 if reverse else 0): stomp_reverse = False stomp_actions += CallFunc(stomp_channel.play, stomp_sound) + Delay(time / num_steps) \ + CallFunc(self.spawnStompCloud, stomp_reverse) total_time += time if func is not None: actions += CallFunc(func) self.do(actions) self.shadow.do(shadow_actions) self.do(stomp_actions) return total_time def _get_cell_move_route(self, to_cell): battle = Battle.BATTLE cell_route = [to_cell] cells_in_range = battle.getCellsInRange(self.battle_mech.col, self.battle_mech.row, self.battle_mech.move) if to_cell not in cells_in_range: return cell_route # starting from the cell being moved to, find the connected cell paths that leads # back to the unit's current cell in as straight a path as possible cell_move_dist = cells_in_range[to_cell] self._recurse_cell_move_route(to_cell, cell_move_dist, cells_in_range, cell_route) return cell_route def _recurse_cell_move_route(self, recurse_cell, cell_move_dist, cells_in_range, cell_route): if cell_move_dist <= 1: return battle = Battle.BATTLE turn_unit = battle.getTurnUnit() turn_player = turn_unit.getPlayer() x = recurse_cell[0] y = recurse_cell[1] next_cell_dist = cell_move_dist - 1 # get all adjacent cells in range with distance equal to the current cell_move_dist minus 1 adjacent_cells = [] for cell, dist in cells_in_range.items(): if dist != next_cell_dist: # must be adjacent in the correct direction toward origin (0) continue cell_x = cell[0] cell_y = cell[1] if x != cell_x and y != cell_y: # must be either in same row or column as cell currently being looked at continue if abs(x - cell_x) != 1 and abs(y - cell_y) != 1: # and needs to be within one cell distance away in some direction continue # allow passing through friendly unit occupied cells cell_unit = battle.getUnitAt(cell_x, cell_y) is_friendly_occupied = False if cell_unit is not None: is_friendly_occupied = battle.isFriendlyUnit(turn_player, cell_unit) if battle.isCellAvailable(cell_x, cell_y) or \ (cell_unit is not None and is_friendly_occupied): adjacent_cells.append(cell) if len(adjacent_cells) == 0: # shouldn't happen... return # determine current course direction to prefer not turning if possible course_x = 0 course_y = 0 if len(cell_route) > 1: prev_cell = cell_route[1] course_x = prev_cell[0] - x course_y = prev_cell[1] - y next_cell = adjacent_cells[0] for cell in adjacent_cells: diff_x = x - cell[0] diff_y = y - cell[1] if course_x == diff_x and course_y == diff_y: next_cell = cell break cell_route.insert(0, next_cell) self._recurse_cell_move_route(next_cell, next_cell_dist, cells_in_range, cell_route) def spawnStompCloud(self, reverse): # show cloud particles from stomps stomp_cloud = Meteor() stomp_cloud.start_color = cocos.particle.Color(0.3, 0.3, 0.3, 1.0) stomp_cloud.end_color = cocos.particle.Color(0.5, 0.5, 0.5, 0.2) stomp_cloud.duration = 0.1 stomp_cloud.blend_additive = False stomp_cloud.size = 10 + (10 * self.battle_mech.getSize() / 4) stomp_cloud.speed = 20 stomp_cloud.gravity = Point2(0, 0) # TODO: offer decreased particle emission rate to improve performance stomp_cloud.emission_rate = 100 stomp_cloud.life = 0.5 stomp_cloud.life_var = 0.1 if not reverse: stomp_cloud.position = self.indicator.position[0] + (self.img_static.width // 4), \ self.indicator.position[1] - self.indicator.height // 5 else: stomp_cloud.position = self.indicator.position[0] - (self.img_static.width // 4), \ self.indicator.position[1] - self.indicator.height // 5 self.add(stomp_cloud, z=1) stomp_action = Delay(stomp_cloud.duration + stomp_cloud.life + stomp_cloud.life_var) \ + CallFunc(stomp_cloud.kill) self.do(stomp_action) def setStatsIndicatorsVisible(self, visible): for child in self.stats.get_children(): child.visible = visible def updateStatsIndicators(self): # TODO: Just testing pips on the indicator, it should be put on a new UI layer on top of everything for child in self.stats.get_children(): child.kill() pip_height = 6 - (self.indicator.height // 2) orig_armor = self.battle_mech.mech.armor for i in range(orig_armor): pip_img = Resources.armor_pip_img if i >= self.battle_mech.armor: pip_img = Resources.empty_pip_img pip = Sprite(pip_img) pip.position = (i * pip.width) - (orig_armor * pip.width) // 2, pip_height self.stats.add(pip, z=1) pip_height -= 4 orig_structure = self.battle_mech.mech.structure for i in range(orig_structure): pip_img = Resources.structure_pip_img if i >= self.battle_mech.structure: pip_img = Resources.empty_pip_img pip = Sprite(pip_img) pip.position = (i * pip.width) - (orig_structure * pip.width) // 2, pip_height self.stats.add(pip, z=1) pip_height -= 4 rand_heat = self.battle_mech.heat for i in range(rand_heat): pip = Sprite(Resources.heat_pip_img) pip.position = (i * pip.width) - (rand_heat * pip.width) // 2, pip_height self.stats.add(pip, z=1) self.stats.position = 0, -self.img_static.height // 2 + self.indicator.height // 2 + 1 self.add(self.stats, z=1)
def __init__(self, battle_mech): super(MechSprite, self).__init__() self.battle_mech = battle_mech mech_img = pyglet.resource.image(self.battle_mech.getImagePath()) mech_img_grid = pyglet.image.ImageGrid(mech_img, 1, 6) self.static = True img_static = Sprite(mech_img_grid[0]) self.width = img_static.width self.height = img_static.height # TODO: setup the non square friendly/enemy indicators based on team of current player's turn if battle_mech.player.is_bot: indicator = Sprite(Resources.enemy_indicator_img) else: indicator = Sprite(Resources.friendly_indicator_img) indicator.visible = False indicator.position = 0, -img_static.height // 2 + indicator.height // 2 + 1 self.indicator = indicator self.add(indicator, z=0) shadow = Sprite(MechSprite.shadow_img_grid[battle_mech.getSize() - 1]) shadow_rect = shadow.get_rect() shadow_rect.bottomleft = (self.battle_mech.col * Board.TILE_SIZE), \ (self.battle_mech.row * Board.TILE_SIZE) shadow.position = shadow_rect.center self.shadow = shadow rect = img_static.get_rect() rect.bottomleft = (self.battle_mech.col * Board.TILE_SIZE) - (img_static.width//2 - shadow.width//2), \ (self.battle_mech.row * Board.TILE_SIZE) self.position = rect.center self.node = BatchNode() self.add(self.node, z=2) img_static.y = Board.TILE_SIZE//4 self.node.add(img_static) self.img_static = img_static img_ct = Sprite(mech_img_grid[1]) img_ct.y = Board.TILE_SIZE//4 self.img_ct = img_ct img_ll = Sprite(mech_img_grid[4]) img_ll.y = Board.TILE_SIZE//4 self.img_ll = img_ll img_rl = Sprite(mech_img_grid[5]) img_rl.y = Board.TILE_SIZE//4 self.img_rl = img_rl img_la = Sprite(mech_img_grid[2]) img_la.y = Board.TILE_SIZE//4 self.img_la = img_la img_ra = Sprite(mech_img_grid[3]) img_ra.y = Board.TILE_SIZE//4 self.img_ra = img_ra # testing the stats stuff self.stats = BatchNode() self.updateStatsIndicators()
class Interface(cocos.layer.Layer): UI = None ACTION = "ACTION" ACTION_MOVE = "MOVE" ACTION_EVADE = "EVADE" ACTION_SPRINT = "SPRINT" ACTION_FIRE = "FIRE" ACTION_OVR = "OVR" ACTION_END = "END" ACTION_LIST_MOVES = [ACTION_MOVE, ACTION_EVADE, ACTION_SPRINT] ACTION_LIST_ATTACKS = [ACTION_FIRE, ACTION_OVR] SUB_MOVE = "MV" SUB_EVADE = "EVA" SUB_SPRINT = "SPR" SUB_FIRE = "ATK" SUB_OVR = "OVR" SUB_END = "END TURN" def __init__(self): super(Interface, self).__init__() from board import Board Interface.UI = self self.action_btn = None self.action_btn_bg = BatchNode() action_bg = Sprite(Resources.action_buttons_bg_img) self.action_btn_bg.add(action_bg) self.action_btn_bg.width = action_bg.width self.action_btn_bg.height = action_bg.height self.action_btn_bg.visible = False self.add(self.action_btn_bg, z=-1) self.action_super_label = TextFloater("<super>", font_name='TranscendsGames', font_size=16, anchor_x='center', anchor_y='bottom') self.action_super_icon = Sprite(Resources.enemy_indicator_img) self.action_super_icon.scale = 0.75 self.action_sub_label = TextFloater("<sub>", font_name='TranscendsGames', font_size=14, anchor_x='center', anchor_y='top') self.action_super_label.visible = False self.action_super_icon.visible = False self.action_sub_label.visible = False self.add(self.action_super_label) self.add(self.action_super_icon) self.add(self.action_sub_label) self.buttons = [] self.button_action_labels = {} self.button_action = {} self.unit_display = None self.unit_display_bg = None self.target_display = None self.target_display_bg = None # used to retain the labels that show the to hit % over each enemy self.to_hit_labels = {} # used to retain the lines that show LOS to each enemy self.los_lines = [] # add clickable UI button bar self.move_btn = Button(action_label=Interface.ACTION_MOVE, icon=Resources.move_button_img, action=actions.selectMoveAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.evade_btn = Button(action_label=Interface.ACTION_EVADE, icon=Resources.evade_button_img, action=actions.selectEvadeAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.sprint_btn = Button(action_label=Interface.ACTION_SPRINT, icon=Resources.sprint_button_img, action=actions.selectSprintAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.weapon_btn = Button(action_label=Interface.ACTION_FIRE, icon=Resources.weapon_button_img, action=actions.selectWeaponAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.overheat_btn = Button(action_label=Interface.ACTION_OVR, icon=Resources.overheat_button_img, action=actions.selectOverheatAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.end_btn = Button(action_label=Interface.ACTION_END, icon=Resources.end_button_img, action=actions.selectEndAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.addButton(self.move_btn, actions.doMoveAction) # self.addButton(self.evade_btn, actions.doEvadeAction) # self.addButton(self.sprint_btn, actions.doSprintAction) self.addButton(self.weapon_btn, actions.doWeaponAction) self.addButton(self.overheat_btn, actions.doOverheatAction) self.addButton(self.end_btn, actions.doEndAction) self.arrangeButtons() def isActionButton(self, button): return button is self.action_btn def clearButtons(self): for button in self.buttons: button.kill() self.buttons = [] def addButton(self, button, action_call): if button is not None: self.buttons.append(button) self.add(button) before_txt = "/// " after_txt = " \\\\\\" self.button_action_labels[button.action_label] = before_txt + button.action_label + after_txt self.button_action[button.action_label] = action_call def getButtonByActionLabel(self, action_label): for button in self.buttons: if button.action_label == action_label: return button return None def selectButtonByActionLabel(self, action_label): button = self.getButtonByActionLabel(action_label) if button is not None: button.set_selected(True) from board import Board battle = Board.BOARD.battle turn_unit = battle.getTurnUnit() sel_cell_pos = battle.getSelectedCellPosition() return button.do_action(**{'unit': turn_unit, 'cell_pos': sel_cell_pos}) return button def getSelectedButton(self): for button in self.buttons: if button.selected: return button return None def deselectAllButtons(self, hide_action=True): if hide_action and self.action_btn is not None: self.action_btn.visible = False self.action_btn_bg.visible = False self.action_super_label.visible = False self.action_super_icon.visible = False self.action_sub_label.visible = False if self.action_btn is not None: self.action_btn.set_selected(False) for button in self.buttons: button.clearVars() button.set_selected(False) button.draw_border() def buttonSelected(self, selected_button): if selected_button is self.action_btn: selected_button.selected = True selected_button.update_selected() return from board import Board if self.action_btn is not None: self.action_btn.kill() # a button has been selected, add an action button with the appropriate text action_label = selected_button.action_label action_call = self.button_action[action_label] action_text = self.button_action_labels[action_label] action_font_size = 2 * Board.TILE_SIZE // 3 self.action_btn = TextButton(text=action_text, font_size=action_font_size, action_label=Interface.ACTION, icon=None, action=action_call, width=4 + len(action_text) * 3 * action_font_size // 4, height=4 + Board.TILE_SIZE) self.action_btn.visible = True self.action_btn_bg.visible = True self.add(self.action_btn) self.arrangeButtons() def arrangeButtons(self): num_buttons = len(self.buttons) if num_buttons == 0: return from board import Board size = director.get_window_size() width = size[0] height = size[1] total_width = 0 for button in self.buttons: total_width += button.width + button.border_width // 2 button_x = (width // 2) - (total_width // 2) button_y = 0 for button in self.buttons: button.x = button_x button.y = button_y + button.border_width // 2 button_x += button.width + button.border_width self.action_btn_bg.x = (width // 2) self.action_btn_bg.y = self.action_btn_bg.height // 2 if self.action_btn is not None: self.action_btn.x = (width // 2) - (self.action_btn.width // 2) self.action_btn.y = button_y + Board.TILE_SIZE * 2 self.action_super_icon.x = (width // 2) self.action_super_icon.y = self.action_btn.y + self.action_btn.height \ + self.action_super_icon.height // 2 + 2 self.action_super_label.x = (width // 2) self.action_super_label.y = self.action_super_icon.y + self.action_super_icon.height // 2 self.action_sub_label.x = (width // 2) self.action_sub_label.y = self.action_btn.y - 2 def setButtonsVisible(self, visible): if self.action_btn is not None and self.getSelectedButton() is not None: self.action_super_label.visible = visible self.action_super_icon.visible = visible self.action_btn.visible = visible self.action_btn_bg.visible = visible self.action_sub_label.visible = visible for button in self.buttons: button.visible = visible def getButtonAt(self, x, y): if self.action_btn is not None and self.action_btn.is_at(x, y): return self.action_btn for button in self.buttons: if button.is_at(x, y): return button return None def setActionButtonEnabled(self, enabled): self.action_btn.set_enabled(enabled) def updateActionSubLabelText(self, text): if text is None: self.action_sub_label.visible = False else: size = director.get_window_size() width = size[0] height = size[1] self.action_sub_label.visible = True self.action_sub_label.set_text(text) self.action_sub_label.x = (width // 2) self.action_sub_label.y = self.action_btn.y - 2 def updateActionSuperLabelText(self, text): if text is None: self.action_super_icon.visible = False self.action_super_label.visible = False else: size = director.get_window_size() width = size[0] height = size[1] self.action_super_icon.visible = True self.action_super_label.visible = True self.action_super_label.set_text(text) self.action_super_icon.x = (width // 2) self.action_super_icon.y = self.action_btn.y + self.action_btn.height \ + self.action_super_icon.height // 2 + 2 self.action_super_label.x = (width // 2) self.action_super_label.y = self.action_super_icon.y + self.action_super_icon.height // 2 def setUnitStatsIndicatorsVisible(self, visible, except_units=None): from board import Board if except_units is None: except_units = [] for battle_unit in Board.BOARD.battle.unit_list: if battle_unit.isDestroyed() or battle_unit in except_units: continue battle_unit.sprite.setStatsIndicatorsVisible(visible) def updatePlayerUnitStats(self, battle_unit): if self.unit_display is not None: self.unit_display.kill() self.unit_display_bg.kill() if battle_unit is None: # Hide player unit stats at bottom left self.unit_display = None self.unit_display_bg = None return from board import Board # size = director.get_window_size() # width = size[0] # height = size[1] self.unit_display = UnitCard(battle_unit) self.unit_display.position = Board.TILE_SIZE // 2, Board.TILE_SIZE self.add(self.unit_display) self.unit_display_bg = BatchNode() bg_sprite = Sprite(Resources.unit_card_bg_left_img) self.unit_display_bg.add(bg_sprite) bg_position = self.unit_display.sprite.get_rect().topleft self.unit_display_bg.position = bg_position[0] + bg_sprite.width // 2, bg_position[1] self.add(self.unit_display_bg, z=-1) def updateTargetUnitStats(self, target_unit, is_friendly=False): if self.target_display is not None: self.target_display.kill() self.target_display_bg.kill() if target_unit is None: # Hide target unit stats at top right self.target_display = None self.target_display_bg = None return from board import Board size = director.get_window_size() width = size[0] height = size[1] self.target_display = UnitCard(target_unit, is_friendly=is_friendly, reverse=True) self.target_display.position = width - self.target_display.width - Board.TILE_SIZE // 2, \ height - self.target_display.height - Board.TILE_SIZE // 2 self.add(self.target_display) self.target_display_bg = BatchNode() bg_sprite = Sprite(Resources.unit_card_bg_right_img) self.target_display_bg.add(bg_sprite) self.target_display_bg.position = width - bg_sprite.width // 2, \ height - bg_sprite.height // 2 - Board.TILE_SIZE // 2 self.add(self.target_display_bg, z=-1) def clearToHitLabels(self): for battle_unit in self.to_hit_labels: self.to_hit_labels[battle_unit].kill() self.to_hit_labels.clear() # also clear LOS lines that tend to go with them self.clearLosLines() def updateToHitLabels(self): from board import Board board = Board.BOARD battle = board.battle self.clearToHitLabels() self.clearLosLines() if battle.isBotTurn(): return turn_unit = battle.getTurnUnit() if turn_unit is None or turn_unit.isShutdown(): return enemy_units = battle.getEnemyUnits(turn_unit) for enemy in enemy_units: if enemy.isDestroyed(): continue to_hit = battle.getToHit(turn_unit, enemy) if to_hit > 0: to_hit_text = '{:>3}'.format(str(to_hit) + "%") to_hit_label = TextFloater(to_hit_text, font_name='TranscendsGames', font_size=14, anchor_x='center', anchor_y='bottom') to_hit_label.x = enemy.sprite.x + Board.TILE_SIZE // 4 to_hit_label.y = enemy.sprite.y + enemy.sprite.height // 2 + Board.TILE_SIZE // 2 self.to_hit_labels[enemy] = to_hit_label board.add(to_hit_label, z=9000) # draw LOS line indicator to target self.drawLosLine(turn_unit.getPosition(), enemy.getPosition()) def clearLosLines(self): for los_line in self.los_lines: los_line.kill() self.los_lines = [] def drawLosLine(self, source_coords, target_coords, width=2, alpha=0.8): from board import Board board = Board.BOARD source_x, source_y = Board.board_to_layer(*source_coords) target_x, target_y = Board.board_to_layer(*target_coords) cell_offset = Board.TILE_SIZE // 2 los_line = SingleLine((source_x + cell_offset, source_y + cell_offset), (target_x + cell_offset, target_y + cell_offset), width=width, color=(255, 50, 50, int(255 * alpha))) board.add(los_line, z=10000) self.los_lines.append(los_line) def generateLosLinesFrom(self, source_unit, source_coords=None): from board import Board board = Board.BOARD battle = board.battle self.clearLosLines() if source_unit is None: return if source_coords is None: source_coords = source_unit.getPosition() enemy_units = battle.getEnemyUnits(source_unit) for enemy in enemy_units: if enemy.isDestroyed(): continue target_coords = enemy.getPosition() if battle.hasTargetLOS(source_coords, target_coords): # draw LOS line indicator to target self.drawLosLine(source_coords, target_coords) def generateTargetLosLine(self, source_unit, target_unit): from board import Board board = Board.BOARD battle = board.battle self.clearLosLines() if source_unit is None: return source_coords = source_unit.getPosition() enemy_units = battle.getEnemyUnits(source_unit) for enemy in enemy_units: if enemy.isDestroyed(): continue target_coords = enemy.getPosition() if battle.hasTargetLOS(source_coords, target_coords): # draw LOS line indicator brightest to current target line_alpha = 1.0 if enemy is target_unit else 0.3 line_width = 3 if enemy is target_unit else 2 self.drawLosLine(source_coords, target_coords, width=line_width, alpha=line_alpha)
class Interface(cocos.layer.Layer): UI = None def __init__(self): super(Interface, self).__init__() Interface.UI = self self.unit_display = None self.unit_name = None self.unit_variant = None self.unit_stats = None self.unit_values = None self.target_display = None self.target_name = None self.target_variant = None self.target_stats = None self.target_values = None # size = director.get_window_size() # width = size[0] # height = size[1] # # test1 = Sprite(Resources.friendly_indicator_img) # test1.position = 0 + test1.width//2, 0 + test1.height//2 # # test2 = Sprite(Resources.friendly_indicator_img) # test2.position = width - test1.width // 2, 0 + test1.height // 2 # # test3 = Sprite(Resources.friendly_indicator_img) # test3.position = 0 + test1.width // 2, height - test1.height // 2 # # test4 = Sprite(Resources.friendly_indicator_img) # test4.position = width - test1.width // 2, height - test1.height // 2 # # self.add(test1) # self.add(test2) # self.add(test3) # self.add(test4) def updatePlayerUnitStats(self, battle_unit): if self.unit_display is not None: self.unit_display.kill() self.unit_name.kill() self.unit_variant.kill() self.unit_stats.kill() self.unit_values.kill() if battle_unit is None: # Hide player unit stats at bottom left self.unit_display = None self.unit_name = None self.unit_variant = None self.unit_stats = None self.unit_values = None return size = director.get_window_size() width = size[0] height = size[1] self.unit_display = BatchNode() self.unit_display.position = 0, 0 mech_img_grid = pyglet.image.ImageGrid( pyglet.resource.image(battle_unit.getImagePath()), 1, 6) mech_img_static = mech_img_grid[0] pitch = -(mech_img_static.width * len('RGBA')) img_data = mech_img_static.get_image_data() # testing with masking only a portion of the image damage_height = int( mech_img_static.height) # int(mech_img_static.height * 0.67) data = img_data.get_region(0, 0, mech_img_static.width, damage_height).get_data('RGBA', pitch) mask = Image.frombytes('RGBA', (mech_img_static.width, damage_height), data) # the first image is the color that the stamp will be img1 = Image.new('RGBA', mask.size, color=(0, 0, 0, 255)) # second image is the background img2 = Image.new('RGBA', mask.size, color=(225, 225, 225, 200)) img1 = img1.convert('RGBA') # apply mask to background image img = Image.composite(img1, img2, mask) raw_image = img.tobytes() img_x = mask.size[0] img_y = mask.size[1] pyg_img = pyglet.image.ImageData(img_x, img_y, 'RGBA', raw_image, pitch=-img_x * len('RGBA')) mech_sprite = Sprite(pyg_img) mech_sprite.position = Board.TILE_SIZE // 2 + mech_sprite.width // 2, \ Board.TILE_SIZE + mech_sprite.height // 2 self.unit_display.add(mech_sprite) self.add(self.unit_display) # Show unit name above the image self.unit_name = floaters.TextFloater(battle_unit.getName(), font_name='TranscendsGames', font_size=Board.TILE_SIZE // 2, anchor_x='left', anchor_y='bottom') self.unit_name.position = Board.TILE_SIZE // 2, mech_sprite.get_rect( ).topleft[1] self.add(self.unit_name) # Show unit variant below the image self.unit_variant = floaters.TextFloater( battle_unit.getVariant().upper(), font_name='TranscendsGames', font_size=Board.TILE_SIZE // 3, anchor_x='left', anchor_y='top') self.unit_variant.position = Board.TILE_SIZE // 2, Board.TILE_SIZE - 4 self.add(self.unit_variant) # Show armor, structure, heat stats next to the image (top) self.unit_stats = UnitStats(battle_unit) stats_pos = mech_sprite.get_rect().topright self.unit_stats.position = 4 + stats_pos[0], stats_pos[ 1] - self.unit_stats.height self.add(self.unit_stats) # Show move and attack numbers next to the image (bottom) values = "MV %i ATK %i/%i/%i" % (battle_unit.getTurnMove(), battle_unit.short, battle_unit.medium, battle_unit.long) self.unit_values = floaters.TextFloater(values, font_name='TranscendsGames', font_size=Board.TILE_SIZE // 4, anchor_x='left', anchor_y='bottom') values_pos = mech_sprite.get_rect().bottomright self.unit_values.position = 4 + values_pos[0], values_pos[1] - 2 self.add(self.unit_values) def updateTargetUnitStats(self, target_unit, is_friendly=False): if self.target_display is not None: self.target_display.kill() self.target_name.kill() self.target_variant.kill() self.target_stats.kill() self.target_values.kill() if target_unit is None: # Hide player unit stats at bottom left self.target_display = None self.target_name = None self.target_variant = None self.target_stats = None self.target_values = None return size = director.get_window_size() width = size[0] height = size[1] # Show target name above the image self.target_name = floaters.TextFloater(target_unit.getName(), font_name='TranscendsGames', font_size=Board.TILE_SIZE // 2, anchor_x='right', anchor_y='bottom') self.target_name.position = width - Board.TILE_SIZE // 2, height - Board.TILE_SIZE self.add(self.target_name) self.target_display = BatchNode() self.target_display.position = 0, 0 mech_img_grid = pyglet.image.ImageGrid( pyglet.resource.image(target_unit.getImagePath()), 1, 6) mech_img_static = mech_img_grid[0] pitch = -(mech_img_static.width * len('RGBA')) img_data = mech_img_static.get_image_data() # testing with masking only a portion of the image damage_height = int( mech_img_static.height) # int(mech_img_static.height * 0.67) data = img_data.get_region(0, 0, mech_img_static.width, damage_height).get_data('RGBA', pitch) mask = Image.frombytes('RGBA', (mech_img_static.width, damage_height), data) # the first image is the color that the stamp will be img1 = Image.new('RGBA', mask.size, color=(0, 0, 0, 255)) # second image is the background bg_color = (200, 75, 75, 200) if is_friendly: bg_color = (225, 225, 225, 200) img2 = Image.new('RGBA', mask.size, color=bg_color) img1 = img1.convert('RGBA') # apply mask to background image img = Image.composite(img1, img2, mask) raw_image = img.tobytes() img_x = mask.size[0] img_y = mask.size[1] pyg_img = pyglet.image.ImageData(img_x, img_y, 'RGBA', raw_image, pitch=-img_x * len('RGBA')) mech_sprite = Sprite(pyg_img) mech_sprite.position = width - mech_sprite.width // 2 - Board.TILE_SIZE // 2, \ height - mech_sprite.height // 2 - Board.TILE_SIZE self.target_display.add(mech_sprite) self.add(self.target_display) # Show target variant below the image self.target_variant = floaters.TextFloater( target_unit.getVariant().upper(), font_name='TranscendsGames', font_size=Board.TILE_SIZE // 3, anchor_x='right', anchor_y='top') variant_rect = mech_sprite.get_rect().bottomright self.target_variant.position = variant_rect[0], variant_rect[1] - 4 self.add(self.target_variant) # Show armor, structure, heat stats next to the image (top) self.target_stats = UnitStats(target_unit, reverse=True) stats_pos = mech_sprite.get_rect().topleft self.target_stats.position = stats_pos[ 0] - self.target_stats.width - 4, stats_pos[ 1] - self.target_stats.height self.add(self.target_stats) # Show move and attack numbers next to the image (bottom) values = "MV %i ATK %i/%i/%i" % (target_unit.getTurnMove(), target_unit.short, target_unit.medium, target_unit.long) self.target_values = floaters.TextFloater(values, font_name='TranscendsGames', font_size=Board.TILE_SIZE // 4, anchor_x='right', anchor_y='bottom') values_pos = mech_sprite.get_rect().bottomleft self.target_values.position = values_pos[0] - 4, values_pos[1] self.add(self.target_values)
class Layers: globalPanel = None stats = None walls = [] objects = [] backgrounds = [] bullets = [] tanks = None main_scene = None def __init__(self, main_scene): self.bullets = BatchNode() self.walls = BatchNode() self.objects = BatchNode() self.backgrounds = BatchNode() self.tanks = BatchNode() # self.decorations = BatchNode() #main_scene = get_main_scene_layer() self.main_scene = main_scene self.main_scene.add(self.backgrounds, z=0) self.main_scene.add(self.bullets, z=1) # self.main_scene.add(self.decorations) self.main_scene.add(self.walls) self.main_scene.add(self.objects) self.main_scene.add(self.tanks) self.globalPanel = cocos.layer.Layer() self.main_scene.add(self.globalPanel, z=1) # self.stats = StatsLayer() def init_panel_with_stats(self): self.main_scene.init_panel_with_stats() def setHealth(self, health): self.main_scene.setHealth(health) def damage(self, damage, position): self.main_scene.damage(damage, position) def addElement(self, item, time=0): self.globalPanel.add(item) if time: t = Timer(time, lambda: self.globalPanel.remove(item)) t.start() tankz = 3 def addTank(self, tank): self.tankz += 1 print(tank.position) self.tanks.add(tank, z=2) self.tanks.add(tank.Gun, z=3) self.tanks.add(tank.healthHelper, z=4) def removeTank(self, tank): self.tanks.remove(tank) self.tanks.remove(tank.Gun) self.tanks.remove(tank.healthHelper) def addAnimation(self, anim): self.globalPanel.add(anim) def addObject(self, obj, z=0): self.objects.add(obj, z=z) if obj.healthHelper: self.objects.add(obj.healthHelper, z=2) def removeObject(self, obj): self.objects.remove(obj) if obj.healthHelper: self.objects.remove(obj.healthHelper) def addWall(self, wall, z=0): self.walls.add(wall, z=z) def removeWall(self, wall): self.walls.remove(wall) def removeAnimation(self, anim): self.globalPanel.remove(anim) # try: # if anim in self.globalPanel: self.globalPanel.remove(anim) # except Exception: # pass def addBullet(self, bullet): self.bullets.add(bullet) def removeBullet(self, bullet): if bullet in self.bullets: self.bullets.remove(bullet)
def __init__(self, image): self.image = image self.batch = BatchNode() self.create_background()
class MechSprite(cocos.layer.Layer): shadow_img = pyglet.resource.image("images/ui/shadows.png") shadow_img_grid = pyglet.image.ImageGrid(shadow_img, 1, 4) def __init__(self, battle_mech): super(MechSprite, self).__init__() self.battle_mech = battle_mech mech_img = pyglet.resource.image(self.battle_mech.getImagePath()) mech_img_grid = pyglet.image.ImageGrid(mech_img, 1, 6) self.static = True img_static = Sprite(mech_img_grid[0]) self.width = img_static.width self.height = img_static.height # TODO: setup the non square friendly/enemy indicators based on team of current player's turn if battle_mech.player.is_bot: indicator = Sprite(Resources.enemy_indicator_img) else: indicator = Sprite(Resources.friendly_indicator_img) indicator.visible = False indicator.position = 0, -img_static.height // 2 + indicator.height // 2 + 1 self.indicator = indicator self.add(indicator, z=0) shadow = Sprite(MechSprite.shadow_img_grid[battle_mech.getSize() - 1]) shadow_rect = shadow.get_rect() shadow_rect.bottomleft = (self.battle_mech.col * Board.TILE_SIZE), \ (self.battle_mech.row * Board.TILE_SIZE) shadow.position = shadow_rect.center self.shadow = shadow rect = img_static.get_rect() rect.bottomleft = (self.battle_mech.col * Board.TILE_SIZE) - (img_static.width//2 - shadow.width//2), \ (self.battle_mech.row * Board.TILE_SIZE) self.position = rect.center self.node = BatchNode() self.add(self.node, z=2) img_static.y = Board.TILE_SIZE//4 self.node.add(img_static) self.img_static = img_static img_ct = Sprite(mech_img_grid[1]) img_ct.y = Board.TILE_SIZE//4 self.img_ct = img_ct img_ll = Sprite(mech_img_grid[4]) img_ll.y = Board.TILE_SIZE//4 self.img_ll = img_ll img_rl = Sprite(mech_img_grid[5]) img_rl.y = Board.TILE_SIZE//4 self.img_rl = img_rl img_la = Sprite(mech_img_grid[2]) img_la.y = Board.TILE_SIZE//4 self.img_la = img_la img_ra = Sprite(mech_img_grid[3]) img_ra.y = Board.TILE_SIZE//4 self.img_ra = img_ra # testing the stats stuff self.stats = BatchNode() self.updateStatsIndicators() def get_width(self): return self.img_static.width def get_height(self): return self.img_static.height + int(self.img_static.y) def showIndicator(self, visible=True): self.indicator.visible = visible def showStats(self, visible=True): self.stats.visible = visible def timeBySize(self): times = { 4: 0.25, 3: 0.22, 2: 0.19, 1: 0.16 } return times.get(self.battle_mech.getSize(), times[4]) def destroy(self): # TODO: animate the destruction and show a wreckage self.node.kill() self.shadow.kill() self.indicator.kill() self.kill() def strut(self, reverse=False): self.reset() # make smaller mechs move faster time = self.timeBySize() shift = MoveBy((0, 3), duration=time) move = MoveBy((0, -4), duration=time) if reverse: # start with raising the left leg/right arm first self.img_ra.do(Repeat(shift + Reverse(shift) + Reverse(shift) + shift)) self.img_la.do(Repeat(Reverse(shift) + shift + shift + Reverse(shift))) self.img_rl.do(Repeat(Delay(time * 2) + Reverse(move) + move)) self.img_ll.do(Repeat(Reverse(move) + move + Delay(time * 2))) else: # start with raising the right leg/left arm first self.img_la.do(Repeat(shift + Reverse(shift) + Reverse(shift) + shift)) self.img_ra.do(Repeat(Reverse(shift) + shift + shift + Reverse(shift))) self.img_ll.do(Repeat(Delay(time * 2) + Reverse(move) + move)) self.img_rl.do(Repeat(Reverse(move) + move + Delay(time * 2))) rise = MoveBy((0, 2), duration=time) self.img_ct.do(Repeat(rise + Reverse(rise) + rise + Reverse(rise))) def sulk(self): if not self.static: self.stop() if self.static: self.static = False for section in self.node.get_children(): section.kill() z = 1 self.node.add(self.img_ct, z=z) z += 1 self.node.add(self.img_ll, z=z) z += 1 self.node.add(self.img_rl, z=z) z += 1 self.node.add(self.img_la, z=z) z += 1 self.node.add(self.img_ra, z=z) # TODO: adjust Z order only AFTER a Y position move # TODO: Z order should be based on the number of rows in the board new_z = (Board.numRows - self.battle_mech.row) * 10 parent = self.parent parent.remove(self.shadow) parent.remove(self) parent.add(self.shadow, z=new_z) parent.add(self, z=new_z+2) # make smaller mechs move faster time = self.timeBySize() shift = MoveBy((0, 2), duration=time) self.img_la.do(Repeat(shift + Reverse(shift) + Reverse(shift) + shift)) self.img_ra.do(Repeat(shift + Reverse(shift) + Reverse(shift) + shift)) sink = MoveBy((0, -2), duration=time) self.img_ct.do(Repeat(Delay(time * 2) + sink + Reverse(sink))) def reset(self): for section in self.node.get_children(): section.stop() section.position = 0, Board.TILE_SIZE//4 def stop(self): self.shadow.stop() for section in self.node.get_children(): section.stop() section.position = 0, Board.TILE_SIZE//4 if not self.static: self.static = True for section in self.node.get_children(): section.kill() self.node.add(self.img_static) def pause(self): self.shadow.pause() for section in self.node.get_children(): section.pause() def resume(self): self.shadow.resume() for section in self.node.get_children(): section.resume() def moveBy(self, x, y, func): time = self.timeBySize() * 6 actions = MoveBy((x, y), duration=time) if func is not None: actions += CallFunc(func) self.do(actions) self.shadow.do(actions) def moveToCell(self, col, row, reverse=False, func=None): num_steps = 1 + int(math.ceil(Point2(col, row).distance(Point2(self.battle_mech.col, self.battle_mech.row)))) time = self.timeBySize() * (num_steps * 2) self.battle_mech.col = col self.battle_mech.row = row shadow_rect = self.shadow.get_rect() shadow_rect.bottomleft = (col * 32), (row * 32) rect = self.img_static.get_rect() rect.bottomleft = (col * Board.TILE_SIZE) - (self.img_static.width // 2 - self.shadow.width // 2), \ (row * Board.TILE_SIZE) actions = MoveTo(rect.center, duration=time) if func is not None: actions += CallFunc(func) self.do(actions) shadow_action = MoveTo(shadow_rect.center, duration=time) self.shadow.do(shadow_action) # play movement sounds sound_index = self.battle_mech.getSize() - 1 stomp_sound = Resources.stomp_sounds[sound_index] stomp_action = Delay(0) for i in range(num_steps): # use channel 0 and 1 for alternating steps stomp_channel = pygame.mixer.Channel(i % 2) stomp_reverse = True if i % 2 == (1 if reverse else 0): stomp_reverse = False stomp_action += CallFunc(stomp_channel.play, stomp_sound) + Delay(time / num_steps) \ + CallFunc(self.spawnStompCloud, stomp_reverse) self.do(stomp_action) return time def spawnStompCloud(self, reverse): # show cloud particles from stomps stomp_cloud = Meteor() stomp_cloud.start_color = cocos.particle.Color(0.3, 0.3, 0.3, 1.0) stomp_cloud.end_color = cocos.particle.Color(0.5, 0.5, 0.5, 0.2) stomp_cloud.duration = 0.1 stomp_cloud.blend_additive = False stomp_cloud.size = 10 + (10 * self.battle_mech.getSize() / 4) stomp_cloud.speed = 20 stomp_cloud.gravity = Point2(0, 0) # TODO: offer decreased particle emission rate to improve performance stomp_cloud.emission_rate = 100 stomp_cloud.life = 0.5 stomp_cloud.life_var = 0.1 if not reverse: stomp_cloud.position = self.indicator.position[0] + (self.img_static.width // 4), \ self.indicator.position[1] - self.indicator.height // 5 else: stomp_cloud.position = self.indicator.position[0] - (self.img_static.width // 4), \ self.indicator.position[1] - self.indicator.height // 5 self.add(stomp_cloud, z=1) stomp_action = Delay(stomp_cloud.duration + stomp_cloud.life + stomp_cloud.life_var) \ + CallFunc(stomp_cloud.kill) self.do(stomp_action) def updateStatsIndicators(self): # TODO: Just testing pips on the indicator, it should be put on a new UI layer on top of everything for child in self.stats.get_children(): child.kill() pip_height = 6 - (self.indicator.height // 2) orig_armor = self.battle_mech.mech.armor for i in range(orig_armor): pip_img = Resources.armor_pip_img if i >= self.battle_mech.armor: pip_img = Resources.empty_pip_img pip = Sprite(pip_img) pip.position = (i * pip.width) - (orig_armor * pip.width) // 2, pip_height self.stats.add(pip, z=1) pip_height -= 4 orig_structure = self.battle_mech.mech.structure for i in range(orig_structure): pip_img = Resources.structure_pip_img if i >= self.battle_mech.structure: pip_img = Resources.empty_pip_img pip = Sprite(pip_img) pip.position = (i * pip.width) - (orig_structure * pip.width) // 2, pip_height self.stats.add(pip, z=1) pip_height -= 4 # TESTING: Use actual heat!!! rand_heat = random.randint(0, 4) for i in range(rand_heat): pip = Sprite(Resources.heat_pip_img) pip.position = (i * pip.width) - (rand_heat * pip.width) // 2, pip_height self.stats.add(pip, z=1) self.stats.position = 0, -self.img_static.height // 2 + self.indicator.height // 2 + 1 self.add(self.stats, z=1)
class Task(ColorLayer, pyglet.event.EventDispatcher): d = Dispatcher() actr_d = JNI_Dispatcher() states = ["INIT", "WAIT_ACTR_CONNECTION", "WAIT_ACTR_MODEL", "CALIBRATE", "IGNORE_INPUT", "WAIT", "STUDY", "SEARCH", "RESULTS"] STATE_INIT = 0 STATE_CALIBRATE = 1 STATE_IGNORE_INPUT = 2 STATE_WAIT_ACTR_CONNECTION = 3 STATE_WAIT_ACTR_MODEL = 4 STATE_WAIT = 5 STATE_STUDY = 6 STATE_SEARCH = 7 STATE_RESULTS = 8 is_event_handler = True def __init__(self, client, actr): self.screen = director.get_window_size() super(Task, self).__init__(168, 168, 168, 255, self.screen[1], self.screen[1]) self.state = self.STATE_INIT self.client = client self.client_actr = actr self.circles = [] self.trial_complete = False def on_enter(self): if isinstance(director.scene, TransitionScene): return super(Task, self).on_enter() header = [] if director.settings['mode'] == 'Experiment': header += ["datestamp", "encrypted_rin"] header += ["system_time", "mode", "trial", "state", "event_source", "event_type", "event_id", "screen_width", "screen_height", "mouse_x", "mouse_y", "study_time", "search_time"] if director.settings['eyetracker'] and self.client: self.smi_spl_header = ["smi_time", "smi_type", "smi_sxl", "smi_sxr", "smi_syl", "smi_syr", "smi_dxl", "smi_dxr", "smi_dyl", "smi_dyr", "smi_exl", "smi_exr", "smi_eyl", "smi_eyr", "smi_ezl", "smi_ezr"] header += self.smi_spl_header + ["smi_fx", "smi_fy"] self.logger = Logger(header) self.tarfile = tarfile.open('data/%s.tar.gz' % director.settings['filebase'], mode='w:gz') self.position = ((self.screen[0] - self.screen[1]) / 2, 0) self.cm = CollisionManagerBruteForce() self.mono = font.load("Mono", 32) self.shapes = {"oval":"F", # "diamond":"T", "crescent":"Q", "cross":"Y", "star":"C"} # star 83x79 1.05 2581/6557 .39 # oval 55x83 .66 3427/4565 .75 # crescent 51x77 .66 1580/3927 .40 # cross 61x62 .98 1783/3782 .47 # rect 46x73. .63 3358/3358 1 # cross2 57x84 .67 1532/4788 .31 self.shape_mod = {"oval":[1.0, 1.0, 1.0], # "diamond":"T", "crescent":[1.07, 1.07, 1.07], "cross":[1.15, 1.15, 1.15], "star":[1.0, 1.0, 1.0]} self.font = font.load('Cut Outs for 3D FX', 128) for shape in self.shapes: self.shapes[shape] = self.font.get_glyphs(self.shapes[shape])[0].get_texture(True) s = 50 v = 100 self.colors = {"red": hsv_to_rgb(0, s, v), "yellow": hsv_to_rgb(72, s, v), "green": hsv_to_rgb(144, s, v), # "purple": hsv_to_rgb(288, s, v), "blue": hsv_to_rgb(216, s, v)} self.side = self.screen[1] / 11 self.ratio = self.side / 128 self.scales = [self.ratio * 2, self.ratio * 1.25, self.ratio * .5] self.sizes = ["large", "medium", "small"] self.ready_label = Label("Click mouse when ready!", position=(self.width / 2, self.height / 2), font_name='Pipe Dream', font_size=24, color=(0, 0, 0, 255), anchor_x='center', anchor_y='center') self.gaze = Label('G',font_name='Cut Outs for 3D FX', font_size=48, position=(self.width / 2, self.height / 2), color=(255, 0, 0, 192), anchor_x='center', anchor_y='center') self.attention = Label('G',font_name='Cut Outs for 3D FX', font_size=48, position=(self.width / 2, self.height / 2), color=(0, 0, 255, 192), anchor_x='center', anchor_y='center') self.reset_state() if director.settings['player'] == "ACT-R": self.add(self.gaze, z=99) self.add(self.attention, z=99) self.client_actr.addDispatcher(self.actr_d) self.state = self.STATE_WAIT_ACTR_CONNECTION self.dispatch_event("actr_wait_connection") elif director.settings['eyetracker']: self.state = self.STATE_CALIBRATE self.dispatch_event("start_calibration", self.calibration_ok, self.calibration_bad) else: self.next_trial() def reset_state(self): s = int(director.settings['seed']) if s > 0: seed(s) self.current_trial = 0 self.total_trials = None if director.settings['mode'] == 'Experiment': self.gen_trials() self.fake_cursor = (self.screen[0] / 2, self.screen[1] / 2) def calibration_ok(self): self.dispatch_event("stop_calibration") self.next_trial() def calibration_bad(self): self.dispatch_event("stop_calibration") self.logger.close(True) self.tarfile.close() director.scene.dispatch_event("show_intro_scene") def on_exit(self): if isinstance(director.scene, TransitionScene): return if self.client_actr: self.client_actr.removeDispatcher(self.actr_d) self.client_actr.disconnect() super(Task, self).on_exit() for c in self.get_children(): if c != self.gaze and c != self.attention: self.remove(c) def next_trial(self): self.trial_complete = False if self.current_trial == self.total_trials: self.logger.close(True) self.tarfile.close() director.scene.dispatch_event("show_intro_scene") else: self.search_time = -1 self.study_time = -1 director.window.set_mouse_visible(False) self.clear_shapes() self.log_extra = {'screen_width':self.screen[0], 'screen_height': self.screen[1]} if director.settings['player'] == 'Human' and director.settings['mode'] == 'Experiment': self.log_extra['datestamp'] = director.settings['si']['timestamp'] self.log_extra['encrypted_rin'] = director.settings['si']['encrypted_rin'] self.state = self.STATE_WAIT self.current_trial += 1 self.gen_combos() self.add(self.ready_label) self.logger.open(StringIO()) self.logger.write(system_time=get_time(), mode=director.settings['mode'], trial=self.current_trial, event_source="TASK", event_type=self.states[self.state], state=self.states[self.state], event_id="START", **self.log_extra) self.dispatch_event("new_trial", self.current_trial, self.total_trials) if self.client: self.dispatch_event("show_headposition") if director.settings['player'] == 'ACT-R': X = VisualChunk(None, "text", self.screen[0] / 2, self.screen[1] / 2, value="Click mouse when ready!", width=self.ready_label.element.content_width, height=self.ready_label.element.content_height) self.client_actr.update_display([X], clear=True) def trial_done(self): self.trial_complete = True t = get_time() self.search_time = t - self.start_time self.logger.write(system_time=t, mode=director.settings['mode'], trial=self.current_trial, event_source="TASK", event_type=self.states[self.state], state=self.states[self.state], event_id="END", **self.log_extra) self.state = self.STATE_RESULTS self.logger.write(system_time=t, mode=director.settings['mode'], trial=self.current_trial, event_source="TASK", event_type=self.states[self.state], state=self.states[self.state], study_time=self.study_time, search_time=self.search_time, **self.log_extra) tmp = self.logger.file.getvalue() data = tarfile.TarInfo("%s/trial-%02d.txt" % (director.settings['filebase'], self.current_trial)) data.size = len(tmp) self.tarfile.addfile(data, StringIO(tmp)) tmp = StringIO() screenshot().save(tmp, "png") data = tarfile.TarInfo("%s/trial-%02d.png" % (director.settings['filebase'], self.current_trial)) data.size = len(tmp.getvalue()) tmp.seek(0) self.tarfile.addfile(data, tmp) self.logger.close() if director.settings['eyetracker'] and self.client: self.client.removeDispatcher(self.d) self.client.stopFixationProcessing() if director.settings['player'] == 'ACT-R' and director.settings['mode'] != 'Experiment': self.client_actr.trigger_event(":trial-complete") else: self.next_trial() def gen_trials(self): self.trials = [] for scale in self.sizes: for color in self.colors: for shape in self.shapes: for c in range(0, 8): self.trials.append([shape, color, scale, c]) self.total_trials = len(self.trials) shuffle(self.trials) def gen_combos(self): ids = range(1, len(self.sizes) * len(self.colors) * len(self.shapes) + 1) shuffle(ids) self.combos = [] for scale in self.sizes: for color in self.colors: for shape in self.shapes: self.combos.append([shape, color, scale, ids.pop()]) def gen_probe(self): for c in self.get_children(): if c != self.gaze and c != self.attention: self.remove(c) s = 0 if director.settings['mode'] == 'Experiment': trial = self.trials.pop() for c in self.combos: if c[0] == trial[0] and c[1] == trial[1] and c[2] == trial[2]: chunk = c s = trial[3] break else: if director.settings['mode'] == 'Moderate': s = choice(range(0, 4)) elif director.settings['mode'] == 'Hard': s = choice(range(0, 7)) elif director.settings['mode'] == 'Insane': s = choice(range(0, 8)) chunk = choice(self.combos) self.probe = Probe(chunk, s, self.side, (self.screen[1] / 2, self.screen[1] / 2), 14 * self.ratio) self.add(self.probe) def clear_shapes(self): self.circles = [] self.cm.clear() for c in self.get_children(): if c != self.gaze and c != self.attention: self.remove(c) self.batch = BatchNode() self.id_batch = BatchNode() def show_shapes(self): self.cm.add(self.probe) ratio = self.side / 128 self.circles = [] shapeinfo = {} shapeinfo['probe'] = {"id": self.probe.chunk[3], "color": self.probe.color_visible, "shape": self.probe.shape_visible, "size": self.probe.size_visible} actr_chunks = self.probe.actr_chunks for c in self.combos: img = self.shapes[c[0]] img.anchor_x = 'center' img.anchor_y = 'center' sprite = Shape(img, chunk=c, rotation=randrange(0, 365), color=self.colors[c[1]], scale=self.shape_mod[c[0]][self.sizes.index(c[2])] * self.scales[self.sizes.index(c[2])]) pad = sprite.radius sprite.set_position(uniform(pad, self.screen[1] - pad), uniform(pad, self.screen[1] - pad)) while self.cm.objs_colliding(sprite): sprite.set_position(uniform(pad, self.screen[1] - pad), uniform(pad, self.screen[1] - pad)) fs = 14 * ratio text.Label("%02d" % c[3], font_size=fs, x=sprite.position[0], y=sprite.position[1], font_name="Monospace", color=(32, 32, 32, 255), anchor_x='center', anchor_y='center', batch=self.id_batch.batch) shapeinfo[c[3]] = {'shape':c[0], 'color':c[1], 'size':c[2], 'id': c[3], 'radius':sprite.cshape.r, 'x':sprite.position[0], 'y':sprite.position[1]} self.circles.append(Circle(sprite.position[0] + (self.screen[0] - self.screen[1]) / 2, sprite.position[1], width=2 * sprite.cshape.r)) self.cm.add(sprite) self.batch.add(sprite) actr_chunks.append(PAAVChunk(None, "visual-object", sprite.position[0] + (self.screen[0] - self.screen[1]) / 2, sprite.position[1], width = 2 * sprite.cshape.r, height = 2 * sprite.cshape.r, fshape = ":w67-%s" % c[0], fcolor = ":w67-%s" % c[1], fsize = ":w67-%s" % c[2])) actr_chunks.append(VisualChunk(None, "text", sprite.position[0] + (self.screen[0] - self.screen[1]) / 2, sprite.position[1], width = 2 * fs, height = fs, value = "%02d" % c[3])) if director.settings['player'] == 'ACT-R' and actr_chunks: self.client_actr.update_display(actr_chunks, clear=False) self.circles.append(Circle(self.probe.position[0] + (self.screen[0] - self.screen[1]) / 2, self.probe.position[1], width=2 * self.probe.cshape.r)) self.add(self.batch, z=1) self.add(self.id_batch, z=2) s = StringIO(json.dumps(shapeinfo, sort_keys=True, indent=4)) data = tarfile.TarInfo("%s/trial-%02d.json" % (director.settings['filebase'], self.current_trial)) data.size = len(s.getvalue()) s.seek(0) self.tarfile.addfile(data, s) if ACTR6: @actr_d.listen('connectionMade') def ACTR6_JNI_Event(self, model, params): print "ACT-R Connection Made" self.state = self.STATE_WAIT_ACTR_MODEL self.dispatch_event("actr_wait_model") self.client_actr.setup(self.screen[1], self.screen[1]) @actr_d.listen('connectionLost') def ACTR6_JNI_Event(self, model, params): print "ACT-R Connection Lost" self.state = self.STATE_WAIT_ACTR_CONNECTION self.dispatch_event("actr_wait_connection") @actr_d.listen('reset') def ACTR6_JNI_Event(self, model, params): print "ACT-R Reset" self.state = self.STATE_WAIT_ACTR_MODEL self.dispatch_event("actr_wait_model") self.reset_state() @actr_d.listen('model-run') def ACTR6_JNI_Event(self, model, params): print "ACT-R Model Run" self.dispatch_event("actr_running") if params['resume']: if self.trial_complete: self.next_trial() else: self.reset_state() self.next_trial() @actr_d.listen('model-stop') def ACTR6_JNI_Event(self, model, params): print "ACT-R Model Stop" @actr_d.listen('gaze-loc') def ACTR6_JNI_Event(self, model, params): if params['loc']: params['loc'][0] -= (self.screen[0] - self.screen[1]) / 2 print "ACT-R Gaze: ", print params['loc'] self.gaze.position = params['loc'] self.gaze.visible = True else: self.gaze.visible = False @actr_d.listen('attention-loc') def ACTR6_JNI_Event(self, model, params): if params['loc']: params['loc'][0] -= (self.screen[0] - self.screen[1]) / 2 print "ACT-R Attention: ", print params['loc'] self.attention.position = params['loc'] self.attention.visible = True else: self.attention.visible = False @actr_d.listen('keypress') def ACTR6_JNI_Event(self, model, params): print "ACT-R Keypress: %s" % chr(params['keycode']) self.on_key_press(params['keycode'], None) @actr_d.listen('mousemotion') def ACTR6_JNI_Event(self, model, params): # Store "ACT-R" cursor in variable since we are # not going to move the real mouse print "ACT-R Mousemotion: ", print params self.fake_cursor = params['loc'] self.on_mouse_motion(self.fake_cursor[0], self.fake_cursor[1], None, None) @actr_d.listen('mouseclick') def ACTR6_JNI_Event(self, model, params): # Simulate a button press using the "ACT-R" cursor loc print "ACT-R Mouseclick" self.on_mouse_press(self.fake_cursor[0], self.fake_cursor[1], 1, None) if eyetracking: @d.listen('ET_FIX') def iViewXEvent(self, inResponse): eyedata = {} eyedata.update(self.log_extra) eyedata["smi_type"] = inResponse[0] eyedata["smi_time"] = inResponse[1] eyedata["smi_fx"] = inResponse[2] eyedata["smi_fy"] = inResponse[3] self.logger.write(system_time=get_time(), mode=director.settings['mode'], state=self.states[self.state], trial=self.current_trial, event_source="SMI", event_type="ET_FIX", **eyedata) @d.listen('ET_SPL') def iViewXEvent(self, inResponse): eyedata = {} eyedata.update(self.log_extra) for i, _ in enumerate(self.smi_spl_header): eyedata[self.smi_spl_header[i]] = inResponse[i] self.logger.write(system_time=get_time(), mode=director.settings['mode'], state=self.states[self.state], trial=self.current_trial, event_source="SMI", event_type="ET_SPL", **eyedata) # def draw(self): # super(Task, self).draw() # for c in self.circles: c.render() def on_mouse_press(self, x, y, buttons, modifiers): if self.state < self.STATE_IGNORE_INPUT: return if self.state == self.STATE_WAIT: self.logger.write(system_time=get_time(), mode=director.settings['mode'], trial=self.current_trial, event_source="TASK", event_type=self.states[self.state], state=self.states[self.state], event_id="END", **self.log_extra) self.gen_probe() self.state = self.STATE_STUDY if director.settings['player'] == 'ACT-R': self.client_actr.update_display(self.probe.actr_chunks, clear=True) t = get_time() self.start_time = t self.logger.write(system_time=t, mode=director.settings['mode'], trial=self.current_trial, event_source="TASK", event_type=self.states[self.state], state=self.states[self.state], event_id="START", **self.log_extra) if director.settings['eyetracker'] and self.client: self.dispatch_event("hide_headposition") self.client.addDispatcher(self.d) self.client.startFixationProcessing() elif self.state == self.STATE_SEARCH: self.logger.write(system_time=get_time(), mode=director.settings['mode'], trial=self.current_trial, event_source="USER", event_type=self.states[self.state], state=self.states[self.state], event_id="MOUSE_PRESS", mouse_x=x, mouse_y=y, **self.log_extra) if director.settings['player'] != "ACT-R": x, y = director.get_virtual_coordinates(x, y) for obj in self.cm.objs_touching_point(x - (self.screen[0] - self.screen[1]) / 2, y): if obj != self.probe and obj.chunk == self.probe.chunk: self.trial_done() else: t = get_time() self.study_time = t - self.start_time self.logger.write(system_time=t, mode=director.settings['mode'], trial=self.current_trial, event_source="TASK", event_type=self.states[self.state], state=self.states[self.state], event_id="END", **self.log_extra) self.show_shapes() window = director.window.get_size() nx = int(window[0] / 2) ny = int(window[1] / 2 - self.probe.cshape.r * .75 * (window[1] / self.screen[1])) t = get_time() self.start_time = t self.state = self.STATE_SEARCH self.logger.write(system_time=t, mode=director.settings['mode'], trial=self.current_trial, event_source="TASK", event_type=self.states[self.state], state=self.states[self.state], event_id="START", **self.log_extra) self.logger.write(system_time=t, mode=director.settings['mode'], trial=self.current_trial, event_source="TASK", event_type=self.states[self.state], state=self.states[self.state], event_id="MOUSE_RESET", mouse_x=nx, mouse_y=ny, **self.log_extra) if director.settings['player'] == "ACT-R": self.client_actr.set_cursor_location([nx, ny]) else: director.window.set_mouse_position(nx, ny) director.window.set_mouse_visible(True) def on_mouse_motion(self, x, y, dx, dy): if self.state < self.STATE_IGNORE_INPUT: return if self.state == self.STATE_SEARCH: self.logger.write(system_time=get_time(), mode=director.settings['mode'], trial=self.current_trial, event_source="USER", event_type=self.states[self.state], state=self.states[self.state], event_id="MOUSE_MOTION", mouse_x=x, mouse_y=y, **self.log_extra) def on_key_press(self, symbol, modifiers): if self.state <= self.STATE_IGNORE_INPUT: return if symbol == key.W and (modifiers & key.MOD_ACCEL): self.logger.close(True) self.tarfile.close() director.scene.dispatch_event("show_intro_scene") True elif symbol == key.ESCAPE and director.settings['player'] == "ACT-R": if self.state == self.STATE_WAIT_ACTR_CONNECTION: director.scene.dispatch_event("show_intro_scene") True elif self.state > self.STATE_WAIT_ACTR_MODEL: self.client_actr.trigger_event(":break") True
class GameLayer(ScrollableLayer): def __init__(self, *args): super().__init__() self.hud = args[0] self.obstacle_map = args[1] self.objects_map = args[2] self.tileset = args[3] self.create_mario() self.create_cliff() self.create_flag() self.enemies = BatchNode() self.add(self.enemies) self.enemy_objs = self.objects_map.match(label="enemy") self.exist_enemy_index = [] width, height = director.get_window_size() self.cm = CollisionManagerGrid(0, width, 0, height, 20, 20) stats.reset_current_game() Sound.play("mario") def on_enter(self): super().on_enter() self.schedule(self.update) def on_exit(self): super().on_exit() self.unschedule(self.update) def create_mario(self): obj = self.objects_map.match(label="start point")[0] self.mario = Mario(obj.position, self.obstacle_map) self.add(self.mario, z=50) def create_cliff(self): self.cliffs = BatchNode() self.add(self.cliffs) for i, _ in enumerate(self.obstacle_map.cells): if not self.obstacle_map.cells[i][0].tile: self.cliffs.add( Cliff(self.obstacle_map.cells[i][0].center, self.obstacle_map)) def create_flag(self): obj = self.objects_map.match(label="flag")[0] self.flag = Flag(obj.position) self.add(self.flag) def find_new_enemies(self): for obj in self.enemy_objs: if self.obstacle_map.is_visible(obj) and \ obj["index"] not in self.exist_enemy_index: yield obj def create_enemies(self): for obj in self.find_new_enemies(): if obj.name == "Goomba": self.enemies.add(Goomba(obj.position, self.obstacle_map)) elif obj.name == "Koopa": self.enemies.add(Koopa(obj.position, self.obstacle_map)) self.exist_enemy_index.append(obj["index"]) def update(self, dt): self.mario.update_(dt) self.create_enemies() self.handle_collide() self.update_timer(dt) def handle_collide(self): self.collide_with_obstacle() self.collide_with_objects() def collide_with_obstacle(self): if not self.mario.collide_cells: return cell = self.mario.collide_cells.popleft() label = cell.get("label") if label == "normal brick": if self.mario.state == Mario.SMALL: Sound.play("bump") self.popup_brick("normal", cell) else: Sound.play("brick_smash") self.smash_brick(cell) elif label == "unknown brick": self.popup_brick("unknown", cell) objs = self.objects_map.get_in_region(cell.left, cell.bottom, cell.right, cell.top) if objs: Sound.play("powerup_appears") # normally, only 1 object collide with cell self.collide_unknown_brick_with_obj(objs[0]) else: Sound.play("coin") self.collide_unknown_brick_without_obj(cell) elif label == "flagpole": self.world_complete() def popup_brick(self, name, cell): self.obstacle_map.set_cell_opacity(cell.i, cell.j, 0) self.add(PopupBrick(name, cell.center)) def recover_opacity(): self.obstacle_map.set_cell_opacity(cell.i, cell.j, 255) self.obstacle_map.set_cell_color(cell.i, cell.j, (255, 255, 255)) self.do(Delay(0.2) + CallFunc(recover_opacity)) if name == "unknown": # change cell image to "bumped brick" cell.tile = self.tileset[1] self.obstacle_map.set_dirty() def smash_brick(self, cell): cell.tile = None self.obstacle_map.set_dirty() self.add(BrokenBrick(cell.midtop)) def collide_unknown_brick_with_obj(self, obj): if obj.name == "Normal mushroom": self.add(NormalMushroom(obj.position, self.obstacle_map)) elif obj.name == "Life mushroom": self.add(LifeMushroom(obj.position, self.obstacle_map)) elif obj.name == "Reward": if self.mario.state == Mario.SMALL: self.add(NormalMushroom(obj.position, self.obstacle_map)) elif self.mario.state == Mario.BIG: self.add(FireFlower(obj.position, self.obstacle_map)) elif self.mario.state == Mario.FIRE: self.add(FireFlower(obj.position, self.obstacle_map)) def collide_unknown_brick_without_obj(self, cell): self.add(Coin(cell.midtop)) stats.coins += 1 stats.score += 200 def collide_with_objects(self): self.cm.xmin = self.obstacle_map.view_x self.cm.xmax = self.obstacle_map.view_x + self.obstacle_map.view_w self.cm.clear() for _, enemy in self.enemies.children: if enemy.active: self.cm.add(enemy) for _, cliff in self.cliffs.children: self.cm.add(cliff) for _, node in self.children: if isinstance(node, Mushroom) or isinstance(node, FireFlower): self.cm.add(node) for obj in self.cm.iter_colliding(self.mario): if isinstance(obj, Enemy): self.collide_enemy(obj) elif isinstance(obj, Cliff): self.collide_cliff() break else: self.collide_prop(obj) def collide_enemy(self, obj): if self.mario.collide_bottom_obj(obj): Sound.play("stomp") stats.score += 100 obj.die() self.mario.do(JumpBy((0, 0), 16, 1, 0.3)) else: if self.mario.state == Mario.SMALL: self.game_over("enemy") elif self.mario.state == Mario.BIG: self.mario.state = Mario.SMALL elif self.mario.state == Mario.FIRE: self.mario.state = Mario.BIG self.enemies.remove(obj) def collide_cliff(self): self.game_over("cliff") def collide_prop(self, obj): Sound.play("powerup") if isinstance(obj, NormalMushroom): stats.score += 1000 if self.mario.state == Mario.SMALL: self.mario.state = Mario.BIG elif isinstance(obj, LifeMushroom): stats.life += 1 elif isinstance(obj, FireFlower): stats.score += 1000 if self.mario.state == Mario.BIG: self.mario.state = Mario.FIRE elif self.mario.state == Mario.FIRE: # do something else pass self.remove(obj) def enter_info_scene(self, world_complete=False): from info_scene.info_scene import InfoScene director.replace(InfoScene(self.hud, world_complete)) def game_over(self, reason): stats.life -= 1 Sound.stop("mario") if stats.life > 0: Sound.play("death") else: Sound.play("game_over") # change current layer z-order, make it the top self.parent.remove(self) self.parent.add(self, z=3) self.unschedule(self.update) if reason == "enemy" or reason == "timeout": self.mario.die() self.do(Delay(1) + CallFunc(self.enter_info_scene)) elif reason == "cliff": self.enter_info_scene() else: pass def world_complete(self): stats.update_score_flagpole_height(self.mario.y) Sound.stop("mario") Sound.play("flagpole") self.unschedule(self.update) end_point_pos_x = 0 castle_flag_pos = 0, 0 for obj in self.objects_map.objects: if obj.name == "End point": end_point_pos_x = obj.x elif obj.name == "Castle flag": castle_flag_pos = obj.position self.flag.lower() self.mario.raise_flag(end_point_pos_x) self.do( Delay(5) + CallFunc(lambda: self.add(CastleFlag(castle_flag_pos))) + Delay(5) + CallFunc(self.enter_info_scene, True)) def update_timer(self, dt): stats.update_timer(dt) if stats.time == 100: Sound.stop("mario") Sound.play("out_of_time") self.do(Delay(2) + CallFunc(Sound.play, "mario")) if stats.time <= 0: self.game_over("timeout")
class CalibrationLayer(ColorLayer, event.EventDispatcher): is_event_handler = True d = Dispatcher() STATE_REFUSED = -1 STATE_INIT = 0 STATE_CALIBRATE = 1 STATE_VALIDATE = 2 STATE_DONE = 3 def __init__(self, client, points=9, eye=1, wait=1, randomize=1, auto=0, speed=1, level=3): super(CalibrationLayer, self).__init__(0, 0, 255, 255) self.client = client self.points = points self.eye = eye self.wait = wait self.randomize = randomize self.auto = auto self.speed = speed self.level = level self.on_success = None self.on_failure = None self.window = director.window.get_size() self.screen = director.get_window_size() self.center_x = self.screen[0] / 2 self.center_y = self.screen[1] / 2 self.win_scale = (self.screen[0] / self.window[0], self.screen[1] / self.window[1]) self.font = font.load("Cut Outs for 3D FX", 32) self.circle_img = self.font.get_glyphs("E")[0].get_texture(True) self.circle_img.anchor_x = "center" self.circle_img.anchor_y = "center" self.pnt_img = self.font.get_glyphs("Y")[0].get_texture(True) self.pnt_img.anchor_x = "center" self.pnt_img.anchor_y = "center" self.circle = Sprite(self.circle_img, color=(255, 255, 0), scale=1, opacity=0) self.spinner = Sprite( resource.image("spinner.png"), position=(self.screen[0] / 2, self.screen[1] / 2), color=(255, 255, 255) ) def on_enter(self): super(CalibrationLayer, self).on_enter() if isinstance(director.scene, TransitionScene): return director.window.set_mouse_visible(False) self.client.addDispatcher(self.d) self.reset() self.start() def on_exit(self): super(CalibrationLayer, self).on_exit() if isinstance(director.scene, TransitionScene): return self.reset() self.client.removeDispatcher(self.d) def init(self): self.ts = -1 self.eye_position = None self.calibrationPoints = [None] * 9 self.calibrationResults = [] self.add(self.circle, z=2) self.state = self.STATE_INIT def reset(self): self.client.cancelCalibration() for c in self.get_children(): c.stop() self.remove(c) self.batch1 = BatchNode() self.batch2 = BatchNode() self.init() def start(self): if self.state > self.STATE_REFUSED: print "start" self.dispatch_event("show_headposition") self.state = self.STATE_CALIBRATE self.client.stopDataStreaming() self.client.setSizeCalibrationArea(self.width, self.height) self.client.setCalibrationParam(0, self.wait) self.client.setCalibrationParam(1, self.randomize) self.client.setCalibrationParam(2, self.auto) self.client.setCalibrationParam(3, self.speed) self.client.setCalibrationCheckLevel(self.level) if self.eye == 1 or self.eye == 2: self.client.startCalibration(self.points, self.eye) else: self.client.startCalibration(self.points) def on_key_press(self, symbol, modifiers): if symbol == key.SPACE: if self.state == self.STATE_CALIBRATE and not self.circle.actions: self.client.acceptCalibrationPoint() return True elif self.state == self.STATE_DONE: self.reset() self.on_success() return True elif symbol == key.R: self.reset() self.start() return True elif symbol == key.W and (modifiers & key.MOD_ACCEL): # self.reset() self.on_failure() return True @d.listen("CONNECTION_REFUSED") def iViewXEvent(self, inResponse): self.state = self.STATE_REFUSED self.label = Label( "Connection to iViewX server refused!", position=(self.screen[0] / 2, self.screen[1] / 2), align="center", anchor_x="center", anchor_y="center", width=self.screen[0], font_size=32, color=(255, 255, 255, 255), font_name="Monospace", multiline=True, ) self.add(self.label, z=1) @d.listen("ET_CAL") def iViewXEvent(self, inResponse): print "ET_CAL", inResponse @d.listen("ET_CSZ") def iViewXEvent(self, inResponse): print "ET_CSZ", inResponse @d.listen("ET_PNT") def iViewXEvent(self, inResponse): if self.state == self.STATE_CALIBRATE: print "ET_PNT", inResponse, self.calibrationPoints i = int(inResponse[0]) - 1 self.calibrationPoints[i] = (int(inResponse[1]), int(inResponse[2])) s = Sprite(self.pnt_img, color=(255, 0, 0), scale=0.75) s.set_position(self.calibrationPoints[i][0], self.calibrationPoints[i][1]) self.add(s, z=1) elif self.state == self.STATE_VALIDATE: pass @d.listen("ET_CHG") def iViewXEvent(self, inResponse): print "ET_CHG", inResponse currentPoint = int(inResponse[0]) - 1 x = self.calibrationPoints[currentPoint][0] * self.win_scale[0] y = self.calibrationPoints[currentPoint][1] * self.win_scale[1] self.circle.opacity = 255 if currentPoint == 0: self.circle.set_position(x, y) else: self.circle.do(MoveTo((x, y), 0.75)) @d.listen("ET_VLS") def iViewXEvent(self, inResponse): print "ET_VLS", inResponse if self.state == self.STATE_VALIDATE: self.calibrationResults.append(" ".join(inResponse)) if len(self.calibrationResults) == 2: self.remove(self.spinner) self.remove(self.label) text = "\n".join(self.calibrationResults).decode("cp1252") text += "\n\n\nPress 'R' to recalibrate, spres 'Spacebar' to continue..." self.label = Label( text, position=(self.screen[0] / 2, self.screen[1] / 2), align="center", anchor_x="center", anchor_y="center", width=self.screen[0], font_size=32, color=(255, 255, 255, 255), font_name="Monospace", multiline=True, ) self.add(self.label) self.state = self.STATE_DONE @d.listen("ET_CSP") def iViewXEvent(self, inResponse): sl = Sprite(self.pnt_img, color=(255, 255, 0), scale=0.25, opacity=128) sl.set_position(int(float(inResponse[1])), int(float(inResponse[2]))) self.batch1.add(sl) sr = Sprite(self.pnt_img, color=(0, 255, 0), scale=0.25, opacity=128) sr.set_position(int(float(inResponse[3])), int(float(inResponse[4]))) self.batch2.add(sr) @d.listen("ET_FIN") def iViewXEvent(self, inResponse): print "ET_FIN", inResponse if self.state != self.STATE_VALIDATE: self.add(self.batch1, z=1) self.add(self.batch2, z=1) self.dispatch_event("hide_headposition") self.state = self.STATE_VALIDATE self.remove(self.circle) self.add(self.spinner) self.spinner.do(Repeat(RotateBy(360, 1))) self.label = Label( "CALCULATING CALIBRATION ACCURACY", position=(self.screen[0] / 2, self.screen[1] / 4 * 3), font_size=32, color=(255, 255, 255, 255), font_name="Monospace", anchor_x="center", anchor_y="center", ) self.add(self.label) self.client.requestCalibrationResults() self.client.validateCalibrationAccuracy()
def main(): global keyboard, player_layer, bullets_layer, walls_layer, collision_manager # Declare this as global so it can be accessed within class methods. # Initialize the window. director.init(width=1000, height=1000, do_not_scale=True, resizable=True) collision_manager = cm.CollisionManagerBruteForce() # Create a layer and add a sprite to it. #player_layer = layer.Layer() player_layer = Game() bullets_layer = BatchNode() walls_layer = BatchNode() Tank1 = TankRank1() collision_manager.add(Tank1) player_layer.add(Tank1) player_layer.add(Tank1.getGunSprite()) player_layer.add(bullets_layer) player_layer.add(walls_layer) for i in range(10): wall = sprite.Sprite('sprites/walls/sprite_bricks_tutorial_1.png') walls_layer.add(wall) wall.position = (i*32, 500) wall.cshape = cm.AARectShape( wall.position, wall.width // 2, wall.height // 2 ) collision_manager.add(wall) walls_array.append(wall) # load the example running.png as a pyglet image #spritesheet = pyglet.image.load('sprites/effects/explose2.png') # use ImageGrid to divide your sprite sheet into smaller regions #grid = pyglet.image.ImageGrid(spritesheet, 6, 5, item_width=78, item_height=121) #textures = pyglet.image.TextureGrid(grid) #explose = pyglet.image.Animation.from_image_sequence(textures, 0.1, loop=True) animation = pyglet.image.load_animation('sprites/effects/nuke-ani.gif') #bin = pyglet.image.TextureBin() #animation.add_to_texture_bin(bin) anim = sprite.Sprite(animation) anim.position = (500, 500) player_layer.add(anim) # Set initial position and velocity. Tank1.setDefaultState() # Set the sprite's movement class. Tank1.do(SetDefaultMovingHandlers()) # Create a scene and set its initial layer. main_scene = scene.Scene(player_layer) #http://css.spritegen.com/ #scene.add(background_layer, z=0) #scene.add(game_layer, z=1) # Attach a KeyStateHandler to the keyboard object. keyboard = key.KeyStateHandler() director.window.push_handlers(keyboard) # Play the scene in the window. director.run(main_scene)
class GameLayer(Layer): is_event_handler = True def __init__( self, director, dificuldade ): super( GameLayer, self ).__init__() self.director = director self.tabuleiro = [] self.offsetX = director.get_window_size()[0]/3 self.offsetY = director.get_window_size()[1]/8 lado = 45 self.lado = lado self.dificuldade = dificuldade self.cpu = False self.prolog = Prolog() self.prolog.consult("reversi.pl") self.tabMatriz = list(self.prolog.query("novotab(X)"))[0]['X'] self.matriz = deepcopy(self.tabMatriz) pyglet.font.add_directory('.') self.jogadorAtivo = Label("Jogador: Player1", font_name = 'Blood Of Dracula', font_size = 22, x = 20, y = 350) self.add(self.jogadorAtivo) self.dif = Label("Dificuldade: " + self.dificuldade, font_name = 'Blood Of Dracula', font_size = 16, x = 20, y = 300) self.add(self.dif) self.p = list(self.prolog.query("winner(" + str(self.tabMatriz) + ", P0, P1, P2)"))[0] self.p1 = Label("P1: " + str(self.p['P1']) + self.dificuldade, font_name = 'Bloodsuckers', font_size = 26, x = 20, y = 200) self.p2 = Label("P1: " + str(self.p['P2']) + self.dificuldade, font_name = 'Bloodsuckers', font_size = 26, x = 20, y = 150) self.add(self.p1) self.add(self.p2) #Batch que vai segurar todos os pecas self.spriteBatch = BatchNode() self.add(self.spriteBatch) size = 8*self.lado for i in range(8): l = [] for j in range(8): peca = Peca(self.tabMatriz[i][j], (j*lado + lado/2, size - (i*lado + lado/2))) l.append(peca) self.spriteBatch.add(peca) self.tabuleiro.append(l) self.spriteBatch.add(Sprite("tabuleiro.png", (self.tabuleiro[4][4].position[0] - lado/2, self.tabuleiro[4][4].position[1] + lado/2) , 0, 1, 32), 0) self.spriteBatch.position = (self.offsetX, self.offsetY) self.spriteBatch.scale = 1.0 self.hud = GameHud() self.add(self.hud) self.schedule(self.gameLoop) def criarCena(self): background = Background("caldron.jpg") background.position = (self.director.get_window_size()[0]/2, self.director.get_window_size()[1]/2) background.fundo.opacity = 100 cena = Scene(background, self ) return cena #Funcao que atualiza o tabuleiro def atualizaTabuleiro(self, newMatrix): delay = 0.0 for i in range(8): for j in range(8): if(self.tabMatriz[i][j] != newMatrix[i][j]): delay += 0.04 self.tabuleiro[i][j].mudarCor(delay, newMatrix[i][j]) def gameLoop(self, dt): #Implementar o loop do game self.atualizarJogador() retorno = list(self.prolog.query("dont_game_over(" + str(self.tabMatriz) + ")")) self.p = list(self.prolog.query("winner(" + str(self.tabMatriz) + ", P0, P1, P2)"))[0] self.p1.element.text = "P1: " + str(self.p['P1']) self.p2.element.text = "P2: " + str(self.p['P2']) if(not retorno): self.schedule_interval(self.gameOver, 3.0) pass def gameOver(self, dt): v = list(self.prolog.query("winner("+ str(self.tabMatriz) + ", V)"))[0]['V'] print(v) self.director.replace(GameOverLayer(v).criarCena()) def atualizarJogador(self): if(self.cpu): self.jogadorAtivo.element.text = "CPU" self.jogadorAtivo.element.font_size = 26 else: self.jogadorAtivo.element.font_size = 22 self.jogadorAtivo.element.text = "Jogador: Player1" def turnoCPU(self, dt): if(self.cpu): consulta = self.dificuldade +"_play("+ str(self.tabMatriz) + ", Novo)" retorno = list(self.prolog.query(consulta)) if(retorno): #se for possivel jogar self.matriz = retorno[0]['Novo'] self.atualizaTabuleiro(self.matriz) self.tabMatriz = deepcopy(self.matriz) self.cpu = False self.unschedule(self.turnoCPU) def on_mouse_press (self, x, y, buttons, modifiers): if(not self.cpu): posx, posy = self.director.get_virtual_coordinates (x, y) posx = posx - self.offsetX posy = posy - self.offsetY j = int(posx / self.lado) i = 7 - int(posy / self.lado) if((i > 7) | (j > 7) | (i < 0) | (j < 0)): return if(not list(self.prolog.query("macaco(" + str(self.tabMatriz) + ", 0, I, J, 1)"))[0]): self.cpu = True return if(buttons == LEFT): consulta = "play(" + str(self.tabMatriz) + ", " + str(i) + ", " + str(j) + ", 1, Novo)" if(buttons == RIGHT): consulta = "play(" + str(self.tabMatriz) + ", " + str(i) + ", " + str(j) + ", 2, Novo)" retorno = list(self.prolog.query(consulta)) if(retorno): # se for possivel jogar self.matriz = retorno[0]['Novo'] self.atualizaTabuleiro(self.matriz) self.tabMatriz = deepcopy(self.matriz) self.cpu = True self.schedule_interval(self.turnoCPU, 2.0)
class Game(ScrollableLayer): is_event_handler = True def __init__(self): super(Game, self).__init__() # Set map dimensions self.px_width = 7680 self.px_height = 4320 # Set player score self.score = 0 self.destroy_flag = False self.trail_list = [Sprite('ships/trail.png'), Sprite('ships/trail2.png')] self.trail_choice = random.choice (self.trail_list) # Set physics space self.space = pm.Space(iterations = 500) self.space.gravity = 0, 0 self.space.add_collision_handler(0, 1, post_solve=self.player_asteroid_collision) self.space.add_collision_handler(1, 2, post_solve=self.asteroid_planet_collision) # Set batches and add them to the layer self.star_batch = BatchNode() self.planet_batch = BatchNode() self.weapon_batch = BatchNode() self.asteroid_batch = BatchNode() self.trail_batch = BatchNode() self.add(self.star_batch) self.add(self.planet_batch) self.add(self.weapon_batch) self.add(self.asteroid_batch) self.add(self.trail_batch) # Generate star map and add stars, planets, and suns self.world = CreateWorld() self.world.make_map(self.star_batch, self.planet_batch, self, self.space) self.asteroids = Asteroids(self.asteroid_batch, self.space) # Track keys, lasers to move self.keys_being_pressed = set() self.laser_count = set() # Create a player, add to space and layer self.player = create_player() self.player.name = "player" self.space.add(self.player.body, self.player.poly) self.player2 = create_player() self.player2.name = "player2" self.space.add(self.player2.body, self.player2.poly) self.players = [self.player, self.player2] self.player.cooldown = 0 self.player2.cooldown = 0 self.add(self.player) self.add(self.player2) # Schedule update and debug self.schedule(self.update) self.schedule_interval(self.debug, 1) def on_key_press(self, key, mod): try: self.keys_being_pressed.add( key ) except KeyError: pass def on_key_release(self, key, mod): try: self.keys_being_pressed.remove(key) except KeyError: pass def remove_from_set(self, item, container): new_set = container.copy() try: new_set.remove(item) except KeyError: new_set.remove(item) finally: return new_set def player_asteroid_collision(self, space, arbiter): for asteroid in self.asteroids.asteroid_count: # This for loop checks the identity of the arbiter-asteroid with every asteroid until it finds a match # Then it calculates the damage to the player if asteroid.body is arbiter.shapes[1].body: if self.player.body is arbiter.shapes[0].body: player = self.player player.speed = sqrt(pow(player.body.velocity[0], 2) + pow(player.body.velocity[1], 2) ) elif self.player2.body is arbiter.shapes[0].body: player = self.player2 player.speed = sqrt(pow(player.body.velocity[0], 2) + pow(player.body.velocity[1], 2) ) else: print "error did not find player" # Get the speed of an asteroid from it's velocity using the pythagoras theorem asteroid.speed = sqrt(pow(asteroid.body.velocity[0], 2) + pow(asteroid.body.velocity[1], 2) ) # The damage is just the asteroid speed minus the player speed plus an arbitary number if asteroid.morph == 'large': damage = abs(5 + asteroid.speed - player.speed) player.health -= damage elif asteroid.morph == 'medium': damage = abs(10 + asteroid.speed - player.speed ) player.health -= damage elif asteroid.morph == 'small': damage = abs(15 + asteroid.speed - player.speed ) player.health -= damage def asteroid_planet_collision(self, space, arbiter): for asteroid in self.asteroids.asteroid_count: # This for loop checks the identity of the arbiter with the asteroid for every asteroid until it finds a match if asteroid.body is arbiter.shapes[0].body: self.explode(asteroid) # Remove asteroids from world self.space.remove(asteroid.body, asteroid.poly) self.asteroids.asteroid_count = self.remove_from_set(asteroid, self.asteroids.asteroid_count) self.asteroid_batch.remove(asteroid) self.destroy_flag = True # Regenerate asteroids and adjust score if asteroid.morph == 'large': self.asteroids.create_asteroid(asteroid.position, asteroid.morph) self.asteroids.create_asteroid(asteroid.position, asteroid.morph) elif asteroid.morph == 'medium': self.asteroids.create_asteroid(asteroid.position, asteroid.morph) self.asteroids.create_asteroid(asteroid.position, asteroid.morph) def update_asteroids(self,dt): for player in self.players: if player.cooldown < 20: player.cooldown += 1 # Move asteroids and collide them with lasers for asteroid in self.asteroids.asteroid_count: self.planetoid_gravity(asteroid.body, 5000000, 1.0, dt) asteroid.position = asteroid.body.position asteroid.rotation = asteroid.body.angle for laser in self.laser_count: collide = asteroid.get_rect().contains(laser.position[0], laser.position[1]) if collide: # Remove laser from world laser.do(FadeOut(0.09) + CallFunc (self.weapon_batch.remove, laser) ) self.laser_count = self.remove_from_set(laser, self.laser_count) # Create an explosion self.explode(asteroid) try: self.asteroids.asteroid_count = self.remove_from_set(asteroid, self.asteroids.asteroid_count) self.space.remove(asteroid.body, asteroid.poly) self.asteroid_batch.remove(asteroid) except: print "WARNING: could not remove asteroid" continue self.destroy_flag = True # Regenerate asteroids and adjust score if asteroid.morph == 'large': self.asteroids.create_asteroid(asteroid.position, asteroid.morph) self.asteroids.create_asteroid(asteroid.position, asteroid.morph) player = laser.owner player.score += 10 elif asteroid.morph == 'medium': self.asteroids.create_asteroid(asteroid.position, asteroid.morph) self.asteroids.create_asteroid(asteroid.position, asteroid.morph) player = laser.owner player.score += 25 elif asteroid.morph == "small": player = laser.owner player.score += 50 def planetoid_gravity(self, body, gravity, damping, dt): # for every planet created adjust a body's velocity to imitate gravity for planet in self.world.planet_count: p = pm.Vec2d(body.position) - pm.Vec2d(planet.position) sqdist = p.get_length_sqrd() g = (p * -gravity)/(sqdist * sqrt(sqdist)) pm.Body.update_velocity(body, g, damping, dt) def update_trail(self, trail_choice, player): if trail_choice == self.trail_list[0]: # Red trail trail = Sprite('ships/trail.png') elif trail_choice == self.trail_list[1]: # Blue trail trail = Sprite('ships/trail2.png') trail.position = player.position self.trail_batch.add(trail) trail.do(FadeOut(1) + CallFunc (self.trail_batch.remove, trail ) ) def explode(self, asteroid): explode = Explosion() ''' if asteroid.morph == "large": explode.size = 25 elif asteroid.morph == 'medium': explode.size = 15 elif asteroid.morph == 'small': explode.size = 5 ''' explode.size = 5 explode.start_color = Color( 255, 0, 0, 255 ) explode.end_color = Color(255,0,0,255) explode.total_particles = 10 explode.position = asteroid.position explode.auto_remove_on_finish = True self.add(explode) def debug(self, dt): ''' print "#########################" print "Asteroid count" print len(self.asteroids.asteroid_count) print "asteroid_batch children" print len(self.asteroid_batch.get_children()) print "Laser count" print len(self.laser_count) print "weapon_batch children" print len(self.weapon_batch.get_children()) print "number of bodies" print len(self.space.bodies) print "#########################" ''' pass def player_player_damage(self): for player in self.players: for laser in self.laser_count: collide = player.get_rect().contains(laser.position[0], laser.position[1]) if collide: if laser.owner is not player: player.health -= laser.damage player.score -= 50 laser.owner.score += 50 laser.do(FadeOut(0.09) + CallFunc (self.weapon_batch.remove, laser) ) self.laser_count = self.remove_from_set(laser, self.laser_count) self.explode(player) def update(self, dt): # Create a list of pressed keys key_names = [symbol_string(k) for k in self.keys_being_pressed] # Turn player angle to radians # Get the vector angle of the player player2_radians = self.player2.rotation * (pi/180) player_radians = self.player.rotation * (pi/180) self.player.vector_angle = xAngle, yAngle = sin(player_radians), cos(player_radians) self.player2.vector_angle = xAngle, yAngle = sin(player2_radians), cos(player2_radians) for key in key_names: # Handle player input if key == "LEFT": self.player2.rotation -= 1 elif key == "RIGHT": self.player2.rotation += 1 elif key == "UP": self.player2.body.apply_impulse ( (self.player2.vector_angle[0] * 20, self.player2.vector_angle[1] * 20) ) elif key == "DOWN": self.player2.body.apply_impulse( (-self.player2.vector_angle[0] * 20, -self.player2.vector_angle[1] * 20) ) if key == "BACKSPACE": if self.player2.cooldown >= 20: laser = Sprite('weapons/LaserMKI.png') laser.rotation = self.player2.rotation laser.position = self.player2.get_rect().center laser.vector = self.player2.vector_angle laser.owner = self.player2 laser.damage = 100 self.weapon_batch.add(laser) self.laser_count.add(laser) self.player2.cooldown = 0 if key == "A": self.player.rotation -= 1 elif key == "D": self.player.rotation += 1 elif key == "W": self.player.body.apply_impulse ( (self.player.vector_angle[0] * 20, self.player.vector_angle[1] * 20) ) elif key == "S": self.player.body.apply_impulse( (-self.player.vector_angle[0] * 20, -self.player.vector_angle[1] * 20) ) if key == "SPACE": if self.player.cooldown >= 20: laser = Sprite('weapons/LaserMKI.png') laser.rotation = self.player.rotation laser.position = self.player.get_rect().center laser.vector = self.player.vector_angle laser.owner = self.player laser.damage = 100 self.weapon_batch.add(laser) self.laser_count.add(laser) self.player.cooldown = 0 for laser in self.laser_count: laser.position = laser.position[0] + laser.vector[0] * dt * 2000, laser.position[1] + laser.vector[1] * dt * 2000 # Update asteroids and planetary gravity self.planetoid_gravity(self.player.body, 5000000, 1.0, dt) self.planetoid_gravity(self.player2.body, 5000000, 1.0, dt) self.update_asteroids(dt) if self.destroy_flag == True: if len(self.asteroids.asteroid_count) <= 5: #print "There are %s asteroids in the scene" % (str(len(self.asteroids.asteroid_count))) self.asteroids.create_asteroid("garbage input", 'new') self.destroy_flag = False # Step the simulation self.space.step(0.05) self.player_player_damage() # Update player position self.player.position = self.player.body.position self.player2.position = self.player2.body.position # Update player tails self.update_trail(self.trail_list[0], self.player) self.update_trail(self.trail_list[1], self.player2) if self.player.health <= 0 or self.player2.health <= 0: director.replace(SplitColsTransition(GameOver(self.player.score, self.player2.score)))
def __init__(self): super(Game, self).__init__() # Set map dimensions self.px_width = 7680 self.px_height = 4320 # Set player score self.score = 0 self.destroy_flag = False self.trail_list = [Sprite('ships/trail.png'), Sprite('ships/trail2.png')] self.trail_choice = random.choice (self.trail_list) # Set physics space self.space = pm.Space(iterations = 500) self.space.gravity = 0, 0 self.space.add_collision_handler(0, 1, post_solve=self.player_asteroid_collision) self.space.add_collision_handler(1, 2, post_solve=self.asteroid_planet_collision) # Set batches and add them to the layer self.star_batch = BatchNode() self.planet_batch = BatchNode() self.weapon_batch = BatchNode() self.asteroid_batch = BatchNode() self.trail_batch = BatchNode() self.add(self.star_batch) self.add(self.planet_batch) self.add(self.weapon_batch) self.add(self.asteroid_batch) self.add(self.trail_batch) # Generate star map and add stars, planets, and suns self.world = CreateWorld() self.world.make_map(self.star_batch, self.planet_batch, self, self.space) self.asteroids = Asteroids(self.asteroid_batch, self.space) # Track keys, lasers to move self.keys_being_pressed = set() self.laser_count = set() # Create a player, add to space and layer self.player = create_player() self.player.name = "player" self.space.add(self.player.body, self.player.poly) self.player2 = create_player() self.player2.name = "player2" self.space.add(self.player2.body, self.player2.poly) self.players = [self.player, self.player2] self.player.cooldown = 0 self.player2.cooldown = 0 self.add(self.player) self.add(self.player2) # Schedule update and debug self.schedule(self.update) self.schedule_interval(self.debug, 1)
# pr.print_stats() benchmark(1) import sys sys.path.extend(['/home/andrei/Python/tanks']) sys.path.extend(['/home/andrei/Python/tanks/assets']) import numpy as np from cocos import director from cocos import scene from cocos.batch import BatchNode from cocos import sprite from objects.Tank import Tank director.director.init(width=2048, height=960, resizable=True, autoscale=False) layer = BatchNode() c = sprite.Sprite('gil-brazo2.png') c.position = (12, 11) layer.add(c) layer.add(c) layer.get_children() t = tanks_list[3] tanks_list.index(t) tanks_list = layer.get_children() tanks = np.array(list(map(lambda obj: obj.position, tanks_list))) dist_sq = np.sum((tanks[:, np.newaxis] - tanks[np.newaxis, :])**2, axis=-1) K = 3 nearest_sorted = np.argsort(dist_sq, axis=1)[:, :K + 1]
def __init__(self): super(Board, self).__init__() Board.BOARD = self self.boardMap = {} self.cellMap = {} # add basic ground ground_img = Resources.ground_img node = BatchNode() self.add(node, z=0) for row in range(self.numRows): for col in range(self.numCols): cell = Cell(ground_img) rect = cell.get_rect() rect.bottomleft = col * 32, row * 32 cell.position = rect.center node.add(cell, z=0) self.cellMap[(col, row)] = cell # add buildings buildings_tex = Resources.buildings_tex # test 3x2 Building at 1,4 self.boardMap[(1, 4)] = {self.KEY_TYPE: self.TYPE_BUILDING, self.KEY_COLUMNS: 3, self.KEY_ROWS: 2, self.KEY_LEVEL: 1, self.KEY_ELEVATION: 0, self.KEY_IMAGES: buildings_tex[(0, 0):(3, 3)]} self.boardMap[(2, 4)] = {self.KEY_REF: (1, 4)} self.boardMap[(3, 4)] = {self.KEY_REF: (1, 4)} self.boardMap[(1, 5)] = {self.KEY_REF: (1, 4)} self.boardMap[(2, 5)] = {self.KEY_REF: (1, 4)} self.boardMap[(3, 5)] = {self.KEY_REF: (1, 4)} # test 2x2 Building at 5,4 self.boardMap[(5, 4)] = {self.KEY_TYPE: self.TYPE_BUILDING, self.KEY_COLUMNS: 2, self.KEY_ROWS: 2, self.KEY_LEVEL: 1, self.KEY_ELEVATION: 0, self.KEY_IMAGES: buildings_tex[(3, 0):(7, 2)]} self.boardMap[(6, 4)] = {self.KEY_REF: (5, 4)} self.boardMap[(5, 5)] = {self.KEY_REF: (5, 4)} self.boardMap[(6, 5)] = {self.KEY_REF: (5, 4)} # test 2x2 Building at 10,6 self.boardMap[(10, 6)] = {self.KEY_TYPE: self.TYPE_BUILDING, self.KEY_COLUMNS: 2, self.KEY_ROWS: 2, self.KEY_LEVEL: 1, self.KEY_ELEVATION: 0, self.KEY_IMAGES: buildings_tex[(3, 2):(7, 4)]} self.boardMap[(11, 6)] = {self.KEY_REF: (10, 6)} self.boardMap[(10, 7)] = {self.KEY_REF: (10, 6)} self.boardMap[(11, 7)] = {self.KEY_REF: (10, 6)} # test 3x2 Building at 10,2 self.boardMap[(10, 2)] = {self.KEY_TYPE: self.TYPE_BUILDING, self.KEY_COLUMNS: 3, self.KEY_ROWS: 2, self.KEY_LEVEL: 1, self.KEY_ELEVATION: 0, self.KEY_IMAGES: buildings_tex[(3, 5):(7, 8)]} self.boardMap[(11, 2)] = {self.KEY_REF: (10, 2)} self.boardMap[(12, 2)] = {self.KEY_REF: (10, 2)} self.boardMap[(10, 3)] = {self.KEY_REF: (10, 2)} self.boardMap[(11, 3)] = {self.KEY_REF: (10, 2)} self.boardMap[(12, 3)] = {self.KEY_REF: (10, 2)} # test 2x2x2 Building at 12,12 self.boardMap[(12, 12)] = {self.KEY_TYPE: self.TYPE_BUILDING, self.KEY_COLUMNS: 2, self.KEY_ROWS: 2, self.KEY_LEVEL: 2, self.KEY_ELEVATION: 0, self.KEY_IMAGES: buildings_tex[(3, 10):(8, 12)]} self.boardMap[(13, 12)] = {self.KEY_REF: (12, 12)} self.boardMap[(12, 13)] = {self.KEY_REF: (12, 12)} self.boardMap[(13, 13)] = {self.KEY_REF: (12, 12)} # test 3x3 Building at 15,10 self.boardMap[(15, 10)] = {self.KEY_TYPE: self.TYPE_BUILDING, self.KEY_COLUMNS: 3, self.KEY_ROWS: 3, self.KEY_LEVEL: 1, self.KEY_ELEVATION: 0, self.KEY_IMAGES: buildings_tex[(7, 10):(13, 13)]} self.boardMap[(16, 10)] = {self.KEY_REF: (15, 10)} self.boardMap[(17, 10)] = {self.KEY_REF: (15, 10)} self.boardMap[(15, 11)] = {self.KEY_REF: (15, 10)} self.boardMap[(16, 11)] = {self.KEY_REF: (15, 10)} self.boardMap[(17, 11)] = {self.KEY_REF: (15, 10)} self.boardMap[(15, 12)] = {self.KEY_REF: (15, 10)} self.boardMap[(16, 12)] = {self.KEY_REF: (15, 10)} self.boardMap[(17, 12)] = {self.KEY_REF: (15, 10)} # test 5x2 Building at 3,14 self.boardMap[(3, 14)] = {self.KEY_TYPE: self.TYPE_BUILDING, self.KEY_COLUMNS: 5, self.KEY_ROWS: 2, self.KEY_LEVEL: 0, self.KEY_ELEVATION: 0, self.KEY_IMAGES: buildings_tex[(9, 0):(11, 5)]} self.boardMap[(4, 14)] = {self.KEY_REF: (3, 14)} self.boardMap[(5, 14)] = {self.KEY_REF: (3, 14)} self.boardMap[(6, 14)] = {self.KEY_REF: (3, 14)} self.boardMap[(7, 14)] = {self.KEY_REF: (3, 14)} self.boardMap[(3, 15)] = {self.KEY_REF: (3, 14)} self.boardMap[(4, 15)] = {self.KEY_REF: (3, 14)} self.boardMap[(5, 15)] = {self.KEY_REF: (3, 14)} self.boardMap[(6, 15)] = {self.KEY_REF: (3, 14)} self.boardMap[(7, 15)] = {self.KEY_REF: (3, 14)} for col, row in self.boardMap: loc = (col, row) cell_data = self.boardMap[loc] cell_images = cell_data.get(self.KEY_IMAGES) if cell_images is not None: cell_level = cell_data[self.KEY_LEVEL] cell_z = (self.numCols - row - cell_level) * 10 cell_batch = BatchNode() cell_batch.position = col * self.TILE_SIZE, row * self.TILE_SIZE self.add(cell_batch, z=cell_z) cell_cols = cell_data[self.KEY_COLUMNS] cell_rows = cell_data[self.KEY_ROWS] for this_row in range(cell_rows + cell_level): for this_col in range(cell_cols): cell_index = this_col + (this_row * cell_cols) cell_sprite = Sprite(cell_images[cell_index]) cell_rect = cell_sprite.get_rect() cell_rect.bottomleft = this_col * self.TILE_SIZE, this_row * self.TILE_SIZE cell_sprite.position = cell_rect.center cell_batch.add(cell_sprite)
def __init__(self): super(Interface, self).__init__() from board import Board Interface.UI = self self.action_btn = None self.action_btn_bg = BatchNode() action_bg = Sprite(Resources.action_buttons_bg_img) self.action_btn_bg.add(action_bg) self.action_btn_bg.width = action_bg.width self.action_btn_bg.height = action_bg.height self.action_btn_bg.visible = False self.add(self.action_btn_bg, z=-1) self.action_super_label = TextFloater("<super>", font_name='TranscendsGames', font_size=16, anchor_x='center', anchor_y='bottom') self.action_super_icon = Sprite(Resources.enemy_indicator_img) self.action_super_icon.scale = 0.75 self.action_sub_label = TextFloater("<sub>", font_name='TranscendsGames', font_size=14, anchor_x='center', anchor_y='top') self.action_super_label.visible = False self.action_super_icon.visible = False self.action_sub_label.visible = False self.add(self.action_super_label) self.add(self.action_super_icon) self.add(self.action_sub_label) self.buttons = [] self.button_action_labels = {} self.button_action = {} self.unit_display = None self.unit_display_bg = None self.target_display = None self.target_display_bg = None # used to retain the labels that show the to hit % over each enemy self.to_hit_labels = {} # used to retain the lines that show LOS to each enemy self.los_lines = [] # add clickable UI button bar self.move_btn = Button(action_label=Interface.ACTION_MOVE, icon=Resources.move_button_img, action=actions.selectMoveAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.evade_btn = Button(action_label=Interface.ACTION_EVADE, icon=Resources.evade_button_img, action=actions.selectEvadeAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.sprint_btn = Button(action_label=Interface.ACTION_SPRINT, icon=Resources.sprint_button_img, action=actions.selectSprintAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.weapon_btn = Button(action_label=Interface.ACTION_FIRE, icon=Resources.weapon_button_img, action=actions.selectWeaponAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.overheat_btn = Button(action_label=Interface.ACTION_OVR, icon=Resources.overheat_button_img, action=actions.selectOverheatAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.end_btn = Button(action_label=Interface.ACTION_END, icon=Resources.end_button_img, action=actions.selectEndAction, width=4 + Board.TILE_SIZE, height=4 + Board.TILE_SIZE) self.addButton(self.move_btn, actions.doMoveAction) # self.addButton(self.evade_btn, actions.doEvadeAction) # self.addButton(self.sprint_btn, actions.doSprintAction) self.addButton(self.weapon_btn, actions.doWeaponAction) self.addButton(self.overheat_btn, actions.doOverheatAction) self.addButton(self.end_btn, actions.doEndAction) self.arrangeButtons()
def updatePlayerUnitStats(self, battle_unit): if self.unit_display is not None: self.unit_display.kill() self.unit_name.kill() self.unit_variant.kill() self.unit_stats.kill() self.unit_values.kill() if battle_unit is None: # Hide player unit stats at bottom left self.unit_display = None self.unit_name = None self.unit_variant = None self.unit_stats = None self.unit_values = None return size = director.get_window_size() width = size[0] height = size[1] self.unit_display = BatchNode() self.unit_display.position = 0, 0 mech_img_grid = pyglet.image.ImageGrid( pyglet.resource.image(battle_unit.getImagePath()), 1, 6) mech_img_static = mech_img_grid[0] pitch = -(mech_img_static.width * len('RGBA')) img_data = mech_img_static.get_image_data() # testing with masking only a portion of the image damage_height = int( mech_img_static.height) # int(mech_img_static.height * 0.67) data = img_data.get_region(0, 0, mech_img_static.width, damage_height).get_data('RGBA', pitch) mask = Image.frombytes('RGBA', (mech_img_static.width, damage_height), data) # the first image is the color that the stamp will be img1 = Image.new('RGBA', mask.size, color=(0, 0, 0, 255)) # second image is the background img2 = Image.new('RGBA', mask.size, color=(225, 225, 225, 200)) img1 = img1.convert('RGBA') # apply mask to background image img = Image.composite(img1, img2, mask) raw_image = img.tobytes() img_x = mask.size[0] img_y = mask.size[1] pyg_img = pyglet.image.ImageData(img_x, img_y, 'RGBA', raw_image, pitch=-img_x * len('RGBA')) mech_sprite = Sprite(pyg_img) mech_sprite.position = Board.TILE_SIZE // 2 + mech_sprite.width // 2, \ Board.TILE_SIZE + mech_sprite.height // 2 self.unit_display.add(mech_sprite) self.add(self.unit_display) # Show unit name above the image self.unit_name = floaters.TextFloater(battle_unit.getName(), font_name='TranscendsGames', font_size=Board.TILE_SIZE // 2, anchor_x='left', anchor_y='bottom') self.unit_name.position = Board.TILE_SIZE // 2, mech_sprite.get_rect( ).topleft[1] self.add(self.unit_name) # Show unit variant below the image self.unit_variant = floaters.TextFloater( battle_unit.getVariant().upper(), font_name='TranscendsGames', font_size=Board.TILE_SIZE // 3, anchor_x='left', anchor_y='top') self.unit_variant.position = Board.TILE_SIZE // 2, Board.TILE_SIZE - 4 self.add(self.unit_variant) # Show armor, structure, heat stats next to the image (top) self.unit_stats = UnitStats(battle_unit) stats_pos = mech_sprite.get_rect().topright self.unit_stats.position = 4 + stats_pos[0], stats_pos[ 1] - self.unit_stats.height self.add(self.unit_stats) # Show move and attack numbers next to the image (bottom) values = "MV %i ATK %i/%i/%i" % (battle_unit.getTurnMove(), battle_unit.short, battle_unit.medium, battle_unit.long) self.unit_values = floaters.TextFloater(values, font_name='TranscendsGames', font_size=Board.TILE_SIZE // 4, anchor_x='left', anchor_y='bottom') values_pos = mech_sprite.get_rect().bottomright self.unit_values.position = 4 + values_pos[0], values_pos[1] - 2 self.add(self.unit_values)
def __init__(self): """ label: players: grass: projectiles: controllers: robots: castle: """ super().__init__() width, height = game_board["size"] self.label = Label("debug") self.label.position = 100, 100 # players... self.players = [ #Actor(item_types["player1"], (500, 100), self.label), Actor(item_types["player2"], (100, 600)), #Actor(item_types["player3"], (250, 600)), #Actor(item_types["player4"], (900, 600)), ] last_player_id = 0 # controllers... self.controllers = [Player(p) for p in self.players] for controller in self.controllers: controller.id = last_player_id last_player_id += 1 # grass... grass_distance = 50 x_margin, y_margin, width, height = (width // 2, grass_distance, width, height - game_board["castle_depth"]) self.grass = [[ Actor(item_types["grass" + str(randint(1, 3))], (x, y)) for x in range(-x_margin, width + x_margin, grass_distance) ] for y in range(-y_margin, height, grass_distance)] # projectiles... self.projectiles = [] # robots... self.robots = [ Actor(item_types["robot1"], (200, 700)), Actor(item_types["robot1"], (800, 400)), Actor(item_types["robot1"], (300, 500)), Actor(item_types["robot1"], (600, 600)), Actor(item_types["robot2"], (500, 800)), Actor(item_types["robot3"], (800, 900)), ] # castle... self.castle = Actor(item_types["castle1"], (500, 1000)) # add to game layer... # create grass in batches to speed up game from cocos.batch import BatchNode for grass_batch in self.grass: batch = BatchNode() for grass in grass_batch: grass.alpha = 0.8 batch.add(grass) self.add(batch, -grass_batch[0].coord.y) self.add(self.label) for robot in self.robots: self.add(robot, -robot.coord.y) for player in self.players: self.add(player, -player.coord.y) for controller in self.controllers: self.add(controller) self.add(self.castle, -self.castle.coord.y) print("Game Layer Children" + str(len(self.children))) self.do(CollisionAction())
class Tabuleiro(Layer): is_event_handler = True def __init__(self, director): super(Tabuleiro, self).__init__() self.director = director self.tabuleiro = [] self.offsetX = 100 self.offsetY = 100 lado = 32 #montagem da matriz inicial self.tabMatriz = [] for i in range(8): linha = [] for j in range(8): linha.append(0) self.tabMatriz.append(linha) self.tabMatriz[3][3] = 1 self.tabMatriz[3][4] = 2 self.tabMatriz[4][3] = 2 self.tabMatriz[4][4] = 1 ################################### #Batch que vai segurar todos os pecas self.spriteBatch = BatchNode() self.add(self.spriteBatch) for i in range(8): l = [] for j in range(8): if (self.tabMatriz[i][j] == 0): peca = Peca("vazio.png", (i * lado + lado / 2, j * lado + lado / 2)) elif (self.tabMatriz[i][j] == 1): peca = Peca("preto.png", (i * lado + lado / 2, j * lado + lado / 2)) elif (self.tabMatriz[i][j] == 2): peca = Peca("branco.png", (i * lado + lado / 2, j * lado + lado / 2)) l.append(peca) self.spriteBatch.add(peca) self.tabuleiro.append(l) self.spriteBatch.position = (self.offsetX, self.offsetY) self.teste = Sprite("grossini.png", (300, 200)) self.spriteBatch.add(self.teste) self.hud = GameHud() self.add(self.hud) for i in self.tabMatriz: print(i) #Funcao que atualiza o tabuleiro def atualizaTabuleiro(self, newMatrix): delay = 0.0 for i in range(8): for j in range(8): if (self.tabMatriz[i][j] != newMatrix[i][j]): delay += 0.02 self.tabuleiro[i][j].mudarCor(delay, newMatrix[i][j]) def on_mouse_press(self, x, y, buttons, modifiers): """This function is called when any mouse button is pressed (x, y) are the physical coordinates of the mouse 'buttons' is a bitwise or of pyglet.window.mouse constants LEFT, MIDDLE, RIGHT 'modifiers' is a bitwise or of pyglet.window.key modifier constants (values like 'SHIFT', 'OPTION', 'ALT') """ #self.tabuleiro.mudarCor(1.0) print(self.director.get_virtual_coordinates(x, y))
class DudeDamageLayer(ResizableLayer): is_event_handler = True def __init__(self, game_layer): super(DudeDamageLayer, self).__init__() self.game_layer = game_layer self.red_bp = BatchNode() self.normal_bp = BatchNode() self.armored_bp = BatchNode() self.ui_body = {'back': {}, 'front': {}, 'armored': {}} self._init_body_parts('back') self._init_body_parts('front') self._init_body_parts('armored') # the layer now listens to on_take_damage event from hero self.game_layer.hero.push_handlers(self.on_take_damage) armored_bp = self._get_armored_body_parts() for body_part in self.ui_body['back']: self.red_bp.add(self.ui_body['back'][body_part]) for body_part in self.ui_body['front']: self.normal_bp.add(self.ui_body['front'][body_part]) for body_part in self.ui_body['armored']: if body_part in armored_bp: self.armored_bp.add(self.ui_body['armored'][body_part]) self.add(self.red_bp, z=-1) self.add(self.normal_bp, z=0) self.add(self.armored_bp, z=1) def _get_armored_body_parts(self): armored = set() for bp in self.game_layer.hero.body.body_parts: if bp.attached is not None: if bp.slot == con.HEAD: armored.add('head') elif bp.slot == con.CHEST: armored.add('chest') elif bp.slot == con.LEGS: armored.add('legs') return armored def _init_body_parts(self, layer_type='front'): self.ui_body[layer_type]['head'] = Sprite(con.body[layer_type]['head'], position=(50, self.cur_y-50)) self.ui_body[layer_type]['chest'] = Sprite(con.body[layer_type]['chest'], position=(50, self.cur_y-85)) self.ui_body[layer_type]['left_arm'] = Sprite(con.body[layer_type]['left_arm'], position=(34, self.cur_y-90)) self.ui_body[layer_type]['right_arm'] = Sprite(con.body[layer_type]['right_arm'], position=(66, self.cur_y-91)) self.ui_body[layer_type]['legs'] = Sprite(con.body[layer_type]['legs'], position=(50, self.cur_y-119)) def on_hud_shift_needed(self): for layer_type in ('back', 'front', 'armored'): for body_part in self.ui_body[layer_type]: self.ui_body[layer_type][body_part].y += self.dy def on_take_damage(self, body_part): armor_damage = False if body_part.slot >= con.ARMOR: slot = body_part.slot - con.ARMOR armor_damage = True else: slot = body_part.slot body_parts = {con.HEAD: 'head', con.CHEST: 'chest', con.LEGS: 'legs'} if slot in body_parts: bp_name = body_parts[slot] else: bp_name = 'right_arm' # why not? if armor_damage: self.ui_body['armored'][bp_name].opacity = 255.0 * body_part.armor / body_part.max_armor else: self.ui_body['front'][bp_name].opacity = 255.0 * body_part.health / body_part.max_health
def __init__(self, battle_unit, is_friendly=True, reverse=False, mask_image=True, menu_selected=False): super(UnitCard, self).__init__() from board import Board self.battle_unit = battle_unit self.reverse = reverse self.width = 0 self.height = 0 self.unit_display = BatchNode() self.unit_display.position = 0, 0 mech_img_grid = pyglet.image.ImageGrid(pyglet.resource.image(battle_unit.getImagePath()), 1, 6) mech_img_static = mech_img_grid[0] pitch = -(mech_img_static.width * len('RGBA')) img_data = mech_img_static.get_image_data() pyg_img = mech_img_static if mask_image: # masking only a portion of the image based on damage damage_height = int(mech_img_static.height) data = img_data.get_region(0, 0, mech_img_static.width, damage_height).get_data('RGBA', pitch) mask = Image.frombytes('RGBA', (mech_img_static.width, damage_height), data) # the first image is the color that the stamp will be img1 = Image.new('RGBA', mask.size, color=(0, 0, 0, 255)) # second image is the background bg_color = (200, 75, 75, 200) if is_friendly: bg_color = (225, 225, 225, 200) img2 = Image.new('RGBA', mask.size, color=bg_color) img1 = img1.convert('RGBA') # apply mask to background image img = Image.composite(img1, img2, mask) raw_image = img.tobytes() img_x = mask.size[0] img_y = mask.size[1] pyg_img = pyglet.image.ImageData(img_x, img_y, 'RGBA', raw_image, pitch=-img_x * len('RGBA')) mech_sprite = Sprite(pyg_img) mech_sprite.position = mech_sprite.width // 2, Board.TILE_SIZE // 2 + mech_sprite.height // 2 self.sprite = mech_sprite self.unit_display.add(mech_sprite) self.add(self.unit_display) # Show unit name above the image unit_name_str = "%it %s [%ipv]" % (battle_unit.getTonnage(), battle_unit.getName(), battle_unit.getPointValue()) unit_name_font_size = Board.TILE_SIZE // 2 if menu_selected: unit_name_font_size = int(unit_name_font_size * 1.5) if reverse: self.unit_name = floaters.TextFloater(unit_name_str, font_name='TranscendsGames', font_size=unit_name_font_size, anchor_x='right', anchor_y='bottom') name_rect = mech_sprite.get_rect().topright self.unit_name.position = name_rect[0], name_rect[1] else: self.unit_name = floaters.TextFloater(unit_name_str, font_name='TranscendsGames', font_size=unit_name_font_size, anchor_x='left', anchor_y='bottom') name_rect = mech_sprite.get_rect().topleft self.unit_name.position = name_rect[0], name_rect[1] self.add(self.unit_name) # Show unit variant below the image unit_variant_str = battle_unit.getVariant().upper() unit_variant_font_size = Board.TILE_SIZE // 3 if menu_selected: unit_variant_font_size = int(unit_variant_font_size * 1.5) if reverse: self.unit_variant = floaters.TextFloater(unit_variant_str, font_name='TranscendsGames', font_size=unit_variant_font_size, anchor_x='right', anchor_y='top') variant_rect = mech_sprite.get_rect().bottomright self.unit_variant.position = variant_rect[0], variant_rect[1] - 4 else: self.unit_variant = floaters.TextFloater(unit_variant_str, font_name='TranscendsGames', font_size=unit_variant_font_size, anchor_x='left', anchor_y='top') variant_rect = mech_sprite.get_rect().bottomleft self.unit_variant.position = variant_rect[0], variant_rect[1] - 4 if menu_selected: # when selected in a menu the fonts are larger and needs more space away from the image stamp self.unit_variant.y -= unit_variant_font_size self.add(self.unit_variant) # Show armor, structure, heat stats next to the image (top) unit_stats = cocos.layer.Layer() stats_width = 0 stats_height = 0 # Show move and attack numbers next to the image (bottom) # values = "MV %i ATK %i/%i/%i" % (battle_unit.getTurnMove(), # battle_unit.short, battle_unit.medium, battle_unit.long) # self.unit_values = floaters.TextFloater(values, font_name='TranscendsGames', # font_size=Board.TILE_SIZE // 4, anchor_x='left', anchor_y='bottom') # values_pos = mech_sprite.get_rect().bottomright # self.unit_values.position = 4 + values_pos[0], values_pos[1] - 2 # self.add(self.unit_values) # create move icon and label of values move_icon = Sprite(Resources.move_icon_img) move_str = str(battle_unit.getTurnMove()) unit_values_font_size = Board.TILE_SIZE // 3 if menu_selected: unit_values_font_size = int(unit_values_font_size * 1.25) if reverse: move_icon.position = -move_icon.width // 2, stats_height + move_icon.height // 2 move_label = floaters.TextFloater(move_str, font_name='TranscendsGames', font_size=unit_values_font_size, anchor_x='right', anchor_y='bottom') move_label.position = move_icon.get_rect().bottomleft unit_stats.add(move_label, z=2) else: move_icon.position = move_icon.width // 2, stats_height + move_icon.height // 2 move_label = floaters.TextFloater(move_str, font_name='TranscendsGames', font_size=unit_values_font_size, anchor_x='left', anchor_y='bottom') move_label.position = move_icon.get_rect().bottomright unit_stats.add(move_label, z=2) unit_stats.add(move_icon, z=2) stats_height += move_icon.height # create attack icon and label of values attack_icon = Sprite(Resources.weapon_icon_img) attack_short = battle_unit.getDamageForRange('short') attack_medium = battle_unit.getDamageForRange('medium') attack_long = battle_unit.getDamageForRange('long') attack_str = "%i/%i/%i" % (attack_short, attack_medium, attack_long) if reverse: attack_icon.position = -attack_icon.width // 2, stats_height + attack_icon.height // 2 attack_label = floaters.TextFloater(attack_str, font_name='TranscendsGames', font_size=unit_values_font_size, anchor_x='right', anchor_y='bottom') attack_label.position = attack_icon.get_rect().bottomleft unit_stats.add(attack_label, z=2) else: attack_icon.position = attack_icon.width // 2, stats_height + attack_icon.height // 2 attack_label = floaters.TextFloater(attack_str, font_name='TranscendsGames', font_size=unit_values_font_size, anchor_x='left', anchor_y='bottom') attack_label.position = attack_icon.get_rect().bottomright unit_stats.add(attack_label, z=2) unit_stats.add(attack_icon, z=2) stats_height += attack_icon.height # create heat icon and bars heat_icon = Sprite(Resources.heat_icon_img) if reverse: heat_icon.position = -heat_icon.width // 2, stats_height + heat_icon.height // 2 else: heat_icon.position = heat_icon.width // 2, stats_height + heat_icon.height // 2 unit_stats.add(heat_icon, z=2) for i in range(battle_unit.heat): pip = Sprite(Resources.heat_pip_img) pip.scale = 2.0 if reverse: pip.position = -heat_icon.width - (i * pip.width) - pip.width, stats_height + pip.height // 2 else: pip.position = heat_icon.width + (i * pip.width) + pip.width // 2, stats_height + pip.height // 2 unit_stats.add(pip, z=1) if pip.x + pip.width > stats_width: stats_width = pip.x + pip.width stats_height += heat_icon.height # create structure icon and bars structure_icon = Sprite(Resources.structure_icon_img) if reverse: structure_icon.position = -structure_icon.width // 2, stats_height + structure_icon.height // 2 else: structure_icon.position = structure_icon.width // 2, stats_height + structure_icon.height // 2 unit_stats.add(structure_icon, z=2) orig_structure = battle_unit.mech.structure for i in range(orig_structure): pip_img = Resources.structure_pip_img if i >= battle_unit.structure: pip_img = Resources.empty_pip_img pip = Sprite(pip_img) pip.scale = 2.0 if reverse: pip.position = -structure_icon.width - (i * pip.width) - pip.width, stats_height + pip.height // 2 else: pip.position = structure_icon.width + (i * pip.width) + pip.width // 2, stats_height + pip.height // 2 unit_stats.add(pip, z=1) if pip.x + pip.width > stats_width: stats_width = pip.x + pip.width stats_height += structure_icon.height # create armor icon and bars armor_icon = Sprite(Resources.armor_icon_img) if reverse: armor_icon.position = -armor_icon.width // 2, stats_height + armor_icon.height // 2 else: armor_icon.position = armor_icon.width // 2, stats_height + armor_icon.height // 2 unit_stats.add(armor_icon, z=2) orig_armor = battle_unit.mech.armor for i in range(orig_armor): pip_img = Resources.armor_pip_img if i >= battle_unit.armor: pip_img = Resources.empty_pip_img pip = Sprite(pip_img) pip.scale = 2.0 if reverse: pip.position = -armor_icon.width - (i * pip.width) - pip.width, stats_height + pip.height // 2 else: pip.position = armor_icon.width + (i * pip.width) + pip.width // 2, stats_height + pip.height // 2 unit_stats.add(pip, z=1) if pip.x + pip.width > stats_width: stats_width = pip.x + pip.width stats_height += armor_icon.height if reverse: stats_pos = mech_sprite.get_rect().topleft unit_stats.position = stats_pos[0] - 4, stats_pos[1] - stats_height else: stats_pos = mech_sprite.get_rect().topright unit_stats.position = 4 + stats_pos[0], stats_pos[1] - stats_height self.add(unit_stats) # calculate actual width and height of this element self.width = mech_sprite.width + stats_width self.height = mech_sprite.height + (3 * Board.TILE_SIZE // 2)