# Building Space Invaders Using PyGame – Python

• Last Updated : 22 Nov, 2021

## Approach:

• 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
• Create an infinite loop to execute the code continuously.

## isCollision():

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

 `# 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`

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.

## game_over():

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 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`

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 450``if` `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.

## show_score(x, y):

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` `pygame``import` `random``import` `math``from` `pygame ``import` `mixer`` ` `# initializing pygame``pygame.init()`` ` `# creating screen``screen_width ``=` `800``screen_height ``=` `600``screen ``=` `pygame.display.set_mode((screen_width,``                                  ``screen_height))`` ` `# caption and icon``pygame.display.set_caption("Welcome to Space\``Invaders Game by:``-` `styles")`` ` ` ` `# Score``score_val ``=` `0``scoreX ``=` `5``scoreY ``=` `5``font ``=` `pygame.font.Font(``'freesansbold.ttf'``, ``20``)`` ` `# Game Over``game_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 Sound``mixer.music.load(``'data/background.wav'``)``mixer.music.play(``-``1``)`` ` `# player``playerImage ``=` `pygame.image.load(``'data/spaceship.png'``)``player_X ``=` `370``player_Y ``=` `523``player_Xchange ``=` `0`` ` `# Invader``invaderImage ``=` `[]``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 moving``bulletImage ``=` `pygame.image.load(``'data/bullet.png'``)``bullet_X ``=` `0``bullet_Y ``=` `500``bullet_Xchange ``=` `0``bullet_Ychange ``=` `3``bullet_state ``=` `"rest"`` ` `# Collision Concept``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`` ` `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 loop``running ``=` `True``while` `running:`` ` `    ``# RGB``    ``screen.fill((``0``, ``0``, ``0``))``    ``for` `event ``in` `pygame.event.get():``        ``if` `event.``type` `=``=` `pygame.QUIT:``            ``running ``=` `False`` ` `        ``# Controling 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:

My Personal Notes arrow_drop_up