Table of Contents
About the project
In this project, let’s create a Python application that can be used to test and increase your own typing speed. For the graphical interface we will use the library pygame, which is designed for this purpose. Also draw an image which will be shown on the screen.
Requirements
For work on the project basic knowledge of programming in Python and pygame library is required. Use the following command in the terminal to install the library.
pip install pygame
Steps to create a project
Use this link to download the entire source code of the project: typing-speed-game.rar First, let’s understand the file structure of the project:
- background.jpg – the background image for the program
- icon.jpg – icon for the reset button
- sentences.txt – text file with the list of sentences
- speed_typing.py – file with all the code
- typing-speed-open.png – an icon to display when you start the game
Let’s create a file sentences.txt, in which we will add a sentence on each line. We will use the principles of object-oriented programming to create the project.
Importing Libraries
For this project, we will use the pygame library. It must be imported along with other built-in Python modules like time
and random
.
import pygame
from pygame.locals import *
import sys
import time
import random
Create a game class
Next we create a game class that contains functions for starting, resetting and a few other calculating functions. Create a constructor of the class, which will define all variables of the project.
class Game:
def __init__(self):
self.w=750
self.h=500
self.reset=True
self. active=False
self.input_text=''
self. word= ''
self.time_start = 0
self.total_time = 0
self.accuracy = '0%'
self.results = 'Time:0 Accuracy:0 % Wpm:0 '
self.wpm = 0
self.end = False
self.HEAD_C = (255,213,102)
self.TEXT_C = (240,240,240)
self.RESULT_C = (255,70,70)
pygame.init()
self.open_img = pygame.image.load('type-speed-open.png')
self.open_img = pygame.transform.scale(self.open_img, (self.w,self.h))
self.bg = pygame.image.load('background.jpg')
self.bg = pygame.transform.scale(self.bg, (500,750))
self.screen = pygame.display.set_mode((self.w,self.h))
pygame.display.set_caption('Type Speed test')
In this constructor, we initialize the width and height of the window, as well as the variables we need for calculations. Finally, we’ll initialize pygame itself and load the images. The most important thing is the screen variable where the interface will be displayed.
The draw_text() method
The draw_text()
method is an auxiliary function for the Game
class that displays text on the screen. It takes as its argument the screen, the message to be displayed, the y-coordinate
of the screen where the text should be drawn, and the size and color of the font. In this case, everything should appear centered. After the pygame is drawn, you need to refresh the screen.
def draw_text(self, screen, msg, y ,fsize, color):
font = pygame.font.Font(None, fsize)
text = font.render(msg, 1,color)
text_rect = text.get_rect(center=(self.w/2, y))
screen.blit(text, text_rect)
pygame.display.update()
Get_sentence() method
The sentences.txt file stores a list of sentences. The get_sentence()
method will open it and return a random sentence from the list. An entire line will be broken up with a newline character.
def get_sentence(self):
f = open('sentences.txt').read()
sentences = f.split('n')
sentence = random.choice(sentences)
return sentence
The show_results() method
show_results()
method calculates the typing speed. The timer starts when the user presses the input field and stops when the user presses Enter. Then the difference is calculated and the time in seconds is determined.Math is used to calculate accuracy. The correctly entered characters are counted by comparing the entered text to the one you should have entered. The formula is as follows: (correct characters) x 100 / (total characters in the sentence) WPM (words per minute) is the number of words per minute. A typical word consists of approximately 5 characters, so we calculate the index by dividing the total number of words by 5. The result is then divided by the total time it took to type. Since the total time is in seconds, it must first be converted to minutes by dividing by 60. Finally, at the bottom there is an icon that acts as a reset button. When the user presses this, the game is reset. The reset_game()
method will be discussed next.
def show_results(self, screen):
if(not self.end):
# Time calculation
self.total_time = time.time() - self.time_start
# Calculation of accuracy
count = 0
for i,c in enumerate(self.word):
try:
if self.input_text[i] == c:
count += 1
except:
pass
self.accuracy = count/len(self.word)*100
# Calculating the number of words per minute
self.wpm = len(self.input_text)*60/(5*self.total_time)
self.end = True
print(self.total_time)
self.results = ' Time:'+str(round(self.total_time)) +" secs Accuracy: "+ str(round(self.accuracy)) + "%" + ' Wpm: ' + str(round(self.wpm))
# Loading the icon
self.time_img = pygame.image.load('icon.png')
self.time_img = pygame.transform.scale(self.time_img, (150,150))
# screen.blit(self.time_img, (80,320))
screen.blit(self.time_img, (self.w/2-75,self.h-140))
self.draw_text(screen,"Reset", self.h - 70, 26, (100,100,100))
print(self.results)
pygame.display.update()
Method run()
This is the main method of the class, responsible for handling all events. The reset_game()
method is called at the beginning of the method, which resets all variables. Then an infinite loop is executed, which captures all mouse and keyboard events. After that, the header and input field are drawn on the screen. Another loop waits for mouse and keyboard events. When the mouse button is pressed, its position is checked. If it is over the input field, the timer is started and the active
variable becomes True
. If over the reset button, the game is reset. When active
is True
and typing is not complete, keyboard events are expected. If the user presses any key, the input field message must be updated. The Enter key completes typing and then calculations occur. Another event is for the Backspace key, which removes the last character of the entered text.
def run(self):
self.reset_game()
self.running=True
while(self.running:)
clock = pygame.time.Clock()
self.screen.fill((0,0,0), (50,250,650,50))
pygame.draw.draw(self.screen,self.HEAD_C, (50,250,650,50), 2)
# Update the text in the user input
self.draw_text(self.screen, self.input_text, 274, 26,(250,250,250))
pygame.display.update()
for event in pygame.event.get():
if event.type == QUIT:
self.running = False
sys.exit()
elif event.type == pygame.MOUSEBUTTONUP:
x,y = pygame.mouse.get_pos()
# input box position
if(x>=50 and x<=650 and y>=250 and y<=300):
self.active = True
self.input_text = ''
self.time_start = time.time()
# Reset button location
if(x>=310 and x<=510 and y>=390 and self.end):
self.reset_game()
x,y = pygame.mouse.get_pos()
elif event.type == pygame.KEYDOWN:
if self.active and not self.end:
if event.key == pygame.K_RETURN:
print(self.input_text)
self.show_results(self.screen)
print(self.results)
self.draw_text(self.screen, self.results,350, 28, self.RESULT_C)
self.end = True
elif event.key == pygame.K_BACKSPACE:
self.input_text = self.input_text[:-1]
else:
try:
self.input_text += event.unicode
except:
pass
pygame.display.update()
clock.tick(60)
Reset_game() method
The reset_game()
method resets all variables, so you can check the typing speed again. Once again, a random sentence is selected using the get_sentence()
method. At the end, the class definition is closed. We create an object of the Game
class and run the program.
def reset_game(self):
self.screen.blit(self.open_img, (0,0))
pygame.display.update()
time.sleep(1)
self.reset=False
self.end = False
self.input_text=''
self. word= ''
self.time_start = 0
self.total_time = 0
self.wpm = 0
# get a random sentence
self.word = self.get_sentence()
if (not self.word): self.reset_game()
# window load
self.screen.fill((0,0,0))
self.screen.blit(self.bg,(0,0))
msg = "Typing Speed Test"
self.draw_text(self.screen, msg,80, 80,self.HEAD_C)
# Drawing the input field
pygame.draw.rect(self.screen,(255,192,25), (50,250,650,50), 2)
# Draw the sentence line
self.draw_text(self.screen, self.word,200, 28,self.TEXT_C)
pygame.display.update()
Game().run()
Output:
Conclusion
In this project, we created a game in Python using pygame that tracks the user’s typing speed.