1. Preview of running results
Start Interface
First level
Second level
Third level
Level 4
Level 5
Game over
2. Introduction of Game Functions
2.1 Development Environment:
python version: python 3.7
2.2 Related modules:
pygame modules, as well as some modules that come with Python.
2.3 Introduction to the game:
The game is timed in 120 seconds.
The first 40 seconds are the first level, and the mouse appears very slowly.
40-60 seconds for the second level, the mouse appeared slowly;
60-80 seconds for the third level, the mouse appears at a moderate speed;
80-100 seconds for the fourth level, the mouse appears faster;
After 100 seconds, the fifth level, the mice appeared very quickly.
When the countdown ends, the game ends and scores are compared.
3. Development ideas
py file defined in 3.1
3.1.1 mouse.py (main function entry)
Link the entire hamster function through the mouse.py file.
3.1.2cfg.py file (basic configuration such as fonts)
The cfg file defines the basic configuration, font, color, size, and so on
3.1.3mole.py file (hamster)
mole defines the hamster, including picture loading, display, reset, etc.
3.1.4 hammer.py file (hammer)
Hammer defines a hammer, including its picture loading, display, effect on hitting, reset, etc.
3.1.5 endinterface.py file (end interface)
endinterface defines the end-time page, including the score display and the maximum score display
3.1.6 startinterface.py file (start interface)
startinterface defines the starting page.
3.2 Defined Functions
3.2.1 Game Initialization
def initGame(): pygame.init() pygame.mixer.init() screen = pygame.display.set_mode(cfg.SCREENSIZE) pygame.display.set_caption('Yuan Xin Zhang Chen-en's Hamster Game') return screen
3.2.2 Main Entrance to Games
def main():
3.2.3 Mouse in Game
class Mole(pygame.sprite.Sprite):
3.2.4 Hammers in Games
class Hammer(pygame.sprite.Sprite):
3.2.5 Game Start Interface
def startInterface(screen, begin_image_paths):
3.2.6 End of Game Interface
def endInterface(screen, end_image_path, again_image_paths, score_info, font_path, font_colors, screensize):
4. Related Codes
4.1mouse.py (main function entry)
def main(): # Initialization screen = initGame()
4.1.1 Load background music and other sound effects
pygame.mixer.music.load(cfg.BGM_PATH) pygame.mixer.music.play(-1) audios = { 'count_down': pygame.mixer.Sound(cfg.COUNT_DOWN_SOUND_PATH), 'hammering': pygame.mixer.Sound(cfg.HAMMERING_SOUND_PATH) }
4.1.2 Loading Fonts
font = pygame.font.Font(cfg.FONT_PATH, 40)
4.1.3 Load background pictures
bg_img = pygame.image.load(cfg.GAME_BG_IMAGEPATH)
4.1.4 Beginning Interface
startInterface(screen, cfg.GAME_BEGIN_IMAGEPATHS)
4.1.5 Timing of Hamster Position Change
hole_pos = random.choice(cfg.HOLE_POSITIONS) change_hole_event = pygame.USEREVENT pygame.time.set_timer(change_hole_event, 800)
4.1.6 Hamster
mole = Mole(cfg.MOLE_IMAGEPATHS, hole_pos)
4.1.7 Hammer
hammer = Hammer(cfg.HAMMER_IMAGEPATHS, (500, 250))
4.1.8 Clock
clock = pygame.time.Clock()
4.1.9 Score
your_score = 0
Level 4.1.10
number = 1 flag = False
4.1.11 Main Game Cycle
while True: # --120s game time time_remain = round((121000 - pygame.time.get_ticks()) / 1000.)
4.1.12 Game time decreased and hamsters moved faster
# First level if time_remain == 100 and not flag: hole_pos = random.choice(cfg.HOLE_POSITIONS) mole.reset() mole.setPosition(hole_pos) pygame.time.set_timer(change_hole_event, 650) flag = True # Second level elif time_remain == 80 and not flag: hole_pos = random.choice(cfg.HOLE_POSITIONS) mole.reset() mole.setPosition(hole_pos) pygame.time.set_timer(change_hole_event, 600) flag = True # Third level elif time_remain == 60 and not flag: hole_pos = random.choice(cfg.HOLE_POSITIONS) mole.reset() mole.setPosition(hole_pos) pygame.time.set_timer(change_hole_event, 550) flag = True # Level 4 elif time_remain == 40 and not flag: hole_pos = random.choice(cfg.HOLE_POSITIONS) mole.reset() mole.setPosition(hole_pos) pygame.time.set_timer(change_hole_event, 500) flag = True # Level 5 elif time_remain == 20 and flag: hole_pos = random.choice(cfg.HOLE_POSITIONS) mole.reset() mole.setPosition(hole_pos) pygame.time.set_timer(change_hole_event, 450) flag = False # Level display if time_remain == 100: number = 1 elif time_remain == 80: number = 2 elif time_remain == 60: number = 3 elif time_remain == 40: number = 4 elif time_remain == 20: number = 5
4.1.13 Countdown Sound
if time_remain == 10: audios['count_down'].play()
4.1.14 Game over
if time_remain < 0: break count_down_text = font.render('Time: '+str(time_remain), True, cfg.WHITE)
4.1.15 Key Detection
for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.MOUSEMOTION: hammer.setPosition(pygame.mouse.get_pos()) elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: hammer.setHammering() elif event.type == change_hole_event: hole_pos = random.choice(cfg.HOLE_POSITIONS) mole.reset() mole.setPosition(hole_pos)
4.1.16 - Collision detection
if hammer.is_hammering and not mole.is_hammer: is_hammer = pygame.sprite.collide_mask(hammer, mole) if is_hammer: audios['hammering'].play() mole.setBeHammered() your_score += 10
4.1.17 Score
your_score_text = font.render('Score: '+str(your_score), True, cfg.BROWN) your_number_text2 = font.render('No. '+str(number)+'shut', True, cfg.WHITE)
4.1.18 Bind the necessary game elements to the screen (note the order)
screen.blit(bg_img, (0, 0)) screen.blit(count_down_text, (800, 8)) screen.blit(your_score_text, (750, 430)) screen.blit(your_number_text2, (600, 430)) mole.draw(screen) hammer.draw(screen)
4.1.19 Read Best Score
try: best_score = int(open(cfg.RECORD_PATH).read()) except: best_score = 0
4.1.20 Update the best score if the current score is greater than the best score
if your_score > best_score: f = open(cfg.RECORD_PATH, 'w') f.write(str(your_score)) f.close()
4.1.21 End Interface
score_info = {'your_score': your_score, 'best_score': best_score} is_restart = endInterface(screen, cfg.GAME_END_IMAGEPATH, cfg.GAME_AGAIN_IMAGEPATHS, score_info, cfg.FONT_PATH, [cfg.WHITE, cfg.RED], cfg.SCREENSIZE) return is_restart
4.2cfg.py file (basic configuration such as fonts)
import os CURPATH = os.getcwd() SCREENSIZE = (993, 477) HAMMER_IMAGEPATHS = [os.path.join(CURPATH, 'resources/images/hammer0.png'), os.path.join(CURPATH, 'resources/images/hammer1.png')] GAME_BEGIN_IMAGEPATHS = [os.path.join(CURPATH, 'resources/images/begin.png'), os.path.join(CURPATH, 'resources/images/begin1.png')] GAME_AGAIN_IMAGEPATHS = [os.path.join(CURPATH, 'resources/images/again1.png'), os.path.join(CURPATH, 'resources/images/again2.png')] GAME_BG_IMAGEPATH = os.path.join(CURPATH, 'resources/images/background.png') GAME_END_IMAGEPATH = os.path.join(CURPATH, 'resources/images/end.png') MOLE_IMAGEPATHS = [os.path.join(CURPATH, 'resources/images/mole_1.png'), os.path.join(CURPATH, 'resources/images/mole_laugh1.png'), os.path.join(CURPATH, 'resources/images/mole_laugh2.png'), os.path.join(CURPATH, 'resources/images/mole_laugh3.png')] HOLE_POSITIONS = [(90, -20), (405, -20), (720, -20), (90, 140), (405, 140), (720, 140), (90, 290), (405, 290), (720, 290)] BGM_PATH = 'resources/audios/bgm.mp3' COUNT_DOWN_SOUND_PATH = 'resources/audios/count_down.wav' HAMMERING_SOUND_PATH = 'resources/audios/hammering.wav' FONT_PATH = 'resources/font/Font stewardship fat baby body.ttf' BROWN = (150, 75, 0) WHITE = (255, 255, 255) RED = (255, 0, 0) RECORD_PATH = 'score.rec'
4.3mole.py file (hamster)
import pygame class Mole(pygame.sprite.Sprite): def __init__(self, image_paths, position, **kwargs): pygame.sprite.Sprite.__init__(self) self.images = [pygame.transform.scale(pygame.image.load(image_paths[0]), (101, 103)), pygame.transform.scale(pygame.image.load(image_paths[-1]), (101, 103))] self.image = self.images[0] self.rect = self.image.get_rect() self.mask = pygame.mask.from_surface(self.image) self.setPosition(position) self.is_hammer = False
4.3.1 Set Location
def setPosition(self, pos): self.rect.left, self.rect.top = pos
4.3.2 setting hit
def setBeHammered(self): self.is_hammer = True
4.3.3 Display on screen
def draw(self, screen): if self.is_hammer: self.image = self.images[1] screen.blit(self.image, self.rect)
4.3.4 Reset
def reset(self): self.image = self.images[0] self.is_hammer = False
4.4hammer.py file (hammer)
import pygame class Hammer(pygame.sprite.Sprite): def __init__(self, image_paths, position, **kwargs): pygame.sprite.Sprite.__init__(self) self.images = [pygame.image.load(image_paths[0]), pygame.image.load(image_paths[1])] self.image = self.images[0] self.rect = self.image.get_rect() self.mask = pygame.mask.from_surface(self.images[1]) self.rect.left, self.rect.top = position
4.4.1 Used to show special effects when hammering
self.hammer_count = 0 self.hammer_last_time = 4 self.is_hammering = False
4.4.2 Set Location
def setPosition(self, pos): self.rect.centerx, self.rect.centery = pos
4.4.3 Setting up hammering
def setHammering(self): self.is_hammering = True
4.4.4 Display on screen
def draw(self, screen): if self.is_hammering: self.image = self.images[1] self.hammer_count += 1 if self.hammer_count > self.hammer_last_time: self.is_hammering = False self.hammer_count = 0 else: self.image = self.images[0] screen.blit(self.image, self.rect)
4.5endinterface.py file (end interface)
import sys import pygame def endInterface(screen, end_image_path, again_image_paths, score_info, font_path, font_colors, screensize): end_image = pygame.image.load(end_image_path) again_images = [pygame.image.load(again_image_paths[0]), pygame.image.load(again_image_paths[1])] again_image = again_images[0] font = pygame.font.Font(font_path, 50) your_score_text = font.render('Your Score: %s' % score_info['your_score'], True, font_colors[0]) your_score_rect = your_score_text.get_rect() your_score_rect.left, your_score_rect.top = (screensize[0] - your_score_rect.width) / 2, 215 best_score_text = font.render('Best Score: %s' % score_info['best_score'], True, font_colors[1]) best_score_rect = best_score_text.get_rect() best_score_rect.left, best_score_rect.top = (screensize[0] - best_score_rect.width) / 2, 275 while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.MOUSEMOTION: mouse_pos = pygame.mouse.get_pos() if mouse_pos[0] in list(range(419, 574)) and mouse_pos[1] in list(range(374, 416)): again_image = again_images[1] else: again_image = again_images[0] elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1 and mouse_pos[0] in list(range(419, 574)) and mouse_pos[1] in list(range(374, 416)): return True screen.blit(end_image, (0, 0)) screen.blit(again_image, (416, 370)) screen.blit(your_score_text, your_score_rect) screen.blit(best_score_text, best_score_rect) pygame.display.update()
4.6startinterface.py file (start interface)
import sys import pygame def startInterface(screen, begin_image_paths): begin_images = [pygame.image.load(begin_image_paths[0]), pygame.image.load(begin_image_paths[1])] begin_image = begin_images[0] while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() sys.exit() elif event.type == pygame.MOUSEMOTION: mouse_pos = pygame.mouse.get_pos() if mouse_pos[0] in list(range(419, 574)) and mouse_pos[1] in list(range(374, 416)): begin_image = begin_images[1] else: begin_image = begin_images[0] elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1 and mouse_pos[0] in list(range(419, 574)) and mouse_pos[1] in list(range(374, 416)): return True screen.blit(begin_image, (0, 0)) pygame.display.update()