原标题:Python制作打地鼠小游戏
导语
大家好,欢迎来到 Crossin的编程教室 !
打地鼠游戏相信大家都知道,这里就不多介绍了,反正就是不停地拿锤子打洞里钻出来的地鼠呗~
今天就给大家分享一个用python写的打地鼠小游戏。同时也祝大家在新的一年把不开心的事情统统打跑~
环境搭建
安装Python并添加到环境变量,安装 pygame 模块
pipinstall pygame
或下载离线安装:
http://www.lfd.uci.edu/~gohlke/pythonlibs/#pygame
先睹为快
获取源码后在cmd窗口运行如下命令即可:
pythonGame21.py
效果如下:
原理简介
首先,让我们确定一下游戏中有哪些元素。打地鼠打地鼠,地鼠当然得有啦,那我们就写个地鼠的游戏精灵类呗:
'''地鼠'''
classMole(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
'''设置位置'''
defsetPosition(self, pos):
self.rect.left, self.rect.top = pos
'''设置被击中'''
defsetBeHammered(self):
self.is_hammer = True
'''显示在屏幕上'''
defdraw(self, screen):
ifself.is_hammer: self.image = self.images[ 1]
screen.blit(self.image, self.rect)
'''重置'''
defreset(self):
self.image = self.images[ 0]
self.is_hammer = False
地鼠有被锤子击中和未被锤子击中这两种状态,所以需要加载两张图,当地鼠被击中时从未被击中的地鼠状态图切换到被击中后的地鼠状态图(我找的图可能不太像地鼠,请各位老哥见谅)。然后我们再来定义一下锤子这个游戏精灵类,和地鼠类似,锤子也有未锤下去和已锤下去两种状态,只不过锤下去之后需要迅速恢复回未锤下去的状态。
代码实现如下:
classHammer( 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
# 用于显示锤击时的特效
self.hammer_count = 0
self.hammer_last_time = 4
self.is_hammering = False
'''设置位置'''
defsetPosition( self, pos):
self.rect.centerx, self.rect.centery = pos
'''设置hammering'''
defsetHammering( self):
self.is_hammering = True
'''显示在屏幕上'''
defdraw( self, screen):
ifself. is_hammering:
self.image = self.images[ 1]
self.hammer_count += 1
ifself.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)
OK,定义完游戏精灵之后,我们就可以开始写主程序啦。首先自然是游戏初始化:
'''游戏初始化'''
definitGame:
pygame.init
pygame.mixer.init
screen = pygame.display.set_mode(cfg.SCREENSIZE)
pygame.display.set_caption( 'Whac A Mole-微信公众号:Charles的皮卡丘')
returnscreen
然后加载必要的游戏素材和定义必要的游戏变量(我都注释的比较详细了,就不在文章里赘述一遍了,自己看注释呗~)
# 加载背景音乐和其他音效
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)
}
# 加载字体
font= pygame.font.Font(cfg.FONT_PATH, 40)
# 加载背景图片
bg_img= pygame.image.load(cfg.GAME_BG_IMAGEPATH)
# 开始界面
startInterface(screen,cfg.GAME_BEGIN_IMAGEPATHS)
# 地鼠改变位置的计时
hole_pos= random.choice(cfg.HOLE_POSITIONS)
change_hole_event= pygame.USEREVENT
pygame.time.set_timer(change_hole_event,800)
# 地鼠
mole= Mole(cfg.MOLE_IMAGEPATHS, hole_pos)
# 锤子
hammer= Hammer(cfg.HAMMER_IMAGEPATHS, (500, 250))
# 时钟
clock= pygame.time.Clock
# 分数
your_score= 0
接着就是游戏主循环啦:
# 游戏主循环
whileTrue:
# --游戏时间为60s
time_remain = round(( 61000- pygame.time.get_ticks) / 1000.)
# --游戏时间减少, 地鼠变位置速度变快
iftime_remain == 40:
pygame.time.set_timer(change_hole_event, 650)
eliftime_remain == 20:
pygame.time.set_timer(change_hole_event, 500)
# --倒计时音效
iftime_remain == 10:
audios[ 'count_down'].play
# --游戏结束
iftime_remain < 0: break
count_down_text = font.render( 'Time: '+str(time_remain), True, cfg.WHITE)
# --按键检测
forevent inpygame.event.get:
ifevent.type == pygame.QUIT:
pygame.quit
sys.exit
elifevent.type == pygame.MOUSEMOTION:
hammer.setPosition(pygame.mouse.get_pos)
elifevent.type == pygame.MOUSEBUTTONDOWN:
ifevent.button == 1:
hammer.setHammering
elifevent.type == change_hole_event:
hole_pos = random.choice(cfg.HOLE_POSITIONS)
mole.reset
mole.setPosition(hole_pos)
# --碰撞检测
ifhammer.is_hammering andnotmole.is_hammer:
is_hammer = pygame.sprite.collide_mask(hammer, mole)
ifis_hammer:
audios[ 'hammering'].play
mole.setBeHammered
your_score += 10
# --分数
your_score_text = font.render( 'Score: '+str(your_score), True, cfg.BROWN)
# --绑定必要的游戏元素到屏幕(注意顺序)
screen.blit(bg_img, ( 0, 0))
screen.blit(count_down_text, ( 875, 8))
screen.blit(your_score_text, ( 800, 430))
mole.draw(screen)
hammer.draw(screen)
# --更新
pygame.display.flip
clock.tick( 60)
每一部分我也都做了注释,逻辑很简单,就不多废话了。
60s后,游戏结束,我们就可以统计分数以及和历史最高分做对比了:
# 读取最佳分数(try块避免第一次游戏无.rec文件)
try:
best_score= int(open(cfg.RECORD_PATH).read)
except:
best_score= 0
# 若当前分数大于最佳分数则更新最佳分数
ifyour_score > best_score:
f= open(cfg.RECORD_PATH, 'w')
f.write(str(your_score))
f.close
为了使游戏看起来更“正式”,再随手添个开始界面和结束界面呗:
'''游戏开始界面'''
defstartInterface(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]
whileTrue:
forevent inpygame.event.get:
ifevent.type == pygame.QUIT:
pygame.quit
sys.exit
elifevent.type == pygame.MOUSEMOTION:
mouse_pos = pygame.mouse.get_pos
ifmouse_pos[ 0] inlist(range( 419, 574)) andmouse_pos[ 1] inlist(range( 374, 416)):
begin_image = begin_images[ 1]
else:
begin_image = begin_images[ 0]
elifevent.type == pygame.MOUSEBUTTONDOWN:
ifevent.button == 1andmouse_pos[ 0] inlist(range( 419, 574)) andmouse_pos[ 1] inlist(range( 374, 416)):
returnTrue
screen.blit(begin_image, ( 0, 0))
pygame.display.update
'''结束界面'''defendInterface(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_rectyour_score_rect.left, your_score_rect.top = (screensize[ 0] - your_score_rect.width) / 2, 215best_score_text = font.render( 'Best Score: %s'% score_info[ 'best_score'], True, font_colors[ 1])best_score_rect = best_score_text.get_rectbest_score_rect.left, best_score_rect.top = (screensize[ 0] - best_score_rect.width) / 2, 275whileTrue:forevent inpygame.event.get:ifevent.type == pygame.QUIT:pygame.quitsys.exitelifevent.type == pygame.MOUSEMOTION:mouse_pos = pygame.mouse.get_posifmouse_pos[ 0] inlist(range( 419, 574)) andmouse_pos[ 1] inlist(range( 374, 416)):again_image = again_images[ 1]else:again_image = again_images[ 0]elifevent.type == pygame.MOUSEBUTTONDOWN:ifevent.button == 1andmouse_pos[ 0] inlist(range( 419, 574)) andmouse_pos[ 1] inlist(range( 374, 416)):returnTruescreen.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
大功告成~
源码下载
获取源码及图片素材可在公众号内回复关键字打地鼠
音频与图片素材源于网络,仅供个人学习交流使用,如有侵权请联系作者删除。
如果文章对你有帮助,欢迎转发/点赞/收藏~
作者:白露未晞me
来源:Charles的皮卡丘
用python写一个简单的贪吃蛇游戏 返回搜狐,查看更多
责任编辑: