第一次码的完整的python代码
熟悉一下python 类,tkinter的使用,pyinstaller实现的对py直接封装成exe 以及水掉python期末的300行大作业
这个简陋的程序时用来模拟炮弹的飞行,通过输入炮弹的角度以及速度以使炮弹命中靶子。
emm这里是封装好了的exe
程序的各个部分的注解都标上去了
使用了大量的GUI界面(不然我咋弄个300行来 )以及类
其实代码的核心功能实现非常简单.
以下是核心代码的实现:即从控制台输入相关参数实现炮弹轨迹
from graphics import *
import time
import math
from random import randint
##l为标靶的长度,h为标靶的高度
l=10
h=4
class Projectile:
def __init__(self, angle, vel, height):
self.xpos = 0.0
self.ypos = height
theta = math.radians(angle)
self.xvel = vel * math.cos(theta)##x方向初速度
self.yvel = vel * math.sin(theta)##y方向初速度
def getX(self):
return self.xpos
def getY(self):
return self.ypos
def update(self, time):
self.xpos = self.xpos + time * self.xvel
yvel1 = self.yvel - time * 9.8
self.ypos = self.ypos + time * (self.yvel + yvel1)/2.0
self.yvel = yvel1
def highest(self):
return self.ypos+0.5*9.8*(self.yvel/9.8)**2
def getInputs():
a = float(input("输入你要发射炮弹的角度 (度数): "))
v = float(input("发射炮弹的速度 (米/秒): "))
h = float(input("发射台的高度 (米): "))
return a,v,h
class ShotTracker:
def __init__(self, win, angle, velocity, height):
self.proj = Projectile(angle, velocity, height)
self.marker = Circle(Point(0,height), 2)
self.marker.setFill("red")
self.marker.setOutline("red")
self.marker.draw(win)
def update(self, dt):
self.proj.update(dt)
# move the circle to the new projectile location
center = self.marker.getCenter()
dx = self.proj.getX() - center.getX()
dy = self.proj.getY() - center.getY()
self.marker.move(dx,dy)
def getX(self):
return self.proj.getX()
def getY(self):
""" return the current y coordinate of the shot’s center """
return self.proj.getY()
def undraw(self):
""" undraw the shot """
self.marker.undraw()
def main():
# 打印出窗口
win = GraphWin("Projectile Animation", 960, 480, autoflush=False)
win.setCoords(-10, -10, 312, 155)
#打印一个随机位置的标靶
tag_x=randint(10+l,315)
Line(Point(tag_x-l/2,h), Point(tag_x+l/2,h)).draw(win)
Line(Point(tag_x-l/2,0), Point(tag_x-l/2,h)).draw(win)
Line(Point(tag_x+l/2,0), Point(tag_x+l/2,h)).draw(win)
# 打印出坐标轴
Line(Point(-10,0), Point(315,0)).draw(win)
# 打印坐标轴上的距离
for x in range(0, 315, 50):
Text(Point(x,-5), str(x)).draw(win)
Line(Point(x,0), Point(x,2)).draw(win)
n=0
flag=0#标记有无命中以跳出循环
while 1:
if flag==1:
break
if n>0:#为了能先把坐标轴打印出来
angle, vel, height = getInputs()
else:#先进行一次无效射击
angle, vel, height=0,0,0
shot = ShotTracker(win, angle, vel, height)
t_s=0
while 0 <= shot.getY() and -10 < shot.getX() <= 315:
shot.update(0.005)
if 0 <=shot.getY() <=h and tag_x-l/2 < shot.getX() <= tag_x+l/2:
print("你击中了")
flag=1;
break;
s_t=0.001-0.000001*t_s**1.2
if s_t<0:
s_t=0.0000001
time.sleep(s_t)
update()
加粗样式 t_s+=1
if flag==0 and n!=0:
print("错失!")
n+=1
main()
以下是带GUI界面的版本
#coding=gbk
import tkinter as tk
from tkinter.messagebox import *
from graphics import *
import time
import math
from random import randint
##l为标靶的长度,h为标靶的高度
angle,vel,height=0,0,0
player=''
try_t=0
his_n=[]
his_t=[]
le=10
he=4
class RegUi(tk.Frame):#输入昵称的部分
def __init__(self):
self.Reg=tk.Toplevel()
self.Reg.title('昵称')
tk.Frame.__init__(self,master=self.Reg)
self.pack()
sw = self.Reg.winfo_screenwidth()
#得到屏幕宽度
sh = self.Reg.winfo_screenheight()
x=(sw-200)/2
y=(sh-80)/2
self.Reg.geometry("200x80+%d+%d" %(x,y))
#这里是学习一下实现窗口居中
self.createWidgets()
def createWidgets(self):
self.PName=tk.Label(self,text='输入你的昵称')
self.PName.pack(side='top')
self.Name=tk.Entry(self)
self.Name.pack()
btnOk=tk.Button(self,text='开始游戏',command=self.GetName)
btnOk.pack(side='bottom')
def GetName(self):
global player
player=self.Name.get()
if player=='':
showwarning(title='错误!',message='昵称不能为空')
else:
self.Reg.destroy()
Getinputs()
class Gamegui(tk.Frame):#这里是实现开始游戏的地方
#内容包括顶部菜单栏的难度选择部分,底部的开始,查看排名,退出游戏以及关于本人的个人信息
def __init__(self,master=None):
tk.Frame.__init__(self,master)
self.pic=tk.PhotoImage(file = 'bg-start.gif')
self.pack()
self.Menubar=tk.Menu(self)
self.createMenu()
root['menu']=self.Menubar
self.createWidgets()
def createMenu(self):
self.menuhard=tk.Menu(self.Menubar,tearoff=0)
self.Menubar.add_cascade(label='难度',menu=self.menuhard)
self.menuhard.add_command(label='简单',command=self.easy)
self.menuhard.add_command(label='普通',command=self.normal)
self.menuhard.add_command(label='困难',command=self.hard)
self.menuhard.add_command(label='地狱',command=self.leg)
def createWidgets(self):
self.bgImage=tk.Label(self,width=300,height=300)
self.bgImage['image']=self.pic
self.bgImage.pack(expand='1')
self.btnStart=tk.Button(self,text='开始游戏',font=("微软雅黑"), fg="red",command=self.start).pack(side='left')
self.btnRank=tk.Button(self,text='查看排名',font=("微软雅黑"), fg="red",command=self.rank).pack(side='left')
self.btnAbout=tk.Button(self,text='关于',font=("微软雅黑",6),command=self.about,pady=15).pack(side='right')
self.btnQuit=tk.Button(self,text='退出游戏',font=("微软雅黑"), fg="red",command=self.quit).pack(side='right')
def easy(self):
global le
global he
le=10
he=4
showinfo(title='提示',message='当前难度是简单!不计入排行榜!')
def normal(self):
global le
global he
le=8
he=3
showinfo(title='提示',message='当前难度是普通!不计入排行榜!')
def hard(self):
global le
global he
le=6
he=2
showinfo(title='提示',message='当前难度是困难!计入排行榜!')
def leg(self):
global le
global he
le=2
he=1
showinfo(title='提示',message='当前难度是地狱!计入排行榜,并且射击次数减半!兄弟好勇气!')
def start(self):
global len
if le > 6:
showerror(title='提示',message='当前难度不是困难或者地狱,将不会记录排名中!')
self.ent_name=tk.Frame()
self.pack()
RegUi()
def rank(self):
global his_n
global his_t
str1='排行榜如下:\n'
for i in range(0,len(his_n)):
str1+='第'
str1+=str(i+1)
str1+='名---'
str1+='玩家:'
str1+=his_n[i]
str1+=' 发射次数:'
str1+=str(his_t[i])
str1+='\n'
showinfo(title='排名',message=str1)
def quit(self):
root.destroy()
def about(self):#别骂了别骂了,垃圾学校,垃圾学校,跟各位大佬比不了
str1=''
str1+='注意:\n本程序由\n华东交通大学\n2019级软件工程9班\n乐嘉伟完成\n版权所有\nv1.0.0'
showinfo(title='关于',message=str1)
class Projectile:#这里是对炮弹轨迹进行计算
def __init__(self, angle, vel, height):
self.xpos = 0.0
self.ypos = height
theta = math.radians(angle)
self.xvel = vel * math.cos(theta)##x方向初速度
self.yvel = vel * math.sin(theta)##y方向初速度
def getX(self):
return self.xpos
def getY(self):
return self.ypos
def update(self, time):
self.xpos = self.xpos + time * self.xvel
yvel1 = self.yvel - time * 9.8
self.ypos = self.ypos + time * (self.yvel + yvel1)/2.0
self.yvel = yvel1
def highest(self):
return self.ypos+0.5*9.8*(self.yvel/9.8)**2
class Getinputs:
def __init__(self):
self.a=tk.StringVar()#这里是纯粹的学习。。。不晓得这里用这个有啥子用那
self.v=tk.StringVar()
global le
global he
self.l=le
self.h=he
self.n=0#这里本来也想输入的,然后感觉意义不大来着
self.win = GraphWin("游戏界面", 960, 480, autoflush=False)
self.win.setCoords(-10, -10, 312, 155)
#打印一个随机位置的标靶
self.tag_x=randint(10+self.l,315)
Line(Point(self.tag_x-self.l/2,self.h), Point(self.tag_x+self.l/2,self.h)).draw(self.win)
Line(Point(self.tag_x-self.l/2,0), Point(self.tag_x-self.l/2,self.h)).draw(self.win)
Line(Point(self.tag_x+self.l/2,0), Point(self.tag_x+self.l/2,self.h)).draw(self.win)
# 打印出坐标轴
Line(Point(-10,0), Point(315,0)).draw(self.win)
# 打印坐标轴上的距离
for x in range(0, 315, 50):
Text(Point(x,-5), str(x)).draw(self.win)
Line(Point(x,0), Point(x,2)).draw(self.win)
self.InPut=tk.Toplevel()
self.InPut.title('发射参数')
self.Label_v=tk.Label(self.InPut,text='炮弹发射速度')
self.Label_v.grid(row=0,column=0)
self.Scale_v=tk.Scale(self.InPut,from_=1,to=80,length=100,orient=tk.HORIZONTAL,resolution=1,showvalue=1,variable=self.v)
self.Scale_v.grid(row=0,column=2)
self.Label_a=tk.Label(self.InPut,text='炮弹发射角度')
self.Label_a.grid(row=1,column=0)
self.Scale_a=tk.Scale(self.InPut,from_=90,to=1,length=100,orient=tk.VERTICAL,resolution=1,showvalue=1,variable=self.a)
self.Scale_a.grid(row=1,column=1)
self.Pic=tk.PhotoImage(file = 'bg-fire.gif')
self.bgImage=tk.Label(self.InPut,width=100,height=100)
self.bgImage['image']=self.Pic
self.bgImage.grid(row=1,column=2)
self.BtnOk=tk.Button(self.InPut,text='发射!',command=self.playgame).grid(row=2,column=2)
self.InPut.mainloop()
def playgame(self):
angle, vel, height=int(self.a.get()),int(self.v.get()),0
flag=0#标记有无命中以跳出循环
shot = ShotTracker(self.win, angle, vel, height)
while 0 <= shot.getY() and -10 < shot.getX() <= 315:
shot.update(0.005)
if 0 <=shot.getY() <=self.h and self.tag_x-self.l/2 < shot.getX() <= self.tag_x+self.l/2:
flag=1;
break;
time.sleep(0.001)
update()
self.n+=1
if flag==0:
if shot.getY()>0:
showinfo(title='太可惜了',message='错失!'+'\n'+'你射出界了!\n'+'这是你第'+str(self.n)+'次尝试'+'\n'+'再接再厉,加油!')
else:
showinfo(title='太可惜了',message='错失!'+'\n'+'你射到'+str(int(shot.getX()))+'米了!\n'+'这是你第'+str(self.n)+'次尝试'+'\n'+'再接再厉,加油!')
else:
global player
global try_t
global le
try_t=self.n
self.InPut.destroy()
showinfo(title='干得漂亮!',message='干得漂亮!'+player+'\n'+'你击中了靶子!'+'\n'+'你尝试了:'+str(self.n)+'次')
if le<=6:
Update_rec()
else:
showinfo(title='注意!',message='你的当前难度不是困难,不配进入排行榜!!加油吧骚年!')
self.win.close()
class ShotTracker:
def __init__(self, win, angle, velocity, height):
self.proj = Projectile(angle, velocity, height)
self.marker = Circle(Point(0,height), 2)
self.marker.setFill("red")
self.marker.setOutline("red")
self.marker.draw(win)
def update(self, dt):
self.proj.update(dt)
# move the circle to the new projectile location
center = self.marker.getCenter()
dx = self.proj.getX() - center.getX()
dy = self.proj.getY() - center.getY()
self.marker.move(dx,dy)
def getX(self):
return self.proj.getX()
def getY(self):
""" return the current y coordinate of the shot’s center """
return self.proj.getY()
def undraw(self):
""" undraw the shot """
self.marker.undraw()
def Update_rec():
global player
global try_t
global his_n
global his_t
global le
temp=0
if le ==2:
showinfo(title='牛逼',message='我真的没想到还真有人能击中!!!')
try_t/=2
try_t=int(try_t)
player+='------(地狱勇士)'
for i in range(0,len(his_n)):
if his_t[i]<try_t:
temp+=1
else:
break
his_n.insert(temp,player)
his_t.insert(temp,try_t)
##保存进文件##
fo = open("rank.txt", "r+")
up_n=0
if len(his_n)>=10:
up_n=10
else:
up_n=len(his_n)
for i in range(0,len(his_n)):
fo.write( his_n[i]+' '+str(his_t[i]))
if i != len(his_n)-1:
fo.write('\n')
fo.close()
##############
##从文件输入历史记录###
fo = open("rank.txt", "r")
ti=0
for line in fo.readlines(): #依次读取每行
line = line.strip()#去掉每行头尾空白
name=''
times=''
ptr=0
while 1:
if line[ptr]==' ':
ptr+=1
break;
name+=line[ptr]
ptr+=1
for i in range(ptr,len(line)):
times+=line[ptr]
ptr+=1
his_n.append(name)
his_t.append(int(times))
ti+=1
fo.close()
#####################
root = tk.Toplevel()
root.title('炮弹发射')
game=Gamegui(master=root)
game.mainloop()