Python编程娃娃源代码

    xiaoxiao2022-06-25  184

    """bcwawa.py 《编程娃娃Python版》是继《编程娃娃》的姊妹篇。它不需要拖曳编程命令,采用的是直接编排图形化指令的模式,指挥一个娃娃回家。 此版本更重要的是能做为一个模块导入到Python原生环境,从而实现用真正的Python命令去指挥娃娃移动。 本版本新增命令如下: forward:前进50像素,缩写为:fd,使用方法: fd() backward:倒退50,缩写为:bk,back,使用方法:bk() right:右转90,缩写:rt, 使用方法:rt() left:左转90,缩写:lt,使用方法:lt() jump:前进100,主要用来跳过炸弹。使用方法:jump() bomb_ahead:检测娃娃前面是否有炸弹,返回布尔值。使用方法: bomb_ahead() playmusic:播放音乐,不输入参数会播放小星星曲子。使用方法: playmusic() pausemusic:暂停播放音乐。使用方法: playmusic() stopmusic:停止播放音乐。使用方法: stopmusic() unpausemusic:继续播放音乐。使用方法: unpausemusic() set_level:设置当前关卡号。使用方法: set_level(3) 娃娃根据指令前进的主要原理如下: 在作品中设计了三排按钮,娃娃能访问这三排按钮。 第一排是子指令表1(相当于子程序1),以橙星开始,后面跟着9个指令按钮。 第二排也是子指令表2(相当于子程序2),以绿星开始,后面跟着9个指令按钮。 第三排代表主指令表(相当于主程序),以信封开始,后面跟着9个指令按钮. 程序启动后,娃娃对象生成,它会注册回车键绑定自己的execute方法。 当按回车键或单击信封按钮时,娃娃就像是收到了信的内容,会根据信的内容执行它的execute方法。 这个方法执行时会遍历主指令列表,从而根据主指令表中的命令让娃娃前进,转向或执行子指令表。 子程序也能调用子程序,但不能调用主程序。当子程序递归调用过多时,娃娃会自动停止移动。 让娃娃移动的三种方法: 1、按键:直接按上、下、左、右,空格键,手动操作娃娃。适合于体验按键。 2、编排图形化指令:单击信封及五角星后面的按钮,给娃娃编排指令。信封后面的9个按钮为主指令表,橙星为调用子程序1指令,绿星为调用子程序2指令。 向上箭头为前进指令(并不仅仅是向上移动,而是朝它当前的方向移动)。向右转箭头为右转指令,向左转箭头为左转指令,弯箭头为跳跃指令。 3、Python编程模式:把本程序做为模块导入,然后通过编写Python代码指挥娃娃前进。典型代码举例: from bcwawa import * set_level(9) # 设置当前关卡为第9关。 sleep(3) for i in range(4): # 这个for循环的意思是重复4次“前进前进右转” fd();fd() rt() 配置文件名:cfg.txt 本程序的房子和炸弹这两种道具摆放方式分为过关模式与随机模式。过关模式是按内置的排列顺序每关摆放在固定的位置。 随机模式每个关卡都是随机的。 如果配置文件不存在,则默认为过关模式。 如果配置文件存在,里面的字符串为1,则也是关卡模式,其它字符则为随机摆放模式。 主要原理:在生成娃娃对象时,传递__game_mode__变量的值,让娃娃知道模式,当它碰到房子就能决定采用哪种方式重新摆放道具。 """ __author__ = "李兴球" __date__ = "2018/10" __email__ = "406273900@qq.com" __version__ = "1.0" import sys,os,webbrowser from turtle import * from codewawa.gridturtle import * from codewawa.bomb import * from codewawa.house import * from codewawa.wawa import * from codewawa.command import * from random import randint from time import sleep "全局变量加双下划线,不污染全局名称空间" __gamename__ = "编程娃娃Python版" __images_folder__ = os.getcwd() + os.sep + "images" + os.sep __audios_folder__ = os.getcwd() + os.sep + "audios" + os.sep __explosion_sound__=__crystalsound__=__stepsound__=__rotatesound__=__jumpsound__ = None __sounds__ = [ ] # 娃娃的三个音效表 __pygame_normal__ = True # 描述pygame是否正常或能否初始化混音器 __wawagif__ = [] # 娃娃的4个方向gif图片表 __commandpic__= [] # 命令按钮gif图片表 __screen_width__,__screen_height__ = 660,660 # 设定屏幕宽度和高度 __explode_image_list__ = [] # 爆炸效果造型表 __house_list__ = [] # 多个图片只是为了房子有动态效果 __mute_list__ = [] __all_images__ = ['invalid.gif', 'roundman_down.gif', 'roundman_left.gif', 'roundman_right.gif', 'roundman_up.gif', 'volumeOff.gif', 'volumeOn.gif', '信封.gif', '前进.gif', '右转.gif', '左转.gif', '房子0.gif', '房子1.gif', '橙星.gif', '橙色星.gif', '炸弹.gif', '爆炸效果-0.gif', '爆炸效果-1.gif', '爆炸效果-10.gif', '爆炸效果-11.gif', '爆炸效果-2.gif', '爆炸效果-3.gif', '爆炸效果-4.gif', '爆炸效果-5.gif', '爆炸效果-6.gif', '爆炸效果-7.gif', '爆炸效果-8.gif', '爆炸效果-9.gif', '绿星.gif', '绿色星.gif', '跳跃.gif'] __all_images__ = [ __images_folder__ + image for image in __all_images__] __download_url__ = "http://www.scratch8.net/downloads/bcwawa_python.rar" def check_images(): """图像文件丢失检测,在主程序所在文件夹下面要有名为images目录名的文件夹,存储图像资源。""" for image in __all_images__: if not os.path.exists(image): info = image + "文件丢失。" info = info + "请从以下网址重新下载本软件:" + "\n" info = info + __download_url__ showerror(__gamename__,info) return False return True def __load_cfg__(filename): """加载配置文件""" if os.path.exists(filename): # 配置文件存在则读取字符串 f = open(filename) __game_mode__ = f.read() f.close() if __game_mode__.strip() == "1":# 字符串为1,关卡模式为过关模式 __game_mode__ = 1 else: __game_mode__ = 0 # 为其它字符串为随机摆放模式 else: __game_mode__ = 1 # 文件不存在,默认为关卡模式 return __game_mode__ def __init_screen__(width,height,bgcolor,title): """初始化屏幕,注册gif图到形状列表""" __wawagif__.append(__images_folder__ + "roundman_right.gif") # 娃娃朝向右的图形 __wawagif__.append(__images_folder__ + "roundman_up.gif") # 娃娃朝向上的图形 __wawagif__.append(__images_folder__ + "roundman_left.gif") # 娃娃朝向左的图形 __wawagif__.append(__images_folder__ + "roundman_down.gif") # 娃娃朝向下的图形 __commandpic__.append(__images_folder__ + "前进.gif") # “前进”指令的图形 __commandpic__.append(__images_folder__ + "左转.gif") # “左转” 指令的图形 __commandpic__.append(__images_folder__ + "右转.gif") # “右转”指令的图形 __commandpic__.append(__images_folder__ + "橙星.gif") # “子程序1”指令的图形 __commandpic__.append(__images_folder__ + "绿星.gif") # “子程序2”指令的图形 __commandpic__.append(__images_folder__ + "跳跃.gif") # “跳跃”指令的图形 __commandpic__.append(__images_folder__ + "invalid.gif") # “无”指令的图形 __explode_image_list__ .append( __images_folder__ + "炸弹.gif") # 定义爆炸造型表 __explode_image_list__.extend([ __images_folder__ + "爆炸效果-" + str(i) + ".gif" for i in range(12)]) __house_list__.append(__images_folder__ + "房子0.gif") __house_list__.append(__images_folder__ + "房子1.gif") __mute_list__.append(__images_folder__ + "volumeOn.gif") __mute_list__.append(__images_folder__ + "volumeOff.gif") screen = Screen() screen.title(title) screen.bgcolor(bgcolor) screen.setup(width,height) screen.delay(0) if not check_images():screen.bye();return [screen.addshape(image) for image in __commandpic__] # 注册所有命令按钮的造型到屏幕 [screen.addshape(image) for image in __wawagif__] # 注册所有娃娃的造型到屏幕的形状列表 [screen.addshape(image) for image in __explode_image_list__] # 注册炸弹的所有造型到形状列表 [screen.addshape(image) for image in __house_list__] # 注册房子的造型到形状列表 [screen.addshape(image) for image in __mute_list__] # 注册静音按钮的造型到形状列表 return screen def __draw_grid__(start,end,rowscols): """画格子的函数,参数说明: start:起始坐标元组,左上角 end:结束坐标元组, 右下角 rowscols:行和列数 """ g = Gridturtle() # 画格子的海龟对象 g.drawgrid(start,end,rowscols,"gray",4) # 格子海龟专业画格子 def __make_button__(): """生成命令按钮,每个按钮有7种指令,对应7张gif图,它们都在列表中。 单击按钮会调用相应的方法切换指令,同时切换到相应的图形。 """ suborange = [] # 子程序1指令序列 for x in range(-200,201,50): suborange.append(Command(__commandpic__,__commandlist__,x,-100)) subgreen = [] # 子程序2指令序列 for x in range(-200,201,50): subgreen.append(Command(__commandpic__,__commandlist__,x,-150)) main = [] # 主程序指令序列 for x in range(-200,201,50): main.append(Command(__commandpic__,__commandlist__,x,-200)) return suborange,subgreen,main def forward(): """让娃娃前进50个像素""" wawa.fd50() def right(): """让娃娃右转90度""" wawa.rt90() def left(): """让娃娃左转90度""" wawa.lt90() def jump(): """让娃娃跳过一格,实际上是前进100个像素""" wawa.jump() def backward(): """让娃娃倒退50个像素""" wawa.fd_50() def bomb_ahead(): """检测在娃娃的前进方向上是否有一个炸弹""" return wawa.front_have_bomb_check() def playmusic(filename = __audios_folder__ + "小星星.wav",times = -1): """播放音乐,times:播放次数,-1表示无限,0表示1次,1表示播放1次,2表示播放3次,详情看pygame说明书""" try: pygame.mixer.music.load( filename) pygame.mixer.music.play(times,0) except: print("出错了,音乐文件不存在或无法播放。") def stopmusic(): """停止播放音乐""" try: pygame.mixer.music.stop() except: pass def pausemusic(): """暂停播放音乐""" try: pygame.mixer.music.pause() except: pass def unpausemusic(): """继续播放音乐""" try: pygame.mixer.music.unpause() except: pass def __init_audio__(): """本函数试图导入pygame模块,如果导入不成功或者混音初 始化不成功,相关变量的值都为None,程序仍旧能运行,只是不发声。 """ global __pygame_normal__,__explosion_sound__,__crystalsound__,__stepsound__,__rotatesound__,__jumpsound__ try: import pygame pygame.mixer.init() except: pygame = None __pygame_normal__ = False print("pygame模块没有安装或混音器初始化不成功。请重新安装pygame模块。\n安装方法,请在命令提示符下输入:pip install pygame --user。") if __pygame_normal__: # 如果pygame正常 try: __explosion_sound__ = pygame.mixer.Sound( __audios_folder__ + "BOMB2.wav") __crystalsound__ = pygame.mixer.Sound( __audios_folder__ + "水晶.wav") __stepsound__ = pygame.mixer.Sound( __audios_folder__ + "步进声.wav") __rotatesound__ = pygame.mixer.Sound( __audios_folder__ + "转弯声.wav") __jumpsound__ = pygame.mixer.Sound( __audios_folder__ + "跳跃声.wav") except: pass __sounds__.append(__stepsound__) __sounds__.append(__rotatesound__) __sounds__.append(__jumpsound__) return pygame def set_level(number = 0): """设置起始关卡""" if type(number) != type(3) : number = 1 if number <= 0 :number = 1 wawa.level_number = number - 1 wawa.resetbombs() wawa.display_info() #显示信息 """定义别名""" 前进 = 走你 = fd = qianjin = qj = go = forward 后退 = 倒退 = bk = daotui = dt = back = backward 右转 = 向右 = rt = right 左转 = 向左 = lt = left 关卡 = 设关卡 = 设定关卡 = 设置关卡 = 设置关卡号 = setlevel = set_level 等待 = 延时 = sleep 跳 = 跳跃 = jump pygame = __init_audio__() screen = __init_screen__(__screen_width__,__screen_height__,"white",__gamename__) # 新建屏幕对象 if screen==None:sys.exit(0) __game_mode__ = __load_cfg__("cfg.txt") #-------------------------画格子 ---------------------------------- """画一个5x9的格子,每个格子的像素为50x50。 """ __draw_grid__((-225,250),(225,0),(5,9)) # 画格子,起始坐标,结束坐标,行列数 #------------------------生成命令按钮------------------------------ """这段程序生成三行命令按钮,每行有9个按钮,从上到下。 第一行的按钮是代码娃娃的子程序1,它用橙色星星代表。用suborange列表保存。 第二行的按钮是代码娃娃的子程序2,它用绿色星星代表。用subgreen列表保存。 第三行的按钮是代码娃娃的主程序, 它用一封信代表。用main列表保存。 """ __commandlist__ = ["前进","左转","右转","suborange","subgreen","跳跃","pass"] suborange,subgreen,main = __make_button__() # 生成橙,绿,主程序指列按钮 #----------------------炸弹 ---------------------------------- """本段程序新建12个炸弹 """ def __manual_bomb__(): """按z键人工生成一个炸弹,在(0,-25)坐置""" zd = Bomb(__explode_image_list__,__explosion_sound__) zd.goto(0,-25) zd.showturtle() bombs.append(zd) if __game_mode__ == 1: bombs = [Bomb(__explode_image_list__,__explosion_sound__) for i in range(36)] # 新建36个炸弹 else: bombs = [Bomb(__explode_image_list__,__explosion_sound__) for i in range(12)] # 新建12个炸弹 screen.onkeypress(__manual_bomb__,"z") #按z键可人工生成一颗炸弹 #----------------------6、房子 ---------------------------------- """本段程序生成房子对象,参数为房子造型列表,水晶声,炸弹列表 """ house = House(__house_list__,__crystalsound__,bombs) # 新建房子对象 #----------------------娃娃 ---------------------------------- """本段程序生成娃娃对象,它的参数如下: __wawagif__:它是已经注册到形状列表的娃娃的4个造型。 main:娃娃的要执行的主程序指令表。 suborange:娃娃的主程序将调用的子程序1。 subgreen:娃娃的程序将调用的子程序2。 house:娃娃可访问房子。 __allcoordinates__:所有格子中央坐标点。洗牌后就是随机的,用于随机放置炸弹。 bombs:娃娃可访问所有炸弹。 __sounds__:娃娃的音效列表。 """ __allcoordinates__=[] # 所有格子的坐标中心点 __gridx__,__gridy__ = -200,25 # 左下角格子中心点坐标 for __x__ in range(__gridx__,201,50): for __y__ in range(__gridy__,226,50): #print("(",__x__,",",__y__,")",end = ",") __allcoordinates__.append((__x__,__y__)) #print() __ps__ = __wawagif__,main,suborange,subgreen,house,__allcoordinates__,bombs,__sounds__,__game_mode__,Command wawa =Wawa(*__ps__) # 新建娃对象,它的默认的坐标为(-200,25) if __game_mode__ != 1 : # 随机模式 wawa.resetbombs() # 重置炸弹的位置 else: set_level() #----------------------放几个标志---------------------------------- __flag_images__ = [ __images_folder__ + "橙色星.gif", __images_folder__ + "绿色星.gif", __images_folder__ + "信封.gif"] [screen.addshape(image) for image in __flag_images__] __flag__ = Turtle(visible = False) # 初始状态是不可见的 __flag__.pencolor("orange") __flag__.penup() __x__,__y__ = 0,270 __flag__.goto(__x__,__y__) __flag__.write(__gamename__,align='center',font=("黑体",16,"normal")) __x__,__y__ = -260,-100 for __i__ in range(3): __flag__.shape(__flag_images__[__i__]) __flag__.goto(__x__,__y__) if __i__ < 2 : __flag__.stamp() # 最后一个不盖章,要不然无法单击信封实现运行指令 __y__ = __y__ - 50 __envelopex__ = __flag__.xcor() __envelopey__ = __flag__.ycor() __x__,__y__ = -230,-110 __flag__.pencolor("gray") for __i__ in range(3): __flag__.goto(__x__,__y__) __flag__.write("=",align='center',font=("Arial",14,"normal")) __y__ = __y__ - 50 __flag__.goto(__envelopex__,__envelopey__) __flag__.showturtle() __flag__.onclick(lambda __x__,__y__:wawa.execute()) # 单击左键执行main指令集 __flag__.onclick(lambda __x__,__y__:wawa.gohome(),3) # 单击右键回到左下角格子 #----------------------播放与静音按钮 ---------------------------------- "静音按钮,起始状态是on,单击后放音乐。造型列表为:__mutebutton__" __mute_index__ = 0 def __alt_music_status__(): """播放音乐或停止播放""" global __mute_index__ __mutebutton__.shape(__mute_list__[1 -__mute_index__]) if __mute_index__ == 1: playmusic() else: stopmusic() __mute_index__ = 1 - __mute_index__ __x__,__y__ = -260,-250 __mutebutton__ = Turtle(shape = __mute_list__[0],visible = False) # 初始状态是不可见的 __mutebutton__.penup() __mutebutton__.goto(__x__,__y__) __mutebutton__.showturtle() __mutebutton__.onclick(lambda x,y:__alt_music_status__()) playmusic() screen.listen() if __name__ == "__main__": def open_url(x,y): #print(x,",",y) if x>=-328 and x<=323 and y>=-321 and y<=-270: webbrowser.open("http://www.scratch8.net/wawa_python.php") copyrighter = Turtle(visible=False) copyrighter.penup() copyrighter.color("gray") copyrighter.sety(-300) copyrighter.write("风火轮少儿编程出品,操作说明:http://www.scratch8.net/wawa_python.php",align='center',move=False,font=("楷体",12,"normal")) screen.onclick(open_url) screen.mainloop()

     


    最新回复(0)