Tank Game in Python with Source Code
Master Python with 70+ Hands-on Projects and Get Job-ready - Learn Python
Have you ever played a tank game? If not, do play this interesting game with the computer by building it on your own. So, let’s not wait and create Tank Game using Python.
What is a Tank Game?
A tank game is a video game where a player plays with the computer and tries to reduce the power by attacking the opponent’s tank by firing. Similarly, the computer tries to reduce the player’s power.
Tank Game in Python
We build this game using the Pygame module. In this, the player uses the keyboard button to control the game as follows:
- Right and left arrows to move the tank
- Up and down arrows to move the turret
- a and d keys to reduce and increase the power respectively
- Space to fire
Download Tank Game Code
Please download the source code for the tank game using the link: Tank Game Project
Project Prerequisites
The developers are expected to have prior knowledge of the Pygame module to build this project. You can also install this module using the below command.
pip install pygame
Steps to build Python Tank Game
We follow the below steps to build the tank game using Pygame:
1. First, we download modules
2. Then we write the code to initiate the pygame and create global variables
3. After this, we write functions to add information to screen
4. Next, we create the button class
5. Now we create the function to create the main window
6. And then the controls window
7. Now we create a function to create tank
8. Next, we create the function to create the explosion
9. Then we create a function to fire for both the players
10. We now create the functions for game over and pause conditions
11. Finally, we create the main window
1. Importing Python modules for Tank Game Project
First, we import the required modules. The pygame module is the main one that we use to build the game.
import pygame import time import random
2. Initiating pygame and global variables
Now, we initiate the pygame module, set dimensions, and add the caption. We also create some global variables to set other dimensions for tank, turret, and base ground.
pygame.init() width = 800 height = 600 gameWin = pygame.display.set_mode((width, height)) pygame.display.set_caption('DataFlair Tanks Game') clock = pygame.time.Clock() tankWidth = 40 tankHeight = 20 turretWidth = 5 wheelWidth = 5 groundHeight = 35
3. Function to show text on screen
This is a basic function we create to add any text on the screen of required properties at specified location. We create this to reduce the redundancy by using just a link to add text.
The function textObjects() creates the font object of the specified attributes. And we use the show_message() function to add the text object to the window at specified location.
def textObjects(text, color, size="small"): if size == "vsmall": font=pygame.font.SysFont("Calibre", 15) textSurf = font.render(text, True, color) if size == "small": font=pygame.font.SysFont("Calibre", 25) textSurf = font.render(text, True, color) if size == "medium": font=pygame.font.SysFont("Calibre", 35) textSurf = font.render(text, True, color) if size == "large": font=pygame.font.SysFont("Calibre", 50) textSurf = font.render(text, True, color) return textSurf, textSurf.get_rect() def show_message(msg, color, y_displace=0, size="small"): textSurf, textRect = textObjects(msg, color, size) textRect.center = (int(width / 2), int(height / 2) + y_displace) gameWin.blit(textSurf, textRect)
4. Creating button class
We create a Button class to name the buttons, place them on screen based on the position given. And then run the click() function to execute the respective function based on the ‘action’ property of that button clicked by using the action property.
class Button: """Create a button, then blit the surface in the while loop""" def __init__(self, text,pos, font, bg="blue"): self.x, self.y = pos self.font = pygame.font.SysFont("Arial", font) self.text=text self.text = self.font.render(self.text, 1, pygame.Color("blue")) self.change_text(bg) def change_text(self, bg="blue"): self.size = self.text.get_size() self.surface = pygame.Surface(self.size) self.surface.fill(bg) self.surface.blit(self.text, (0, 0)) self.rect = pygame.Rect(self.x, self.y, self.size[0], self.size[1]) def show(self): gameWin.blit(self.text , (self.x, self.y)) def click(self, event,action): x, y = pygame.mouse.get_pos() if event.type == pygame.MOUSEBUTTONDOWN: if pygame.mouse.get_pressed()[0]: if self.rect.collidepoint(x, y): if action == "quit": pygame.quit() quit() if action == "controls": controlsWin() if action == "play": mainGame() if action == "main": mainWindow()
5. Creating main window function
Here, we create the main window with welcoming text and three buttons:
a. ‘Play’ to start the game
b. ‘Controls’ to see the guidelines
c. ‘Quit’ to exit the game
We create three button objects for the above actions.
def mainWindow (): button1 = Button("Play", (350, 350), font=30) button2 = Button("Controls", (350, 430), font=30) button3 = Button("Quit", (350, 510), font=30) while True: gameWin.fill('#ffffff') Green = (0, 255, 0) show_message("DataFlair Tank Game", '#000000', -200, size="large") show_message("Welcome to the game!", 'red', -100, size="medium") show_message("Choose any of the following to move forward", 'red', -50, size="medium") for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() button1.click(event,'play') button2.click(event,'controls') button3.click(event,'quit') button1.show() button2.show() button3.show() clock.tick(30) pygame.display.update()
6. Creating controls window function
Using controlsWin() function, we create the controls window with welcoming text and three buttons:
d. ‘Play’ to start the game
e. ‘Main’ to go to to main window
f. ‘Quit’ to exit the game
We create three button objects for the above actions
def controlsWin(): button1 = Button("Play", (150, 500), font=30) button2 = Button("Main", (350, 500), font=30) button3 = Button("Quit", (550, 500), font=30) while True: gameWin.fill('#ffffff') Green = (0, 255, 0) show_message("DataFlair Tank Game", '#000000', -200, size="large") show_message("Here are the instructions to play:", 'red', -100, size="medium") show_message("The objective is to shoot and destroy the enemy tank before they destroy you.", Green, -30) show_message("Fire using the Spacebar", 'gray', 0) show_message("Move Turret using the Up and Down arrows", Green, 30) show_message("Move Tank using the Left and Right arrows", 'gray', 60) show_message("Press D to raise Power AND Press A to reduce Power ", Green, 90) show_message("Finally press P to pause", 'gray', 120) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() button1.click(event,'play') button2.click(event,'main') button3.click(event,'quit') button1.show() button2.show() button3.show() clock.tick(30) pygame.display.update()
7. Creating function for tank
This function creates a tank at a specified location. We use the circle() of pygame to add shape to the tank.
def tank(x, y, turPos,tank): #tank=1 if player's tank and -1 if computer's tank x = int(x) y = int(y) locs=[[27,2],[26,5],[25,8],[23,12],[20,14],[18,15],[15,17],[13,19],[11,21]] possibleTurrets=[] for i in locs: possibleTurrets.append((x-tank*i[0],y-i[1])) pygame.draw.circle(gameWin, '#000000', (x, y), int(tankHeight / 2)) for i in range(-15,16,5): pygame.draw.circle(gameWin,'#000000', (x+i, y + 20), wheelWidth) return possibleTurrets[turPos]
8. Creating function for explosion
This function connects the firing tank to the probable target location by drawing a curve with circles. This gives a clear picture of the shot made.
def explosion(x, y, size=50): explode = True while explode: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() startPoint = x, y colorChoices = ['red', 'brown2', 'yellow', 'gold1'] magnitude = 1 while magnitude < size: exploding_bit_x = x + random.randrange(-1 * magnitude, magnitude) exploding_bit_y = y + random.randrange(-1 * magnitude, magnitude) pygame.draw.circle(gameWin, colorChoices[random.randrange(0, 4)], (exploding_bit_x, exploding_bit_y), random.randrange(1, 5)) magnitude += 1 pygame.display.update() clock.tick(100) explode = False
9. Function to create the bar
Now, we create the bars of the player and the computer of the length and color based on the power left.
def show_health_bars(player_health, enemy_health): if player_health > 75: player_color = 'green' elif player_health > 50: player_color = 'yellow' else: player_color = 'red' if enemy_health > 75: enemy_color = 'green' elif enemy_health > 50: enemy_color = 'yellow' else: enemy_color = 'red' pygame.draw.rect(gameWin, player_color, (680, 25, player_health, 25)) pygame.draw.rect(gameWin, enemy_color, (20, 25, enemy_health, 25))
10. Creating a function to fire by player
This function runs when the player presses the spacebar indicating the fire action. In this function, we start from the position of the player. And then, we draw the trajectory based on the power set by the player and the angle of the turret.
Then we check the distance of the hit from the computer’s tank and calculate the reduction in the computer’s score. Finally, run the explosion() function to show the trajectory.
def fireShell(xy, tankx, tanky, turPos, gun_power, xlocation, barrier_width, randomHeight, enemyTankX, enemyTankY): #pygame.mixer.Sound.play(fire_sound) fire = True damage = 0 startingShell = list(xy) print("FIRE!", xy) while fire: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() # print(startingShell[0],startingShell[1]) pygame.draw.circle(gameWin, 'red', (startingShell[0], startingShell[1]), 5) startingShell[0] -= (12 - turPos) * 2 # y = x**2 startingShell[1] += int( (((startingShell[0] - xy[0]) * 0.015 / (gun_power / 50)) ** 2) - (turPos + turPos / (12 - turPos))) if startingShell[1] > height - groundHeight: print("Last shell:", startingShell[0], startingShell[1]) hit_x = int((startingShell[0] * height - groundHeight) / startingShell[1]) hit_y = int(height - groundHeight) print("Impact:", hit_x, hit_y) if enemyTankX + 10 > hit_x > enemyTankX - 10: print("Critical Hit!") damage = 25 elif enemyTankX + 15 > hit_x > enemyTankX - 15: print("Hard Hit!") damage = 18 elif enemyTankX + 25 > hit_x > enemyTankX - 25: print("Medium Hit") damage = 10 elif enemyTankX + 35 > hit_x > enemyTankX - 35: print("Light Hit") damage = 5 explosion(hit_x, hit_y) fire = False check_x_1 = startingShell[0] <= xlocation + barrier_width check_x_2 = startingShell[0] >= xlocation check_y_1 = startingShell[1] <= height check_y_2 = startingShell[1] >= height - randomHeight if check_x_1 and check_x_2 and check_y_1 and check_y_2: hit_x = int((startingShell[0])) hit_y = int(startingShell[1]) explosion(hit_x, hit_y) fire = False pygame.display.update() clock.tick(60) return damage
11. Creating a function to fire by computer
This function runs when it’s the computer’s chance to fire. In this, we set the power of the computer and then calculate the probable player’s tank location. And then repeat the same function as fireShell().
def compfireShell(xy, tankx, tanky, turPos, gun_power, xlocation, barrier_width, randomHeight, ptankx, ptanky): damage = 0 currentPower = 1 power_found = False while not power_found: currentPower += 1 if currentPower > 100 power_found = True fire = True startingShell = list(xy) while fire: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() startingShell[0] += (12 - turPos) * 2 startingShell[1] += int( (((startingShell[0] - xy[0]) * 0.015 / (currentPower / 50)) ** 2) - (turPos + turPos / (12 - turPos))) if startingShell[1] > height - height: hit_x = int((startingShell[0] * height - height) / startingShell[1]) hit_y = int(height - height) if ptankx + 15 > hit_x > ptankx - 15: print("target acquired!") power_found = True fire = False check_x_1 = startingShell[0] <= xlocation + barrier_width check_x_2 = startingShell[0] >= xlocation check_y_1 = startingShell[1] <= height check_y_2 = startingShell[1] >= height - randomHeight if check_x_1 and check_x_2 and check_y_1 and check_y_2: hit_x = int((startingShell[0])) hit_y = int(startingShell[1]) fire = False fire = True startingShell = list(xy) print("FIRE!", xy) while fire: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() pygame.draw.circle(gameWin, 'red', (startingShell[0], startingShell[1]), 5) startingShell[0] += (12 - turPos) * 2 gun_power = random.randrange(int(currentPower * 0.90), int(currentPower * 1.10)) startingShell[1] += int( (((startingShell[0] - xy[0]) * 0.015 / (gun_power / 50)) ** 2) - (turPos + turPos / (12 - turPos))) if startingShell[1] > height - groundHeight: print("last shell:", startingShell[0], startingShell[1]) hit_x = int((startingShell[0] * height - groundHeight) / startingShell[1]) hit_y = int(height - groundHeight) print("Impact:", hit_x, hit_y) if ptankx + 10 > hit_x > ptankx - 10: print("Critical Hit!") damage = 25 elif ptankx + 15 > hit_x > ptankx - 15: print("Hard Hit!") damage = 18 elif ptankx + 25 > hit_x > ptankx - 25: print("Medium Hit") damage = 10 elif ptankx + 35 > hit_x > ptankx - 35: print("Light Hit") damage = 5 explosion(hit_x, hit_y) fire = False check_x_1 = startingShell[0] <= xlocation + barrier_width check_x_2 = startingShell[0] >= xlocation check_y_1 = startingShell[1] <=height check_y_2 = startingShell[1] >= height - randomHeight if check_x_1 and check_x_2 and check_y_1 and check_y_2: print("Last shell:", startingShell[0], startingShell[1]) hit_x = int((startingShell[0])) hit_y = int(startingShell[1]) print("Impact:", hit_x, hit_y) explosion(hit_x, hit_y) fire = False pygame.display.update() clock.tick(60) return damage
12. Functions for game over and pause conditions
The game_over() function runs when one of the player’s scores is less than 0. We quit the game and show who is the winner. It also has three buttons to play again, show controls and quit.
And the pause() function pause the game and give a chance to either continue or quit the game. The keyboard button ‘c’ is used to continue and ‘q’ to quit.
def game_over(winner): button1 = Button("Play Again", (350, 350), font=30) button2 = Button("Controls", (350, 430), font=30) button3 = Button("Quit", (350, 510), font=30) while True: gameWin.fill('#ffffff') Green = (0, 255, 0) Red=(255,0,0) text='' color='' if(winner == 1): text="Congratulations, You Won!" color=Green else: text="Sorry, game over. Better luck next time!" color=Red show_message("DataFlair Tank Game", '#000000', -200, size="large") show_message(text, color, -100, size="medium") for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() button1.click(event,'play') button2.click(event,'controls') button3.click(event,'quit') button1.show() button2.show() button3.show() clock.tick(30) pygame.display.update() def pause(): paused = True show_message("Paused", 'white', -100, size="large") show_message("Press C to continue playing or Q to quit", 'wheat', 25) pygame.display.update() while paused: #gameDisplay.fill(black) for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() quit() if event.type == pygame.KEYDOWN: if event.key == pygame.K_c: paused = False elif event.key == pygame.K_q: pygame.quit() quit() clock.tick(5)
13. Function to create the main window
This is the main game window. In this function, we mainly check the button activity of the player. And do the respective activity based on the controls mentioned initially.
We continually update the window based on the changes made by continuous firing, reducing score, moving tanks, and checking conditions to end the game.
def mainGame(): gameExit = False gameOver = False player_health = 100 enemy_health = 100 barrier_width = 50 mainTankX = width * 0.9 mainTankY = height * 0.9 tankMove = 0 currentTurPos = 0 changeTur = 0 enemyTankX = width * 0.1 enemyTankY = height * 0.9 fire_power = 50 power_change = 0 xlocation = (width / 2) + random.randint(int(-0.1 * width),int( 0.1 * width)) randomHeight = random.randint(int(height * 0.1), int(height * 0.6)) while True: gameWin.fill('#ffffff') Green = (0, 255, 0) Red=(255,0,0) text='' color='' show_message("DataFlair Tank Game", '#000000', -200, size="large") for event in pygame.event.get(): if event.type == pygame.QUIT: gameExit = True if event.type == pygame.KEYDOWN: if event.key == pygame.K_LEFT: tankMove = -5 elif event.key == pygame.K_RIGHT: tankMove = 5 elif event.key == pygame.K_UP: changeTur = 1 elif event.key == pygame.K_DOWN: changeTur = -1 elif event.key == pygame.K_p: pause() elif event.key == pygame.K_SPACE: gameWin.fill('white') show_message("DataFlair Tank Game", '#000000', -200, size="large") show_health_bars(player_health, enemy_health) gun = tank(mainTankX, mainTankY, currentTurPos,1) enemy_gun = tank(enemyTankX, enemyTankY, 8,-1) fire_power += power_change font=pygame.font.SysFont("Calibre", 30) text = font.render("Power: " + str(fire_power) + "%", True, 'black') gameWin.blit(text, [width / 2, 0]) text = font.render("Height: " + str(currentTurPos) + "%", True, 'black') gameWin.blit(text, [width / 2, 20]) pygame.draw.rect(gameWin, 'green', [xlocation, height - randomHeight, barrier_width, randomHeight]) gameWin.fill('green', rect=[0,height - groundHeight, width, height]) pygame.display.update() clock.tick(30) damage = fireShell(gun, mainTankX, mainTankY, currentTurPos, fire_power, xlocation, barrier_width, randomHeight, enemyTankX, enemyTankY) enemy_health -= damage possibleMovement = ['f', 'r'] moveIndex = random.randrange(0, 2) for x in range(random.randrange(0, 10)): if width * 0.3 > enemyTankX > width * 0.03: if possibleMovement[moveIndex] == "f": enemyTankX += 5 elif possibleMovement[moveIndex] == "r": enemyTankX -= 5 gameWin.fill('white') show_message("DataFlair Tank Game", '#000000', -200, size="large") show_health_bars(player_health, enemy_health) gun = tank(mainTankX, mainTankY, currentTurPos,1) enemy_gun = tank(enemyTankX, enemyTankY, 8,-1) fire_power += power_change font=pygame.font.SysFont("Calibre", 30) text = font.render("Power: " + str(fire_power) + "%", True, 'black') gameWin.blit(text, [width / 2, 0]) text = font.render("Height: " + str(currentTurPos) + "%", True, 'black') gameWin.blit(text, [width / 2, 20]) pygame.draw.rect(gameWin, 'green', [xlocation, height - randomHeight, barrier_width, randomHeight]) gameWin.fill('green', rect=[0,height - groundHeight, width, height]) pygame.display.update() clock.tick(30) damage = compfireShell(enemy_gun, enemyTankX, enemyTankY, 8, 50, xlocation, barrier_width, randomHeight, mainTankX, mainTankY) player_health -= damage elif event.key == pygame.K_a: power_change = -1 elif event.key == pygame.K_d: power_change = 1 elif event.type == pygame.KEYUP: if event.key == pygame.K_LEFT or event.key == pygame.K_RIGHT: tankMove = 0 if event.key == pygame.K_UP or event.key == pygame.K_DOWN: changeTur = 0 if event.key == pygame.K_a or event.key == pygame.K_d: power_change = 0 mainTankX += tankMove currentTurPos += changeTur if currentTurPos > 8: currentTurPos = 8 elif currentTurPos < 0: currentTurPos = 0 if mainTankX - (tankWidth / 2) < xlocation + barrier_width: mainTankX += 5 show_health_bars(player_health, enemy_health) gun = tank(mainTankX, mainTankY, currentTurPos,1) enemy_gun = tank(enemyTankX, enemyTankY, 8,-1) fire_power += power_change if fire_power > 100: fire_power = 100 elif fire_power < 1: fire_power = 1 font=pygame.font.SysFont("Calibre", 30) text = font.render("Power: " + str(fire_power) + "%", True, 'black') gameWin.blit(text, [width / 2, 0]) text = font.render("Height: " + str(currentTurPos) + "%", True, 'black') gameWin.blit(text, [width / 2, 20]) pygame.draw.rect(gameWin, 'green', [xlocation, height - randomHeight, barrier_width, randomHeight]) gameWin.fill('green',rect=[0,height - groundHeight, width, height]) if player_health < 1 : game_over(0) elif enemy_health < 1: game_over(1) pygame.display.update() clock.tick(30) mainWindow()
 Python Tank Game Output
Summary
Hurray, we have built the tank game using Python! Hope you enjoyed building the game with us and also enjoy playing it.
Did you know we work 24x7 to provide you best tutorials
Please encourage us - write a review on Google