这是很早之前课余时间写的基于Python/Tkinter单机小游戏,用来练手,今天将代码贴出来,方便大家一起学习,通过Py/Tk对于学习GUI作为一个入口,其实是个不错入口,在这里推荐一下Tcl/Tk这门工具控制语言也是很好的脚本语言,对于快速构建应用GUI以及Demo都有不错的帮助(支持SWIG),国外有人将Tcl/Tk嵌入到C中,可以实现用C快速构建GUI,一直都想将实现这个目标,终因诸多因素搁浅,不能不说这是个遗憾...
注:打包好的win32位exe程序以及代码文件都已经上传到CSDN
游戏截图:
游戏截图1 游戏截图2阅读代码要求:需要读者对构建TkinterGUI程序函数参数有基本的了解
以及了解基本的Python语法
运行环境:WIN 32位 /LINUX32位
代码行数:700行
游戏介绍
#基于Tk的打飞机游戏
#该游戏是基于TkGUI包开发的小游戏,可以通过键盘上的上下左右按键控制飞机,来躲避和击落敌机#的小游戏,游戏包括飞机的控制和发射子弹,以及敌机的生成与下落,当子弹击中敌机,敌机消失,当飞#机碰到敌机生命值减少,当飞机生命值减少为0的时候,游戏结束。
1.初始化
def __init__(self):
self.base_path=os.getcwd()#当前路径
self.health_point_value=5#生命值
self.mark_value=0#分数
self.shoot_down_plane_num_value=0 #击落飞机数量
self.height_record_val=self.read_pkl_file()#最高历史记录
self.root=Tk()
self.root.option_add("*Font", "华文中宋")
2.读取配置文件(最高游戏记录)
def read_pkl_file(self):
try:
pkl_file=open(self.base_path+"//"+'h_r.pkl','rb')
data1=pickle.load(pkl_file)
pkl_file.close()
except Exception,e:
output=open(self.base_path+"//"+'h_r.pkl','wb')
data_h_r={"heighest_record":0,}
pickle.dump(data_h_r,output)
output.close()
return 0
else:
return data1['heighest_record']
3.写入配置文件
def write_pkl_file(self,value_h_r):
output=open(self.base_path+"//"+'h_r.pkl','wb')
data_h_r={"heighest_record":value_h_r,}
pickle.dump(data_h_r,output)
output.close()
4.游戏主界面
def main_gui(self):
def over_game():
#self.root.quit()
self.root.destroy()
os._exit(1)
self.root.geometry("420x500")
self.root.maxsize(420,500)
self.root.minsize(420,500)
#ico_path=os.path.join(self.base_path,"plane.ico")
#self.root.iconbitmap(ico_path)
self.root.title("飞机大战")
self.canvas_show=Canvas(self.root,width=320,height=500,bg='white')
self.canvas_show.pack(side=LEFT)
self.frame_right=Frame(self.root)
self.frame_right.pack(side=LEFT,anchor=S,pady=20)
self.frame_score1=Frame(self.frame_right)
self.score_value1_label=Label(self.frame_score1,text="最高纪录",width=10)
self.score_value1_label.pack(side=TOP)
self.score_value1_label_tag=Label(self.frame_score1,text=str(self.height_record_val),
font=('Vandana',12),width=10)
self.score_value1_label_tag.pack(side=TOP)
self.frame_score1.pack(side=TOP,pady=20)
self.frame_life=Frame(self.frame_right)
self.frame_life.pack(side=TOP,pady=10)
self.life_num=Label(self.frame_life,text=" ",height=1,font=('Vandana',4),bg="blue")
self.life_num.pack(side=TOP,pady=2)
self.life_num1=Label(self.frame_life,text=" ",height=1,font=('Vandana',4),bg="blue")
self.life_num1.pack(side=TOP,pady=2)
self.life_num2=Label(self.frame_life,text=" ",height=1,font=('Vandana',4),bg="blue")
self.life_num2.pack(side=TOP,pady=2)
self.life_num3=Label(self.frame_life,text=" ",height=1,font=('Vandana',4),bg="blue")
self.life_num3.pack(side=TOP,pady=2)
self.life_num4=Label(self.frame_life,text=" ",height=1,font=('Vandana',4),bg="blue")
self.life_num4.pack(side=TOP,pady=2)
self.life_value_label=Label(self.frame_life,text="生命值",width=10)
self.life_value_label.pack(side=TOP,pady=2)
self.frame_score=Frame(self.frame_right)
self.score_value_label=Label(self.frame_score,text="分数",width=10)
self.score_value_label.pack(side=TOP)
self.score_value_label_tag=Label(self.frame_score,text=str(self.mark_value),
font=('Vandana',12),width=10)
self.score_value_label_tag.pack(side=TOP)
self.frame_score.pack(side=TOP,pady=10)
self.frame_shoot_down_num=Frame(self.frame_right)
self.pl_num_value_label=Label(self.frame_shoot_down_num,text="击落飞机\n数量")
self.pl_num_value_label.pack(side=TOP)
self.shoot_down_pl_num_tag=Label(self.frame_shoot_down_num,
text=str(self.shoot_down_plane_num_value),
font=('Vandana',12),width=10)
self.shoot_down_pl_num_tag.pack(side=TOP)
self.frame_shoot_down_num.pack(side=TOP,pady=10)
self.frame_button=Frame(self.frame_right)
start_pause_but=ttk.Button(self.frame_button,text='开始游戏')
start_pause_but.pack(side=TOP,pady=5,padx=3)
start_pause_but['command']=self.start_game_cmd
over_pause_but=ttk.Button(self.frame_button,text='结束游戏')
over_pause_but.pack(side=TOP,pady=5,padx=3)
over_pause_but['command']=over_game
self.frame_button.pack(side=TOP,pady=10)
self.root.mainloop()
5.游戏逻辑控制主模块
def start_game_cmd(self):
for i in self.canvas_show.find_all():#清空画布
self.canvas_show.delete(i)
self.plane_square()#初始化飞机函数
self.while_ci_1=0
self.over_tag=False
self.loaded_show_list=[]
self.objects_enemy_show=[]
self.space_enemy_tag=4
while True:
self.algorithm_pl_game()
#执行游戏算法
if self.over_tag==True:
#退出游戏算法,给出用户成绩,并且刷新历史记录
tkMessageBox.showinfo("提示","不好意思,你完蛋了!\n你的成绩:\n 分数 "+
str(self.mark_value)+" \n击落飞机数量 "+
str(self.shoot_down_plane_num_value)+" \n")
if int(self.height_record_val)
6.初始化飞机生成以及绑定按键操作函数
def plane_square(self):
#-------------------------------飞机模型的生成以及操作按键的绑定------------------------
center_x_bit=150
center_y_bit=460
center_xx_bit=center_x_bit+10
center_yy_bit=center_y_bit+10
self.square_pl_head_1=self.canvas_show.create_rectangle(center_x_bit+20,
center_y_bit-20,
center_xx_bit+20,
center_yy_bit-20,
fill='red',
tags="pl_head_1")
self.square_pl_head_2=self.canvas_show.create_rectangle(center_x_bit+10,
center_y_bit-10,
center_xx_bit+10,
center_yy_bit-10,
fill='red',
tags="pl_head_2")
self.square_pl_head_3=self.canvas_show.create_rectangle(center_x_bit+20,
center_y_bit-10,
center_xx_bit+20,
center_yy_bit-10,
fill='red',
tags="pl_head_3")
self.square_pl_head_4=self.canvas_show.create_rectangle(center_x_bit+30,
center_y_bit-10,
center_xx_bit+30,
center_yy_bit-10,
fill='red',
tags="pl_head_4")
self.square_pl_wings_1=self.canvas_show.create_rectangle(center_x_bit,
center_y_bit,
center_xx_bit,
center_yy_bit,
fill='red',
tags="pl_wings_1")
self.square_pl_wings_2=self.canvas_show.create_rectangle(center_x_bit+10,
center_y_bit,
center_xx_bit+10,
center_yy_bit,
fill='red',
tags="pl_wings_2")
self.square_pl_wings_3=self.canvas_show.create_rectangle(center_x_bit+20,
center_y_bit,
center_xx_bit+20,
center_yy_bit,
fill='red',
tags="pl_one")
self.square_pl_wings_4=self.canvas_show.create_rectangle(center_x_bit+30,
center_y_bit,
center_xx_bit+30,
center_yy_bit,
fill='red',
tags="pl_wings_4")
self.square_pl_wings_5=self.canvas_show.create_rectangle(center_x_bit+40,
center_y_bit,
center_xx_bit+40,
center_yy_bit,
fill='red',
tags="pl_wings_5")
self.square_pl_fuselage_1=self.canvas_show.create_rectangle(center_x_bit+15,
center_y_bit+10,
center_xx_bit+15,
center_yy_bit+10,
fill='red',
tags="pl_fuselage_1")
self.square_pl_fuselage_2=self.canvas_show.create_rectangle(center_x_bit+25,
center_y_bit+10,
center_xx_bit+25,
center_yy_bit+10,
fill='red',
tags="pl_fuselage_2")
self.square_pl_tail_1=self.canvas_show.create_rectangle(center_x_bit+10,
center_y_bit+20,
center_xx_bit+10,
center_yy_bit+20,
fill='red',
tags="pl_tail_1")
self.square_pl_tail_2=self.canvas_show.create_rectangle(center_x_bit+20,
center_y_bit+20,
center_xx_bit+20,
center_yy_bit+20,
fill='red',
tags="pl_tail_2")
self.square_pl_tail_3=self.canvas_show.create_rectangle(center_x_bit+30,
center_y_bit+20,
center_xx_bit+30,
center_yy_bit+20,
fill='red',
tags="pl_tail_3")
self.square_object=[self.square_pl_head_1,self.square_pl_head_2,
self.square_pl_head_3,self.square_pl_head_4,
self.square_pl_wings_1,self.square_pl_wings_2,
self.square_pl_wings_3,self.square_pl_wings_4,
self.square_pl_wings_5,self.square_pl_fuselage_1,
self.square_pl_fuselage_2,self.square_pl_tail_1,
self.square_pl_tail_2,self.square_pl_tail_3]
self.root.bind('',self.key_press_left)
self.root.bind('',self.key_press_right)
self.root.bind('',self.key_press_up)
self.root.bind('',self.key_press_down)
self.root.bind('',self.key_press_left)
self.root.bind('',self.key_press_right)
self.root.bind('',self.key_press_up)
self.root.bind('',self.key_press_down)
7.光标键左键操作函数
def key_press_left(self,event):
#--------按键操作-----
#--------向左一格-----
self.left_tag=True
if int(self.canvas_show.coords("pl_wings_1")[0])==0:
pass
else:
for i in self.square_object:
self.canvas_show.move(i,-5,0)
self.canvas_show.update()
8.光标键右键操作函数
def key_press_right(self,event):
#-------按键操作-----
#-------向右一格------
self.right_tag=True
if int(self.canvas_show.coords("pl_wings_5")[2])==300:
pass
else:
for i in self.square_object:
self.canvas_show.move(i,5,0)
self.canvas_show.update()
9.光标键上键操作函数
def key_press_up(self,event):
#-------按键操作-----
#-------向上一格------
self.up_tag=True
if int(self.canvas_show.coords("pl_one")[1])==0:
pass
else:
for i in self.square_object:
self.canvas_show.move(i,0,-10)
self.canvas_show.update()
10.光标键下键操作函数
def key_press_down(self,event):
#-------按键操作-----
#-------向下一格------
self.up_tag=True
if int(self.canvas_show.coords("pl_tail_2")[3])==500:
pass
else:
for i in self.square_object:
self.canvas_show.move(i,0,10)
self.canvas_show.update()
11.横向随机方位上自顶而下敌机模块的生成
def enemy_plane(self):
#---------------------横向随机方位上敌机模块的生成------------------------------------
self.rad_pic_min,self.rad_pic_max=5,20
rad_pic_int=random.randint(self.rad_pic_min,self.rad_pic_max)
center_x_bit=rad_pic_int*10
center_y_bit=0
center_xx_bit=center_x_bit+10
center_yy_bit=center_y_bit+10
square_enemy_head_l=self.canvas_show.create_rectangle(center_x_bit+10,
center_y_bit+10,
center_xx_bit+10,
center_yy_bit+10,
fill='red',
tags="enemy_head_l")
square_enemy_head_r=self.canvas_show.create_rectangle(center_x_bit+20,
center_y_bit+10,
center_xx_bit+20,
center_yy_bit+10,
fill='red',
tags="enemy_head_r")
square_enemy_wings_1=self.canvas_show.create_rectangle(center_x_bit,
center_y_bit,
center_xx_bit,
center_yy_bit,
fill='red',
tags="enemy_wings_1")
square_enemy_wings_2=self.canvas_show.create_rectangle(center_x_bit+10,
center_y_bit,
center_xx_bit+10,
center_yy_bit,
fill='red',
tags="enemy_wings_2")
square_enemy_wings_3=self.canvas_show.create_rectangle(center_x_bit+20,
center_y_bit,
center_xx_bit+20,
center_yy_bit,
fill='red',
tags="enemy_wings_3")
square_enemy_wings_4=self.canvas_show.create_rectangle(center_x_bit+30,
center_y_bit,
center_xx_bit+30,
center_yy_bit,
fill='red',
tags="enemy_wings_4")
square_enemy_fuselage=self.canvas_show.create_rectangle(center_x_bit+15,
center_y_bit-10,
center_xx_bit+15,
center_yy_bit-10,
fill='red',
tags="enemy_fuselage")
square_enemy_tail_1=self.canvas_show.create_rectangle(center_x_bit+10,
center_y_bit-20,
center_xx_bit+10,
center_yy_bit-20,
fill='red',
tags="enemy_tail_1")
square_enemy_tail_2=self.canvas_show.create_rectangle(center_x_bit+20,
center_y_bit-20,
center_xx_bit+20,
center_yy_bit-20,
fill='red',
tags="enemy_tail_2")
enemy_obj_square_1=[square_enemy_head_l,square_enemy_head_r,
square_enemy_wings_1,square_enemy_wings_2,
square_enemy_wings_3,square_enemy_wings_4,
square_enemy_fuselage,square_enemy_tail_1,
square_enemy_tail_2]
return enemy_obj_square_1
12.敌机下落方式的生成
def enemy_down_alg(self):
#-----------敌机下落方式的生成------------
#获得敌机的中心点,然后算出距离左右两端的距离,获得距离的随机数
#然后下落的过程中,边下落边左右移动
#返回值为下落标志,左右方向标志,横向移动距离,进行开始横向移动的高度
l_boder=self.canvas_show.coords("enemy_wings_1")[0]
r_boder=self.canvas_show.coords("enemy_wings_4")[2]
l_w_tmp=int(abs(l_boder))
r_w_tmp=abs(300-int(r_boder))
change_tail=random.randint(0,250)
lr_rand_direct=random.randint(0,1)
down_tag=random.choice((False,True))
if lr_rand_direct==0:
lr_w_rand=random.randint(0,l_w_tmp)
else:
lr_w_rand=random.randint(0,r_w_tmp)
return down_tag,lr_rand_direct,lr_w_rand,change_tail
13.敌机与子弹接触以及我机与敌机碰撞以及敌机控制移动算法
def algorithm_pl_game(self):
#-------------------------------飞机算法执行----------------------------------
tag_while=True
while_ci=0
down_way=False
conut_lf_mov=0
self.rate_loaded_num=80
#子弹频率
self.enemy_plane_down_rate_1=50
self.enemy_plane_down_rate_2=90
#敌机频率
self.down_speed=0.02
#下落速度
while tag_while==True:
#添加显示子弹列表
tags_loaded_much=self.while_ci_1%self.rate_loaded_num
#子弹发射频率的确定
if tags_loaded_much==0:
list_canvas_plone=self.canvas_show.coords("pl_head_1")
loaded_square1=self.canvas_show.create_rectangle(list_canvas_plone[0],
list_canvas_plone[1]-10,
list_canvas_plone[2],
list_canvas_plone[3]-10,
fill='red',
tags="loaded")
self.loaded_show_list.append(loaded_square1)
#屏幕子弹的移动
for i in self.loaded_show_list:
self.canvas_show.move(i,0,-3)
#添加显示敌机列表
self.canvas_show.update()
for i in self.objects_enemy_show:
#对下落在底层的敌机进行屏幕删除
try:
for j in i:
xy_point=self.canvas_show.coords(i[8])
if int(xy_point[3])>500:
for k in i:
self.canvas_show.delete(k)
self.objects_enemy_show.remove(i)
break
except Exception,e:
print(e)
continue
if self.space_enemy_tag==self.while_ci_1:
#敌机下落频率的设定
space_enemy_num=random.randint(self.enemy_plane_down_rate_1,
self.enemy_plane_down_rate_2)
self.space_enemy_tag=self.while_ci_1+space_enemy_num
enemy_object=self.enemy_plane()
self.objects_enemy_show.append((enemy_object))
#print(self.objects_enemy_show)
down_way,l_or_r_direct,lf_mov_num,start_tail=self.enemy_down_alg()
if down_way==True:
#屏幕所有敌机的下落显示
if while_ci>=start_tail:
#判断开始横向移动的高度
if conut_lf_mov<=lf_mov_num:
#判断横向移动距离
if l_or_r_direct==0:
#判断敌机横向移动方向
for o in range(len(self.objects_enemy_show)):
for i in self.objects_enemy_show[o]:
if o==len(self.objects_enemy_show)-1:
self.canvas_show.move(i,-1,1)
else:
self.canvas_show.move(i,0,1)
else:
for o in range(len(self.objects_enemy_show)):
for i in self.objects_enemy_show[o]:
if o==len(self.objects_enemy_show)-1:
self.canvas_show.move(i,1,1)
else:
self.canvas_show.move(i,0,1)
conut_lf_mov+=1
else:
for o in self.objects_enemy_show:
for i in o:
self.canvas_show.move(i,0,1)
else:
for o in self.objects_enemy_show:
for i in o:
self.canvas_show.move(i,0,1)
else:
for o in self.objects_enemy_show:
for i in o:
self.canvas_show.move(i,0,1)
self.canvas_show.update()
time.sleep(self.down_speed)
#对游戏速度的调整
while_ci+=1
self.while_ci_1+=1
if len(self.loaded_show_list)>10:
#屏幕子弹显示的消除
self.canvas_show.delete(self.loaded_show_list[0])
del self.loaded_show_list[0]
#---------------------------canvas上所有项的坐标存在检查和存储--------------------
plane_main_tags=["pl_head_1","pl_head_2","pl_head_3","pl_head_4",
"pl_wings_1","pl_wings_2","pl_one","pl_wings_4",
"pl_wings_5","pl_fuselage_1","pl_fuselage_2",
"pl_tail_1","pl_tail_2","pl_tail_3"
]
multiterm_pl_area=[]
for i in plane_main_tags:
#飞机区域多项坐标存在检查和存储
list_pl_position=self.canvas_show.coords(i)
square_area_lap=self.canvas_show.find_overlapping(list_pl_position[0]+4,
list_pl_position[1]+4,
list_pl_position[2]-4,
list_pl_position[3]-4)
multiterm_pl_area.append(square_area_lap)
self.multiterm_enemy_area_object=[]
for i in xrange(len(self.objects_enemy_show)):
#屏幕所有敌机区域坐标多项存在检查和存储
multiterm_enemy_area=[]
for k in self.objects_enemy_show[i]:
#某一敌机区域坐标多项存在检查和存储
list_enemy_position=self.canvas_show.coords(k)
square_area_lap_enemy=self.canvas_show.find_overlapping(list_enemy_position[0]+4,
list_enemy_position[1]+4,
list_enemy_position[2]-4,
list_enemy_position[3]-4)
multiterm_enemy_area.append((square_area_lap_enemy,i))
self.multiterm_enemy_area_object.append(multiterm_enemy_area)
all_loaded_area_list=[]
for i in self.loaded_show_list:
#屏幕所有子弹区域坐标存在多项检查
list_loaded=self.canvas_show.coords(i)
multiterm_loaded_area=self.canvas_show.find_overlapping(list_loaded[0]+4,
list_loaded[1]+4,
list_loaded[2]-4,
list_loaded[3]-4)
all_loaded_area_list.append((multiterm_loaded_area,i))
#---------------------------子弹与敌机碰撞检测-------------------------------
for j in self.multiterm_enemy_area_object:
#遍历屏幕所有敌机
for u in xrange(len(j)):
#遍历某一敌机所有项
for i in xrange(len(all_loaded_area_list)):
#遍历屏幕所有子弹区域存在项
if j[u][0]==all_loaded_area_list[i][0]:
#判断子弹区域与某一敌机的某一区域是否重合
for k in j:
#删除某一敌机在屏幕上的显示所有项
for h in k[0]:
self.canvas_show.delete(h)
self.canvas_show.update()
del self.objects_enemy_show[j[u][1]]
#删除所有显示敌机对象里对应碰撞的敌机对象
self.canvas_show.update()
self.canvas_show.delete(all_loaded_area_list[i][1])
#删除碰撞的子弹在屏幕上的显示所有项
for h in range(len(self.loaded_show_list)):
#删除所有子弹对象里对应碰撞的子弹对象
if all_loaded_area_list[i][1]==self.loaded_show_list[h]:
del self.loaded_show_list[h]
break
#self.while_ci_1=0
while_ci=0
self.canvas_show.update()
self.shoot_down_plane_num_value+=1
#击落飞机数量
self.mark_value=self.shoot_down_plane_num_value*10
#分数
if self.shoot_down_plane_num_value%50==0 and self.rate_loaded_num>20:
self.rate_loaded_num-=5
#改变子弹发射频率
if self.shoot_down_plane_num_value%80==0 and self.down_speed>0.0001:
self.down_speed=self.down_speed/1.5
#改变游戏进行速度
if self.shoot_down_plane_num_value==100:
self.enemy_plane_down_rate_1=50
self.enemy_plane_down_rate_2=80
#改变敌机下落的频率
if self.shoot_down_plane_num_value==200:
self.enemy_plane_down_rate_1=50
self.enemy_plane_down_rate_2=70
#改变敌机下落的频率
if self.shoot_down_plane_num_value==300:
self.enemy_plane_down_rate_1=50
self.enemy_plane_down_rate_2=60
#改变敌机下落的频率
self.shoot_down_pl_num_tag.configure(text=str(self.shoot_down_plane_num_value))
self.score_value_label_tag.configure(text=str(self.mark_value))
#更新屏幕上分数与记录敌机数量的显示
break
else:
continue
break
#---------------------------飞机碰撞检测----------------------------------
self.pengzhuang_stat=False
for o in xrange(len(self.multiterm_enemy_area_object)):
#遍历所有敌机对象
for i in xrange(len(self.multiterm_enemy_area_object[o])):
#遍历某一敌机区域所有项的方位
for j in xrange(len(multiterm_pl_area)):
#遍历飞机区域所有项的方位
if multiterm_pl_area[j]==self.multiterm_enemy_area_object[o][i][0] and self.pengzhuang_stat==False:
#判断某一敌机区域方位是否与飞机区域方位重合
for k in plane_main_tags:
self.canvas_show.itemconfigure(k,fill='blue')
#给出碰撞警示(飞机各个区域显示为蓝色)
self.pengzhuang_stat=True
self.health_point_value-=1
#生命值的减1
if self.health_point_value==24:
self.life_num.configure(bg='white')
elif self.health_point_value==18:
self.life_num1.configure(bg='white')
elif self.health_point_value==12:
self.life_num2.configure(bg='white')
elif self.health_point_value==6:
self.life_num3.configure(bg='white')
elif self.health_point_value==0:
self.life_num4.configure(bg='white')
else:
pass
self.canvas_show.update()
else:
if self.pengzhuang_stat==True:
for k in plane_main_tags:
self.canvas_show.itemconfigure(k,fill='red')
self.pengzhuang_stat==False
if self.health_point_value<0:
#生命值降为0则将生命结束标志置为(真)
self.over_tag=True
#游戏算法执行标志只为False
tag_while=False
<完>
感谢阅读,欢迎交流!