Пример #1
0
    def generate_corner_coordinates(self):
        interval = 120  # The angles between each corner

        # Calculating the angles (since polar coordinates are used), for each corner:
        a = self.angle
        aa = self.angle - interval
        aaa = self.angle - 2 * interval

        # converting 3 polar coordinates to  cartesian:
        c=mt.cartesian(r=self.width/2,theta=a,tuple_new_origin=(self.x,self.y))
        cc=mt.cartesian(r=self.height/2,theta=aa,tuple_new_origin=(self.x,self.y))
        ccc=mt.cartesian(r=self.height/2,theta=aaa,tuple_new_origin=(self.x,self.y))

        return c,cc,ccc
Пример #2
0
    def generate_coordinates(self, given_radius, side_number):
        coordinates = []
        internal_angles = 360 / side_number

        for i in range(
                side_number):  #Generating a corner for each internal angle
            coordinates.append(
                mt.cartesian(given_radius,
                             internal_angles * i + self.inner_angle,
                             (self.x, self.y)))

        return coordinates
Пример #3
0
    def update_position(self, delta_time):
        """Updating the poisition of the asteroid"""
        vel, angle_change = self.get_relative_change(delta_time)

        self.inner_angle += angle_change
        self.inner_angle = self.inner_angle % 360

        self.x, self.y = mt.cartesian(vel, self.drift_angle, (self.x, self.y))
        self.coordinates = self.generate_coordinates(self.radius,
                                                     self.side_num)
        self.inner_coordinates = self.generate_coordinates(
            self.radius * (1 - self.border), self.side_num)
Пример #4
0
    def update_position(self,controls_array,pressed_keys,delta_time,screen_width,screen_height):

        """Updates the position of the plane. The controls array is an array specifying the controls"""
        velocity=self.get_velocity(delta_time=delta_time)#get the velocity in this frame
        angle_dif=self.get_angle_change(delta_time)

        #Making sure the momentum of the ship cannot get infinitely big:
        if self.momentum>velocity*1.2:
            self.momentum=velocity*1.2

        elif self.momentum>0.45: #we make sure that the momentum cannot go under 0.45 . If momentum falls under 0,
            # then the ship will start going backwards
            self.momentum-=0.001



        self.x, self.y = mt.cartesian(self.momentum*1.2, self.momentum_angle, (self.x, self.y))

        if pressed_keys[controls_array[0]]:
            self.angle-= angle_dif
            self.angle=self.angle%360 #we conver it to mod 360 so that the self.angle variable doesn't become
            # insanely big

        if pressed_keys[controls_array[1]]:
            self.angle += angle_dif
            self.angle=self.angle%360 #we conver it to mod 360 so that the self.angle variable doesn't become
            # insanely big

        if pressed_keys[controls_array[2]]and perf_counter()-self.last_hyper_space>=self.hyper_space_cooldown:
            #we go to hyperspace
            self.hyper_space(width=screen_width,height=screen_height)
            self.last_hyper_space=perf_counter() #reseting the hyperspace cooldown
        if pressed_keys[controls_array[3]] :
            self.x,self.y=mt.cartesian(velocity,self.angle,(self.x,self.y))
            self.momentum+=0.004
            self.momentum_angle=self.angle
Пример #5
0
    def __init__(self,
                 radius,
                 x=None,
                 y=None,
                 color=(255, 255, 255),
                 background_color=(0, 0, 0),
                 velocity_interval=(30, 40),
                 angle_change_per_second_interval=(20, 50),
                 border=0.1,
                 player_coordinate_tuple=(),
                 side_num=8):
        self.radius = radius

        #Generating random points if no specific location is given:0

        if x == None and y == None:
            #if not specified, then randomly generate:
            self.x, self.y = mt.cartesian(
                randint(self.radius * 6, self.radius * 20), uniform(0, 360))
        else:
            #if specified, then generate at the specified coordinate
            self.x = x
            self.y = y

        self.color = color
        self.background_color = background_color
        self.drift_angle = uniform(
            0, 360
        )  #the angle must be a decimal. When we generate mass amounts of
        # asteroids with integer angles, then it gives an articifial impression
        self.velocity = uniform(velocity_interval[0], velocity_interval[1])

        self.angle_change_per_second = uniform(
            angle_change_per_second_interval[0],
            angle_change_per_second_interval[1])
        self.side_num = side_num
        self.border = border
        #Initializing side_num amount of corners:
        self.inner_angle = 0
        self.coordinates = self.generate_coordinates(self.radius,
                                                     self.side_num)
Пример #6
0
    def draw(self, pygame, window, delta_time):
        pygame.draw.circle(window, self.color, (self.x, self.y),
                           self.r)  #this is the main bullet.

        #DRAWING THE BULLET TRAIL:

        trail_bullet_num = 4
        velocity = self.get_velocity(delta_time)
        new_color = self.color

        newx, newy = self.x, self.y

        for i in range(trail_bullet_num):
            new_color = (
                new_color[0] * 0.6,
                new_color[1] * 0.6,
                new_color[2] * 0.6,
            )  #creating a dimmer rgb color
            newx, newy = mt.cartesian(r=1.2 * velocity,
                                      theta=self.angle - 180,
                                      tuple_new_origin=(newx, newy))
            pygame.draw.circle(window, new_color, (newx, newy),
                               self.r)  # this is the main bullet.
Пример #7
0
 def update_position(self, delta_time):
     #convert everything to polar coordinates, with the bullet taken as the new origin. This way we can increase
     # the 'r' value without needing to do any calculations on what x and y will be.
     self.x, self.y = mt.cartesian(
         self.direction * self.get_velocity(delta_time), self.angle,
         (self.x, self.y))
Пример #8
0
def start_level(saucer_frequency, asteroid_num, alien_bullet_cooldown,
                big_side):
    global window, screen_size, width, height, score, player, bullet_color, bullet_cooldown

    bullets = []  # array of bullets to be stored
    asteroids = []  # array of asteroid objects in the game
    saucers = []  # array of ufo objects

    last_bullet_shot = perf_counter()  # when the last bullet was shot
    run = True

    death_animation_asteroids = [
    ]  # asteroids who have died, but still need to play their animation
    border_dic = {
        3: 0.19,
        4: 0.17,
        5: 0.14,
        6: 0.12,
        7: 0.1
    }  # dictionary of which side number gets how much border

    alien_bullets = []  # array of bullets shot by ufos

    # generating the initial round of asteroids:
    for i in range(asteroid_num):
        asteroids.append(
            asteroid(radius=30,
                     player_coordinate_tuple=(player.x, player.y),
                     side_num=big_side,
                     velocity_interval=(50, 100),
                     border=border_dic[5]))

    point_values = {big_side: 20, big_side - 1: 50, big_side - 2: 100}

    last_saucer = perf_counter()  # when the last saucer was generated

    while run and player.lives > 0 and len(asteroids) > 0:

        start = perf_counter()

        pygame.time.wait(10)

        update_text("Score: " + str(score) + " Lives: " + str(player.lives),
                    where=(140 + len(str(score)) * 10, 30))
        for event in pygame.event.get():
            if event.type == pygame.QUIT:

                pygame.quit()
                quit()
                break
            if event.type == pygame.VIDEORESIZE:
                height = pygame.display.get_window_size()
                width, height = height
                screen_size = (width, height)

        keys = pygame.key.get_pressed()
        #checking to see if spacebar is pressed, and the cooldown has passed
        if keys[pygame.
                K_x] and perf_counter() - last_bullet_shot >= bullet_cooldown:
            #initializing a bullet:

            #new coordinates generated so that the bullet matches the tip of the ship
            initx, inity = mt.cartesian(player.height, player.angle,
                                        (player.x, player.y))
            bullets.append(
                bullet(initx, inity, player.angle, 1, color=bullet_color))
            last_bullet_shot = perf_counter()

        #UPDATING AND DRAWING PLAYER:
        player.update_position(
            CONTROLS,  #specifying controls
            pygame.key.get_pressed(),  #which keys are pressed
            delta_time=perf_counter() -
            start,  # timing how much time has passed
            screen_width=width,
            screen_height=height)
        player.fix_out_of_screen(screen_width=width, screen_height=height)
        player.draw(pygame, window)
        pygame.display.update()
        window.fill(background_color)

        #UPDATING AND DRAWING ALIEN BULLETS:
        for bul in alien_bullets:
            #The problem with the player's  coordinates, is that the bullet is initialized at the back of the
            # ship. To fix  this, we convert everything to polar coordinates, and increase the radius to match the tip of the ship.

            if ct.separating_axis_theorem(player.generate_corner_coordinates(),
                                          [(bul.x - bul.r, bul.y - bul.r),
                                           (bul.x + bul.r, bul.y + bul.r),
                                           (bul.x - bul.r, bul.y + bul.r),
                                           (bul.x + bul.r, bul.y - bul.r)]):
                #they have collided
                player.lives -= 1
                player.x, player.y = width / 2, height / 2
                alien_bullets.pop(alien_bullets.index(bul))

            else:
                #they have not collided, keep going
                bul.update_position(delta_time=perf_counter() - start)
                bul.draw(pygame, window, perf_counter() - start)

                #Checking to see if the bullet is out of the frame:
                if bul.x + bul.r >= width or bul.x + bul.r <= 0:
                    alien_bullets.pop(alien_bullets.index(bul))
                elif bul.y + bul.r > height or bul.y + bul.r < 0:
                    alien_bullets.pop(alien_bullets.index(bul))

        #UPDATING AND DRAWING BULLETS:
        for b in bullets:
            #The problem with the player's  coordinates, is that the bullet is initialized at the back of the
            # ship. To fix  this, we convert everything to polar coordinates, and increase the radius to match the tip of the ship.
            b.update_position(delta_time=perf_counter() - start)
            b.draw(pygame, window, perf_counter() - start)

            #Checking to see if the bullet is out of the frame:
            if b.x + b.r >= width or b.x + b.r <= 0:
                bullets.pop(bullets.index(b))
            elif b.y + b.r > height or b.y + b.r < 0:
                bullets.pop(bullets.index(b))

        #UPDATING THE SAUCERS:
        if perf_counter(
        ) - last_saucer >= saucer_frequency:  #checking the ufo cooldown
            last_saucer = perf_counter()
            saucers.append(
                ufo(pygame, (player.x + (width / 3)) % width,
                    (player.y + (height / 3)) % height))
        for u in saucers:
            #checking to see if the ufo's bullet cooldown is down:
            if perf_counter() - u.last_bullet_shot >= alien_bullet_cooldown:
                u.last_bullet_shot = perf_counter()  #reset cooldown
                alien_bullets.append(
                    u.generate_alien_bullet((player.x, player.y)))

            hit = False
            for b in bullets:
                if ct.separating_axis_theorem(u.coordinates(),
                                              [(b.x - b.r, b.y - b.r),
                                               (b.x + b.r, b.y + b.r),
                                               (b.x - b.r, b.y + b.r),
                                               (b.x + b.r, b.y - b.r)]):

                    hit = True
                    hit_bul = b

                    break

            if hit:
                score += 200
                if score % player.given_extra * 10000 == 0:
                    #player.lives+=1
                    player.given_extra += 1
                saucers.pop(saucers.index(u))
                bullets.pop(bullets.index(hit_bul))
            else:
                if ct.separating_axis_theorem(
                        player.generate_corner_coordinates(), u.coordinates()):
                    player.lives -= 1
                    player.x, player.y = width / 2, height / 2

                u.update_position(perf_counter() - start)
                u.draw(pygame, window)
                if u.out_of_screen(screen_width=width, screen_height=height):
                    saucers.pop(saucers.index(u))

            # UPDATING AND DRAWING ASTEROIDS:
        for a in asteroids:
            # updated information:
            a.update_position(perf_counter() - start)
            a.draw(pygame, window)
            a.fix_out_of_screen(width, height)

            # checking to see if asteroid is hitting player:
            if ct.separating_axis_theorem(
                    a.coordinates, player.generate_corner_coordinates()):
                player.lives -= 1
                player.x, player.y = width / 2, height / 2

            for b in bullets:
                # Checking to see if any bullet has hit any asteroid:
                if ct.radius_collision(a.x, a.y, a.radius, b.x, b.y, b.r):

                    # BEFORE ANYTHING, WE GET RID OF THE BULLET. EACH BULLET CAN ONLY POP 1 ASTEROID
                    bullets.pop(bullets.index(b))
                    if a.side_num > big_side - 2:

                        # the asteroid splits into 2 child asteroids with 1 less side number, and slightly smaller radius
                        child_1 = asteroid(radius=a.radius * 0.9,
                                           x=a.x,
                                           y=a.y,
                                           side_num=a.side_num - 1)
                        child_2 = asteroid(radius=a.radius * 0.9,
                                           x=a.x,
                                           y=a.y,
                                           side_num=a.side_num - 1)

                        child_2.drift_angle = 180 + child_1.drift_angle  # They need to explode in different directions

                        child_1.velocity = a.velocity + 20  # Children explode faster then their parent
                        child_2.velocity = a.velocity + 20

                        child_1.border = border_dic[
                            child_1.
                            side_num]  # modifying their border according to their side number
                        child_2.border = border_dic[child_2.side_num]
                        asteroids.append(child_1)
                        asteroids.append(child_2)

                    else:
                        # this is the last piece, we have killed the entire asteroid:
                        pass
                    # death_animation_asteroids.append(a) #the asteroid will play it's death animation (which is a bunch of
                    # particles)
                    score += point_values[a.side_num]

                    asteroids.pop(asteroids.index(
                        a))  # if they are colliding, we destroy the asteroid

    window.fill(background_color)