예제 #1
0
    def shift(self, _delta_chunk):
        """Updates the EntityBuffer's list of entities based on the player's movement.

        Args:
            _delta_chunk (int): Number of chunks the Player crossed after the previous iteration.
        """
        prev_entities = self.entities.copy()
        if _delta_chunk > 0:
            for i in range(_delta_chunk):
                self.entities.append(
                    self.load(self.chunk_buffer.get_end_chunk_ind() + i + 1))
                self.save(self.entities[i],
                          self.chunk_buffer.get_start_chunk_ind() + i)
                self.entities.pop(0)
        else:
            for i in range(abs(_delta_chunk)):
                self.entities.insert(
                    i,
                    self.load(self.chunk_buffer.get_start_chunk_ind() - i - 1))
                self.save(self.entities[-i - 1],
                          self.chunk_buffer.get_end_chunk_ind() - i)
                self.entities.pop(-1)
        if self.entities != prev_entities:
            consts.dbg(1, "ENTITY BUFFER - END OF SHIFT - ENTITIES LIST:",
                       self.entities)
예제 #2
0
    def __init__( self, world_name ):
        """Initializes the Serializer object.

        Args:
            world_name (str): Name of the world.
        """
        self.name = "Worlds/" + world_name + '.db'
        self.world_time = 0
        self.day_time   = 0

        if not os.path.isdir("Worlds"): os.mkdir("Worlds")
        self.conn = sqlite3.connect( self.name )
        c = self.conn.cursor()
        try:
            # Create Table
            c.execute( '''CREATE TABLE terrain(keys INTEGER NOT NULL PRIMARY KEY, list TEXT, local TEXT, chunk_time TEXT, entity TEXT)''' )
            self.conn.commit()
            c.execute( '''CREATE TABLE player(playername TEXT NOT NULL PRIMARY KEY, pickledplayer TEXT)''' )
            self.conn.commit()
            c.execute( '''CREATE TABLE info(world_time TEXT)''' )
            self.conn.commit()
        except Exception as e:
            consts.dbg(1, "EXCEPTION IN SERIALIZER INIT:", e)

        self.world_time = self.get_world_time()
예제 #3
0
    def add_entity(self, _entity):
        """Adds the given Entity or ItemEntity to the EntityBuffer's entity list.

        Args:
            _entity (Entity | ItemEntity): Entity or ItemEntity object to be added.
            _ind (int): Index at which the Entity or ItemEntity is to be added.
        """
        _ind = self.get_curr_chunk_ind(_entity.get_pos().copy())
        consts.dbg(1, "ADD ENTITY INDEX:", _ind)
        self.entities[_ind].append(_entity)
예제 #4
0
 def calc_friction(self):
     """Updates the Entity's friction based on the tile in contact with
         the bottom left point in the entity's hitbox.
     """
     try:
         tile = self.tile((self.friction_point(self.pos)[0],
                           self.friction_point(self.pos)[1] - 1))
         consts.dbg(0, "IN CALC FRICTION - TILE:", tile)
         self.friction = consts.TILE_ATTR[tile][consts.tile_attr.FRICTION]
     except Exception as e:
         consts.dbg(0, "IN CALC FRICTION - EXCEPTION", e)
         self.friction = consts.AIR_FRICTION
예제 #5
0
 def pick_item(self, _pos, _range):
     items = []
     for index in range(self.len - 1, -1, -1):
         for entity_ind in range(len(self.entities[index]) - 1, -1, -1):
             entity = self.entities[index][entity_ind]
             if (isinstance(entity,
                            ItemEntity)) and (consts.dist_between_points(
                                entity.pos, _pos) <= _range):
                 items.append(entity)
                 consts.dbg(1, "ENTITY BUFFER BEFORE PICK ITEM:",
                            self.entities)
                 self.entities[index].pop(entity_ind)
     return items
예제 #6
0
    def get_world_time( self ):
        """Gets the pickled world time from the database.

        Returns:
            Union[bytes, None]: The pickled world time or None if it does not exist.
        """
        c = self.conn.cursor()
        c.execute( '''SELECT world_time FROM info''' )
        res = c.fetchone()
        self.conn.commit()
        try:
            return bz2.decompress( res[0] )
        except Exception as e:
            consts.dbg( 1, "EXCEPTION IN SERIALIZER GET_WORLD_TIME:", e )
            return res
예제 #7
0
    def set_world_time( self, _time ):
        """Saves/Updates the pickled world time in the database.

        Args:
            _time (bytes): Pickled world time.
        """
        c = self.conn.cursor()
        try:
            # Set world time for the first time
            c.execute( '''INSERT INTO info (world_time) VALUES (?)''', ( bz2.compress( _time ), ) )
            self.conn.commit()
        except Exception as e:
            # Update world time
            consts.dbg( 1, "EXCEPTION IN SERIALIZER SET_WORLD_TIME:", e )
            c.execute( '''UPDATE info SET world_time=?''', ( bz2.compress( _time ), ) )
            self.conn.commit()
예제 #8
0
    def set_entity(self, _key, _li):
        """Saves/Updates the pickled entity list in the database at the given key.

        Args:
            _key (int): Key at which the bytes object is to be saved.
            _li (bytes): Pickled entity list.
        """
        c = self.conn.cursor( )
        try:
            # Save string at new key location
            c.execute( '''INSERT INTO terrain (entity, keys) VALUES (?,?)''', (bz2.compress( _li ), _key) )
            self.conn.commit( )
        except Exception as e:
            consts.dbg(1, "EXCEPTION IN SERIALIZER SET_ENTITY:", e )
            # Update string at existing key
            c.execute( '''UPDATE terrain SET entity =? WHERE keys=?''', (bz2.compress( _li ), _key) )
            self.conn.commit( )
예제 #9
0
    def set_chunk_time( self, _key, _time ):
        """Saves/Updates the pickled chunk time in the database at the given key.

        Args:
            _key (int): Key at which the bytes object is to be saved.
            _time (bytes): Pickled chunk time.
        """
        c = self.conn.cursor()
        try:
            # Set world time for the first time
            c.execute( '''INSERT INTO terrain (chunk_time) VALUES (?) WHERE keys=?''', ( bz2.compress( _time ), _key) )
            self.conn.commit()
        except Exception as e:
            # Update world time
            consts.dbg( 1, "EXCEPTION IN SERIALIZER SET_CHUNK_TIME:", e )
            c.execute( '''UPDATE terrain SET chunk_time=? WHERE keys=?''', ( bz2.compress( _time ), _key) )
            self.conn.commit()
예제 #10
0
    def save_player( self, _id, _pickled_player ):
        """Saves/Updates the pickled player in the database at the given ID.

        Args:
            _id (int): ID at which the pickled player is to be saved.
            _pickled_player (bytes): Pickled player.
        """
        c = self.conn.cursor()
        try:
            # Save pickledplayer at new playername
            c.execute( '''INSERT INTO player (playername, pickledplayer) VALUES (?,?)''', (_id, bz2.compress( _pickled_player )) )
            self.conn.commit()
        except Exception as e:
            # Update pickledplayer at existing playername
            consts.dbg( 1, "EXCEPTION IN SERIALIZER SAVE_PLAYER:", e )
            c.execute( '''UPDATE player SET pickledplayer =?  WHERE playername=?''', (bz2.compress( _pickled_player ), _id) )
            self.conn.commit()
예제 #11
0
    def get_chunk_time( self, _key ):
        """Gets the pickled chunk time from the database at the given key.

        Args:
            _key (int): Key at which the bytes object is to be loaded.

        Returns:
            Union[bytes, None]: The pickled chunk time or None if it does not exist.
        """
        c = self.conn.cursor()
        c.execute( '''SELECT chunk_time FROM terrain WHERE keys=?''', ( _key, ))
        res = c.fetchone()
        self.conn.commit()
        try:
            return bz2.decompress( res[0] )
        except Exception as e:
            consts.dbg( 1, "EXCEPTION IN SERIALIZER GET_CHUNK_TIME:", e )
            return res
예제 #12
0
    def load_player( self, _id ):
        """Gets the pickled player from the database at the given ID.

        Args:
            _id (int): ID at which the pickled player is to be loaded.

        Returns:
            Union[bytes, None]: The pickled player or None if it does not exist.
        """
        c = self.conn.cursor()
        c.execute( '''SELECT pickledplayer FROM player WHERE playername=?''', (_id,) )
        res = c.fetchone()
        self.conn.commit()
        try:
            return bz2.decompress( res[0] )
        except Exception as e:
            consts.dbg( 1, "EXCEPTION IN SERIALIZER LOAD_PLAYER:", e )
            return res
예제 #13
0
    def set_chunk( self, _key, _t0, _t1 ):
        """Saves/Updates the pickled chunk tile list and the local tile table in the database at the given key.

        Args:
            _key (int): Key at which the bytes object is to be saved.
            _t0 (bytes): Pickled chunk tile list.
            _t1 (bytes): Pickled chunk tile table.
        """
        t = _t0, _t1
        c = self.conn.cursor()
        try:
            # Save string at new key location
            c.execute( '''INSERT INTO terrain (keys, list, local) VALUES (?,?,?)''', (_key, bz2.compress( t[0 ] ), bz2.compress( t[1 ] )) )
            self.conn.commit()
        except Exception as e:
            # Update string at existing key
            consts.dbg( 1, "EXCEPTION IN SERIALIZER SETITEM:", e )
            c.execute( 'UPDATE terrain SET list =?, local =?  WHERE keys=?', (bz2.compress( t[0] ), bz2.compress( t[1] ), _key) )
            self.conn.commit()
예제 #14
0
    def get_entity(self, _key):
        """Gets the pickled entity list from the database at the given key.

        Args:
            _key (int): Key at which the bytes object is to be loaded.

        Returns:
            Union[bytes, None]: The pickled entity list or None if it does not exist.
        """
        c = self.conn.cursor()
        c.execute( '''SELECT entity FROM terrain WHERE keys=?''', (_key,) )
        li = c.fetchone()
        self.conn.commit()
        try:
            li = bz2.decompress( li[0] )
            return li
        except Exception as e:
            consts.dbg( 1, "EXCEPTION IN SERIALIZER GET_ENTITY:", e )
            return None
예제 #15
0
    def update(self, _dt):
        update_index_entities = []
        index = 0
        entities_copy = [
            self.entities[_ind].copy() for _ind in range(self.len)
        ]
        while index < self.len:
            entity_ind = 0
            while entity_ind < len(entities_copy[index]):
                entity = entities_copy[index][entity_ind]
                prev_entity_ind = entity_ind
                entity_ind += 1
                if entity not in self.entities[index]:
                    continue

                # prev_entity_pos = entity.get_pos( ).copy( )
                chk_a = time.time()
                entity.run(_dt)
                entity.update(_dt)
                consts.dbg(1, "ENTITY UPDATE TIME TAKEN(in milliseconds):",
                           (time.time() - chk_a) * 1000)
                new_index = self.get_curr_chunk_ind(entity.get_pos())
                if new_index != prev_entity_ind:
                    self.entities[index].remove(entity)
                    update_index_entities.append(entity)
            index += 1

        for entity in update_index_entities:
            consts.dbg(1, "UPDATE ENTITY INDEX:", update_index_entities)
            index = self.get_curr_chunk_ind(entity.get_pos())
            consts.dbg(1, "NEW INDEX OF ENTITY:", index)
            self.entities[index].append(entity)
예제 #16
0
    def get_chunk(self, _key):
        """Gets the pickled chunk tile list and the local tile table from the database at the given key.

        Args:
            _key (int): Key at which the bytes object is to be loaded.

        Returns:
            Union[bytes, None]: The pickled chunk tile list and the local tile table or None if it does not exist.
        """
        c = self.conn.cursor()
        c.execute( '''SELECT list FROM terrain WHERE keys=?''', (_key,) )
        li = c.fetchone()
        c.execute( '''SELECT local FROM terrain WHERE keys=?''', (_key,) )
        lo = c.fetchone()
        self.conn.commit()
        try:
            li = bz2.decompress( li[0] )
            lo = bz2.decompress( lo[0] )
            return li, lo
        except Exception as e:
            consts.dbg( 1, "EXCEPTION IN SERIALIZER GETITEM:", e )
            return None
예제 #17
0
 def run(self, _dt):
     self.acc = [0, 0]
     player_pos = self.entity_buffer.player.pos
     if self.grounded:
         self.vel = [0, 0]
         self.cooldown = max(0, self.cooldown - _dt)
         if not self.cooldown:
             consts.dbg(1, "IN RUN - SLIME TOUCHED GROUND")
             # self.vel = [0, 0]
             self.jump()
             self.cooldown = 2
     else:
         if not self.grounded:
             if player_pos[0] > self.pos[0]:
                 consts.dbg(1, "SLIME - IN RUN - MOVING RIGHT")
                 self.vel[0] = 0.5
             elif player_pos[0] < self.pos[0]:
                 consts.dbg(1, "SLIME - IN RUN - MOVING LEFT")
                 self.vel[0] = -0.5
예제 #18
0
    def check(self, _pos):
        """Checks whether the hitbox of the Entity collides with a tile.

        Args:
            _pos (list): Position of the entity from which the hitbox is computed.

        Returns:
            bool: True if the hitbox is colliding else False.
        """
        # For every corresponding tile between hitbox endpoints including the endpoints,
        # check that the hitbox and the tile don't intersect
        if self.tangibility:
            return True
        hitbox = self.hitbox(_pos)
        for point in hitbox:
            consts.dbg(1, "IN CHECK - ENTERED FOR LOOP")
            if self.tile(point) != consts.tiles.air:
                consts.dbg(1, "CHECK RETURNED FALSE")
                return False
        consts.dbg(1, "CHECK RETURNED TRUE")
        return True
예제 #19
0
    def run(self, _dt):
        """Updates the Player's variables to handle the user's input.

        Args:
            _dt (float): Time passed between previous and current iteration.
        """
        self.acc[0] = 0
        self.acc[1] = 0
        self.hitting = False
        self.placing = False
        if self.key_state[pygame.K_a] and not self.key_state[pygame.K_d]:
            consts.dbg(1, "IN RUN - MOVING LEFT")
            self.move_left()
            self.texture_strct.run_left(_dt)
        elif self.key_state[pygame.K_d] and not self.key_state[pygame.K_a]:
            consts.dbg(1, "IN RUN - MOVING RIGHT")
            self.move_right()
            self.texture_strct.run_right(_dt)
        else:
            self.texture_strct.run_static()

        if self.key_state[pygame.K_s] and not self.key_state[pygame.K_w]:
            consts.dbg(1, "IN RUN - MOVING DOWN")
            self.move_down()
        elif (self.tangibility or self.grounded) and self.key_state[
                pygame.K_w] and not self.key_state[pygame.K_s]:
            consts.dbg(1, "IN RUN - MOVING UP")
            self.jump()

        if self.mouse_state[pygame.BUTTON_LEFT]:
            consts.dbg(1, "IN RUN - LEFT MOUSE BUTTON PRESSED")
            self.left_click(_dt, self.cursor_pos)

        if self.mouse_state[pygame.BUTTON_RIGHT]:
            consts.dbg(1, "IN RUN - RIGHT MOUSE BUTTON PRESSED")
            self.right_click(_dt, self.cursor_pos)
예제 #20
0
    def update(self, _dt):
        """Updates the Entity's position, velocity and state.

        Args:
            _dt (float): Time passed between previous and current iteration.
        """
        self.pick()
        consts.dbg(1, "IN ENTITY - ENTERING UPDATE")
        dt2 = _dt
        _dt = 1 / (consts.MAX_VEL * consts.SCALE_VEL)
        while dt2 > 0:
            if dt2 <= _dt:
                _dt = dt2
                dt2 = 0
            else:
                dt2 -= _dt
            consts.dbg(0, "IN UPDATE WHILE LOOP - AFTER CALCULATING - DT:",
                       _dt)
            consts.dbg(0, "IN UPDATE WHILE LOOP - AFTER CALCULATING - DT2:",
                       dt2)
            consts.dbg(1, "INSIDE UPDATE WHILE LOOP")
            self.calc_friction()
            consts.dbg(0,
                       "IN UPDATE WHILE LOOP - AFTER CALCULATING - FRICTION:",
                       self.friction)
            self.check_ground(self.pos)
            if consts.GRAVITY_ACC and (not self.grounded):
                self.acc[1] = -consts.GRAVITY_ACC
            consts.dbg(0, "IN UPDATE - AT START - PLAYER VEL:", self.vel)
            consts.dbg(0, "IN UPDATE - AT START - PLAYER ACC:", self.acc)
            for i in range(0, 2):
                next_pos = self.pos.copy()
                next_vel = self.vel[i] + self.acc[i] * _dt
                if next_vel >= abs(self.friction * _dt):
                    self.vel[i] -= self.friction * _dt
                elif next_vel <= -abs(self.friction * _dt):
                    self.vel[i] += self.friction * _dt
                else:
                    self.vel[i] = 0
                    self.acc[i] = 0

                    if self.acc[i] > consts.MAX_ACC * 2:
                        self.acc[i] = consts.MAX_ACC * 2
                    elif self.acc[i] < -consts.MAX_ACC * 2:
                        self.acc[i] = -consts.MAX_ACC * 2

                self.vel[i] += self.acc[i] * _dt
                if self.vel[i] < -consts.MAX_VEL * (1 - self.friction * 0.2):
                    self.vel[i] = -consts.MAX_VEL * (1 - self.friction * 0.2)
                elif self.vel[i] > consts.MAX_VEL * (1 - self.friction * 0.2):
                    self.vel[i] = consts.MAX_VEL * (1 - self.friction * 0.2)

                next_pos[i] += self.vel[i] * consts.SCALE_VEL * _dt
                move = self.check(next_pos)
                if move:
                    if (i == 0) or (i == 1 and
                                    consts.CHUNK_HEIGHT_P >= next_pos[i] >= 0):
                        self.pos[i] += self.vel[i] * consts.SCALE_VEL * _dt
                    if consts.CHUNK_HEIGHT_P < self.pos[1]:
                        self.pos[1] = consts.CHUNK_HEIGHT_P
                        consts.dbg(
                            -1,
                            "IN UPDATE WHILE LOOP - IN MOVE - POS > MAX HEIGHT"
                        )
                    elif 0 > self.pos[1]:
                        self.pos[1] = 0
                        consts.dbg(
                            -1,
                            "IN UPDATE WHILE LOOP - IN MOVE - POS < MIN HEIGHT"
                        )
                else:
                    self.vel[i] = 0
            if self.vel == [0, 0]: break
예제 #21
0
 def pick(self):
     items = self.entity_buffer.pick_item(self.pos.copy(), self.range)
     if items:
         consts.dbg(1, "ITEMS TO PICK:", items)
     for item in items:
         self.inventory.add_item(item.id, 1)