Пример #1
0
class DebugTarget(entity.Entity):
    def __init__(self, x, y):
        entity.Entity.__init__(self)
        self.shootable = True
        self.class_id = 4
        self.w = 4
        self.netxpos = NetworkVar(self, x, 1)
        self.netypos = NetworkVar(self, y, 2)
        self.count = 0
        self.velocity = 30

    def get_collision_bounds(self):
        return [(self.netxpos.var - self.w, self.netypos.var - self.w),
                (self.netxpos.var + self.w, self.netypos.var - self.w),
                (self.netxpos.var - self.w, self.netypos.var + self.w),
                (self.netxpos.var + self.w, self.netypos.var + self.w)]

    def update(self, world):
        self.count += world.dt
        self.netxpos.set(self.netxpos.var + self.velocity * world.dt, True)
        if self.count > 10:
            self.velocity = -self.velocity
            self.count = 0

    def get_shot(self, damage):
        return
Пример #2
0
 def __init__(self, x, y):
     entity.Entity.__init__(self)
     self.shootable = True
     self.class_id = 4
     self.w = 4
     self.netxpos = NetworkVar(self, x, 1)
     self.netypos = NetworkVar(self, y, 2)
     self.count = 0
     self.velocity = 30
Пример #3
0
 def __init__(self):
     entity.CEntity.__init__(self)
     self.name = NetworkVar(self, "", 0)
     self.netxpos = NetworkVar(self, 0, 1, True)
     self.netypos = NetworkVar(self, 0, 2, True)
     self.netangle = NetworkVar(self, 0, 3)
     self.netcolour = NetworkVar(self, (0, 0, 0), 4)
     self.netxvel = NetworkVar(self, 0, 5, True)
     self.netyvel = NetworkVar(self, 0, 6, True)
     self.netomega = NetworkVar(self, 0, 7)
     self.health = NetworkVar(self, 0, 8)
     self.orgimage = pg.image.load("sprites/car.png").convert_alpha()
     self.colour = (128, 128, 128)
     self.rotimage = self.orgimage.copy()
Пример #4
0
    def __init__(self, x, y, angle, name, owner=None):
        entity.Entity.__init__(self)
        self.class_id = 1
        self.owner = owner
        self.shootable = True
        self.name = NetworkVar(self, name, 0)
        self.netxpos = NetworkVar(self, x, 1)
        self.netxpos.quantise = 2
        self.netypos = NetworkVar(self, y, 2)
        self.netypos.quantise = 2
        self.angle = angle
        self.netangle = NetworkVar(self, angle, 3)
        self.netangle.quantise = 6
        self.netcolour = NetworkVar(self, (255, 255, 0), 4)
        self.gun_range = 500
        self.dead = False
        self.wheeldirection = 0

        self.xpos = x
        self.ypos = y
        self.w = CAR_SIZE
        self.h = CAR_SIZE
        self.moment_of_inertia = self.w * math.pow(self.h, 3) / 12

        self.xvel = 0
        self.yvel = 0
        self.netxvel = NetworkVar(self, self.xvel, 5)
        self.netxvel.quantise = 2
        self.netxvel.only_send_to_owner = True
        self.netyvel = NetworkVar(self, self.yvel, 6)
        self.netyvel.quantise = 2
        self.netyvel.only_send_to_owner = True
        self.xacc = 0
        self.yacc = 0
        self.omega = 0  # Anglular velocity
        self.netomega = NetworkVar(self, self.omega, 7)
        self.netomega.quantise = 10
        self.netomega.only_send_to_owner = True
        self.alpha = 0  # Angluar acceleration

        self.health = 100
        self.nethealth = NetworkVar(self, self.health, 8)
        self.nethealth.quantise = 0
        self.mass = 10
        self.topSpeed = 10
        self.engine_power = 20
        self.tyre_power = 70
        self.colour = (255, 255, 255)
        self.image = "sprites/car.png"

        self.strength = 2
Пример #5
0
class Player(entity.Entity):
    def __init__(self, x, y, angle, name, owner=None):
        entity.Entity.__init__(self)
        self.class_id = 1
        self.owner = owner
        self.shootable = True
        self.name = NetworkVar(self, name, 0)
        self.netxpos = NetworkVar(self, x, 1)
        self.netxpos.quantise = 2
        self.netypos = NetworkVar(self, y, 2)
        self.netypos.quantise = 2
        self.angle = angle
        self.netangle = NetworkVar(self, angle, 3)
        self.netangle.quantise = 6
        self.netcolour = NetworkVar(self, (255, 255, 0), 4)
        self.gun_range = 500
        self.dead = False
        self.wheeldirection = 0

        self.xpos = x
        self.ypos = y
        self.w = CAR_SIZE
        self.h = CAR_SIZE
        self.moment_of_inertia = self.w * math.pow(self.h, 3) / 12

        self.xvel = 0
        self.yvel = 0
        self.netxvel = NetworkVar(self, self.xvel, 5)
        self.netxvel.quantise = 2
        self.netxvel.only_send_to_owner = True
        self.netyvel = NetworkVar(self, self.yvel, 6)
        self.netyvel.quantise = 2
        self.netyvel.only_send_to_owner = True
        self.xacc = 0
        self.yacc = 0
        self.omega = 0  # Anglular velocity
        self.netomega = NetworkVar(self, self.omega, 7)
        self.netomega.quantise = 10
        self.netomega.only_send_to_owner = True
        self.alpha = 0  # Angluar acceleration

        self.health = 100
        self.nethealth = NetworkVar(self, self.health, 8)
        self.nethealth.quantise = 0
        self.mass = 10
        self.topSpeed = 10
        self.engine_power = 20
        self.tyre_power = 70
        self.colour = (255, 255, 255)
        self.image = "sprites/car.png"

        self.strength = 2

    def update(self, world, actions):
        # world variables
        dt = world.dt

        lvl0 = world.level["wall"]

        # Do actions
        throttle = 0
        self.wheeldirection = 0
        self.xacc = 0
        self.yacc = 0
        self.alpha = 0
        wheel_pos_rear = -8
        wheel_pos_front = 8
        if not self.dead:
            if actions[UPARROW]:
                throttle = self.engine_power
            if actions[DOWNARROW]:
                throttle = -self.engine_power / 2
            if actions[LEFTARROW]:
                self.wheeldirection = math.pi / 8
            if actions[RIGHTARROW]:
                self.wheeldirection = -math.pi / 8
            if actions[SHOOT_BUTTON]:
                latency = actions[SHOOT_BUTTON]
                if not world.client_world:
                    self.shoot(world, latency)

        self.angle = self.angle % (2 * math.pi)
        self.angle = round(self.angle, 10)
        speed = np.hypot(self.xvel, self.yvel)
        vlong = self.xvel * math.cos(self.angle) - self.yvel * math.sin(
            self.angle)
        vlat = self.xvel * math.sin(self.angle) + self.yvel * math.cos(
            self.angle)
        force_centripital = 0
        force_drag = 0.001 * np.sign(vlong) * vlong**2
        force_drag_lat = 1 * np.sign(vlat) * vlat**2
        force_drag_lat = np.clip(force_drag_lat, -self.tyre_power,
                                 self.tyre_power)
        self.omega = 0
        if self.wheeldirection:
            force_drag = force_drag * 1
            force_drag_lat = force_drag_lat * 1
            radius = 32 / math.sin(self.wheeldirection)
            #force_centripital = self.mass*(vlong**2)/radius
            #force_centripital = np.clip(force_centripital, -self.tyre_power, self.tyre_power)
            self.omega = vlong / radius
        #self.apply_force(math.pi/2, force_centripital)
        self.apply_force(0, throttle)
        self.apply_force(0, -force_drag)
        self.apply_force(math.pi / 2, force_drag_lat)
        # Apply the goods
        self.omega += self.alpha * dt
        self.xvel += self.xacc * dt
        self.yvel += self.yacc * dt
        self.angle += self.omega * dt
        self.xpos += self.xvel * dt
        self.ypos += self.yvel * dt

        # COLLISION
        self.do_collision(world, lvl0)
        self.netxpos.set(self.xpos, True)
        self.netypos.set(self.ypos, True)
        self.netxvel.set(self.xvel, True)
        self.netyvel.set(self.yvel, True)
        self.netangle.set(self.angle, True)
        self.netomega.set(self.omega, True)
        self.nethealth.set(self.health, True)
        return None

    def apply_force(self, theta, mag):
        """Apply a force to the car that pushes and gives angular velocity
        theta: Direction of the force relative to the direction of the car
        mag: Magnitude of the force
        """
        # The easy newton
        accel = mag / self.mass
        xcomp = math.cos(self.angle + theta)
        ycomp = -math.sin(self.angle + theta)
        self.xacc += accel * xcomp
        self.yacc += accel * ycomp

    #Breaks when you shoot on a wall
    def shoot(self, world, latency):
        """
        We shoot and do lag compensation
        """

        # Get the hitscan stuff before rewind because client predicts itself in present
        hitscan_endpoint = (self.xpos + math.cos(self.angle) * self.gun_range,
                            self.ypos - math.sin(self.angle) * self.gun_range)
        hitscan_startpoint = (self.xpos, self.ypos)
        hit_point = None
        hit_entity = None

        # Rewind the game
        snapshots_behind = int((latency * 10) // world.dt)
        fastforward = None

        if 0 < snapshots_behind < len(world.snapshots) - 1:
            fastforward = world.rewind_to_snapshot_index(
                -snapshots_behind)  # Rewind to the past

        for _id in world.entdict:
            _entity = world.entdict[_id]
            if _entity is None:
                continue
            if _entity.shootable and _entity != self:
                colpoints = _entity.get_collision_bounds()
                for i in range(len(colpoints)):
                    colpoint1 = colpoints[i - 1]
                    colpoint2 = colpoints[i]
                    intersect_point = self.line_intersection(
                        (colpoint1, colpoint2),
                        (hitscan_startpoint, hitscan_endpoint))
                    if intersect_point is not None:

                        if colpoint1[0] > colpoint2[0]:
                            rightpoint = colpoint1[0]
                            leftpoint = colpoint2[0]
                        else:
                            rightpoint = colpoint2[0]
                            leftpoint = colpoint1[0]

                        if hitscan_endpoint[1] > hitscan_startpoint[1]:
                            bottompoint = hitscan_startpoint[1]
                            toppoint = hitscan_endpoint[1]
                        else:
                            bottompoint = hitscan_endpoint[1]
                            toppoint = hitscan_startpoint[1]
                        if leftpoint < intersect_point[0] < rightpoint:
                            if toppoint > intersect_point[1] > bottompoint:
                                hit_point = intersect_point
                                hit_entity = _entity
                                # The segment hit!
        if hit_point is not None:
            hit = entities.HitMarker(hit_point[0], hit_point[1])
            world.spawn_entity(hit)
        if fastforward is not None:
            world.rewind_to_snapshot(
                fastforward)  # Fast forward back to the real
        if hit_entity is not None:
            hit_entity.get_shot(1)

    def do_collision(self, world, lvl0):
        dt = world.dt
        players_colliding = self.check_player_col(world)
        if players_colliding:
            # Find what my velocity is with momentum transfer
            for player in players_colliding:
                xv = self.xvel
                yv = self.yvel
                self.xvel = player.xvel
                self.yvel = player.yvel
                player.xvel = xv
                player.yvel = yv

        walls = self.check_wall_col(lvl0, False, self.xpos, self.ypos)

        if walls:  # Check if it hit anything
            for col in walls:  # Loop through every wall it hit
                # Right side of block
                if self.xvel < 0:
                    if self.check_wall_col(
                            lvl0, col) and not self.check_wall_col(
                                lvl0, col, self.xpos - self.xvel * dt,
                                self.ypos):
                        self.xpos = col[0] + col[2]
                        self.take_damage(abs(self.xvel) / self.strength)
                        self.xvel = 0
                # Left side of block
                elif self.xvel > 0:
                    if self.check_wall_col(
                            lvl0, col) and not self.check_wall_col(
                                lvl0, col, self.xpos - self.xvel * dt,
                                self.ypos):
                        self.xpos = col[0] - self.w
                        self.take_damage(abs(self.xvel) / self.strength)
                        self.xvel = 0
                # Bottom side of block
                if self.yvel < 0:
                    if self.check_wall_col(lvl0,
                                           col) and not self.check_wall_col(
                                               lvl0, col, self.xpos,
                                               self.ypos - self.yvel * dt):
                        self.ypos = col[1] + col[3]
                        self.take_damage(abs(self.yvel) / self.strength)
                        self.yvel = 0
                # Top side of block
                elif self.yvel > 0:
                    if self.check_wall_col(lvl0,
                                           col) and not self.check_wall_col(
                                               lvl0, col, self.xpos,
                                               self.ypos - self.yvel * dt):
                        self.ypos = col[1] - self.h
                        self.take_damage(abs(self.yvel) / self.strength)
                        self.yvel = 0

    def rect_col(self, rect1, rect2):
        # not to the right and not to the left
        if not rect1[0] >= rect2[0] + rect2[2] and not rect1[0] + rect1[
                2] <= rect2[0]:
            # not below and not above
            if not rect1[1] >= rect2[1] + rect2[3] and not rect1[1] + rect1[
                    3] <= rect2[1]:
                return True
        return False

    def get_collision_bounds(self):
        return [(self.xpos - self.w / 2, self.ypos - self.h / 2),
                (self.xpos + self.w / 2, self.ypos - self.h / 2),
                (self.xpos - self.w / 2, self.ypos + self.h / 2),
                (self.xpos + self.w / 2, self.ypos + self.h / 2)]

    def line_intersection(self, line1, line2):
        """Line intersect function from Paul Draper
        https://stackoverflow.com/questions/20677795/how-do-i-compute-the-intersection-point-of-two-lines"""
        xdiff = (line1[0][0] - line1[1][0], line2[0][0] - line2[1][0])
        ydiff = (line1[0][1] - line1[1][1], line2[0][1] - line2[1][1])

        def det(a, b):
            return a[0] * b[1] - a[1] * b[0]

        div = det(xdiff, ydiff)
        if div == 0:
            return None

        d = (det(*line1), det(*line2))
        x = det(d, xdiff) / div
        y = det(d, ydiff) / div
        return x, y

    def check_wall_col(self, lvl0, wall=False, x=False, y=False):
        # If wall is set it will only check collisions with that specific wall, otherwise it checks all walls
        if x == False:
            x = self.xpos
        if y == False:
            y = self.ypos
        walls = []
        if wall:
            if self.rect_col([x, y, self.w, self.h],
                             [wall[0], wall[1], wall[2], wall[3]]):
                return True
            return False
        else:
            for wall in lvl0:
                if self.rect_col([x, y, self.w, self.h],
                                 [wall[0], wall[1], wall[2], wall[3]]):
                    walls.append(wall)
        if walls:
            return walls
        return False

    def check_player_col(self, world):
        collided_players = []
        for player in world.player_table:
            if player != self:
                if self.rect_col(
                    [self.xpos, self.ypos, self.w, self.h],
                    [player.xpos, player.ypos, player.w, player.h]):
                    collided_players.append(player)
        return collided_players

    def get_shot(self, damage):
        """Take some damage"""
        self.take_damage(damage)

    def take_damage(self, damage):
        self.health -= damage
        if self.health <= 0:
            self.dead = True
            self.health = 0
Пример #6
0
 def __init__(self, x, y):
     entity.Entity.__init__(self)
     self.class_id = 4
     self.netxpos = NetworkVar(self, x, 1)
     self.netypos = NetworkVar(self, y, 2)
     self.frames = 0
Пример #7
0
 def __init__(self):
     entity.CEntity.__init__(self)
     self.netxpos = NetworkVar(self, 0, 1, True)
     self.netypos = NetworkVar(self, 0, 2, True)