90.pygame游戏-玩个球(play the ball)最终版
文章目录
- 游戏部分截图
- 游戏操作说明
- 代码
- 所有图片素材
- 音乐素材
- 下载链接
游戏部分截图
游戏操作说明
1.鼠标上下左右晃动,在摩擦板中摩擦,会使得灰色求变绿色
2.上下左右(W,S,A,D)四个键可控制浅绿色的小球
3.将绿色小球移动到背景的黑洞上,覆盖黑色球
4.绿色球到黑洞位置时按下空格键,若听到音效声音,则覆盖成功
5.直至五个球全部归位,游戏胜利,自动结束游戏;倘若开始游戏伴随的音乐(一首歌)放完,五个球还没有全部覆盖黑洞,则游戏失败,将播放嘲讽的声乐。
代码
一个模块版本
main.py
import pygame
import sys # 退出需要
import traceback
from pygame.locals import * # 把pygame的常量名导进去
from random import * # 随机生成数需要class Ball(pygame.sprite.Sprite): # 球类,继承自Spirte类def __init__(self, grayball_image, greenball_image, position, speed, bg_size, target):pygame.sprite.Sprite.__init__(self) # 初始化动画精灵# 使用 .convert_alpha() 可以转换像素格式,提高 blit 的速度self.grayball_image = pygame.image.load(grayball_image).convert_alpha() # 加载灰球图片self.greenball_image = pygame.image.load(greenball_image).convert_alpha() # 加载绿球图片self.rect = self.grayball_image.get_rect() # 获取小球位置# 将小球放在指定位置self.rect.left, self.rect.top = position # position赋值给小球的左边和上边# choice() 方法返回一个列表,元组或字符串的随机项。self.side = [choice([-1, 1]), choice([-1, 1])] # 移动小球方向self.speed = speed # 移动速度self.collide = False # 默认未碰撞self.target = target # 为每一个小球设定一个不同的目标# 5、小球应该添加一个 control 属性,用于记录当前的状态(绿色 -> 玩家控制 or 灰色 -> 随机移动)self.control = Falseself.width, self.height = bg_size[0], bg_size[1] # 窗口的宽高self.radius = self.rect.width / 2 # 增加半径属性def move(self): # 球的移动方法if self.control: # 为真self.rect = self.rect.move(self.speed) # 移动后的矩形位置else: # 为假self.rect = self.rect.move(self.side[0] * self.speed[0],self.side[1] * self.speed[1]) # 移动小球矩形位置"""" 如果小球的左侧出了边界,那么将小球左侧的位置改为右侧的边界这样便实现了从左边进入,右边出来的效果"""if self.rect.right <= 0: # 小球右边界<0,即小球出左边self.rect.left = self.width # 从右边进来elif self.rect.left >= self.width: # 小球左边界>窗口宽度,即小球出右边self.rect.right = 0 # 从左边进来elif self.rect.bottom <= 0: # 小球下边界<0,即小球出上边self.rect.top = self.height # 从下边出来elif self.rect.top >= self.height: # 小球上边界>窗口高度self.rect.bottom = 0 # 从上边出来# 3、为小球添加一个 check() 方法,用于判断鼠标在1秒钟内产生的事件数量是否匹配此目标;def check(self, motion):if self.target < motion < self.target + 5:return Trueelse:return Falseclass Glass(pygame.sprite.Sprite): # 摩擦板类def __init__(self, glass_image, mouse_image, bg_size): # 这两行代码跟前面的一样pygame.sprite.Sprite.__init__(self) # 初始化动画精灵self.glass_image = pygame.image.load(glass_image).convert_alpha() # 加载摩擦板图像self.glass_rect = self.glass_image.get_rect() # 获取摩擦板的矩形位置# 摩擦板矩形为左边和上边界,水平位置在中心,垂直位置在下边self.glass_rect.left, self.glass_rect.top = \(bg_size[0] - self.glass_rect.width) // 2, \bg_size[1] - self.glass_rect.heightself.mouse_image = pygame.image.load(mouse_image).convert_alpha() # 加载手图像self.mouse_rect = self.mouse_image.get_rect() # 获取手的矩形位置# 手的左边和上边界 = 摩擦板的左边和上边界, 相当于初始化位置self.mouse_rect.left, self.mouse_rect.top = \self.glass_rect.left, self.glass_rect.toppygame.mouse.set_visible(False) # 鼠标不可见def main(): # 主函数,把一群东西封装起来了pygame.init() # 初始化grayball_image = "gray_ball.png" # 球图像greenball_image = "green_ball.png" # 球图像bg_image = "background.png" # 背景图像glass_image = "glass.png" # 摩擦板图像mouse_image = "hand.png" # 摩擦的手的图像running = True # 初始化running为True# 添加背景音乐pygame.mixer.music.load("bg_music.ogg") # 加载背景音乐pygame.mixer.music.set_volume(0.2) # 设置音量pygame.mixer.music.play() # 播放背景音乐# 添加音效loser_sound = pygame.mixer.Sound("fail.ogg") # 失败的时候的声音loser_sound.set_volume(0.2)laugh_sound = pygame.mixer.Sound("laugh.ogg") # 嘲笑的声音laugh_sound.set_volume(0.2)winner_sound = pygame.mixer.Sound("win.ogg") # 成功的时候的声音winner_sound.set_volume(0.2)hole_sound = pygame.mixer.Sound("hole.ogg")hole_sound.set_volume(0.2)""""# 背景音乐会贯穿游戏的始终,背景音乐完整播放一次我们视为游戏的时间,# 因此我们需要想办法让游戏在背景音乐停止时结束,我们应该有留意到:# music 模块有一个 set_endevent() 方法,该方法的作用就是在音乐播放完时# 发送一条事件消息,发送什么消息是我们自定义的,USEREVENT 就是自定义消息,# Pygame 给我们预定了很多事件,像我们熟悉的 键盘事件、鼠标事件等。这些预定义# 的事件都有一个标记符,例如:MOUSEBUTTONDOWN 、KEYDOWN等。这些都是# 一些数字的等值定义,其实在内部,2 就表示鼠标按下,但是人类难以记住,所以定义为# MOUSEBUTTONDOWN。# USEREVENT 就是数字24,24以上就是我们可以自定义的事件,我们可以像这样自定义事件:# MY_EVENT = USEREVENT。# MY_EVENT_1 = USEREVENT + 1........"""# 音乐播放完时游戏结束GAMEOVER = USEREVENTpygame.mixer.music.set_endevent(GAMEOVER)# 根据背景图片指定游戏界面尺寸bg_size = width, height = 1024, 681 # 窗口尺寸screen = pygame.display.set_mode(bg_size) # 绘制窗口pygame.display.set_caption("小游戏") # 窗口名background = pygame.image.load(bg_image).convert_alpha() # 加载背景图片# 黑洞范围(x1, x2, y1, y2)hole = [(115, 121, 197, 203), (223, 229, 388, 394), (501, 507, 318, 324),(696, 702, 190, 196), (904, 910, 417, 423)]msgs = []balls = [] # 用来存放小球对象的列表group = pygame.sprite.Group() # 这里的group在碰撞检测需要# 创建五个小球,位置随机,速度随机for i in range(5):# position = (小球的左边,上边)position = randint(0, width - 100), randint(0, height - 100) # 随机生成位置speed = [randint(1, 10), randint(1, 10)] # 随机生成速度"""四个参数ball_image, position, speed, bg_size 前面都设置了"""ball = Ball(grayball_image, greenball_image, position, speed, bg_size, 5 * (i+1)) # 实例化小球"""spritecollide(sprite, group, dokill, collided = None)第一个参数 sprite 是指定被检测的精灵;(就是我们写的里面的 item)第二个参数 group 是指定一个组(就是我们写的里面的 target 列表),它是 sprite 的组,因此要使用 sprite.Group() 来生成;第三个参数 dokill 是设置是否从组中删除检测到碰撞的精灵,设置为True,则删除;第四个参数 collided 是指定一个回调函数,用于定制特殊的检测方法,如果第四个参数忽略的话,默认是检测精灵之间的 rect 属性。"""# 在创建小球这里必须进行一下碰撞检测while pygame.sprite.spritecollide(ball, group, False, pygame.sprite.collide_circle):# 小球 group 不删除 圆形属性# 随机生成的小球碰撞了就再次随机生成位置ball.rect.left, ball.rect.top = randint(0, width - 100), randint(0, height - 100)balls.append(ball) # 列表用appendgroup.add(ball) # 集合用addglass = Glass(glass_image, mouse_image, bg_size) # 实例化摩擦板# 2、创建一个motion 变量来记录每一秒钟产生事件数量motion = 0# 4.1、添加一个自定义事件,每一秒钟触发一次MYTIMER = USEREVENT + 1 # 自定义事件的知识点可以查看上一节课的末尾注解pygame.time.set_timer(MYTIMER, 1000)pygame.key.set_repeat(100, 100)clock = pygame.time.Clock() # 设置帧率需要while running: # 主循环for event in pygame.event.get(): # 遍历事件if event.type == QUIT: # ×掉窗口pygame.quit()sys.exit() # 退出游戏elif event.type == GAMEOVER: # 判断事件是否为我们自定义的GAMEOVER事件loser_sound.play() # 失败的声音播放pygame.time.delay(2000) # 暂停2秒laugh_sound.play() # 嘲笑的声音播放running = False # 退出循环了# 4.2、 调用每个小球的 check() 检测 motion 的值是否匹配某一个小球的目标,# 并将motion重新初始化,以便记录下1秒鼠标事件数量elif event.type == MYTIMER:if motion:for each in group:if each.check(motion):each.speed = [0, 0]each.control = Truemotion = 0# 需要计算一下motionelif event.type == MOUSEMOTION: # 鼠标事件motion += 1elif event.type == KEYDOWN: # 键按下if event.key == K_w: # 按下w键for each in group: # 上移if each.control:each.speed[1] -= 1if event.key == K_s: # 按下s键for each in group: # 下移if each.control:each.speed[1] += 1if event.key == K_a: # 按下a键for each in group: # 左移if each.control:each.speed[0] -= 1if event.key == K_d: # 按下d键for each in group: # 右移if each.control:each.speed[0] += 1if event.key == K_SPACE: # 按下空格键for each in group:if each.control:for i in hole:if i[0] <= each.rect.left <= i[1] and \i[2] <= each.rect.top <= i[3]:hole_sound.play()each.speed = [0, 0] # 固定该小球group.remove(each) # 不会被撞到# 下面两行语句就是完成该小球第一个绘制,# 然后其它小球就在该小球上边了temp = balls.pop(balls.index(each)) # 先从temp 中弹出balls.insert(0, temp) # 然后插入到第一个的位置,就会第一个画了hole.remove(i) # 把这个黑洞去掉if not hole: # 所有洞补完,游戏结束pygame.mixer.music.stop() # 停止背景音乐winner_sound.play() # 播放胜利音效pygame.time.delay(3000) # 播放音效需要时间,延迟3秒msg = pygame.image.load("win.png").convert_alpha()msg_pos = (width - msg.get_width()) // 2, \(height - msg.get_height()) // 2msgs.append((msg, msg_pos))# 播放音效laugh_sound.play()"""blit:第一个参数为一个Surface对象,第二个为左上角位置。画完以后得用update更新,否则画面一片漆黑。"""# 更新图像的位置,这里是更新背景图像的位置screen.blit(background, (0, 0))screen.blit(glass.glass_image, glass.glass_rect) # 更新摩擦板位置glass.mouse_rect.left, glass.mouse_rect.top = pygame.mouse.get_pos() # 获得鼠标当前位置if glass.mouse_rect.left < glass.glass_rect.left: # 鼠标左边<摩擦板左边,即从左边出去了glass.mouse_rect.left = glass.glass_rect.left # 让鼠标手保持在左边界if glass.mouse_rect.left > glass.glass_rect.right - glass.mouse_rect.width:glass.mouse_rect.left = glass.glass_rect.right - glass.mouse_rect.widthif glass.mouse_rect.top < glass.glass_rect.top:glass.mouse_rect.top = glass.glass_rect.topif glass.mouse_rect.top > glass.glass_rect.bottom - glass.mouse_rect.height:glass.mouse_rect.top = glass.glass_rect.bottom - glass.mouse_rect.heightscreen.blit(glass.mouse_image, glass.mouse_rect) # 更新手位置for each in balls: # 遍历小球each.move() # 移动小球if each.collide:each.speed = [randint(1, 10), randint(1, 10)] # 随机生成速度each.collide = Falseif each.control:screen.blit(each.greenball_image, each.rect)else:screen.blit(each.grayball_image, each.rect) # 更新小球位置for each in group:group.remove(each) # 把自身拿出来if pygame.sprite.spritecollide(each, group, False, pygame.sprite.collide_circle): # 把自己和别的球进行碰撞检测each.side[0] = -each.side[0]each.side[1] = -each.side[1]each.collide = Trueif each.control:each.side[0] = -1each.side[1] = -1each.control = Falsegroup.add(each) # 还要把自己放进去# 打印消息for msg in msgs:screen.blit(msg[0], msg[1])pygame.display.flip() # 刷新界面# 数越大越快clock.tick(30)if __name__ == "__main__": # 运行try:main()except SystemExit: # 这是按下 × 的异常,直接忽略passexcept:traceback.print_exc()pygame.quit()input()
所有图片素材
1.背景(background.png)
2.摩擦板(grass.png) 3.胜利显示的图片(win.png)
4.灰球(gray_ball.png) 5.绿球 (green_ball.png) 6.摩擦板内的摩擦手(hand.png)
音乐素材
以下的 .ogg文件 音乐素材这里发不了,请在评论区自留邮箱,看到发你邮箱
下载链接
或者直接下载,里面代码和各种素材齐全
https://download.csdn.net/download/qq_39236499/12692654
90.pygame游戏-玩个球(play the ball)最终版相关推荐
- 大球吞小球html5游戏在线玩,大球吃小球大作战
大球吃小球大作战是以大鱼吃小鱼这个定论做的一款休闲类游戏,游戏玩法如题,尽量多的吃掉比你小的,不要被比你大的吃掉了哟. 官方介绍 大球吃小球大作战是一款酷萌的休闲游戏,玩家在游戏中就要大球吃小球,努力 ...
- “玩个球啊”,我开发的联网对战游戏
项目预览地址: Moderate入口:zero2one.moderate.run/center/game[2] 独立入口:blog.moderate.run/[3] 我看到这个活动,我就兴奋了 首先我 ...
- 【pygame游戏开发】这几个经典游戏,勾起了少年的快乐
给大家分享几个好玩有趣的小游戏,既提升了学习的兴趣,又提升了学习效率,告别枯燥的学习. 一.飞机大战 1.源码部分 模块导入 import sys import cfg import pygame f ...
- 50个新的游戏玩法机制
50个新的游戏玩法机制 Hero86 https://www.jianshu.com/p/c244075cac63 游戏玩法创新 我这里所说的游戏设置是指游戏提供给玩家的挑战,以及玩家为了应对这些挑 ...
- python和pygame游戏开发指南_学习记录
<python和pygame游戏开发指南> Making Games With Python and Palme [美]Ai Sweigart 著,李强 译,2015.12第一版 文章目录 ...
- ar ebs 销售订单关闭_本周大新闻|《哈利波特》AR游戏玩法公开,谷歌关闭VR影视部门...
本周,AR方面,专利显示苹果可能会推出AR/VR混合设计的头显:Vuzix将与Verizon合作,通过运营商渠道分销:Niantic<哈利波特:巫师联盟>AR游戏玩法公开,比<精灵宝 ...
- 休闲经营的农场小游戏推荐,果蔬连连看h5版游戏玩法技巧
想必许多80.90后的小伙伴们对农场小游戏并不陌生,当年经典的人人农场游戏,开创了农场小游戏玩法的先河,随着游戏的玩法不断更新,玩家对于农场游戏的品质也是越来越高!今天咱们就来聊聊农场游戏和农场果蔬连 ...
- Axie Infinity 是一个受神奇宝贝启发的宇宙,任何人都可以通过熟练的游戏玩法和对生态系统的贡献来赚取代币
Axie Infinity Axie Infinity 是一个受神奇宝贝启发的宇宙,任何人都可以通过熟练的游戏玩法和对生态系统的贡献来赚取代币.玩家可以为他们的宠物战斗.收集.饲养和建立一个陆地王国. ...
- 自学一周python做的一个小游戏《大球吃小球》
需求 1,显示一个窗口. 2,我们要做到的功能有鼠标点击屏幕生成小球. 3,生成的小球大小随机,颜色随机,向随机方向移动,速度也随机. 4,大的球碰到小球时可以吃掉小球,吃掉后会变大. 5,球碰到边界 ...
最新文章
- python 释放变量所指向的内存_通俗易懂的Python垃圾回收机制及内存管理
- pycharm Application cannot start in headless mode
- 【HDU2683 TCE-frep number system 完全数+二项展开式】
- 程序员必备:Java 日期处理的十个坑
- 31岁博士副县长拟提任正处,3年前毕业被人才引进
- HTML+CSS+JS实现 ❤️echarts省市区地图城市选择❤️
- 利用CSS使元素在水平方向或水平,竖直同时居中
- java中notify是什么意思_java中wait,notify,notifyAll是什么?
- adoption/adaption
- Echarts 地图基本使用
- 非计算机专业,如何学习计算机视觉
- dpbs和pbs的区别_简单问题:PBS缓冲液到底是什么?
- 栈的图文解析 和 对应3种语言的实现(C/C++/Java)
- 北斗卫星短信通信与定位详解
- 用VMware安装Windows 8.x虚拟机镜像系统详细流程
- LeetCode(89)GrayCode
- Leetcode刷题149. 直线上最多的点数
- 考研英语阅读理解错8个,我今年会不会凉?
- vscode json文件配置
- 当一个摆子前端太闲的时候会做什么
热门文章
- JS 事件代理和事件委托
- 关于SAP采购信息记录的价格失效后,采购订单不要带出失效价格具体实现
- 安卓搭建http文件服务器,如何在安卓上搭建http服务器
- 进销存软件修改调整商品的成本(库存成本)
- qca4004 linux wifi,物联网 WIFI 一键配置原理(smartconfig) ESP8266/QCA4004
- Linux Oracle install studing
- 《强化学习》 基本概念和交叉熵方法
- 机器学习中的范数理解(L0,L1,L2)
- OpenCV图像处理基础(C++版)
- 微信新BUG曝光:好友偷偷删了你,用这招就能查出来!