网站优化怎么学,龙岗百度快速排名,互联网线上推广是什么工作,浅谈中兴电子商务网站建设1.视频效果演示 python自制黄金矿工#xff0c;细节拉满沉浸式体验#xff0c;看了你也会 2.开发准备的工具
python3.8, pygame库(python3.5以上的版本应该都可以)
图片处理工具#xff0c;美图秀秀
截图工具#xff0c;电脑自带的
自动抠图网页#xff1a;https://ko…1.视频效果演示 python自制黄金矿工细节拉满沉浸式体验看了你也会 2.开发准备的工具
python3.8, pygame库(python3.5以上的版本应该都可以)
图片处理工具美图秀秀
截图工具电脑自带的
自动抠图网页https://koutu.gaoding.com/m
mp4格式文件转游戏音频https://www.aconvert.com/cn/audio/mp4-to-wav/#google_vignette
声音录制工具oCam 3.开发和设计思路
素材来源主要是在4399的黄金矿工游戏录制游戏音频和截图游戏里面的元素
游戏设计了12个关卡
3.1游戏中的元素
游戏矿石7种大黄金小黄金中等黄金钻石小石头大石头,盲盒
大黄金价值500
小黄金价值75
中等黄金价值200
钻石价值600
小石头价值20
大石头价值60
盲盒 -300 --- 700 也就是有可能抓的盲盒是负的
钻石会随着等级的升级而变得更贵
7种矿石在每局游戏种会随机出现。并不会每次全部出现。 游戏道具6种小黄金升值道具钻石升值道具钻石数量增加道具时间延长道具幸运四叶草强壮水石头收藏书
在商城里面每次只会提供三种道具这是随机的
游戏道具每次的价格是随机的所以要根据你的金钱数量调整游戏策略 小黄金道具如果购买了小黄金的价格会变成125 25 * 游戏关卡小黄金的价格
钻石升值道具使用了钻石变成600 300 增值300 300 75 * Game_config.level
钻石数量增加道具如果在商店购买了钻石的数量会在之前的基础上生成钻石的随机值最大的可能值会3
时间延长道具使用之后游戏时间会变成80秒正常一局游戏60s
幸运四叶草: 幸运四叶草在商店买了的化抓取到了神秘礼包盲盒金额会随机的变多 500 -- 1000 否则是 -300 --- 700
强壮水抓取物品的速度会变的更快speed 2
石头收藏书: 石头增值道具如果买了大石头的价格会*4
1到12关的目标金额 [1000, 2200, 3600, 5400, 7500, 10000, 12500, 17000, 21500, 26000, 30000, 45000]
3.2音频素材
音频素材6段抓到大黄金的声音抓到石头的声音绳子变长的声音金钱变多的声音绳子摆动的声音目标分数的声音
3.2游戏界面
游戏界面四个开始界面游戏界面商城界面失败或者结束界面
3.3关于如何让矿工动起来
关于如何让矿工动起来 使用不同的图片让pygame在不同时间播放不同的图片。
我最喜欢这个游戏的部分就是矿工满头大汗抓矿石的样子哈哈哈。
还有就是商城道具和矿石的随机性。
3.4如何让绳子和钩子动起来
如何让钩子和绳子动起来。
钩子的摆动幅度是-70 到 70 度每次变化的幅度是3度
这里使用了三角函数sin cos 来实现
总共有9张钩子的图片随着角度的变化显示不同的图片 3.5关于每个关卡矿石的生成策略
#每个关卡游戏界面物品的生成 钻石的基础数量是0
如果在商店买了钻石水 3
如果等级能被4整除 钻石的数量 no_diamond 2 int(level/3) 如果等级大于6
钻石的数量 no_diamond 2 如果等级大于等于8
钻石的数量 no_diamond 4 如果等级大于等于12
钻石的数量 no_diamond 10 神秘包裹盲盒的数量
如果等级能被2整除 no_random 3 int(level/2)
否则 no_random 1 大黄金的数量
如果等级大于等于3no_big 1 no_big level//2
否则大黄金数量等于0 如果等级大于等于6 no_big 2 如果等级大于等于8 no_big 3
如果等级大于等于12 no_big 6 base 一些物品的最小基础值
如果等级大于等于6 base 1 否则 base 0
如果等级大于等于8 base 2 如果等级大于等于12 base 5 如果等级大于等于8 小石头的数量[0,2] 如果等级大于等于8 小黄金的数量[0,2或者3] 如果等级小于8 小石头的数量 [5,7]
如果等级小于8 小黄金的数量 5 level // 2, 12 level // 2 中等黄金的数量
0, random.randint(5level//2, 8level//2) 大石头的数量 0, random.randint(1 level // 4 base, 3 level // 4 base) 大黄金的数量 0, random.randint(base, no_big) 钻石的数量
0, random.randint(base, no_diamond) 神秘包裹的数量
0, random.randint(base, no_random) 游戏的fps
ticks_per_second 30 表示是1000/30 的刷新频率 如果生成的物品模型发生了重叠那么要重新生成
3.6代码文件
代码文件:gamebox.py 对pygame库的二次封装
Gold_mine.py 游戏逻辑主要代码 4.代码部分
gold_miner.py文件
import timeimport pygame
from enum import Enum, unique
import gamebox
import random
import mathunique #此装饰器可以帮助我们检查保证没有重复值
class Screen(Enum):screen_begin 0screen_game 1screen_shop 2screen_target_score 3screen_failed 4unique #此装饰器可以帮助我们检查保证没有重复值
class Character(Enum):character_up 0character_down 1class Character_Getthing(Enum):character_up_getthin 0character_down_getthin 1class Game_Background(Enum):background_begin 0background_game_heard 1background_game_body 2background_shop 3background_target_score 4background_failed 5class Audio(Enum):audio_money_increase 0audio_target_score 1audio_rope_swing 2audio_go_long 3audio_get_big_gold 4audio_get_stone 5
#矿石
unique
class Mineral(Enum):gold_small 0gold_middle 1gold_big 2stone_small 3stone_big 4Diamond 5random_big 6#钩子的每一帧图片hook_dict {}
hook_dict[-70] hook/hook_70.png
hook_dict[-43] hook/hook_43.png
hook_dict[-31] hook/hook_31.png
hook_dict[-16] hook/hook_16.png
hook_dict[1] hook/hook_1.png
hook_dict[14] hook/hook14.png
hook_dict[32] hook/hook32.png
hook_dict[44] hook/hook44.png
hook_dict[68] hook/hook68.png#游戏配置类
class Game_config():speed 5# 游戏关卡从第一关开始level 1#游戏金钱money 0#钩子摆动的角度 -70 --- 70radins -70#摆动的角度每次偏移的值radins_offset 3radins_min -70radins_max 70#绳子的初始长度距离chain_distance 30#绳子的变化速度 抓到不同的重量 速度不一样weight_item_caught speed 5#钩子的变化速度控制抓到不同物体速度变化不一样pict_index 0#控制一局游戏的时间 和刷新频率有关系 当前1s刷新15次计数器60s刷新900次counter 900popped_up_word_counterdown 16#大黄金的价格和标志gold_large_value 500gold_small_value 75gold_middle_value 200dimaond_value 600small_rock_value 20big_rock_value 60#抓到了神秘背包那么绳子移动速度是随机的-45#价值也是随机的# 每局游戏的目标分数money_goal [1000, 2200, 3600, 5400, 7500, 10000, 12500, 17000, 21500, 26000, 30000, 45000]#矿石生成的随机区域的范围控制mineral_race_min_x 50mineral_race_max_x 900mineral_race_min_y 240mineral_race_max_y 690#按钮的范围绘制#开始按钮的坐标范围button_start_min_x 38button_start_max_x 400button_start_min_y 18button_start_max_y 370#音频文件#游戏开始和目标分数的音频sound_start sound/audio_target_score.wav#绳子摆动的音频sound__rope_swing sound/audio_rope_swing.wav#金钱增加的声音sound__money_increase sound/audio_money_increase.wav#绳子变长的声音sound_go_long sound/audio_go_long.wav#抓到石头的声音sound_get_stone sound/audio_get_stone.wav#抓到大黄金的声音sound_get_big_gold sound/audio_get_big_gold.wav#商店的三个格子每次只能点击一次store_index Falsestore_index2 Falsestore_index3 False#生成物品的算法如果发生了碰撞最多尝试10次try_times 10#商店
class Store():# 如果购买了小黄金的价格会变成125 25 * levelitem_gold_modifer False# 如果购买了钻石的价值会增加300item_polisher False# 如果在商店购买了钻石的数量会在之前的基础上生成钻石的随机值最大的可能值会3item_lamp False# 时间延长器如果在商店买了计数增加到1200item_time False#幸运四叶草在商店买了的化抓取到了神秘礼包金额会随机的变多# 500 -- 1000# 否则是# -300 --- 700item_luck False#如果购买了会变得强壮速度2item_strong False# 石头增值道具如果买了大石头的价格会*4item_rocks False#商品的枚举类型
unique
class Store_index(Enum):index_gold_modifer 0index_polisher 1index_lamp 2index_time 3index_luck 4index_strong 5index_rocks 6dict_goods_picture {}
dict_goods_picture[Store_index.index_gold_modifer.value] goods/gold_modifer.png
dict_goods_picture[Store_index.index_polisher.value] goods/polisher.png
dict_goods_picture[Store_index.index_lamp.value] goods/lamp.png
dict_goods_picture[Store_index.index_time.value] goods/time.png
dict_goods_picture[Store_index.index_luck.value] goods/luck.png
dict_goods_picture[Store_index.index_rocks.value] goods/rocks.png
dict_goods_picture[Store_index.index_strong.value] goods/strong.png
dict_goods_text {}dict_goods_text[Store_index.index_gold_modifer.value] 小黄金会变得更值钱
dict_goods_text[Store_index.index_polisher.value] 钻石会变得更值钱
dict_goods_text[Store_index.index_lamp.value] 钻石会变得更多
dict_goods_text[Store_index.index_time.value] 游戏时间会变得更长
dict_goods_text[Store_index.index_luck.value] 神秘礼包的金额会变得更多
dict_goods_text[Store_index.index_rocks.value] 大石头的价格会增加4倍
dict_goods_text[Store_index.index_strong.value] 矿工会变更强壮加快#矿石图片存储列表
picture_mineral [picture/gold_small.png,picture/gold_middle.png,picture/gold_big.png,picture/rock_small.png,picture/rock_big.png,picture/dimaond.png,picture/mystery_bag.png]
#平常状态的角色
picture_list_character [picture/character_up.png,picture/character_down.png]
#抓取到东西的时候的角色图片
picture_list_character_getthing [picture/character_up_getthin.png,picture/character_down_getthin.png]
#商品的图片
picture_list_goods [picture/character_up_getthin.png]
#音频文件
sound_list [sound/audio_money_increase.png,sound/audio_target_score.png,sound/audio_rope_swing.png,picture/audio_go_long.png,picture/audio_get_big_gold.png,picture/audio_get_stone7.png]
picture_list_screen [picture/screen_begin.png,picture/screen_game_head.png,picture/screen_game_body.png,picture/screen_shop.png,picture/screen_target_score.png,picture/screen_failed.png]#全局变量
#界面index
#0开始界面
#1游戏界面
#2商城界面
#3目标分数界面
#4失败界面
screen 0
#游戏界面的长宽
cameragamebox.Camera(1000, 700)
# 在左上角绘制文字
pygame.display.set_caption(制作人:慕白白ls)#Item value
#抓到的东西的价格
value_caught 0
#人物角色的控制每一帧显示的图片
character_index 0#bool 游戏中元素的状态值
#钩子的状态
chain_thrown_out False
#钩子的方向状态 右- 左 or 左-右
direction_left_to_rightTrue
#钩子是否被仍出去了
chain_thrown_out False
#绳子是伸长状态还是收缩状态
chain_thrown_out_away True
#钩子是否抓取到了东西
chain_thrown_out_catchsomething False#钩子对象
chainhead gamebox.from_image(200, 200, hook_dict[-70])
#人物对象
character gamebox.from_image(507, 41, picture_list_character[0])character_getthing gamebox.from_image(507, 41, picture_list_character_getthing[character_index])#显示在游戏界面的物品
gold_middle_object gamebox.from_image(400,400,picture_mineral[Mineral.gold_middle.value])
gold_small_object gamebox.from_image(500,500,picture_mineral[Mineral.gold_small.value])
gold_large_object gamebox.from_image(700,500,picture_mineral[Mineral.gold_big.value])
gold_dimaond_object gamebox.from_image(700, 500, picture_mineral[Mineral.Diamond.value])
gold_small_rock_object gamebox.from_image(400, 600, picture_mineral[Mineral.stone_small.value])
gold_big_rock_object gamebox.from_image(600, 600, picture_mineral[Mineral.stone_big.value])
gold_random_big_object gamebox.from_image(200, 300,picture_mineral[Mineral.random_big.value])hard_object gamebox.from_image(580, 20,picture/strong.png)
#list
gold_middle_list []
gold_small_list []
gold_large_list []
gold_dimaond_list []
gold_small_rock_list []
gold_big_rock_list []
gold_random_big_list []#商品存储列表
shop_list []
shop_price []def Set_Store_value(value):if(value Store_index.index_gold_modifer.value):Store.item_gold_modifer Trueif (value Store_index.index_polisher.value):Store.item_polisher Trueif (value Store_index.index_lamp.value):Store.item_lamp Trueif (value Store_index.index_time.value):Store.item_time Trueif (value Store_index.index_luck.value):Store.item_luck Trueif (value Store_index.index_strong.value):Store.item_strong Trueif (value Store_index.index_rocks.value):Store.item_rocks Trueif Store.item_strong:Game_config.speed 2#回调函数循环接收键盘和鼠标的消息
#钩子的变化范围是从-70 的角度 变化到70
def Callback_Loop(keys):global screen , camera ,character_index,character,value_caughtglobal chain_thrown_out_catchsomething,chain_thrown_out,direction_left_to_rightglobal chain_thrown_out,chain_thrown_out_away,shop_price,shop_priceglobal shop_listcamera.clear(grey)if screen Screen.screen_begin.value:#设置显示的图片大小长宽#screen_surface gamebox.from_image(500, 350, picture_list_screen[Game_Background.background_begin.value])screen_surface gamebox.from_image(500, 350, picture/begin.png)screen_surface.scale_by(0.9)camera.draw(screen_surface)camera.draw(gamebox.from_text(200, 430, 制作人:慕白白ls, SimHei, 30, yellow))# 文字信息camera.draw(gamebox.from_text(200, 500, 点击开始按钮开始游戏, SimHei, 30, yellow))#播放音乐if pygame.mixer.music.get_busy() False:pygame.mixer.music.load(Game_config.sound_start)pygame.mixer.music.play()#监听消息查看是否点击了开始游戏if pygame.MOUSEBUTTONDOWN in keys:#响应了当前点击事件之后马上把这个事件删除keys.remove(pygame.MOUSEBUTTONDOWN)pos pygame.mouse.get_pos()if pos[0] Game_config.button_start_min_x and pos[0] Game_config.button_start_max_x and \pos[1] Game_config.button_start_min_y and pos[1] Game_config.button_start_max_y:screen Screen.screen_game.valueGoods_Generate(Game_config.level)#游戏界面if screen Screen.screen_game.value:#绘制游戏主体背景picture gamebox.from_image(500, 380, picture_list_screen[Game_Background.background_game_body.value])#游戏背景头picture2 gamebox.from_image(500, 37.5, picture_list_screen[Game_Background.background_game_heard.value])picture2.scale_by(0.6)picture.scale_by(0.7)camera.draw(picture)camera.draw(picture2)if pygame.MOUSEBUTTONDOWN in keys:# 响应了当前点击事件之后马上把这个事件删除keys.remove(pygame.MOUSEBUTTONDOWN)pos pygame.mouse.get_pos()if pos[0] 786 and pos[0] 881 and \pos[1] 7 and pos[1] 67 :Game_config.counter 0#绘制人物角色if chain_thrown_out_catchsomething :character_getthing.image picture_list_character_getthing[character_index]camera.draw(character_getthing)# 语气词语camera.draw(hard_object)else:camera.draw(character)if character_index 0:character_index 1else:character_index 0if chain_thrown_out False:#绘制绳子左右摆动的声音if pygame.mixer.music.get_busy() False:pygame.mixer.music.load(Game_config.sound__rope_swing)pygame.mixer.music.play()if Game_config.popped_up_word_counterdown 16:if direction_left_to_right True:Game_config.radins Game_config.radins_offsetelse:Game_config.radins - Game_config.radins_offsetif Game_config.radins Game_config.radins_min:direction_left_to_right Trueif Game_config.radins Game_config.radins_max:direction_left_to_right False# 绘制钩子if Game_config.radins in hook_dict:chainhead.image hook_dict[Game_config.radins]chainhead.x 500 math.sin(Game_config.radins / 57.29) * 75chainhead.y 75 math.cos(Game_config.radins / 57.29) * 75camera.draw(chainhead)# 绳子的本体item gamebox.from_color(500, 75, black, 5, 5)for i in range(0, 26):item gamebox.from_color(500 math.sin(Game_config.radins / 57.29) * 2.5 * i,75 math.cos(Game_config.radins / 57.29) * 2.5 * i, black, 5, 5)camera.draw(item)# 按下向下的方向键的时候if pygame.K_DOWN in keys and chain_thrown_out False and Game_config.popped_up_word_counterdown 16:chain_thrown_out Truechain_thrown_out_away Truechain_thrown_out_catchsomething False# 抓东西的时候角色放大了1.2倍#character.scale_by(1.2)#按下向下的方向键绳子慢慢边长if chain_thrown_out True and chain_thrown_out_away True:Game_config.chain_distance Game_config.speed#绳子变长时候的音乐pygame.mixer.music.stop()if pygame.mixer.music.get_busy() False:pygame.mixer.music.load(Game_config.sound_go_long)pygame.mixer.music.play()#把绳子慢慢增长有多长就画多少个黑色像素for i in range(1, Game_config.chain_distance):item gamebox.from_color(500 math.sin(Game_config.radins / 57.29) * 2.5 * i,75 math.cos(Game_config.radins / 57.29) * 2.5 * i, black, 5, 5)camera.draw(item)chainhead.x 500 math.sin(Game_config.radins / 57.29) * (10 2.5 * Game_config.chain_distance)chainhead.y 75 math.cos(Game_config.radins / 57.29) * (10 2.5 * Game_config.chain_distance)if Game_config.radins in hook_dict:chainhead.image hook_dict[Game_config.radins]camera.draw(chainhead)#到低了绳子开始收缩if chain_thrown_out True and chain_thrown_out_away False:Game_config.chain_distance - Game_config.weight_item_caughtfor i in range(1, Game_config.chain_distance):item gamebox.from_color(500 math.sin(Game_config.radins / 57.29) * 2.5 * i,75 math.cos(Game_config.radins / 57.29) * 2.5 * i, black, 5, 5)camera.draw(item)chainhead.x 500 math.sin(Game_config.radins / 57.29) * (10 2.5 * Game_config.chain_distance)chainhead.y 75 math.cos(Game_config.radins / 57.29) * (10 2.5 * Game_config.chain_distance)camera.draw(chainhead)# 钩子超过界面的边界了if chainhead.x 0 or chainhead.x 1000 or chainhead.y 700:chain_thrown_out_away False#抓到东西到最上面了金钱要增加if Game_config.chain_distance 29 and chain_thrown_out True:if chain_thrown_out_catchsomething True:# 金钱增加的声音pygame.mixer.music.stop()if pygame.mixer.music.get_busy() False:pygame.mixer.music.load(Game_config.sound__money_increase)pygame.mixer.music.play()if value_caught ! 0:Game_config.popped_up_word_counterdown 1Game_config.money value_caughtchain_thrown_out_catchsomething Falsechain_thrown_out False#角色缩小0.833#character.scale_by(0.833)Game_config.weight_item_caught Game_config.speed 5#操作游戏的时候物品的变化for gold in gold_middle_list:if gold.touches(chainhead) and chain_thrown_out_catchsomething False:chain_thrown_out_away Falsechain_thrown_out_catchsomething TrueGame_config.weight_item_caught Game_config.speed - 2Game_config.pict_index Mineral.gold_middle.valuevalue_caught Game_config.gold_middle_valuegold_middle_list.remove(gold)camera.draw(gold)for gold in gold_small_list:if gold.touches(chainhead) and chain_thrown_out_catchsomething False:chain_thrown_out_away Falsechain_thrown_out_catchsomething TrueGame_config.weight_item_caught Game_config.speedGame_config.pict_index Mineral.gold_small.valueif Store.item_gold_modifer True:value_caught 125 25 * Game_config.levelelse:value_caught Game_config.gold_small_valuegold_small_list.remove(gold)camera.draw(gold)for gold in gold_large_list:if gold.touches(chainhead) and chain_thrown_out_catchsomething False:chain_thrown_out_away Falsechain_thrown_out_catchsomething TrueGame_config.weight_item_caught Game_config.speed - 4Game_config.pict_index Mineral.gold_middle.gold_big.valuevalue_caught Game_config.gold_large_valuegold_large_list.remove(gold)#抓到大黄金声音pygame.mixer.music.stop()if pygame.mixer.music.get_busy() False:pygame.mixer.music.load(Game_config.sound_get_big_gold)pygame.mixer.music.play()camera.draw(gold)for gold in gold_dimaond_list:if gold.touches(chainhead) and chain_thrown_out_catchsomething False:chain_thrown_out_away Falsechain_thrown_out_catchsomething TrueGame_config.weight_item_caught Game_config.speed 4Game_config.pict_index Mineral.Diamond.valuegold_dimaond_list.remove(gold)if Store.item_polisher True:value_caught Game_config.dimaond_value 300 75 * Game_config.levelelse:value_caught Game_config.dimaond_value 50 * Game_config.levelcamera.draw(gold)for gold in gold_small_rock_list:if gold.touches(chainhead) and chain_thrown_out_catchsomething False:chain_thrown_out_away Falsechain_thrown_out_catchsomething TrueGame_config.weight_item_caught Game_config.speed - 2Game_config.pict_index Mineral.stone_small.valuevalue_caught Game_config.small_rock_valueif Store.item_rocks True:value_caught value_caught * 4gold_small_rock_list.remove(gold)# 抓到石头pygame.mixer.music.stop()if pygame.mixer.music.get_busy() False:pygame.mixer.music.load(Game_config.sound_get_stone)pygame.mixer.music.play()camera.draw(gold)for gold in gold_big_rock_list:if gold.touches(chainhead) and chain_thrown_out_catchsomething False:chain_thrown_out_away Falsechain_thrown_out_catchsomething TrueGame_config.weight_item_caught Game_config.speed - 4Game_config.pict_index Mineral.stone_big.valueGame_config.value_caught Game_config.big_rock_valueif Store.item_rocks True:value_caught value_caught * 4gold_big_rock_list.remove(gold)# 抓到石头pygame.mixer.music.stop()if pygame.mixer.music.get_busy() False:pygame.mixer.music.load(Game_config.sound_get_stone)pygame.mixer.music.play()camera.draw(gold)for gold in gold_random_big_list:if gold.touches(chainhead) and chain_thrown_out_catchsomething False:if chain_thrown_out_catchsomething False:Game_config.weight_item_caught Game_config.speed random.randint(-4, 5)chain_thrown_out_away Falsechain_thrown_out_catchsomething TrueGame_config.pict_index Mineral.random_big.valueif Store.item_luck True:value_caught random.randint(500, 1000)else:value_caught random.randint(-300, 700)gold_random_big_list.remove(gold)camera.draw(gold)#抓到了物品要把物品挂在钩子上if chain_thrown_out_catchsomething True:item gamebox.from_image(500 math.sin(Game_config.radins / 57.29) * 2.5 * (Game_config.chain_distance10),75 math.cos(Game_config.radins / 57.29) * 2.5 * (Game_config.chain_distance10), picture_mineral[ Game_config.pict_index])camera.draw(item)#绘制游戏的参数的变化Game_config.counter - 1camera.draw(gamebox.from_text(850, 100, 游戏关卡: str(Game_config.level) 目标金额: str(Game_config.money_goal[Game_config.level - 1]), SimHei,20, yellow))camera.draw(gamebox.from_text(135, 25, 你的金钱: $ str(Game_config.money), SimHei, 24, yellow))camera.draw(gamebox.from_text(130, 55, 剩余时间: str(int(Game_config.counter / 15)), SimHei, 22, red))Game_config.popped_up_word_counterdown 1if Game_config.popped_up_word_counterdown 15:if value_caught 0:camera.draw(gamebox.from_text(300, 25, $ str(value_caught), arial, 30, green, boldTrue))else:camera.draw(gamebox.from_text(300, 25, str(value_caught), arial, 30, red, boldTrue))elif Game_config.popped_up_word_counterdown 16:value_caught 0#游戏时间结束之后的处理if Game_config.counter 0:if Game_config.money Game_config.money_goal[Game_config.level - 1] or Game_config.level 12 :#进入游戏失败的界面screen Screen.screen_failed.value#否则进入游戏商城界面else:Game_config.level 1# shop generationsrandom_list [0, 1, 2, 3, 4, 5, 6]random.shuffle(random_list)shop_list []shop_price []shop_selection 0shop_list.append(random_list[0])shop_list.append(random_list[1])shop_list.append(random_list[2])# 商店的商品价格随着等级的增高# 相应的要变贵# 变化的范围是 基础价格 等级*10 到 基础价格等级*150之间for stuff in shop_list:if Game_config.level ! 12:if stuff 0:shop_price.append(random.randint(25 Game_config.level * 10, 300 Game_config.level * 50))elif stuff 1:shop_price.append(random.randint(400, 600 Game_config.level * 50))elif stuff 2:shop_price.append(random.randint(50 Game_config.level * 20, 300 Game_config.level * 30))elif stuff 3:shop_price.append(random.randint(200 Game_config.level * 20, 600 Game_config.level * 75))elif stuff 4:shop_price.append(random.randint(50 Game_config.level * 20, 200 Game_config.level * 50))elif stuff 5:shop_price.append(random.randint(50 Game_config.level * 30, 400 Game_config.level * 150))else:shop_price.append(random.randint(5 Game_config.level * 20, 200 Game_config.level * 10))else:shop_price.append(0)#游戏结束回复游戏的初始参数Game_config.speed 5Store.item_gold_modifer FalseStore.item_polisher FalseStore.item_lamp FalseStore.item_time FalseStore.item_luck FalseStore.item_rocks False#进入商城界面screen Screen.screen_shop.valuechain_thrown_out_catchsomething Falsechain_thrown_out False#character.scale_by(0.833)Game_config.weight_item_caught Game_config.speed 5value_caught 0if screen Screen.screen_shop.value:#播放音乐if pygame.mixer.music.get_busy() False:pygame.mixer.music.load(Game_config.sound_start)pygame.mixer.music.play()picture gamebox.from_image(500, 360, picture_list_screen[Game_Background.background_shop.value])picture.scale_by(0.8)camera.draw(picture)if shop_list[0] ! -1:camera.draw(gamebox.from_image(100, 430, dict_goods_picture[shop_list[0]]))camera.draw(gamebox.from_text(110, 550, $ str(shop_price[0]), SimHei, 22, green))camera.draw(gamebox.from_text(180, 650, 商品1: dict_goods_text[shop_list[0]], SimHei, 16, yellow))if shop_list[1] ! -1:camera.draw(gamebox.from_image(300, 430, dict_goods_picture[shop_list[1]]))camera.draw(gamebox.from_text(310, 550, $ str(shop_price[1]), SimHei, 22, green))camera.draw(gamebox.from_text(430, 650, 商品2: dict_goods_text[shop_list[1]], SimHei, 16, yellow))if shop_list[2] ! -1:camera.draw(gamebox.from_image(500, 430, dict_goods_picture[shop_list[2]]))camera.draw(gamebox.from_text(510, 550, $ str(shop_price[2]), SimHei, 22, green))camera.draw(gamebox.from_text(780, 650, 商品3: dict_goods_text[shop_list[2]], SimHei, 16, yellow))camera.draw(gamebox.from_text(800, 50, 下一个关卡: str(Game_config.level) 目标金额: str(Game_config.money_goal[Game_config.level - 1]),SimHei,20, yellow))camera.draw(gamebox.from_text(850, 25, 你的金钱: $ str(Game_config.money), SimHei, 20, green))if Game_config.level 12:camera.draw(gamebox.from_text(500, 150, 最后一关了所有商品免费, SimHei, 35, green,boldTrue))if pygame.MOUSEBUTTONDOWN in keys:# 响应了当前点击事件之后马上把这个事件删除keys.remove(pygame.MOUSEBUTTONDOWN)pos pygame.mouse.get_pos()if pos[0] 62 and pos[0] 141 and \pos[1] 369 and pos[1] 502 and shop_list[0] ! -1:Game_config.money - shop_price[0]Set_Store_value(shop_list[0])shop_list[0] -1# 播放音乐pygame.mixer.music.load(Game_config.sound__money_increase)pygame.mixer.music.play()if pos[0] 227 and pos[0] 362 and \pos[1] 372 and pos[1] 494 and shop_list[1] ! -1:Game_config.money - shop_price[1]Set_Store_value(shop_list[1])shop_list[1] -1pygame.mixer.music.load(Game_config.sound__money_increase)pygame.mixer.music.play()if pos[0] 438 and pos[0] 596 and \pos[1] 363 and pos[1] 496 and shop_list[2] ! -1:Game_config.money - shop_price[2]Set_Store_value(shop_list[2])shop_list[2] -1pygame.mixer.music.load(Game_config.sound__money_increase)pygame.mixer.music.play()if pos[0] 767 and pos[0] 899 and \pos[1] 122 and pos[1] 180 :screen Screen.screen_game.valueGoods_Generate(Game_config.level)if screen Screen.screen_target_score.value:passif screen Screen.screen_failed.value:picture gamebox.from_image(500, 360, picture_list_screen[Game_Background.background_failed.value])picture.scale_by(0.9)camera.draw(picture)camera.draw(gamebox.from_text(500, 400, 你的总分数是: str(Game_config.money), SimHei, 40, red))if pygame.MOUSEBUTTONDOWN in keys:# 响应了当前点击事件之后马上把这个事件删除keys.remove(pygame.MOUSEBUTTONDOWN)pos pygame.mouse.get_pos()if pos[0] 78 and pos[0] 216 and \pos[1] 619 and pos[1] 673 :screen Screen.screen_game.valueGame_config.level 1print(1)Goods_Generate(Game_config.level)Game_config.money 0#绘制游戏界面camera.display()#每个关卡游戏界面物品的生成# 钻石的基础数量是0
# 如果在商店买了钻石水 3
# 如果等级能被4整除
# 钻石的数量 no_diamond 2 int(level/3)
# 如果等级大于6
# 钻石的数量 no_diamond 2
# 如果等级大于等于8
# 钻石的数量 no_diamond 4
# 如果等级大于等于12
# 钻石的数量 no_diamond 10# 神秘包裹的数量
# 如果等级能被2整除 no_random 3 int(level/2)
# 否则 no_random 1# 大黄金的数量
# 如果等级大于等于3no_big 1 no_big level//2
# 否则大黄金数量等于0
# 如果等级大于等于6 no_big 2
# 如果等级大于等于8 no_big 3
# 如果等级大于等于12 no_big 6# base 一些物品的最小基础值
# 如果等级大于等于6 base 1 否则 base 0
# 如果等级大于等于8 base 2
# 如果等级大于等于12 base 5# 如果等级大于等于8 小石头的数量[0,2]
# 如果等级大于等于8 小黄金的数量[0,2或者3]# 如果等级小于8 小石头的数量 [5,7]
# 如果等级小于8 小黄金的数量 5 level // 2, 12 level // 2# 中等黄金的数量
# 0, random.randint(5level//2, 8level//2)# 大石头的数量
# 0, random.randint(1 level // 4 base, 3 level // 4 base)# 大黄金的数量
# 0, random.randint(base, no_big)# 钻石的数量
# 0, random.randint(base, no_diamond)# 神秘包裹的数量
# 0, random.randint(base, no_random)# 游戏的fps
# ticks_per_second 30 表示是1000/30 的刷新频率# 如果生成的物品模型发生了重叠那么要重新生成
def Goods_Generate(level):global gold_middle_list,gold_small_list,gold_large_list,gold_dimaond_list,gold_small_rock_listglobal gold_big_rock_list,gold_random_big_listgold_middle_list []gold_small_list []gold_large_list []gold_dimaond_list []gold_small_rock_list []gold_big_rock_list []gold_random_big_list []#counter控制时间每局的游戏60sif Store.item_time True:Game_config.counter 1200else:Game_config.counter 900#gold_small_rock_list []if Store.item_lamp True:no_diamond 3else:no_diamond 0if level % 4 0:no_diamond 2no_diamond int(level/3)if level % 2 0:no_random 3no_random int(level/2)else:no_random 1if level 3:no_big 1no_big level//2else:no_big 0if level 6:no_diamond 2no_big 2no_random 2base 1else:base 0if level 8:no_diamond 4no_big 3no_random 3base 2if level 12:no_diamond 10base 5no_big 6no_random 6try_index Game_config.try_timesif level 8:for c in range(0, random.randint(2,3)):item gamebox.from_image(random.randint(Game_config.mineral_race_min_x, Game_config.mineral_race_max_x), random.randint(Game_config.mineral_race_min_y, Game_config.mineral_race_max_y), picture_mineral[Mineral.gold_small.value])gold_small_list.append(item)for c in range(0, 2):touched Truewhile touched and try_index 0:item gamebox.from_image(random.randint(Game_config.mineral_race_min_x, Game_config.mineral_race_max_x), random.randint(Game_config.mineral_race_min_y, Game_config.mineral_race_max_y), picture_mineral[Mineral.stone_small.value])touched Falsefor evaluated_item in gold_small_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_small_rock_list:if item.touches(evaluated_item) True:touched Truetry_index - 1if try_index 0 :gold_small_rock_list.append(item)try_index Game_config.try_timeselse:for c in range(0, random.randint(5 level // 2, 12 level // 2)):item gamebox.from_image(random.randint(Game_config.mineral_race_min_x, Game_config.mineral_race_max_x), random.randint(Game_config.mineral_race_min_y, Game_config.mineral_race_max_y), picture_mineral[Mineral.gold_small.value])gold_small_list.append(item)for c in range(0, random.randint(5, 7)):touched Truewhile touched and try_index 0:item gamebox.from_image(random.randint(Game_config.mineral_race_min_x, Game_config.mineral_race_max_x), random.randint(Game_config.mineral_race_min_y, Game_config.mineral_race_max_y), picture_mineral[Mineral.stone_small.value])touched Falsefor evaluated_item in gold_small_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_small_rock_list:if item.touches(evaluated_item) True:touched Truetry_index - 1if try_index 0 :gold_small_rock_list.append(item)try_index Game_config.try_timesfor c in range(0, random.randint(5level//2, 8level//2)):touched Truewhile touched and try_index 0:item gamebox.from_image(random.randint(Game_config.mineral_race_min_x, Game_config.mineral_race_max_x), random.randint(Game_config.mineral_race_min_y, Game_config.mineral_race_max_y), picture_mineral[Mineral.gold_middle.value])touched Falsefor evaluated_item in gold_small_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_small_rock_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_middle_list:if item.touches(evaluated_item) True:touched Truetry_index - 1if try_index 0:gold_middle_list.append(item)try_index Game_config.try_timesfor c in range(0, random.randint(1level//4base, 3level//4base)):touched Truewhile touched and try_index 0:item gamebox.from_image(random.randint(Game_config.mineral_race_min_x, Game_config.mineral_race_max_x), random.randint(Game_config.mineral_race_min_y, Game_config.mineral_race_max_y), picture_mineral[Mineral.stone_big.value])touched Falsefor evaluated_item in gold_small_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_small_rock_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_middle_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_big_rock_list:if item.touches(evaluated_item) True:touched Truetry_index - 1if try_index 0:gold_big_rock_list.append(item)try_index Game_config.try_timesfor c in range(0, random.randint(base, no_big)):touched Truewhile touched and try_index 0:item gamebox.from_image(random.randint(Game_config.mineral_race_min_x, Game_config.mineral_race_max_x), random.randint(Game_config.mineral_race_min_y, Game_config.mineral_race_max_y), picture_mineral[Mineral.gold_big.value])touched Falsefor evaluated_item in gold_small_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_small_rock_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_middle_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_big_rock_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_large_list:if item.touches(evaluated_item) True:touched Truetry_index - 1if try_index 0:gold_large_list.append(item)try_index Game_config.try_timesfor c in range(0, random.randint(base, no_diamond)):touched Truewhile touched and try_index 0:item gamebox.from_image(random.randint(Game_config.mineral_race_min_x, Game_config.mineral_race_max_x), random.randint(Game_config.mineral_race_min_y, Game_config.mineral_race_max_y), picture_mineral[Mineral.Diamond.value])touched Falsefor evaluated_item in gold_small_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_small_rock_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_middle_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_big_rock_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_large_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_dimaond_list:if item.touches(evaluated_item) True:touched Truetry_index - 1gold_dimaond_list.append(item)if try_index 0:gold_dimaond_list.append(item)try_index Game_config.try_timesfor c in range(0, random.randint(base, no_random)):touched Truewhile touched and try_index 0:item gamebox.from_image(random.randint(Game_config.mineral_race_min_x, Game_config.mineral_race_max_x), random.randint(Game_config.mineral_race_min_y, Game_config.mineral_race_max_y), picture_mineral[Mineral.random_big.value])touched Falsefor evaluated_item in gold_small_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_small_rock_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_middle_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_big_rock_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_large_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_dimaond_list:if item.touches(evaluated_item) True:touched Truefor evaluated_item in gold_random_big_list:if item.touches(evaluated_item) True:touched Truetry_index - 1if try_index 0:gold_random_big_list.append(item)try_index Game_config.try_timesif __name__ __main__:ticks_per_second 20gamebox.timer_loop(ticks_per_second, Callback_Loop)
gamebox.py 文件
# A library file for simplifying pygame interaction. You MUST place this file in the same directory as your game py files.This code is the original work of Luther Tychonievich, who releases it
into the public domain.As a courtesy, Luther would appreciate it if you acknowledged him in any work
that benefited from this code.from __future__ import division
import pygame, sys
import urllib, os.pathif urlretrieve not in dir(urllib):from urllib.request import urlretrieve as _urlretrieve
else:_urlretrieve urllib.urlretrievepygame.init()# a cache to avoid loading images many time
_known_images {}
_known_sounds {}def _image(key, flipFalse, w0, h0, angle0):A method for loading images, caching them, and flipping themif __hash__ not in dir(key):key id(key)angle, w, h int(angle), int(w), int(h)ans Noneif (key, flip, w, h, angle) in _known_images:ans _known_images[(key, flip, w, h, angle)]elif angle ! 0:base _image(key, flip, w, h)img pygame.transform.rotozoom(base, angle, 1)_known_images[(key, flip, w, h, angle)] imgans imgelif w ! 0 or h ! 0:base _image(key, flip)img pygame.transform.smoothscale(base, (w, h))_known_images[(key, flip, w, h, angle)] imgans imgelif flip:base _image(key)img pygame.transform.flip(base, True, False)_known_images[(key, flip, w, h, angle)] imgans imgelse:img, _ _get_image(key)_known_images[(key, flip, w, h, angle)] imgans imgif w 0 and h 0:if angle ! 0:tmp _image(key, flip, w, h)else:tmp ans_known_images[(key, flip, tmp.get_width(), tmp.get_height(), angle)] ansreturn ansdef _image_from_url(url):a method for loading images from urls by first saving them locallyfilename os.path.basename(url)if not os.path.exists(filename):if :// not in url: url http:// url_urlretrieve(url, filename)image, filename _image_from_file(filename)return image, filenamedef _image_from_file(filename):a method for loading images from filesimage pygame.image.load(filename).convert_alpha()_known_images[filename] image_known_images[(image.get_width(), image.get_height(), filename)] imagereturn image, filenamedef _get_image(thing):a method for loading images from cache, then file, then urlif thing in _known_images: return _known_images[thing], thingsid __id__ str(id(thing))if sid in _known_images: return _known_images[sid], sidif type(thing) is str:if os.path.exists(thing): return _image_from_file(thing)return _image_from_url(thing)_known_images[sid] thing_known_images[(thing.get_width(), thing.get_height(), sid)] thingreturn thing, siddef load_sprite_sheet(url_or_filename, rows, columns):Loads a sprite sheet. Assumes the sheet has rows-by-columns evenly-spaced images and returns a list of those images.sheet, key _get_image(url_or_filename)height sheet.get_height() / rowswidth sheet.get_width() / columnsframes []for row in range(rows):for col in range(columns):#把动图做一个切片切成均匀大小clip pygame.Rect(col * width, row * height, width, height)frame sheet.subsurface(clip)frames.append(frame)return frames__all__ [load_sprite_sheet]def from_image(x, y, filename_or_url):Creates a SpriteBox object at the given location from the provided filename or urlimage, key _get_image(filename_or_url)return SpriteBox(x, y, image, None)__all__.append(from_image)def from_color(x, y, color, width, height):Creates a SpriteBox object at the given location with the given color, width, and heightreturn SpriteBox(x, y, None, color, width, height)__all__.append(from_color)def from_text(x, y, text, fontname, fontsize, color, boldFalse, italicFalse):Creates a SpriteBox object at the given location with the given text as its contentfont pygame.font.match_font(fontname.replace( , ).lower())if font is None:sys.stderr.write(ERROR: no font named fontname ; using default font instead)font pygame.font.Font(font, fontsize)font.set_bold(bold)font.set_italic(italic)if type(color) is str: color pygame.Color(color)return from_image(x, y, font.render(text, True, color))__all__.append(from_text)def load_sound(url_or_filename):Reads a sound file from a given filename or urlif url_or_filename in _known_images: return _known_sounds[url_or_filename]if not os.path.exists(url_or_filename):filename os.path.basename(url_or_filename)if not os.path.exists(filename):_urlretrieve(url_or_filename, filename)url_or_filename filenamesound pygame.mixer.Sound(url_or_filename)_known_sounds[url_or_filename] soundreturn sound__all__.append(load_sound)class Camera(object):A camera defines what is visible. It has a width, height, full screen status,and can be moved. Moving a camera changes what is visible.is_initialized False# __slots__ [_surface, x, y, speedx, speedy]def __init__(self, width, height, full_screenFalse):Camera(pixelsWide, pixelsTall, False) makes a window; using True instead makes a full-screen display.if Camera.is_initialized: raise Exception(You can only have one Camera at a time)# if height 768: raise Exception(The Game Expo screens will only be 768 pixels tall)# if width 1366: raise Exception(The Game Expo screens will only be 1366 pixels wide)if full_screen:self.__dict__[_surface] pygame.display.set_mode([width, height], pygame.FULLSCREEN)else:self.__dict__[_surface] pygame.display.set_mode([width, height])self.__dict__[_x] 0self.__dict__[_y] 0Camera.is_initialized Truedef move(self, x, yNone):camera.move(3, -7) moves the screens center to be 3 more pixels to the right and 7 more upif y is None: x, y xself.x xself.y ydef draw(self, thing, *args):camera.draw(box) draws the provided SpriteBox objectcamera.draw(image, x, y) draws the provided image centered at the provided coordinatescamera.draw(Hi, Arial, 12, red, x, y) draws the text Hi in a red 12-point Arial font at x,yif isinstance(thing, SpriteBox):thing.draw(self)elif isinstance(thing, pygame.Surface):try:if len(args) 1:x, y args[0]else:x, y args[:2]self._surface.blit(thing, [x - thing.get_width() / 2, y - thing.get_height() / 2])except e:raise Exception(Wrong arguments; try .draw(surface, [x,y]))elif type(thing) is str:try:font pygame.font.match_font(args[0].replace( , ).lower())if font is None:sys.stderr.write(ERROR: no font named fontname ; using default font instead)size args[1]color args[2]if type(color) is str: color pygame.Color(color)self.draw(pygame.font.Font(font, size).render(thing, True, color), *args[3:])except e:raise Exception(Wrong arguments; try .draw(text, fontName, fontSize, color, [x,y]))else:raise Exception(I dont know how to draw a , type(thing))def display(self):Causes what has been drawn recently by calls to draw(...) to be displayed on the screenpygame.display.flip()def clear(self, color):Erases the screen by filling it with the given colorif type(color) is str: color pygame.Color(color)self._surface.fill(color)def __getattr__(self, name):if name in self.__dict__: return self.__dict__[name]x, y, w, h self._x, self._y, self._surface.get_width(), self._surface.get_height()if name left: return xif name right: return x wif name top: return yif name bottom: return y hif name x: return x w / 2if name y: return y h / 2if name center: return x w / 2, y h / 2if name topleft: return x, yif name topright: return x w, yif name bottomleft: return x, y hif name bottomright: return x w, y hif name width: return wif name height: return hif name size: return w, hif name mousex: return pygame.mouse.get_pos()[0] self._xif name mousey: return pygame.mouse.get_pos()[1] self._yif name mouse: return pygame.mouse.get_pos()[0] self._x, pygame.mouse.get_pos()[1] self._yif name mouseclick: return any(pygame.mouse.get_pressed())raise Exception(There is no name in a Camera object)def __setattr__(self, name, value):if name in self.__dict__:self.__dict__[name] valuereturnw, h self._surface.get_width(), self._surface.get_height()if name left:self._x valueelif name right:self._x value - welif name top:self._y valueelif name bottom:self._y value - helif name x:self._x value - w / 2elif name y:self._y value - h / 2elif name center:self._x, self._y value[0] - w / 2, value[1] - h / 2elif name topleft:self._x, self._y value[0], value[1]elif name topright:self._x, self._y value[0] - w, value[1]elif name bottomleft:self._x, self._y value[0], value[1] - helif name bottomright:self._x, self._y value[0] - w, value[1] - helif name in [width, height, size, mouse, mousex, mousey, mouseclick]:raise Exception(You cannot change the name of a Camera object)else:sys.stderr.write(creating field named name)self.__dict__[name] valuedef __repr__(self):return str(self)def __str__(self):return %dx%d Camera centered at %d,%d % (self.width, self.height, self.x, self.y)__all__.append(Camera)class SpriteBox(object):Intended to represent a sprite (i.e., an image that can be drawn as part of a larger view) and the box that contains it. Has various collision and movement methods built in.# __slots__ [x,y,speedx,speedy,_w,_h,_key,_image,_color]def __init__(self, x, y, image, color, wNone, hNone):You should probably use the from_image, from_text, or from_color method instead of this oneself.__dict__[x] xself.__dict__[y] yself.__dict__[speedx] 0self.__dict__[speedy] 0if image is not None:self._set_key(image, False, 0, 0, 0)if w is not None:if h is not None:self.size w, helse:self.width welif h is not None:self.height helif color is not None:if w is None or h is None: raise Exception(must supply size of color box)self.__dict__[_key] Noneself.__dict__[_image] Noneself.__dict__[_w] wself.__dict__[_h] hself.color colorpassdef _set_key(self, name, flip, width, height, angle):width int(width 0.5)height int(height 0.5)angle ((int(angle) % 360) 360) % 360unrot _image(name, flip, width, height)if width 0 and height 0:width unrot.get_width()height unrot.get_height()self.__dict__[_key] (name, flip, width, height, angle)self.__dict__[_image] _image(*self.__dict__[_key])self.__dict__[_color] Noneself.__dict__[_w] self.__dict__[_image].get_width()self.__dict__[_h] self.__dict__[_image].get_height()def __getattr__(self, name):x, y, w, h self.x, self.y, self._w, self._hif name xspeed: name speedxif name yspeed: name speedyif name left: return x - w / 2if name right: return x w / 2if name top: return y - h / 2if name bottom: return y h / 2if name center: return x, yif name topleft: return x - w / 2, y - h / 2if name topright: return x w / 2, y - h / 2if name bottomleft: return x - w / 2, y h / 2if name bottomright: return x w / 2, y h / 2if name width: return wif name height: return hif name width: return wif name height: return hif name size: return w, hif name speed: return self.speedx, self.speedyif name rect: return pygame.Rect(self.topleft, self.size)if name image: return self.__dict__[_image]if name in self.__dict__:return self.__dict__[name]raise Exception(There is no name in a SpriteBox object)def __setattr__(self, name, value):w, h self._w, self._hif name xspeed: name speedxif name yspeed: name speedyif name in self.__dict__:self.__dict__[name] valueelif name left:self.x value w / 2elif name right:self.x value - w / 2elif name top:self.y value h / 2elif name bottom:self.y value - h / 2elif name center:self.x, self.y value[0], value[1]elif name topleft:self.x, self.y value[0] w / 2, value[1] h / 2elif name topright:self.x, self.y value[0] - w / 2, value[1] h / 2elif name bottomleft:self.x, self.y value[0] w / 2, value[1] - h / 2elif name bottomright:self.x, self.y value[0] - w / 2, value[1] - h / 2elif name width:self.scale_by(value / w)elif name height:self.scale_by(value / h)elif name size:if self.__dict__[_image] is not None:key self.__dict__[_key]self._set_key(key[0], key[1], value[0], value[1], key[4])else:self.__dict__[_w] value[0]self.__dict__[_h] value[1]elif name speed:self.speedx, self.speedy value[0], value[1]elif name color:self.__dict__[_image] Noneself.__dict__[_key] Noneif type(value) is str: value pygame.Color(value)self.__dict__[_color] valueelif name image:self.__dict__[_color] Noneif self.__dict__[_key] is None:self._set_key(value, False, w, h, 0)else:key self.__dict__[_key]self._set_key(value, *key[1:])else:sys.stderr.write(creating filed named name)self.__dict__[name] valuedef overlap(self, other, padding0, padding2None):b1.overlap(b1) returns a list of 2 values such that self.move(result) will cause them to not overlapReturns [0,0] if there is no overlap (i.e., if b1.touches(b2) returns Falseb1.overlap(b2, 5) adds a 5-pixel padding to b1 before computing the overlapb1.overlap(b2, 5, 10) adds a 5-pixel padding in x and a 10-pixel padding in y before computing the overlapif padding2 is None: padding2 paddingl other.left - self.right - paddingr self.left - other.right - paddingt other.top - self.bottom - padding2b self.top - other.bottom - padding2m max(l, r, t, b)if m 0:return [0, 0]elif m l:return [l, 0]elif m r:return [-r, 0]elif m t:return [0, t]else:return [0, -b]def touches(self, other, padding0, padding2None):b1.touches(b1) returns True if the two SpriteBoxes overlap, False if they do notb1.touches(b2, 5) adds a 5-pixel padding to b1 before computing the touchb1.touches(b2, 5, 10) adds a 5-pixel padding in x and a 10-pixel padding in y before computing the touchif padding2 is None: padding2 paddingl other.left - self.right - paddingr self.left - other.right - paddingt other.top - self.bottom - padding2b self.top - other.bottom - padding2return max(l, r, t, b) 0def bottom_touches(self, other, padding0, padding2None):b1.bottom_touches(b2) returns True if both b1.touches(b2) and b1s bottom edge is the one causing the overlap.if padding2 is None: padding2 paddingreturn self.overlap(other, padding 1, padding2 1)[1] 0def top_touches(self, other, padding0, padding2None):b1.top_touches(b2) returns True if both b1.touches(b2) and b1s top edge is the one causing the overlap.if padding2 is None: padding2 paddingreturn self.overlap(other, padding 1, padding2 1)[1] 0def left_touches(self, other, padding0, padding2None):b1.left_touches(b2) returns True if both b1.touches(b2) and b1s left edge is the one causing the overlap.if padding2 is None: padding2 paddingreturn self.overlap(other, padding 1, padding2 1)[0] 0def right_touches(self, other, padding0, padding2None):b1.right_touches(b2) returns True if both b1.touches(b2) and b1s right edge is the one causing the overlap.if padding2 is None: padding2 paddingreturn self.overlap(other, padding 1, padding2 1)[0] 0def contains(self, x, yNone):checks if the given point is inside this SpriteBoxs bounds or notif y is None: x, y xreturn abs(x - self.x) * 2 self._w and abs(y - self.y) * 2 self._hdef move_to_stop_overlapping(self, other, padding0, padding2None):b1.move_to_stop_overlapping(b2) makes the minimal change to b1s position necessary so that they no longer overlapo self.overlap(other, padding, padding2)if o ! [0, 0]:self.move(o)if o[0] * self.speedx 0: self.speedx 0if o[1] * self.speedy 0: self.speedy 0def move_both_to_stop_overlapping(self, other, padding0, padding2None):b1.move_both_to_stop_overlapping(b2) changes both b1 and b2s positions so that they no longer overlapo self.overlap(other, padding, padding2)if o ! [0, 0]:self.move(o[0] / 2, o[1] / 2)other.move(-o[0] / 2, -o[1] / 2)if o[0] ! 0:self.speedx (self.speedx other.speedx) / 2other.speedx self.speedxif o[1] ! 0:self.speedy (self.speedy other.speedy) / 2other.speedy self.speedydef move(self, x, yNone):change position by the given amount in x and y. If only x given, assumed to be a point [x,y]if y is None: x, y xself.x xself.y ydef move_speed(self):change position by the current speed field of the SpriteBox objectself.move(self.speedx, self.speedy)def full_size(self):change size of this SpriteBox to be the original size of the source imageif self.__dict__[_key] is None: returnkey self.__dict__[_key]self._set_key(key[0], key[1], 0, 0, key[4])def __repr__(self):return str(self)def __str__(self):return %dx%d SpriteBox centered at %d,%d % (self._w, self._h, self.x, self.y)def copy_at(self, newx, newy):Make a new SpriteBox just like this one but at the given location instead of herereturn SpriteBox(newx, newy, self._image, self._color, self._w, self._h)def copy(self):Make a new SpriteBox just like this one and in the same locationreturn self.copy_at(self.x, self.y)def scale_by(self, multiplier):Change the size of this SpriteBox by the given factorb1.scale_by(1) does nothing; b1.scale_by(0.4) makes b1 40% of its original width and height.if self.__dict__[_key] is None:self._w * multiplierself._h * multiplierelse:key self.__dict__[_key]self._set_key(key[0], key[1], key[2] * multiplier, key[3] * multiplier, key[4])def draw(self, surface):b1.draw(camera) is the same as saying camera.draw(b1)b1.draw(image) draws a copy of b1 on the image proividedif isinstance(surface, Camera):if self.__dict__[_color] is not None:region self.rect.move(-surface._x, -surface._y)region region.clip(surface._surface.get_rect())surface._surface.fill(self._color, region)elif self.__dict__[_image] is not None:surface._surface.blit(self._image, [self.left - surface._x, self.top - surface._y])else:if self.__dict__[_color] is not None:surface.fill(self._color, self.rect)elif self.__dict__[_image] is not None:surface.blit(self._image, self.topleft)def flip(self):mirrors the SpriteBox left-to-right.Mirroring top-to-bottom can be accomplished byb1.rotate(180)b1.flip()if self.__dict__[_key] is None: returnkey self.__dict__[_key]self._set_key(key[0], not key[1], *key[2:])def rotate(self, angle):Rotates the SpriteBox by the given angle (in degrees).if self.__dict__[_key] is None: returnkey self.__dict__[_key]self._set_key(key[0], key[1], key[2], key[3], key[4] angle)_timeron False
_timerfps 0def timer_loop(fps, callback):Requests that pygame call the provided function fps times a secondfps: a number between 1 and 60callback: a function that accepts a set of keys pressed since the last tick----seconds 0def tick(keys):seconds 1/30if pygame.K_DOWN in keys:print down arrow pressedif not keys:print no keys were pressed since the last tickcamera.draw(box)camera.display()gamebox.timer_loop(30, tick)----global _timeron, _timerfpskeys set([])if fps 1000: fps 1000_timerfps fps_timeron Truepygame.time.set_timer(pygame.USEREVENT, int(1000 / fps))while True:event pygame.event.wait()if event.type pygame.QUIT: breakif event.type pygame.KEYDOWN and event.key pygame.K_ESCAPE: breakif event.type pygame.KEYDOWN:keys.add(event.key)if event.type pygame.KEYUP and event.key in keys:keys.remove(event.key)if event.type pygame.USEREVENT:pygame.event.clear(pygame.USEREVENT)callback(keys)if event.type pygame.MOUSEBUTTONDOWN:keys.add(event.type)callback(keys)pygame.time.set_timer(pygame.USEREVENT, 0)_timeron Falsedef pause():Pauses the timer; an error if there is no timer to pauseif not _timeron: raise Exception(Cannot pause a timer before calling timer_loop(fps, callback))pygame.time.set_timer(pygame.USEREVENT, 0)def unpause():Unpauses the timer; an error if there is no timer to unpauseif not _timeron: raise Exception(Cannot pause a timer before calling timer_loop(fps, callback))pygame.time.set_timer(pygame.USEREVENT, int(1000 / _timerfps))def stop_loop():Completely quits one timer_loop or keys_loop, usually ending the programpygame.event.post(pygame.event.Event(pygame.QUIT))def keys_loop(callback):Requests that pygame call the provided function each time a key is pressedcallback: a function that accepts the key pressed----def onPress(key):if pygame.K_DOWN key:print down arrow pressedif pygame.K_a in keys:print A key pressedcamera.draw(box)camera.display()gamebox.keys_loop(onPress)----while True:event pygame.event.wait()if event.type pygame.QUIT: breakif event.type pygame.KEYDOWN and event.key pygame.K_ESCAPE: breakif event.type pygame.KEYDOWN:callback(event.key)if __name__ __main__:camera Camera(400, 400)camera.x 10b from_text(40, 50, Blue, Arial, 40, red, italicTrue, boldTrue)b.speedx 3b.left 2b.y 100b.move_speed()camera.draw(b)camera.display()smurfs load_sprite_sheet(http://www.flashpulse.com/moho/smurf_sprite.PNG, 4, 4)def tick(keys):if keys:if pygame.K_0 in keys:b.image smurfs[0]elif pygame.K_1 in keys:b.image smurfs[1]elif pygame.K_2 in keys:b.image smurfs[2]elif pygame.K_3 in keys:b.image smurfs[3]elif pygame.K_4 in keys:b.image smurfs[4]elif pygame.K_5 in keys:b.image smurfs[5]elif pygame.K_6 in keys:b.image smurfs[6]elif pygame.K_7 in keys:b.image smurfs[7]elif pygame.K_8 in keys:b.image smurfs[8]elif pygame.K_9 in keys:b.image smurfs[9]elif pygame.K_a in keys:stop_loop()elif keys:b.image http://www.pygame.org/docs/_static/pygame_tiny.pngb.full_size()b.rotate(-5)b.center camera.mouseb.bottom camera.bottomcamera.draw(b)camera.display()timer_loop(30, tick)