예제 #1
0
 def __init__(self, text, color, x, y, width):
     win_width, win_height = get_size()
     self.batch = Batch()
     self._doc = pyglet.text.document.UnformattedDocument(text)
     self._doc.set_style(
         0, len(self._doc.text),
         dict(color=(255, 255, 255, 255), font_name='minecraftia'))
     font = self._doc.get_font()
     height = font.ascent - font.descent
     pad = 2
     self._outline = Rectangle(x - pad,
                               y - pad,
                               width + pad,
                               height + pad,
                               color=color[:3])
     self._outline.opacity = color[-1]
     self._layout = IncrementalTextLayout(self._doc,
                                          width,
                                          height,
                                          multiline=False,
                                          batch=self.batch)
     self._caret = Caret(self._layout, color=(255, 255, 255))
     self._caret.visible = False
     self._layout.x = x
     self._layout.y = y
     self._focus = False
     self._press = False
     super().__init__(x, y, width, height)
     self.last_char = ''
예제 #2
0
 def __init__(self, x=0, y=None, batch=None):
     self.cleared = False
     y = y or random.choice(
         range(self.GAP_HEIGHT, Grid.rows - self.GAP_HEIGHT))
     pos_x = Grid.width + Grid.x(x)
     gap_y = Grid.y(y)
     gap_h = Grid.x(self.GAP_HEIGHT)
     width = Grid.y(self.WIDTH)
     self.lower = Rectangle(
         pos_x,
         0,
         width,
         gap_y,
         color=self.COLOR,
         batch=batch,
     )
     self.upper = Rectangle(
         pos_x,
         gap_y + gap_h,
         width,
         Grid.height - gap_y - gap_h,
         color=self.COLOR,
         batch=batch,
     )
     self.rects = [self.lower, self.upper]
예제 #3
0
def aabb_with_result(a: Rectangle, b: Rectangle, result: Rectangle) -> bool:
    """
    Does Axis Aligned Bounding Box collision detection between two rectangles a and b.
    Also calculates the intersection rectangle.
    :param a:
    :param b:
    :param result:
    :return:
    """
    # Horizontal
    amin = a.x
    amax = a.x + a.width
    bmin = b.x
    bmax = b.x + b.width
    if bmin > amin:
        amin = bmin
    result.x = amin
    if bmax < amax:
        amax = bmax
    result.width = amax - amin

    # Vertical
    amin = a.y
    amax = a.y + a.height
    bmin = b.y
    bmax = b.y + b.height
    if bmin > amin:
        amin = bmin
    result.y = amin
    if bmax < amax:
        amax = bmax
    result.height = amax - amin

    return not utils.rect_empty(result)
예제 #4
0
class Button:
    def __init__(self, width, height, x, y, x_shift, y_shift, text, color, font_color):
        self.width = width
        self.height = height
        self.x = x
        self.y = y
        self.text = text
        self.org_color = color
        self.org_font_color = font_color
        self.color = color
        self.font_color = font_color
        self.x_shift = width / x_shift
        self.y_shift = height / y_shift

    def draw(self):
        self.rect = Rectangle(self.x, self.y, self.width, self.height, self.color)
        self.rect.draw()
        self.description = Label(self.text, self.x + self.x_shift, self.y + self.y_shift, self.font_color)
        self.description.draw()

    def hovered(self):
        self.inverse_colors()
        self.draw()
    
    def not_hovered(self):
        self.color = self.org_color
        self.font_color = self.org_font_color
        self.draw()

    def inverse_colors(self):
        self.color = (self.org_font_color[0], self.org_font_color[1], self.org_font_color[2])
        self.font_color = (self.org_color[0], self.org_color[1], self.org_color[2], 255)
예제 #5
0
파일: wall.py 프로젝트: alexinnes/ArPuGuh
 def init(self, **kwargs):
     self.shape = Rectangle(self.x,
                            self.y,
                            height=self.height,
                            width=self.width,
                            color=self.color,
                            batch=self.batch)
예제 #6
0
파일: wall.py 프로젝트: alexinnes/ArPuGuh
class Wall(Entity):
    defaults = {
        'width': config.block_width,
        'height': config.block_height,
        'collidable': True
    }

    attributes = {'color': RGB(255, 255, 255)}

    def init(self, **kwargs):
        self.shape = Rectangle(self.x,
                               self.y,
                               height=self.height,
                               width=self.width,
                               color=self.color,
                               batch=self.batch)

    def on_collision(self, obj):
        pass

    def take_damage(self, source, damage):
        pass

    def update(self):
        pass

    def draw(self):
        self.shape.draw()
예제 #7
0
 def __init__(self):
     win_width, win_height = get_size()
     self.batch = Batch()
     self._doc = pyglet.text.document.UnformattedDocument('')
     self._doc.set_style(0, len(self._doc.text),
                         dict(color=(255, 255, 255, 255)))
     font = self._doc.get_font()
     self.text_height = font.ascent - font.descent
     self.pad = 2
     self._outline = Rectangle(5,
                               5 + self.pad,
                               get_size()[0] - self.pad - 10,
                               self.text_height + self.pad,
                               color=(0, 0, 0))
     self._outline.opacity = 150
     self._layout = IncrementalTextLayout(self._doc,
                                          get_size()[0] - 14,
                                          self.text_height,
                                          multiline=False,
                                          batch=self.batch)
     self._caret = Caret(self._layout, color=(255, 255, 255))
     self._caret.visible = False
     self._layout.x = 5
     self._layout.y = 5 + self.pad
     self._focus = False
     self._press = False
     self.last_press = [0, 0]
     super().__init__(5, 5 + self.pad,
                      get_size()[0] - self.pad - 10,
                      self.text_height + self.pad)
예제 #8
0
def center_rect_in_rect(center_rect: Rectangle, outer_rect: Rectangle):
    """
    Aligns a rectangle in center of another rectangle.
    """
    center_rect.x = (outer_rect.x +
                     outer_rect.width // 2) - center_rect.width // 2
    center_rect.y = (outer_rect.y +
                     outer_rect.height // 2) - center_rect.height // 2
예제 #9
0
def set_rect(rect: Rectangle, x, y, w, h):
    """
    Sets the rectangle dimensions to different ones.
    """
    rect.x = x
    rect.y = y
    rect.width = w
    rect.height = h
예제 #10
0
    def __init__(self,
                 x: int,
                 y: int,
                 frame: Frame,
                 grid: Grid,
                 renderbox: RenderBox,
                 name: str = 'Player1',
                 batch: Batch = None,
                 debug: bool = False):
        # Player Sprite Select Related
        self.player_res_list = [
            PlayerImages.p1, PlayerImages.p2, PlayerImages.p3
        ]
        self.player_select = 0
        self.player_res = self.player_res_list[self.player_select]

        # Initialize Base Class
        super().__init__(x=x,
                         y=y,
                         res=self.player_res.jump_right,
                         frame=frame,
                         grid=grid,
                         renderbox=renderbox,
                         name=name,
                         batch=batch,
                         usage='dynamic',
                         is_anchor_x_centered=True)

        # Movement Related
        self.BASE_WALKING_SPEED = 200
        self.BASE_JUMPING_SPEED = 300
        self.vx = 0.0
        self.vy = 0.0
        self.facing = 'right'
        self.status = 'jumping'
        self.arrow_key_buffer = ArrowKeyBuffer()

        # Grid Related
        self.up_contact_obj_list = cast(List[GridObject], [])
        self.down_contact_obj_list = cast(List[GridObject], [])
        self.left_contact_obj_list = cast(List[GridObject], [])
        self.right_contact_obj_list = cast(List[GridObject], [])

        # Debug
        self.debug = debug
        self.ref_point = Circle(x=self.camera_x,
                                y=self.camera_y,
                                radius=5,
                                color=(255, 0, 0))
        self.ref_rect = Rectangle(x=self.camera_x,
                                  y=self.camera_y,
                                  width=self.width,
                                  height=self.height,
                                  color=(0, 0, 255))
        self.ref_rect.anchor_x = self.ref_rect.width // 2
예제 #11
0
 def __init__(self, x, y, index=None):
     y = get_size()[1] - y
     super().__init__(x, y, 32, 32)
     self._index = index
     self._on = False
     self._item = self._item_name = None
     self._state = {'set': True, 'get': True}
     self._rect = Rectangle(self.x,
                            get_size()[1] - self.y - 32,
                            32,
                            32,
                            color=(255, ) * 3)
     self._rect.opacity = 100
예제 #12
0
 def __init__(self):
     self.batch = Batch()
     self.background = Rectangle(0, 0, 0, 0)
     self.window = Window()
     self.window.push_handlers(self)
     self.on_resize(self.window.width, self.window.height)
     clock.schedule_interval(self.update, 1 / 60)
     clock.schedule_interval(self.log, 1)
     self.sounds = {
         'fail': media.load('resources/failure.mp3', streaming=False),
         'jump': media.load('resources/jump.wav', streaming=False),
         'score': media.load('resources/score.wav', streaming=False),
     }
     self.reset()
예제 #13
0
 def __init__(self, batch, groups, on_click, on_enter, on_motion,
              on_search):
     # create document
     self.document = FormattedDocument(' ')
     self.document.set_style(
         0, 1,
         dict(font_name=FONT_NAME, font_size=FONT_SIZE, color=FONT_COLOR))
     # calculate font height and margin
     font = self.document.get_font(0)
     self.font_height = font.ascent - font.descent
     self.margin = self.font_height * TEXT_INPUT_MARGIN
     # create text input
     self.input = IncrementalTextLayout(self.document,
                                        100,
                                        self.font_height,
                                        batch=batch,
                                        group=groups[1])
     self.input.x = 100
     self.input.y = 100
     # creating a caret and push it to window handlers
     self.caret = Caret(self.input, FONT_COLOR[:3], on_click, on_enter,
                        on_motion, on_search)
     self.clear_text()
     # create background rectangle
     self.rect = Rectangle(0,
                           0,
                           100,
                           self.font_height + 2 * self.margin,
                           color=TEXT_INPUT_COLOR,
                           batch=batch,
                           group=groups[0])
예제 #14
0
 def __init__(self, x, y, width, height):
     self._element = {}
     self._element['seq'] = Rectangle(x,
                                      y,
                                      width,
                                      height,
                                      color=(200, 200, 200))
예제 #15
0
 def to_drawable(self, x, y, batch, square_size, color):
     r = Rectangle(x,
                   y,
                   square_size,
                   square_size,
                   color=(10, 10, 10),
                   batch=batch)
     return r
예제 #16
0
class EndScreen:
    def __init__(self, window_width, window_height, score, kill_count,
                 total_enemies):
        self.win_width = window_width
        self.win_height = window_height
        self.score = score
        self.kill_count = kill_count
        self.button_width = 300
        self.button_height = 50
        self.x = (self.win_width / 2) - (self.button_width / 2)
        self.y = (self.win_height / 2) - (self.button_height / 2)
        self.pop_up = Rectangle(self.x - 100, self.y - 300, 500, 800,
                                (50, 50, 50))
        self.title = Label('G A M E   O V E R!', self.x + 5, self.y + 90,
                           (150, 1, 1, 255))
        self.info_label_score = Label(f'SCORE: {self.score}', self.x + 50,
                                      self.y, (60, 135, 50, 255))
        self.info_label_kills = Label(
            f'KILLS: {self.kill_count} / {total_enemies}', self.x + 15,
            self.y - 50, (60, 135, 50, 255))
        self.menu_button = Button(self.button_width, self.button_height,
                                  self.x, self.y - 150, 3.4, 5, 'M E N U',
                                  (1, 1, 1), (60, 235, 50, 255))

    def draw(self):
        self.pop_up.draw()
        self.info_label_score.draw()
        self.info_label_kills.draw()
        self.menu_button.draw()
        self.title.draw()

    def button_was_clicked(self, x, y, button):
        if (x >= int(button.x)) and (x <= int(button.x) + (self.button_width)):
            if (y >= int(button.y)) and (y <= int(button.y) +
                                         (self.button_height)):
                return True
        return False

    def button_was_touched(self, x, y, button):
        if (x >= int(button.x)) and (x <= int(button.x) + (self.button_width)):
            if (y >= int(button.y)) and (y <= int(button.y) +
                                         (self.button_height)):
                return True
        return False
예제 #17
0
 def __init__(self):
     width, height = get_size()
     GUI.__init__(self, width, height)
     self._element = {}
     self._element['panel'] = Rectangle(x=(width - 600) / 2,
                                        y=(height - 400) / 2,
                                        width=600,
                                        height=400,
                                        color=(0, 0, 0))
     self._element['panel'].opacity = 200
예제 #18
0
    def to_drawable(self, x, y, batch, square_size, color):
        """A city is represented as square containing a smaller square.
        """
        shapes = []
        r = super().to_drawable(x, y, batch, square_size, color)
        shapes.append(r)

        w = h = square_size * .4
        offset = square_size * .5
        r_inner = Rectangle(x + offset,
                            y + offset,
                            w,
                            h,
                            color=(0, 0, 0),
                            batch=batch)
        r_inner.anchor_position = (w * .5, h * .5)
        r_inner.opacity = 128
        shapes.append(r_inner)

        return shapes
예제 #19
0
    def to_drawable(self, x, y, batch, square_size, color):
        """Return a drawable 2D representation of the piece as a pyglet supported object. Defaults to a square.

        :param x: x position that the piece should be drawn at.
        :param y: y position that the piece should be drawn at.
        :param batch: pyglet Batch that the drawable should be added to.
        :param square_size: size of a square on the grid that the piece will be drawn on.
        :param color: color the piece should have.
        :return: a drawable pyglet object that holds a reference/was added to `batch`.
        """
        r = Rectangle(x, y, square_size, square_size, color=color, batch=batch)
        return r
예제 #20
0
 def __init__(self, window_width, window_height, score, kill_count,
              total_enemies):
     self.win_width = window_width
     self.win_height = window_height
     self.score = score
     self.kill_count = kill_count
     self.button_width = 300
     self.button_height = 50
     self.x = (self.win_width / 2) - (self.button_width / 2)
     self.y = (self.win_height / 2) - (self.button_height / 2)
     self.pop_up = Rectangle(self.x - 100, self.y - 300, 500, 800,
                             (50, 50, 50))
     self.title = Label('G A M E   O V E R!', self.x + 5, self.y + 90,
                        (150, 1, 1, 255))
     self.info_label_score = Label(f'SCORE: {self.score}', self.x + 50,
                                   self.y, (60, 135, 50, 255))
     self.info_label_kills = Label(
         f'KILLS: {self.kill_count} / {total_enemies}', self.x + 15,
         self.y - 50, (60, 135, 50, 255))
     self.menu_button = Button(self.button_width, self.button_height,
                               self.x, self.y - 150, 3.4, 5, 'M E N U',
                               (1, 1, 1), (60, 235, 50, 255))
예제 #21
0
 def __init__(self, items, box, batch, groups):
     super().__init__(items)
     self.box = box
     self.rect = Rectangle(0,
                           0,
                           1,
                           1,
                           color=DRAWER_COLOR,
                           batch=batch,
                           group=groups[1])
     self.handle = batch.add(TRIANGLE_COUNT * 3, GL_TRIANGLES, groups[2],
                             'v2f', 'c3B')
     self.handle.colors = HANDLE_COLOR * TRIANGLE_COUNT * 3
예제 #22
0
 def _rebuild_hotbar(self):
     self._hotbar_sprites = []
     self.hotbar_background.x = self.hotbar_x
     self.hotbar_background.y = self.hotbar_y
     self.hotbar_background.width = self.size_x
     self.hotbar_background.height = self.size_y
     for i in range(HOTBAR_SIZE):
         slot_x = ((self.size_x / HOTBAR_SIZE) * i) + self.hotbar_x
         if len(self._hotbar) <= i:
             empty_slot = Rectangle(slot_x,
                                    self.hotbar_y,
                                    PREVIEW_SIZE,
                                    PREVIEW_SIZE, (200, 200, 200),
                                    batch=self._hotbar_batch,
                                    group=self.hud_group)
             empty_slot.opacity = 100
             self._hotbar_sprites.append(empty_slot)
         else:
             self._draw_inventory_slot(slot_x, self.hotbar_y,
                                       self._hotbar[i].get_block_image(),
                                       self._hotbar_batch,
                                       self._hotbar_sprites)
예제 #23
0
 def __init__(self, font_height, batch, groups):
     self.font_height = font_height
     self.margin = font_height * TEXT_INPUT_MARGIN
     self.line_height = self.font_height + 2 * self.margin
     # create document
     self.text_box = Label('',
                           FONT_NAME,
                           FONT_SIZE,
                           width=1,
                           multiline=True,
                           anchor_y='top',
                           color=ITEM_FONT_COLOR,
                           batch=batch,
                           group=groups[2])
     # create background rectangle
     self.rect = Rectangle(0,
                           0,
                           100,
                           self.line_height,
                           color=ITEM_LIST_COLOR,
                           batch=batch,
                           group=groups[0])
     # create select rectangle
     self.select_rect = Rectangle(0,
                                  0,
                                  100,
                                  self.line_height,
                                  color=ITEM_SELECT_COLOR,
                                  batch=batch,
                                  group=groups[1])
     self.select_rect.visible = False
     # initialze member variables
     self.lines = 0
     self.select_num = 0
     self.items = []
     self.max_h = 1
     self.y = 0
예제 #24
0
    def draw_cursors(self):
        """Draw the cursors of each player.
        """

        rects = []
        for player in self.game.players:
            cursor = tuple(player.cursor)
            x, y = self._get_canvas_pos(*cursor)
            color = self._get_player_color(player)
            color = self.brighten(color, 50)
            r = Rectangle(y,
                          x,
                          self.square_size,
                          self.square_size,
                          color=color,
                          batch=self.batch)
            rects.append(r)

        self.batch.draw()
예제 #25
0
 def render_tiles(self):
     # The colors of each square
     light_square = (0, 122, 4)
     dark_square = (128, 255, 132)
     alternating_count = 1
     # Create a 2D array of rectangles to represent the squares on the board
     for rank in range(9):
         for file in range(9):
             # Generate a tile
             x, y = self.rank_file_to_xy(rank, file)
             rect = Rectangle(
                 x=x, y=y,
                 width=self.tile_width, height=self.tile_height,
                 # Use alternating_count to keep track of tile colorx
                 color=dark_square if alternating_count % 2 == 0 else light_square,
                 batch=self.tile_batch
             )
             alternating_count += 1
             self.tile_list.append(rect)
예제 #26
0
 def __init__(self, organizer, batch, groups):
     # draw organizer background
     self.rect = Rectangle(0,
                           0,
                           100,
                           100,
                           color=BOX_COLOR,
                           batch=batch,
                           group=groups[0])
     # create list of BoxGUI objects from boxes
     boxes_gui = []
     for box in organizer.subelems:
         boxes_gui.append(
             BoxGUI(box.subelems, box.x, box.y, box.w, box.h, batch,
                    groups))
     # intialize parent class with newly created drawers_gui
     super().__init__(boxes_gui)
     self.w = organizer.w
     self.h = organizer.h
예제 #27
0
 def render_pawn_promotion(self):
     promoted_piece = self.board.get_promoting_piece()
     if promoted_piece is not None:
         self.pawn_promotion = []
         background = pyglet.graphics.OrderedGroup(0)
         foreground = pyglet.graphics.OrderedGroup(1)
         rank, file = promoted_piece.rank, promoted_piece.file
         x, y = self.rank_file_to_xy(rank, file)
         self.promotion_menu_pos = x, y
         # Draw the four possible piece promotions at 1/4 the scale of each piece
         queen_image = src.constants.get_image(Queen(0, 0, promoted_piece.color))
         queen = Sprite(queen_image, x=x, y=y, batch=self.pawn_promotion_batch, group=foreground)
         queen.scale = (0.5 * self.tile_width) / queen_image.width
         self.pawn_promotion.append(queen)
         rook_image = src.constants.get_image(Rook(0, 0, promoted_piece.color))
         rook = Sprite(rook_image, x=x + (0.5 * self.tile_width), y=y,
                       batch=self.pawn_promotion_batch, group=foreground)
         rook.scale = (0.5 * self.tile_width) / rook_image.width
         self.pawn_promotion.append(rook)
         knight_image = src.constants.get_image(Knight(0, 0, promoted_piece.color))
         knight = Sprite(knight_image, x=x, y=y + (0.5 * self.tile_width),
                         batch=self.pawn_promotion_batch, group=foreground)
         knight.scale = (0.5 * self.tile_width) / knight_image.width
         self.pawn_promotion.append(knight)
         bishop_image = src.constants.get_image(Bishop(0, 0, promoted_piece.color))
         bishop = Sprite(bishop_image, x=x + (0.5 * self.tile_width) , y=y + (0.5 * self.tile_width),
                         batch=self.pawn_promotion_batch, group=foreground)
         bishop.scale = (0.5 * self.tile_width) / bishop_image.width
         self.pawn_promotion.append(bishop)
         # Draw a grey box on the square as a background for the promotion menu
         rect = Rectangle(
             x=x, y=y,
             width=self.tile_width, height=self.tile_height,
             color=(127, 127, 127),
             batch=self.pawn_promotion_batch,
             group=background
         )
         self.pawn_promotion.append(rect)
예제 #28
0
def test_rect_functions():
    rect = Rectangle(20, -10, 20, 5)
    utils.add_vector_to_rect(rect, (6, 8))
    assert rect.x == 26 and rect.y == -2 and rect.width == 20 and rect.height == 5
    rect = Rectangle(20, -10, 20, 5)
    utils.add_vector_to_rect(rect, (-5, -13))
    assert rect.x == 15 and rect.y == -23 and rect.width == 20 and rect.height == 5
    rect = Rectangle(20, -10, 20, 5)
    utils.add_vector_to_rect(rect, (45, 100))
    assert rect.x == 65 and rect.y == 90 and rect.width == 20 and rect.height == 5

    rect = Rectangle(10, 20, 50, 50)
    rect2 = Rectangle(0, 0, 30, 30)
    utils.center_rect_in_rect(rect2, rect)
    assert rect2.x == 20 and rect2.y == 30 and rect2.width == 30 and rect2.height == 30
    assert rect.x == 10 and rect.y == 20 and rect.width == 50 and rect.height == 50

    rect = Rectangle(10, 20, 50, 50)
    rect2 = Rectangle(0, 0, 30, 30)
    utils.center_rect_in_rect(rect, rect2)
    assert rect.x == -10 and rect.y == -10 and rect.width == 50 and rect.height == 50
    assert rect2.x == 0 and rect2.y == 0 and rect2.width == 30 and rect2.height == 30

    rect = Rectangle(10, 20, 50, 50)
    rect2 = Rectangle(0, 0, 30, 30)
    assert not utils.rect_empty(rect) and not utils.rect_empty(rect2)
    assert utils.rect_empty(Rectangle(10, 10, 1, 0))
    assert utils.rect_empty(Rectangle(10, 10, -0, 5))
    assert utils.rect_empty(Rectangle(10, 10, 43, -2))
    assert utils.rect_empty(Rectangle(10, 10, 0, 0))
    assert not utils.rect_empty(Rectangle(10, 10, 1, 1))

    assert not utils.rect_equal(rect, rect2)
    rect2.x = rect.x
    rect2.y = rect.y
    assert not utils.rect_equal(rect, rect2)
    rect2.width = rect.width
    rect2.height = rect.height
    assert utils.rect_equal(rect, rect2)

    assert utils.rect_in_rect(rect, rect2)
    rect2.x += 1
    assert not utils.rect_in_rect(rect, rect2)
    rect2.height = 10
    rect2.width = 10
    assert utils.rect_in_rect(rect2, rect)

    assert utils.point_in_rect((25, 25), rect)
    assert utils.point_in_rect((rect.x, 25), rect)
    assert utils.point_in_rect((rect.x + rect.width, rect.y), rect)
    assert not utils.point_in_rect((rect.x + rect.width + 1, 25), rect)

    rect = Rectangle(0, 0, 10, 10)
    utils.set_rect(rect, 4, -2, 22, 6)
    assert rect.x == 4 and rect.y == -2 and rect.width == 22 and rect.height == 6

    assert utils.get_center_of_rect(rect) == (15, 1)
예제 #29
0
 def draw(self):
     self.rect = Rectangle(self.x, self.y, self.width, self.height, self.color)
     self.rect.draw()
     self.description = Label(self.text, self.x + self.x_shift, self.y + self.y_shift, self.font_color)
     self.description.draw()
예제 #30
0
 def __init__(self, *args, **kwargs):
     super(Window, self).__init__(*args, **kwargs)
     # 窗口是否捕获鼠标
     self.exclusive = False
     # 玩家状态: 是否潜行, 是否飞行...
     self.player = {}
     self.player['stealing'] = False
     self.player['flying'] = False
     self.player['running'] = False
     self.player['die'] = False
     self.player['in_hud'] = False
     self.player['press_e'] = False
     # Strafing is moving lateral to the direction you are facing,
     # e.g. moving to the left or right while continuing to face forward.
     #
     # First element is -1 when moving forward, 1 when moving back, and 0
     # otherwise. The second element is -1 when moving left, 1 when moving
     # right, and 0 otherwise.
     self.player['strafe'] = [0, 0]
     # 玩家在世界中的位置 (x, y, z)
     self.player['position'] = (0, 4, 0)
     self.player['respawn_position'] = (0, 4, 0)
     # 拓展功能
     self.ext = {}
     self.ext['debug'] = False
     self.ext['open'] = False
     self.ext['position'] = False
     self.ext['running'] = False
     # First element is rotation of the player in the x-z plane (ground
     # plane) measured from the z-axis down. The second is the rotation
     # angle from the ground plane up. Rotation is in degrees.
     #
     # The vertical plane rotation ranges from -90 (looking straight down) to
     # 90 (looking straight up). The horizontal rotation range is unbounded.
     self.rotation = (0, 0)
     # Which sector the player is currently in.
     self.sector = None
     # 这个十字在屏幕中央
     self.reticle = None
     # Velocity in the y (upward) direction.
     self.dy = 0
     # 玩家可以放置的方块, 使用数字键切换
     self.inventory = [
         'grass', 'dirt', 'sand', 'stone', 'log', 'leaf', 'brick', 'plank',
         'craft_table'
     ]
     # 玩家手持的方块
     self.block = self.inventory[0]
     # 数字键列表
     self.num_keys = [
         key._1, key._2, key._3, key._4, key._5, key._6, key._7, key._8,
         key._9, key._0
     ]
     # 这个标签在画布的上方显示
     self.label = {}
     self.label['top'] = pyglet.text.DocumentLabel(decode_attributed(''),
                                                   x=0,
                                                   y=self.height - 30,
                                                   anchor_x='left',
                                                   anchor_y='center')
     self.is_init = True
     # 这个标签在画布正中偏上显示
     self.label['center'] = pyglet.text.DocumentLabel(decode_attributed(''),
                                                      x=self.width // 2,
                                                      y=self.height // 2 +
                                                      50,
                                                      anchor_x='center',
                                                      anchor_y='center')
     # 这个标签在画布正中偏下显示
     self.label['actionbar'] = pyglet.text.DocumentLabel(
         decode_attributed(''),
         x=self.width // 2,
         y=self.height // 2 - 100,
         anchor_x='center',
         anchor_y='center')
     # 加载用图片
     self.loading_image = image.load(
         os.path.join(path['texture'], 'loading.png'))
     self.loading_image.height = self.height
     self.loading_image.width = self.width
     # 覆盖屏幕的矩形
     self.full_screen = Rectangle(0, 0, self.width, self.height)
     # 聊天区
     self.dialogue = Dialogue(self.width, self.height)
     # 将 self.upgrade() 方法每 1.0 / TICKS_PER_SEC 调用一次, 它是游戏的主事件循环
     pyglet.clock.schedule_interval(self.update, 1.0 / TICKS_PER_SEC)
     # 检测玩家是否应该死亡
     pyglet.clock.schedule_interval(self.check_die, 1.0 / TICKS_PER_SEC)
     # 每10秒更新一次方块数据
     pyglet.clock.schedule_interval(self.update_status, 10.0)
     # 每60秒保存一次进度
     pyglet.clock.schedule_interval(self.save, 30.0)
     log_info('welcome %s(id: %s)' % (player['name'], player['id']))