Example #1
0
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
Example #2
0
    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)
Example #3
0
    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()
Example #4
0
 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()
Example #5
0
 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)
Example #6
0
    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))
Example #7
0
    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)
Example #8
0
 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()
Example #9
0
 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)
Example #10
0
    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)
Example #11
0
    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)
Example #12
0
    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)
Example #13
0
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
Example #14
0
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
Example #15
0
    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()
Example #16
0
    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)
Example #17
0
    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)
Example #18
0
    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")
Example #19
0
    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)
Example #20
0
    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)
Example #21
0
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)
Example #22
0
    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()
Example #23
0
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)
Example #24
0
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)
Example #25
0
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)
Example #26
0
 def __init__(self, image):
     self.image = image
     self.batch = BatchNode()
     self.create_background()
Example #27
0
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)
Example #28
0
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
Example #29
0
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")
Example #30
0
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)
Example #32
0
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)
Example #33
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)))	
Example #34
0
	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)
Example #35
0
# 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]
Example #36
0
    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)
Example #37
0
    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()
Example #38
0
    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)
Example #39
0
 def __init__(self, image):
     self.image = image
     self.batch = BatchNode()
     self.create_background()
Example #40
0
    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())
Example #41
0
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))
Example #42
0
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
Example #43
0
    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()
Example #44
0
    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)