Typing Tutor Game

The Fun

Now to make the game actually fun and challenging, we need to introduce some levelling up, or increased difficulty as we play.

There are multitude of ways to achieve this, we can:-

Level up

First let's set a level object member to keep track of how man words have dropped. Levelling up every four or five words is pretty good rate:

class GamePlay():
    def __init__(self, screen):
        self.screen = screen
        pygame.init()
        self.disp_surf = pygame.Surface(self.screen.get_size()).convert()
        self.width, self.height = screen.get_size()
        self.font =  pygame.font.Font('Consolas Bold.ttf', 16)
        self.playing = True
        self.game_objects = GameObjects(self.width, self.height)
        self.last_add = 0 # time of adding word
        self.add_timeout = 2000 # 2 seconds
        self.fps = 25
        self.fps_clock = pygame.time.Clock()
        self.y_delta = 1
        self.typing_flag = False
        self.key_hit = None
        self.score = 0
self.level = 1 self.typed_count = 0

And add counter for number of typed words:

    def add_score(self, score):
        self.score += score
self.typed_count += 1 # Level up if self.typed_count >= 4: self.level += 1 self.typed_count = 0

Let's now put the Level onto our status bar:

Also change draw_score to draw_status.

    def draw_score(self):
        # draw status bar background
        pygame.draw.rect(self.disp_surf, BLACK, (0,0,self.width,20), 0)
        # draw score text
        text = 'Score: %s' % self.score
        self.draw_word(text, YELLOW, (self.width - 150, 2))
# draw level text text = 'Level: %s' % self.level self.draw_word(text, YELLOW, (MARGINX, 2)) return

The words

We have a large collection of words to choose from, so we want to narrow it down.

# play.py
def add_word(self, level):
'''Add new word to drop from top''' if self.game_objects.is_gameover(): return # Check if valid to add if not self.game_objects.game_words or ( (pygame.time.get_ticks() - self.last_add) > self.add_timeout):
if self.game_objects.add_word(self.level):
self.last_add = pygame.time.get_ticks() return
# objects
def add_word(self, level):
'''Add word to game play''' # Check that word doesn't duplicate first character in list
word = self.get_word(level)
firstchar = [word.text[0] for word in self.game_words] while word[0] in firstchar:
word = self.get_word(level)
# Get the list of city blocks still standing avail_blocks = [] for idx, block in enumerate(self.city_line): if block.get_flag() == True: avail_blocks.append(idx) x_avail = random.choice(avail_blocks) * 10 + MARGINX # Calculate the max of x position of word max_x = (self.screen_width - MARGINX) - (FONTWIDTH * len(word)) # Some randomised fun x = random.randint(MARGINX,max_x) x = random.choice([x_avail, x]) x = min(x, max_x) self.game_words.append(Word(word, x)) return True
def get_word(self, level):
'''Randomly select word from word list for game play'''
return random.choice(self.word_list[:min(len(self.word_list), 50 * level)])

Speed

To increase the speed, we can:-

  • Increase the fps
  • Increase y_delta
  • Decrease add word timeout

# play.py
    def add_score(self, score):
        self.score += score
        self.typed_count += 1
        
        # Level up
        if self.typed_count >= 4:
            self.level += 1
            self.typed_count = 0
# Increase difficulty when leveling up if self.level % 5 == 0 and self.y_delta < 3: self.y_delta += 1 elif self.level % 2 == 0 and self.add_timeout > 1000: self.add_timeout -= 100 elif self.fps < 60: self.fps += 3 return