用Python写糖豆人小游戏 你学“废”了么?
近几年来Python语言得到了快速发展,而Pygame作为Python开发应用和游戏必备的库更是展现了Python的优越性。
而今天我们就将借助Pygame建立吃豆人游戏。先附源码:https://pan.baidu.com/s/128id8L-PDPgGOPuH-5uHDg 提取码:rj9f (失效可以再联系我索要)
吃豆人是电子游戏历史上的经典街机游戏,由Namco公司的岩谷彻设计并由Midway Games在1980年发行。Pac-Man被认为是80年代最经典的街机游戏之一,游戏的主角小精灵的形象甚至被作为一种大众文化符号,或是此产业的代表形象。
而Pygame模块是跨平台Python模块,专为电子游戏设计,包含图像、声音。建立在SDL基础上,允许实时电子游戏研发而无需被低级语言(如机器语言和汇编语言)束缚。
最终游戏效果如下可见:
一、实验前的准备
首先我们使用的python版本是3.6.5所用到的模块是pygame模块,用来创建游戏框架。Random模块用来随机生成方向。
素材准备
首先我们将图片放到images目录下,背景音乐放到sounds目录下。
如下图可见:
游戏搭建
1、定义一些精灵:
整体的类变量定义包括墙类,通过pygame的图片填充作为墙类的加载;同理还包括食物类和角色。而怪物的随机运动使用random产生随机运动方向。
其对应的代码如下:
import random
import pygame
墙类
class Wall(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color, **kwargs):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([width, height])
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.left = x
self.rect.top = y
食物类
class Food(pygame.sprite.Sprite):
def __init__(self, x, y, width, height, color, bg_color, **kwargs):
pygame.sprite.Sprite.__init__(self)
self.image = pygame.Surface([width, height])
self.image.fill(bg_color)
self.image.set_colorkey(bg_color)
pygame.draw.ellipse(self.image, color, [0, 0, width, height])
self.rect = self.image.get_rect()
self.rect.left = x
self.rect.top = y
角色类
class Player(pygame.sprite.Sprite):
def __init__(self, x, y, role_image_path):
pygame.sprite.Sprite.__init__(self)
self.role_name = role_image_path.split( / )[-1].split( . )[0]
self.base_image = pygame.image.load(role_image_path).convert()
self.image = self.base_image.copy()
self.rect = self.image.get_rect()
self.rect.left = x
self.rect.top = y
self.prev_x = x
self.prev_y = y
self.base_speed = [30, 30]
self.speed = [0, 0]
self.is_move = False
self.tracks = []
self.tracks_loc = [0, 0]
改变速度方向
def changeSpeed(self, direction):
if direction[0] < 0:
self.image = pygame.transform.flip(self.base_image, True, False)
elif direction[0] > 0:
self.image = self.base_image.copy()
elif direction[1] < 0:
self.image = pygame.transform.rotate(self.base_image, 90)
elif direction[1] > 0:
self.image = pygame.transform.rotate(self.base_image, -90)
self.speed = [direction[0] * self.base_speed[0], direction[1] * self.base_speed[1]]
return self.speed
更新角色位置
def update(self, wall_sprites, gate_sprites):
if not self.is_move:
return False
x_prev = self.rect.left
y_prev = self.rect.top
self.rect.left += self.speed[0]
self.rect.top += self.speed[1]
is_collide = pygame.sprite.spritecollide(self, wall_sprites, False)
if gate_sprites is not None:
if not is_collide:
is_collide = pygame.sprite.spritecollide(self, gate_sprites, False)
if is_collide:
self.rect.left = x_prev
self.rect.top = y_prev
return False
return True
生成随机的方向
def randomDirection(self):
return random.choice([[-0.5, 0], [0.5, 0], [0, 0.5], [0, -0.5]])
2、游戏关卡定义:
在这里设置好了关卡一。关卡的定义必须包括墙的位置,不同关卡墙的位置和怪物的位置不同。更多关卡可以参照设置
对应代码如下:
import pygame
from Sprites import *
NUMLEVELS = 1关卡一
class Level1():def __init__(self):self.info = level1 创建墙 def setupWalls(self, wall_color):self.wall_sprites = pygame.sprite.Group()wall_positions = [[0, 0, 6, 600],[0, 0, 600, 6],[0, 600, 606, 6],[600, 0, 6, 606],[300, 0, 6, 66],[60, 60, 186, 6],[360, 60, 186, 6],[60, 120, 66, 6],[60, 120, 6, 126],[180, 120, 246, 6],[300, 120, 6, 66],[480, 120, 66, 6],[540, 120, 6, 126],[120, 180, 126, 6],[120, 180, 6, 126],[360, 180, 126, 6],[480, 180, 6, 126],[180, 240, 6, 126],[180, 360, 246, 6],[420, 240, 6, 126],[240, 240, 42, 6],[324, 240, 42, 6],[240, 240, 6, 66],[240, 300, 126, 6],[360, 240, 6, 66],[0, 300, 66, 6],[540, 300, 66, 6],[60, 360, 66, 6],[60, 360, 6, 186],[480, 360, 66, 6],[540, 360, 6, 186],[120, 420, 366, 6],[120, 420, 6, 66],[480, 420, 6, 66],[180, 480, 246, 6],[300, 480, 6, 66],[120, 540, 126, 6],[360, 540, 126, 6]]for wall_position in wall_positions:wall = Wall(*wall_position, wall_color)self.wall_sprites.add(wall)return self.wall_sprites创建门 def setupGate(self, gate_color):self.gate_sprites = pygame.sprite.Group()self.gate_sprites.add(Wall(282, 242, 42, 2, gate_color))return self.gate_sprites创建角色 def setupPlayers(self, hero_image_path, ghost_images_path):self.hero_sprites = pygame.sprite.Group()self.ghost_sprites = pygame.sprite.Group()self.hero_sprites.add(Player(287, 439, hero_image_path))for each in ghost_images_path:role_name = each.split( / )[-1].split( . )[0]if role_name == Blinky :player = Player(287, 199, each)player.is_move = Trueplayer.tracks = [[0, -0.5, 4], [0.5, 0, 9], [0, 0.5, 11], [0.5, 0, 3], [0, 0.5, 7], [-0.5, 0, 11], [0, 0.5, 3],[0.5, 0, 15], [0, -0.5, 15], [0.5, 0, 3], [0, -0.5, 11], [-0.5, 0, 3], [0, -0.5, 11], [-0.5, 0, 3],[0, -0.5, 3], [-0.5, 0, 7], [0, -0.5, 3], [0.5, 0, 15], [0, 0.5, 15], [-0.5, 0, 3], [0, 0.5, 3],[-0.5, 0, 3], [0, -0.5, 7], [-0.5, 0, 3], [0, 0.5, 7], [-0.5, 0, 11], [0, -0.5, 7], [0.5, 0, 5]]self.ghost_sprites.add(player)elif role_name == Clyde :player = Player(319, 259, each)player.is_move = Trueplayer.tracks = [[-1, 0, 2], [0, -0.5, 4], [0.5, 0, 5], [0, 0.5, 7], [-0.5, 0, 11], [0, -0.5, 7],[-0.5, 0, 3], [0, 0.5, 7], [-0.5, 0, 7], [0, 0.5, 15], [0.5, 0, 15], [0, -0.5, 3],[-0.5, 0, 11], [0, -0.5, 7], [0.5, 0, 3], [0, -0.5, 11], [0.5, 0, 9]]self.ghost_sprites.add(player)elif role_name == Inky :player = Player(255, 259, each)player.is_move = Trueplayer.tracks = [[1, 0, 2], [0, -0.5, 4], [0.5, 0, 10], [0, 0.5, 7], [0.5, 0, 3], [0, -0.5, 3],[0.5, 0, 3], [0, -0.5, 15], [-0.5, 0, 15], [0, 0.5, 3], [0.5, 0, 15], [0, 0.5, 11],[-0.5, 0, 3], [0, -0.5, 7], [-0.5, 0, 11], [0, 0.5, 3], [-0.5, 0, 11], [0, 0.5, 7],[-0.5, 0, 3], [0, -0.5, 3], [-0.5, 0, 3], [0, -0.5, 15], [0.5, 0, 15], [0, 0.5, 3],[-0.5, 0, 15], [0, 0.5, 11], [0.5, 0, 3], [0, -0.5, 11], [0.5, 0, 11], [0, 0.5, 3], [0.5, 0, 1]]self.ghost_sprites.add(player)elif role_name == Pinky :player = Player(287, 259, each)player.is_move = Trueplayer.tracks = [[0, -1, 4], [0.5, 0, 9], [0, 0.5, 11], [-0.5, 0, 23], [0, 0.5, 7], [0.5, 0, 3],[0, -0.5, 3], [0.5, 0, 19], [0, 0.5, 3], [0.5, 0, 3], [0, 0.5, 3], [0.5, 0, 3],[0, -0.5, 15], [-0.5, 0, 7], [0, 0.5, 3], [-0.5, 0, 19], [0, -0.5, 11], [0.5, 0, 9]]self.ghost_sprites.add(player)return self.hero_sprites, self.ghost_sprites创建食物 def setupFood(self, food_color, bg_color):self.food_sprites = pygame.sprite.Group()for row in range(19):for col in range(19):if (row == 7 or row == 8) and (col == 8 or col == 9 or col == 10):continueelse:food = Food(30*col+32, 30*row+32, 4, 4, food_color, bg_color)is_collide = pygame.sprite.spritecollide(food, self.wall_sprites, False)if is_collide:continueis_collide = pygame.sprite.spritecollide(food, self.hero_sprites, False)if is_collide:continueself.food_sprites.add(food)return self.food_sprites
3、游戏创建:
在通过关卡定义墙等位置后以及精灵自身属性怪物运动、食物定义等后,通过调用已经创建好的类达到搭建游戏的目的。
具体如下可见:
import os
import sys
import pygame
import Levels定义一些必要的参数
BLACK = (0, 0, 0)
WHITE = (255, 255, 255)
BLUE = (0, 0, 255)
GREEN = (0, 255, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
PURPLE = (255, 0, 255)
SKYBLUE = (0, 191, 255)
BGMPATH = os.path.join(os.getcwd(), resources/sounds/bg.mp3 )
ICONPATH = os.path.join(os.getcwd(), resources/images/icon.png )
FONTPATH = os.path.join(os.getcwd(), resources/font/ALGER.TTF )
HEROPATH = os.path.join(os.getcwd(), resources/images/pacman.png )
BlinkyPATH = os.path.join(os.getcwd(), resources/images/Blinky.png )
ClydePATH = os.path.join(os.getcwd(), resources/images/Clyde.png )
InkyPATH = os.path.join(os.getcwd(), resources/images/Inky.png )
PinkyPATH = os.path.join(os.getcwd(), resources/images/Pinky.png )开始某一关游戏
def startLevelGame(level, screen, font):clock = pygame.time.Clock()SCORE = 0wall_sprites = level.setupWalls(SKYBLUE)gate_sprites = level.setupGate(WHITE)hero_sprites, ghost_sprites = level.setupPlayers(HEROPATH, [BlinkyPATH, ClydePATH, InkyPATH, PinkyPATH])food_sprites = level.setupFood(YELLOW, WHITE)is_clearance = Falsewhile True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit(-1)pygame.quit()if event.type == pygame.KEYDOWN:if event.key == pygame.K_LEFT:for hero in hero_sprites:hero.changeSpeed([-1, 0])hero.is_move = Trueelif event.key == pygame.K_RIGHT:for hero in hero_sprites:hero.changeSpeed([1, 0])hero.is_move = Trueelif event.key == pygame.K_UP:for hero in hero_sprites:hero.changeSpeed([0, -1])hero.is_move = Trueelif event.key == pygame.K_DOWN:for hero in hero_sprites:hero.changeSpeed([0, 1])hero.is_move = Trueif event.type == pygame.KEYUP:if (event.key == pygame.K_LEFT) or (event.key == pygame.K_RIGHT) or (event.key == pygame.K_UP) or (event.key == pygame.K_DOWN):hero.is_move = Falsescreen.fill(BLACK)for hero in hero_sprites:hero.update(wall_sprites, gate_sprites)hero_sprites.draw(screen)for hero in hero_sprites:food_eaten = pygame.sprite.spritecollide(hero, food_sprites, True)SCORE += len(food_eaten)wall_sprites.draw(screen)gate_sprites.draw(screen)food_sprites.draw(screen)for ghost in ghost_sprites:# 幽灵随机运动(效果不好且有BUG)res = ghost.update(wall_sprites, None)while not res:ghost.changeSpeed(ghost.randomDirection())res = ghost.update(wall_sprites, None)# 指定幽灵运动路径if ghost.tracks_loc[1] < ghost.tracks[ghost.tracks_loc[0]][2]:ghost.changeSpeed(ghost.tracks[ghost.tracks_loc[0]][0: 2])ghost.tracks_loc[1] += 1else:if ghost.tracks_loc[0] < len(ghost.tracks) - 1:ghost.tracks_loc[0] += 1elif ghost.role_name == Clyde :ghost.tracks_loc[0] = 2else:ghost.tracks_loc[0] = 0ghost.changeSpeed(ghost.tracks[ghost.tracks_loc[0]][0: 2])ghost.tracks_loc[1] = 0if ghost.tracks_loc[1] < ghost.tracks[ghost.tracks_loc[0]][2]:ghost.changeSpeed(ghost.tracks[ghost.tracks_loc[0]][0: 2])else:if ghost.tracks_loc[0] < len(ghost.tracks) - 1:loc0 = ghost.tracks_loc[0] + 1elif ghost.role_name == Clyde :loc0 = 2else:loc0 = 0ghost.changeSpeed(ghost.tracks[loc0][0: 2])ghost.update(wall_sprites, None)ghost_sprites.draw(screen)score_text = font.render("Score: %s" % SCORE, True, RED)screen.blit(score_text, [10, 10])if len(food_sprites) == 0:is_clearance = Truebreakif pygame.sprite.groupcollide(hero_sprites, ghost_sprites, False, False):is_clearance = Falsebreakpygame.display.flip()clock.tick(10)return is_clearance显示文字
def showText(screen, font, is_clearance, flag=False):clock = pygame.time.Clock()msg = Game Over! if not is_clearance else Congratulations, you won! positions = [[235, 233], [65, 303], [170, 333]] if not is_clearance else [[145, 233], [65, 303], [170, 333]]surface = pygame.Surface((400, 200))surface.set_alpha(10)surface.fill((128, 128, 128))screen.blit(surface, (100, 200))texts = [font.render(msg, True, WHITE),font.render( Press ENTER to continue or play again. , True, WHITE),font.render( Press ESCAPE to quit. , True, WHITE)]while True:for event in pygame.event.get():if event.type == pygame.QUIT:sys.exit()pygame.quit()if event.type == pygame.KEYDOWN:if event.key == pygame.K_RETURN:if is_clearance:if not flag:returnelse:main(initialize())else:main(initialize())elif event.key == pygame.K_ESCAPE:sys.exit()pygame.quit()for idx, (text, position) in enumerate(zip(texts, positions)):screen.blit(text, position)pygame.display.flip()clock.tick(10)初始化
def initialize():pygame.init()icon_image = pygame.image.load(ICONPATH)pygame.display.set_icon(icon_image)screen = pygame.display.set_mode([606, 606])pygame.display.set_caption( 吃豆人 )return screen主函数
def main(screen):pygame.mixer.init()pygame.mixer.music.load(BGMPATH)pygame.mixer.music.play(-1, 0.0)pygame.font.init()font_small = pygame.font.Font(FONTPATH, 18)font_big = pygame.font.Font(FONTPATH, 24)for num_level in range(1, Levels.NUMLEVELS+1):if num_level == 1:level = Levels.Level1()is_clearance = startLevelGame(level, screen, font_small)if num_level == Levels.NUMLEVELS:showText(screen, font_big, is_clearance, True)else:showText(screen, font_big, is_clearance)
最终运行程序结果如下:
用Python写糖豆人小游戏 你学“废”了么?相关推荐
- Python 开发接豆人小游戏 TurnipBit
Python 开发接豆人小游戏 TurnipBit 最近入手了一款MicroPython的开发板-TurnipBit,这个板子比较适合单片机入门,以及青少年编程,因为它有配备的在线图形编程. 官网地址 ...
- mblock编程思维开发,自制糖豆人小游戏
Java学习第三天 需求:用mblock创建一个小游戏,糖豆人吃外星人的小游戏.碰到怪物1加分,碰到怪物2和3减分. 分解需求/创作思路 背景:五个背景,对应不同的血量 1.角色血量在0-50范围内为 ...
- 可怜的博主跟小豆人杠起来啦!Python制作的吃豆人小游戏,快来围观!!
相关文件 关注小编,私信小编领取哟! 当然别忘了一件三连哟~~ 对了大家可以关注小编的公众号哟~~ Python日志 开发环境 Python版本:3.6.4 相关模块: pygame模块: 以及一些P ...
- JS实现简单的吃豆人小游戏
吃豆人小游戏 今天练习了一下JS,写了一个吃豆人的小demo Html以及CSS部分 首先定义一个div,用来存放吃豆人的一些元素,我们给他加一个id="game",然后我们在这d ...
- 基于C++控制台(Windows平台)的一个吃豆人小游戏
PacManX --南京大学2019秋季学期 "高级程序设计 "课程设计一 基于C++控制台(Windows平台)的一个吃豆人小游戏 已实现的目标: 地图支持自定义编辑(可编辑地图 ...
- 整活~使用webAI做一个网页AR吃豆人小游戏
一个好习惯,先给结论 使用网页端深度学习框架识别人脸,做一个AR吃豆人小游戏.吃豆人会随着人脸在镜头内的移动而移动,吃完全部豆子即为获胜. 在线体验地址:点我预览 代码地址:点我github 本文首发 ...
- 用JAVA实现吃豆人小游戏
用JAVA实现吃豆人小游戏 游戏运行效果 Model.java Pacman.java 完整的游戏代码及资源文件 游戏运行效果 Model.java package pacman;import jav ...
- C语言实现吃豆人小游戏(转载)
c语言实现吃豆人小游戏(转载) 游戏内还有一些bug,凑活着来玩一玩吧! #include <stdio.h> #include <iostream> #include < ...
- python 吃豆人_pacman 人工智能编程 吃豆人小游戏 可实现智能寻路 吃豆 通关 - 下载 - 搜珍网...
Berkeley人工智能吃豆人作业-Python/ Berkeley人工智能吃豆人作业-Python/再附带一份完整工程源码吧/ Berkeley人工智能吃豆人作业-Python/再附带一份完整工程源 ...
- python写的推箱子小游戏
作者:白露未晞me 来源:Charles的皮卡丘 导语 Python 功能强大,可以写爬虫.服务器.数据分析.AI--当然,也可以写游戏. 用python写了个推箱子小游戏,在这里分享给大家,让我们愉 ...
最新文章
- java returnAddres_JavaClient 查询ES-(重要)
- Metasploit Framework(MSF)的使用
- 查找排序数组的最小值(js)
- android学习笔记---55_frame动画的实现,Java技术qq交流群:JavaDream:251572072
- spring第二冲刺阶段第七天
- 编程趣谈_k++_++k_k一行顺序输出,结果会有差异吗?
- Java后端学习路线
- Tool -- 01 -- xml与map相互转换
- 【知识科普】嵌入式软件开发是什么?
- IPTV机顶盒和网络盒子及转换
- vue 实现图片预览放大以及缩小
- Tac-Simur: Tactic-based Simulative Visual Analytics of Table Tennis
- oracle vm virtualbox增强功能,VirtualBox增强功能包下载
- 高等数学---向量解析几何
- OpenAi ChatGPT注册及使用教程
- mysql高级查询之性能分析explain和日志查看
- 重置计算机网络设置路由器,路由器怎样重新设置_路由器重新设置怎么弄-系统城...
- Git提交合并提交及注释
- git 怎么回退已经push的版本_git push 操作代码回退
- ip中继对接_【关关闯关】AR和Cisco 2900通过SIP IP中继对接案例
热门文章
- 转:为什么你不是真正的快乐
- Google 展示广告
- C-COT -- 超越相关滤波:学习连续卷积算子(Continuous Convolution Operators)
- 【高级操作系统-陈渝】Architecture-计算机架构
- golang连接FTP服务器并下载
- O-RAN专题系列-41:管理面-WG4.MP.V07-规范解读-第8章-故障管理FM
- 微信小程序在线考试系统 刷题考试小程序毕业设计 毕业论文 开题报告和效果图参考
- 国际象棋“马”的走法
- android 手机分辨率占比,Android屏幕密度(Density)和分辨率概念详解
- 【3dsmax插件】FBX转Bip插件 Bippy.ms