Building Space Invaders Using PyGame - Python - GeeksforGeeks

01 Apr, 2022
In this article, we’re going to build space invaders using PyGame in Python. 
The used file can be downloaded from here.
Import the required module.
Initialize the pygame.
Create three functions:isCollision(): Which tells us whether the collision has occurred or not?game_over(): Which returns True or False on the basis of which the code decided if the game has ended.show_score(x, y): This shows the score on the screen
isCollision(): Which tells us whether the collision has occurred or not?
game_over(): Which returns True or False on the basis of which the code decided if the game has ended.
show_score(x, y): This shows the score on the screen
Create an infinite loop to execute the code continuously.
It’s very simple actually. Before explaining this, we want you to take a look at the collision portion of the code inside the game loop first below:
Python3
# Collisioncollision = isCollision(bullet_X, invader_X[i], bullet_Y, invader_Y[i])if collision:        score_val += 1        bullet_Y = 600        bullet_state = "rest"        invader_X[i] = random.randint(64, 736)        invader_Y[i] = random.randint(30, 200)        invader_Xchange[i] *= -1
The value returned by the “isCollision()” function is being stored inside the “collision” variable. The value returned by the function is either True or False based on the criteria set for collision inside the function. Let’s take a look at what is inside the isCollision() function:
Python3
def isCollision(x1, x2, y1, y2):    distance = math.sqrt((math.pow(x1 - x2, 2)) + (math.pow(y1 - y2, 2)))    if distance <= 50:        return True    else:        return False
The criteria for collision set inside the function is the simplest thing as the distance between the bullet and the invader (our enemy). As you can see the formula used for calculating distance is something that every student study in their high school mathematics class. It’s the formula of the distance between two points having coordinates (x1, y1) and (x2, y2) which are being passed as parameters of the isCollision() function. 
Here, we have set the criteria that if the value of the distance is less than or equal to 50, then it means collision has occurred. The value is chosen on the basis of the height and width of the png image used for the bullet and the invader. The value can be tweaked as per your own requirements by using the trial and error method. 
So, whenever the position of the bullet and the invader changes then the isCollision() function checks if a collision has occurred or not. That is the reason why it is being called inside the game loop. 
Which returns True or False on the basis of which the code decided if the game has ended. For understanding the game_over() function, let’s take a look at the below snippet of code which is present inside the game loop:
Python3
# movement of the invaderfor i in range(no_of_invaders):         if invader_Y[i] >= 450:            if abs(player_X-invader_X[i]) < 80:                for j in range(no_of_invaders):                    invader_Y[j] = 2000                    explosion_sound = mixer.Sound('data/explosion.wav')                    explosion_sound.play()                game_over()                break
Before getting into the explanation of code, it is recommended to know about the coordinate system followed in pygame. Take a look at the image below:
So, the criteria for game over is also collision. When the y-coordinate of the invader is greater than the spaceship i.e., 450 (y-coordinate of the spaceship), and the distance between the invader and the spaceship is less than 80 then a collision occurs and the game_over() function is called followed by the explosion sound. 
The following lines will make it more clear:
Python3
# y-coordinate of invader more than 450if invader_Y[i] >= 450:           # distance between the x-coordinate of invader        # and spaceship        if abs(player_X-invader_X[i]) < 80:            #....... rest code .....#
The above is checked for all the invaders present in the game which is ensured by a for-loop at the starting.
It shows the score on the screen.
Python3
def show_score(x, y):    score = font.render("Points: " + str(score_val),                        True, (255, 255, 255))    screen.blit(score, (x, y))
The only thing show_score() function is doing is showing the score on the screen in a proper font selected by the user.  
Every time a collision between the bullet and the invaders is happening a variable “score_val” is being incremented. This variable is then being displayed on the screen by the show_score() function as can be seen in the above code snippet.  
Python3
import pygameimport randomimport mathfrom pygame import mixer # initializing pygamepygame.init() # creating screenscreen_width = 800screen_height = 600screen = pygame.display.set_mode((screen_width,                                  screen_height)) # caption and iconpygame.display.set_caption("Welcome to Space\Invaders Game by:- styles")  # Scorescore_val = 0scoreX = 5scoreY = 5font = pygame.font.Font('freesansbold.ttf', 20) # Game Overgame_over_font = pygame.font.Font('freesansbold.ttf', 64)  def show_score(x, y):    score = font.render("Points: " + str(score_val),                        True, (255,255,255))    screen.blit(score, (x , y )) def game_over():    game_over_text = game_over_font.render("GAME OVER",                                           True, (255,255,255))    screen.blit(game_over_text, (190, 250)) # Background Soundmixer.music.load('data/background.wav')mixer.music.play(-1) # playerplayerImage = pygame.image.load('data/spaceship.png')player_X = 370player_Y = 523player_Xchange = 0 # InvaderinvaderImage = []invader_X = []invader_Y = []invader_Xchange = []invader_Ychange = []no_of_invaders = 8 for num in range(no_of_invaders):    invaderImage.append(pygame.image.load('data/alien.png'))    invader_X.append(random.randint(64, 737))    invader_Y.append(random.randint(30, 180))    invader_Xchange.append(1.2)    invader_Ychange.append(50) # Bullet# rest - bullet is not moving# fire - bullet is movingbulletImage = pygame.image.load('data/bullet.png')bullet_X = 0bullet_Y = 500bullet_Xchange = 0bullet_Ychange = 3bullet_state = "rest" # Collision Conceptdef isCollision(x1, x2, y1, y2):    distance = math.sqrt((math.pow(x1 - x2,2)) +                         (math.pow(y1 - y2,2)))    if distance <= 50:        return True    else:        return False def player(x, y):    screen.blit(playerImage, (x - 16, y + 10)) def invader(x, y, i):    screen.blit(invaderImage[i], (x, y)) def bullet(x, y):    global bullet_state    screen.blit(bulletImage, (x, y))    bullet_state = "fire" # game looprunning = Truewhile running:     # RGB    screen.fill((0, 0, 0))    for event in pygame.event.get():        if event.type == pygame.QUIT:            running = False         # Controlling the player movement        # from the arrow keys        if event.type == pygame.KEYDOWN:            if event.key == pygame.K_LEFT:                player_Xchange = -1.7            if event.key == pygame.K_RIGHT:                player_Xchange = 1.7            if event.key == pygame.K_SPACE:                               # Fixing the change of direction of bullet                if bullet_state is "rest":                    bullet_X = player_X                    bullet(bullet_X, bullet_Y)                    bullet_sound = mixer.Sound('data/bullet.wav')                    bullet_sound.play()        if event.type == pygame.KEYUP:            player_Xchange = 0     # adding the change in the player position    player_X += player_Xchange    for i in range(no_of_invaders):        invader_X[i] += invader_Xchange[i]     # bullet movement    if bullet_Y <= 0:        bullet_Y = 600        bullet_state = "rest"    if bullet_state is "fire":        bullet(bullet_X, bullet_Y)        bullet_Y -= bullet_Ychange     # movement of the invader    for i in range(no_of_invaders):                 if invader_Y[i] >= 450:            if abs(player_X-invader_X[i]) < 80:                for j in range(no_of_invaders):                    invader_Y[j] = 2000                    explosion_sound = mixer.Sound('data/explosion.wav')                    explosion_sound.play()                game_over()                break         if invader_X[i] >= 735 or invader_X[i] <= 0:            invader_Xchange[i] *= -1            invader_Y[i] += invader_Ychange[i]        # Collision        collision = isCollision(bullet_X, invader_X[i],                                bullet_Y, invader_Y[i])        if collision:            score_val += 1            bullet_Y = 600            bullet_state = "rest"            invader_X[i] = random.randint(64, 736)            invader_Y[i] = random.randint(30, 200)            invader_Xchange[i] *= -1         invader(invader_X[i], invader_Y[i], i)      # restricting the spaceship so that    # it doesn't go out of screen    if player_X <= 16:        player_X = 16;    elif player_X >= 750:        player_X = 750      player(player_X, player_Y)    show_score(scoreX, scoreY)    pygame.display.update()
Output:
sagartomar9927
Python-projects
Python-PyGame
Python
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
How to Install PIP on Windows ?
How to drop one or multiple columns in Pandas Dataframe
How To Convert Python Dictionary To JSON?
Check if element exists in list in Python
Python | Pandas dataframe.groupby()
Defaultdict in Python
Python | Get unique values from a list
Python Classes and Objects
Python | os.path.join() method
Create a directory in Python