Pygame实战练习之推箱子游戏
推箱子想必是很多人童年时期的经典游戏,我们依旧能记得抱个老人机娱乐的场景,下面这篇文章主要给大家介绍了关于如何利用python写一个简单的推箱子小游戏的相关资料,需要的朋友可以参考下
导语
要说小时候称霸所有翻盖手机的小游戏,除了贪吃蛇,那就是推箱子了。
控制小人将所有箱子放到指定位置,就是这样简简单单的操作,陪伴我度过了无数个没有动画片的时光。
这个画面是不是特别熟悉?
小编也是从玩「推箱子」那个年代过来的人。那时,我拿个学习机,在老师眼皮子底下,通过了一关又一关。现在想起来,依然觉得很快乐。
今天一天都没给大家更新游戏了,看大家饥渴难耐的样子,也是时候要开始准备了。
那么今天为大家准备了童年经典游戏——推箱子,有看中就赶紧上车入手吧~
正文
游戏规则:
推箱子游戏是一款可玩性极高的策略解谜手游,游戏中玩家将扮演一名可爱Q萌的角色,
你需通过将场景内的箱子,推送到合适的位置上进行摆放,才可以轻松获得游戏胜利。
整个过程虽然极其简单,但极需玩家动脑思考,充分的利用有效地空间,合理得将箱子推送到指定位置,从而获得游戏胜利。
不仅如此,游戏整体画风十分简洁清爽,采用了简单和程式化的图形设计,给予了玩家前所未有的体验感哦。
首先
玩家、箱子、背景等图片素材:
环境安装。
Python3.6、pycharm、pygame游戏模块不能少。
1 | pip install pygame |
导入游戏的素材,增加游戏元素。
1 2 3 4 5 6 7 | def addElement( self , elem_type, col, row): if elem_type = = 'wall' : self .walls.append(elementSprite( 'wall.png' , col, row, cfg)) elif elem_type = = 'box' : self .boxes.append(elementSprite( 'box.png' , col, row, cfg)) elif elem_type = = 'target' : self .targets.append(elementSprite( 'target.png' , col, row, cfg)) |
游戏开始、结束界面设置。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | def startInterface(screen, cfg): screen.fill(cfg.BACKGROUNDCOLOR) clock = pygame.time.Clock() while True : button_1 = Button(screen, ( 95 , 150 ), '开始游戏' , cfg) button_2 = Button(screen, ( 95 , 305 ), '退出游戏' , cfg) for event in pygame.event.get(): if event. type = = pygame.QUIT: pygame.quit() sys.exit() if event. type = = pygame.MOUSEBUTTONDOWN: if button_1.collidepoint(pygame.mouse.get_pos()): return elif button_2.collidepoint(pygame.mouse.get_pos()): pygame.quit() sys.exit( 0 ) clock.tick( 60 ) pygame.display.update() def endInterface(screen, cfg): screen.fill(cfg.BACKGROUNDCOLOR) clock = pygame.time.Clock() font_path = os.path.join(cfg.FONTDIR, 'simkai.ttf' ) text = '机智如你~恭喜通关!' font = pygame.font.Font(font_path, 30 ) text_render = font.render(text, 1 , ( 255 , 255 , 255 )) while True : for event in pygame.event.get(): if event. type = = pygame.QUIT: pygame.quit() sys.exit() screen.blit(text_render, ( 120 , 200 )) clock.tick( 60 ) pygame.display.update() |
如下:
设置游戏的界面,导入关卡地图。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class gameInterface(): def __init__( self , screen): self .screen = screen self .levels_path = cfg.LEVELDIR self .initGame() def loadLevel( self , game_level): with open (os.path.join( self .levels_path, game_level), 'r' ) as f: lines = f.readlines() # 游戏地图 self .game_map = gameMap( max ([ len (line) for line in lines]) - 1 , len (lines)) # 游戏surface height = cfg.BLOCKSIZE * self .game_map.num_rows width = cfg.BLOCKSIZE * self .game_map.num_cols self .game_surface = pygame.Surface((width, height)) self .game_surface.fill(cfg.BACKGROUNDCOLOR) self .game_surface_blank = self .game_surface.copy() for row, elems in enumerate (lines): for col, elem in enumerate (elems): if elem = = 'p' : self .player = pusherSprite(col, row, cfg) elif elem = = '*' : self .game_map.addElement( 'wall' , col, row) elif elem = = '#' : self .game_map.addElement( 'box' , col, row) elif elem = = 'o' : self .game_map.addElement( 'target' , col, row) |
因为游戏界面面积>游戏窗口界面, 所以需要根据人物位置滚动。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | def scroll( self ): x, y = self .player.rect.center width = self .game_surface.get_rect().w height = self .game_surface.get_rect().h if (x + cfg.SCREENSIZE[ 0 ] / / 2 ) > cfg.SCREENSIZE[ 0 ]: if - 1 * self .scroll_x + cfg.SCREENSIZE[ 0 ] < width: self .scroll_x - = 2 elif (x + cfg.SCREENSIZE[ 0 ] / / 2 ) > 0 : if self .scroll_x < 0 : self .scroll_x + = 2 if (y + cfg.SCREENSIZE[ 1 ] / / 2 ) > cfg.SCREENSIZE[ 1 ]: if - 1 * self .scroll_y + cfg.SCREENSIZE[ 1 ] < height: self .scroll_y - = 2 elif (y + 250 ) > 0 : if self .scroll_y < 0 : self .scroll_y + = 2 |
设置玩家的精灵类,可上下左右移动等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | class pusherSprite(pygame.sprite.Sprite): def __init__( self , col, row, cfg): pygame.sprite.Sprite.__init__( self ) self .image_path = os.path.join(cfg.IMAGESDIR, 'player.png' ) self .image = pygame.image.load( self .image_path).convert() color = self .image.get_at(( 0 , 0 )) self .image.set_colorkey(color, pygame.RLEACCEL) self .rect = self .image.get_rect() self .col = col self .row = row '''移动''' def move( self , direction, is_test = False ): # 测试模式代表模拟移动 if is_test: if direction = = 'up' : return self .col, self .row - 1 elif direction = = 'down' : return self .col, self .row + 1 elif direction = = 'left' : return self .col - 1 , self .row elif direction = = 'right' : return self .col + 1 , self .row else : if direction = = 'up' : self .row - = 1 elif direction = = 'down' : self .row + = 1 elif direction = = 'left' : self .col - = 1 elif direction = = 'right' : self .col + = 1 '''将人物画到游戏界面上''' def draw( self , screen): self .rect.x = self .rect.width * self .col self .rect.y = self .rect.height * self .row screen.blit( self .image, self .rect) |
游戏关卡循环,当某个关卡过不去的时候,想重新来按住R键即可返回本关卡。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | def runGame(screen, game_level): clock = pygame.time.Clock() game_interface = gameInterface(screen) game_interface.loadLevel(game_level) font_path = os.path.join(cfg.FONTDIR, 'simkai.ttf' ) text = '按R键重新开始本关' font = pygame.font.Font(font_path, 15 ) text_render = font.render(text, 1 , ( 255 , 255 , 255 )) while True : for event in pygame.event.get(): if event. type = = pygame.QUIT: pygame.quit() sys.exit( 0 ) elif event. type = = pygame.KEYDOWN: if event.key = = pygame.K_LEFT: next_pos = game_interface.player.move( 'left' , is_test = True ) if game_interface.game_map.isValidPos( * next_pos): game_interface.player.move( 'left' ) else : box = game_interface.game_map.getBox( * next_pos) if box: next_pos = box.move( 'left' , is_test = True ) if game_interface.game_map.isValidPos( * next_pos): game_interface.player.move( 'left' ) box.move( 'left' ) break if event.key = = pygame.K_RIGHT: next_pos = game_interface.player.move( 'right' , is_test = True ) if game_interface.game_map.isValidPos( * next_pos): game_interface.player.move( 'right' ) else : box = game_interface.game_map.getBox( * next_pos) if box: next_pos = box.move( 'right' , is_test = True ) if game_interface.game_map.isValidPos( * next_pos): game_interface.player.move( 'right' ) box.move( 'right' ) break if event.key = = pygame.K_DOWN: next_pos = game_interface.player.move( 'down' , is_test = True ) if game_interface.game_map.isValidPos( * next_pos): game_interface.player.move( 'down' ) else : box = game_interface.game_map.getBox( * next_pos) if box: next_pos = box.move( 'down' , is_test = True ) if game_interface.game_map.isValidPos( * next_pos): game_interface.player.move( 'down' ) box.move( 'down' ) break if event.key = = pygame.K_UP: next_pos = game_interface.player.move( 'up' , is_test = True ) if game_interface.game_map.isValidPos( * next_pos): game_interface.player.move( 'up' ) else : box = game_interface.game_map.getBox( * next_pos) if box: next_pos = box.move( 'up' , is_test = True ) if game_interface.game_map.isValidPos( * next_pos): game_interface.player.move( 'up' ) box.move( 'up' ) break if event.key = = pygame.K_r: game_interface.initGame() game_interface.loadLevel(game_level) game_interface.draw(game_interface.player, game_interface.game_map) if game_interface.game_map.levelCompleted(): return screen.blit(text_render, ( 5 , 5 )) pygame.display.flip() clock.tick( 100 ) |
如下:
判断该关卡中所有的箱子是否都在指定位置, 在的话就是通关了。
1 2 3 4 5 6 7 8 9 10 | def levelCompleted( self ): for box in self .boxes: is_match = False for target in self .targets: if box.col = = target.col and box.row = = target.row: is_match = True break if not is_match: return False return True |
效果图第二关卡如下:
总结
《推箱子》
难度星数:5星
小编现在在这2关就被难住了!你还记得怎么玩吗?能过几关?emmm,
非常烧脑,感兴趣的小伙伴可以试试,言而总之,这游戏难~
制作不易,记得一键三连哦!!
到此这篇关于Pygame实战练习之推箱子游戏的文章就介绍到这了
原文链接:https://blog.csdn.net/weixin_55822277/article/details/120158893