Skip to content

Latest commit

 

History

History
132 lines (97 loc) · 5.21 KB

README.md

File metadata and controls

132 lines (97 loc) · 5.21 KB

Tanks

My attempt to build modern tanks with old pygame.

Whatch demo:

Screnshots:

sc1 sc2

After dealing with pygame, I consider myself overqualified for Google Maps.

Challenges:

DANGER: A LOT OF MATHS INVOLVING COS, SIN ANG TRIGONOMETRY FORMULAS

Most of the time working on this game was spent outside the laptop, 
trying to remember trigonometry and geometry formulas from school
and correlating them to pygame coordinate system. 
(which made my brain hurt,
still does)


- rotaing: 
    - rotating in pygame is happening not about center, but relative to top 
    left corner of the rectangle the image is in. While the image is rotating,
    its rectangle is changing its size. To make it look like the image rotates about
    its center you have to change the coordinates of the top left corner of the
    image. 
    It's hard to read, it was even harder to code.
    It was probably the most challenging part of the project.

    - finding center of bottom image to put the tank top in

    - tring to change the relative center of tank top -- the point the top is 
    rotating about

    - finding exact spots where some of theimages should appear (like fire out 
    of the turret when the tank shoots)

    - shooting shells involved rotating too. Despite already having code that 
    handled this kind of stuff quite good, the amount of small bugs accumulated 
    by that time and some inattention made this task increadibly hard.
    It forced me to review my code a couple of hundred of times and do some major
    refactoring

    
- time:    
    - creating time in the game, so that images (like explisions) can render
    depending on that time

- collision:
    - finding the tank area depending on its corners and checking if the point
    lies inside that area. Pygame coordinate system made this task even harder.

Code snippets:

    def move_tank_bottom(self, list_of_objects):
        radians = self.bottom_angle * math.pi / 180
        add_x = math.cos(radians) * self.speed
        add_y = math.sin(radians) * self.speed

        new_bottom_angle = self.bottom_angle + self.turn_speed 
        new_x = self.x + add_x
        new_y = self.y - add_y

        if self.detect_collision(list_of_objects, self.find_corners(new_bottom_angle, new_x, new_y, self.width, self.height)):
            new_x = self.x + add_x/2 
            new_y = self.y - add_y/2
            new_bottom_angle = self.bottom_angle + self.turn_speed/2
        if not self.detect_collision(list_of_objects, self.find_corners(new_bottom_angle, self.x, self.y, self.width, self.height) ):
            self.bottom_angle = new_bottom_angle
        if not self.detect_collision(list_of_objects, self.find_corners(self.bottom_angle, new_x, self.y, self.width, self.height) ):
            self.x = new_x
        if not self.detect_collision(list_of_objects, self.find_corners(self.bottom_angle, self.x, new_y, self.width, self.height) ):
            self.y = new_y
            
            
    def point_within_my_area(self, point_coordinates, corners_list):
        #x1,y1###############x2,y2#
        #                         #
        #                         #
        #x4,y4###############x3,y3#

        ## straight (line) formula =>  ax + bx + c = 0  
        ##  or   (y1 -y2)x + (x2 - x1)y + (x1y2 - x2y1) = 0
        x = point_coordinates[0]
        y = point_coordinates[1]

        for i in range(len(corners_list)):
            x1 = corners_list[i][0]
            y1 = corners_list[i][1]

            next_i = (i + 1) % (len(corners_list))
            x2 = corners_list[next_i][0]
            y2 = corners_list[next_i][1]

            a = y1 - y2
            b = x2 - x1
            c = x1 * y2 - x2 * y1

            if a * x + b * y + c < 0:  ## checking if the point lies on the right side 
                return False           ## of every line, which would mean it's inside
        return True                    ## the area

    def detect_collision(self, list_of_objects, my_corners_list):
        for obj in list_of_objects:
            if obj != self:
                if self.it_within_my_area(obj, my_corners_list) or self.me_within_its_area(obj, my_corners_list ):
                    return True
        return False

All in all, even though there were probably thousands of libraries better suited for game developing at that point, I'm incredibly glad I encountered all of those challenges and were able to persevere.

Of course, I wouldn't be able to do this by myself, especially at the start, when this huge pile of problems seemed to be impossible to solve. For guidence and assistence, I'd like to thank all of my mentors and especially Jonathan Martin @nybblr.