예제 #1
0
 def impulse(self, force, pos=None):
     #change in velo = impulse / mass
     if (pos is None):
         pos = self.pos
     self.velo += Vector2(force[0], force[1]) / self.mass
     #self.velo += force/self.mass; # think these r both V2s now?
     self.angularVelo += Vector2.cross(pos - self.pos, force) / self.momI
예제 #2
0
    def impulse(self, imp, pos=None):
        self.vel += imp / self.mass
        if pos is None:
            pos = self.pos
        else:
            self.avel += Vector2.cross(pos - self.pos, imp) / self.momi


# center of rotation = self.pos
# angular velocity = w = self.avel
# angle = theta = self.angle (radians)
# moment of inertia (angular mass) = I = self.momi
# torque T = self.torque = 0 (scalar)

# need to add rotational motion to the update function
# delta self.avel = t/self.momi * dt
# delta self.angle = self.avel * dt
# also clear the torque in clear_force()

# def world(self, local)
#   rotated = rotated_rad()
#   return self.pos + rotated
# def local(self, world)
#   return local_coordinate
# point = pos + offset.roated_rad(angle)
# def rotated_rad(angle)
#   rotated = Vector2(cosangle * offset.x - sinangle * offset.y, sinangle * offset.x + cosangle * offset.y)
#   return rotated
예제 #3
0
 def addForce(self, force, pos=None):
     self.force += force
     if (pos is None):
         pos = self.pos
     self.torque = Vector2.cross(
         pos - self.pos, force
     )  # r = displacement to obj, and f = where force is being applied
예제 #4
0
    def __init__(self,
                 density=1,
                 localOffsets=[],
                 pos=[0, 0],
                 value=1,
                 **kwargs):
        self.value = value
        # for loop to set localOffsets
        #print("implement whatever logic is happening ")
        #calculate mass Triange, Inertia Triangle, massT times CenterMass Triangle
        #calculate M * I * R
        #adjust center and I

        #mass  = density * area of Triangle
        #break all of our local offsets down into sub triangles?????
        #localOffsets=[[0,0], [100, 0], [100,20], [0,20]]
        # point1= offset[i] , point2= offset[i+1] , point Center = pos.center? even tho its not passed in
        totalMass = 0
        totalMomi = 0
        SumCenterMass = pygame.Vector2(0)
        for i in range(len(localOffsets)):
            #points are actually sides becuz local origin is zero zero
            point1 = Vector2(
                localOffsets[i - 1]
            )  # PYTHON WILL GRAB THE LAST INDEX CUZ ITS WEIRD, so this is desired
            point2 = Vector2(localOffsets[i])
            triangleMass = (density * (0.5 * Vector2.cross(point2, point1)))
            totalMass += triangleMass
            triangleMomi = (triangleMass / 6) * (
                point1.magnitude_squared() + point2.magnitude_squared() +
                pygame.Vector2.dot(point1, point2))
            totalMomi += triangleMomi
            triangleCenterMass = (1 / 3) * (point1 + point2)
            SumCenterMass += triangleCenterMass * triangleMass

        centerOfMassActual = SumCenterMass / totalMass

        newOffsets = []
        for offset in localOffsets:
            newOffsets.append(offset - centerOfMassActual)
            #print(f"newOffset: {offset - centerOfMassActual}")

        newPos = pos + centerOfMassActual
        momiCentered = totalMomi - totalMass * centerOfMassActual.magnitude_squared(
        )

        #print(f"TotalMass= {totalMass} , centerOfMassActual= {centerOfMassActual} , momiCentered={momiCentered}")

        super().__init__(mass=totalMass,
                         momentInertia=momiCentered,
                         pos=newPos,
                         localOffsets=newOffsets,
                         **kwargs)
예제 #5
0
    def __init__(self, density=1, pos=[0, 0], offsets=[], **kwargs):

        sides = []
        for o in offsets:
            sides.append(Vector2(o))

        polygon_mass_of_center_of_mass = Vector2(0)
        total_polygon_mass = 0
        total_polygon_momi = 0

        for i in range(len(sides)):
            triangle_area = (Vector2.cross(sides[i], sides[i - 1])) / 2
            triangle_mass = density * triangle_area
            total_polygon_mass += triangle_mass

            triangle_momi = triangle_mass / 6 * (
                sides[i - 1].magnitude()**2 + sides[i].magnitude()**2 +
                Vector2.dot(sides[i - 1], sides[i]))
            total_polygon_momi += triangle_momi

            triangle_mass_of_center_of_mass = triangle_mass * (1 / 3) * (
                sides[i - 1] + sides[i])
            polygon_mass_of_center_of_mass += triangle_mass_of_center_of_mass
        polygon_center_of_mass = polygon_mass_of_center_of_mass / total_polygon_mass

        # move origin to center of mass
        new_offsets = []
        for o in offsets:
            new_offsets.append(o - polygon_center_of_mass)

        new_pos = pos + polygon_center_of_mass

        momi_center_of_mass = total_polygon_momi - (
            total_polygon_mass * polygon_center_of_mass.magnitude()**2)

        # call superclass constructor
        super().__init__(mass=total_polygon_mass,
                         momi=momi_center_of_mass,
                         pos=new_pos,
                         offsets=new_offsets,
                         **kwargs)
예제 #6
0
 def add_force(self, force, pos=None):
     self.force += force
     if pos is None:
         pos = self.pos
     else:
         self.torque += Vector2.cross(pos - self.pos, force)
예제 #7
0
class Head(object):
    def __init__(self, index, name="player", is_AI=False, Score=0):
        # basic data
        self.name = name
        self.index = index
        self.is_AI = is_AI
        self.color = viewconst.playerColor[index]
        screen_mid = Vec(viewconst.ScreenSize[1] / 2,
                         viewconst.ScreenSize[1] / 2)

        #up down left right
        self.pos = screen_mid + modelconst.init_r * modelconst.Vec_dir[
            self.index]
        self.theta = index * (pi / 2)
        self.direction = Vec(cos(self.theta), -sin(self.theta))

        #information
        self.speed = modelconst.normal_speed
        self.is_dash = False
        self.dash_timer = 0
        self.dash_cool = 0
        self.radius = modelconst.head_radius
        self.is_alive = True
        self.score = Score
        self.body_list = [self]
        self.is_ingrav = False
        self.is_circling = True
        self.circling_radius = modelconst.init_r
        self.ori = 1
        self.init_timer = 200
        self.have_multibullet = False
        self.have_bigbullet = False
        self.always_multibullet = False
        self.always_bigbullet = False
        #if in grav
        self.grav_center = Vec(0, 0)
        self.pos_log = [Vec(self.pos)]

        self.is_rainbow = False

    def update(self, player_list, wb_list, bullet_list, item_list, score_list,
               tmp_score_list):
        if not self.is_alive:
            return 0

        self.pos += self.direction * self.speed

        if self.is_circling:
            self.theta += self.speed / self.circling_radius * self.ori
            #print(self.theta, self.speed/self.circling_radius)
            self.direction = Vec(cos(self.theta), -sin(self.theta))
        if self.init_timer != -1:
            self.init_timer -= 1
        if self.init_timer > 0:
            return 0
        elif self.init_timer == 0:
            self.is_circling = False
            self.init_timer = -1

        #update pos log
        self.pos_log.append(Vec(self.pos))
        if len(self.pos_log) > modelconst.pos_log_max:
            self.pos_log.pop(0)

        #is in circle
        self.is_ingrav = False
        for i in modelconst.grav:
            if (self.pos - i[0]).length_squared() < i[1]**2:
                self.is_ingrav = True
                self.grav_center = i[0]

        #collision with wall
        if (self.direction.x > 0 and self.pos.x + self.radius > viewconst.ScreenSize[1]-modelconst.eps) \
            or (self.direction.x < 0 and self.pos.x - self.radius < 0 - modelconst.eps) :
            self.direction.x *= -1
        if (self.direction.y > 0 and self.pos.y + self.radius > viewconst.ScreenSize[1]-modelconst.eps) \
            or (self.direction.y < 0 and self.pos.y - self.radius < 0 - modelconst.eps) :
            self.direction.y *= -1

        #collision with white ball
        for i in range(len(wb_list) - 1, -1, -1):
            wb = wb_list[i]
            if wb.following:
                continue
            if (self.pos - wb.pos).length_squared() < (self.radius +
                                                       wb.radius)**2:

                wb_list.append(White_Ball(Vec(wb.pos), True, self.index))
                wb_list.pop(i)

        #collision with competitor's body and bullet
        tmp = False
        if not self.is_dash:
            for enemy in player_list:
                if enemy.index == self.index:
                    continue
                for j in enemy.body_list[1:]:
                    if (self.pos - j.pos).length_squared() < (self.radius +
                                                              j.radius)**2:
                        #self die
                        killer = enemy.index
                        self.is_alive = False
                        tmp = True
                        self.add_score(player_list, score_list, tmp_score_list)
                        break
                else:
                    continue
                break
            for bullet in bullet_list:
                if (bullet.index != self.index) and \
                   (self.pos - bullet.pos).length_squared() < (self.radius + bullet.radius)**2 :
                    killer = bullet.index
                    self.is_alive = False
                    if tmp == False:
                        self.add_score(player_list, score_list, tmp_score_list)
                    break
        ##player die
        if not self.is_alive:
            self.is_dash = True
            while len(self.body_list) > 1:
                if killer != -1 and player_list[killer].is_alive:
                    wb_list.append(
                        White_Ball(Vec(self.body_list[-1].pos), True, killer))
                    #player_list[killer].body_list.append(Body(player_list[killer].body_list[-1]))
                self.body_list.pop(-1)

            return 1
        #collision with competitor's head
        if not self.is_dash:
            for enemy in player_list:
                if enemy.index == self.index or enemy.is_dash == True:
                    continue
                if (self.pos - enemy.pos).length_squared() < (self.radius +
                                                              enemy.radius)**2:
                    rrel = enemy.pos - self.pos
                    if (self.direction - enemy.direction).dot(rrel) > 0:
                        self.direction.reflect_ip(rrel)
                        enemy.direction.reflect_ip(rrel)
                        self.is_circling = False
                        enemy.is_circling = False

        #collision with item
        cnt = 0
        for i in player_list:
            if i.is_alive:
                cnt += 1
        if cnt != 1:
            for i in range(len(item_list) - 1, -1, -1):
                item = item_list[i]
                if (self.pos - item.pos).length_squared() < (self.radius +
                                                             item.radius)**2:
                    item.trigger(self.index, player_list, wb_list)
                    item_list.pop(i)
        #dash timer
        if self.is_dash:
            self.dash_timer -= 1
            if self.dash_timer == 0:
                self.is_dash = False
                #self.speed = modelconst.normal_speed
        # dash cool
        if self.dash_cool > 0:
            self.dash_cool -= 1
        #update theta
        #self.theta = atan2(self.direction.x, -self.direction.y)
        for j in range(1, len(self.body_list)):
            self.body_list[j].update()

        if self.is_rainbow:
            self.rainbow_mode()
        return 0

    def click(self, bullet_list, wb_list):
        if not self.is_alive:
            return
        if self.init_timer != -1:
            return
        if not self.is_dash:
            if self.is_circling or self.is_ingrav:
                self.is_circling = (not self.is_circling)
                if self.is_circling:
                    self.circling_radius = (self.pos -
                                            self.grav_center).length()
                    ori = self.direction.cross(self.pos - self.grav_center)
                    if ori > 0:  #counterclockwise
                        self.theta = atan2(
                            self.pos.y - self.grav_center.y,
                            -self.pos.x + self.grav_center.x) - pi / 2
                        self.direction = Vec(cos(self.theta), -sin(self.theta))
                        self.ori = 1
                    else:
                        self.theta = atan2(
                            self.pos.y - self.grav_center.y,
                            -self.pos.x + self.grav_center.x) + pi / 2
                        self.direction = Vec(cos(self.theta), -sin(self.theta))
                        self.ori = -1
                else:
                    self.circling_radius = 0

            elif self.dash_cool == 0:
                self.is_dash = True
                self.dash_timer = modelconst.max_dash_time * modelconst.dash_speed_multiplier
                self.dash_cool = self.dash_timer + modelconst.dash_cool
                #self.speed = modelconst.dash_speed
                if len(self.body_list) > 1:
                    self.body_list.pop(-1)
                    if self.always_multibullet or self.have_multibullet:
                        bullet_list.append(
                            Bullet(self.pos, self.direction, self.index))
                        bullet_list.append(
                            Bullet(self.pos, self.direction.rotate(30),
                                   self.index))
                        bullet_list.append(
                            Bullet(self.pos, self.direction.rotate(-30),
                                   self.index))
                        self.have_multibullet = False
                    elif self.always_bigbullet or self.have_bigbullet:
                        bullet_list.append(
                            Bullet(self.pos, self.direction, self.index,
                                   modelconst.bigbullet_r))
                        self.have_bigbullet = False
                    else:
                        bullet_list.append(
                            Bullet(self.pos, self.direction, self.index))

    def add_score(self, player_list, score_list, tmp_score_list):
        for enemy in player_list:
            if enemy.index == self.index:
                continue
            else:
                if enemy.is_alive:
                    score_list[enemy.index] += 1
                    tmp_score_list[enemy.index] += 1

    def blast(self, bullet_list):
        for i in range(len(self.body_list) - 1, 0, -1):
            cb = self.body_list[i]
            rndtheta = random.random() * 2 * pi
            bullet_list.append(
                Bullet(cb.pos, Vec(cos(rndtheta), sin(rndtheta)), self.index,
                       2 * modelconst.bullet_radius))
            self.body_list.pop()

    def rainbow_mode(self):
        for ii in range(len(self.body_list) - 1, 0, -1):
            i = self.body_list[ii]
            if i.color == i.pre.color:
                i.color = (random.randint(0, 255), random.randint(0, 255),
                           random.randint(0, 255))