Recréation simplifiée du super jeu space flight simulator. Il est possible de modifier de poussée de la fusée (en N), son poids ou son carburant. L’utilisateur peut la piloter et lire des information relatives a sa position (vitesse, angle de vol). Une version sera peut être crée pour créer sa propre fusée et ajouter des planètes.
from math import * from kandinsky import fill_rect as rect, draw_string as txt, fill_polygon as poly, set_pixel, fill_circle as fcircle, draw_line as line from time import * from random import * from ion import keydown as key # MADE BY ARMAND JAMET, started 04.12.22 ended 08.12.22 # HOPE U LIKE IT ! <3 ground,gray,Upsilon=(0,175,0),'gray',(120,160,200) deg=pi/180 rad=lambda θ:radians(θ) ab=lambda x,y:int(sqrt(x**2+y**2)) t=lambda s:monotonic()-s def toPol(list):return [(ab(i[0],i[1]),2*atan(i[1]/(i[0]+ab(i[0],i[1])+1))-pi/2) for i in list] def toCart(list,x,y,θ):return [(x+int(r[0]*cos(θ+r[1])),y-int(r[0]*sin(θ+r[1]))) for r in list] class Graphics(): def __init__(g,dim=1,col=[(0,0,50),(200,)*3,(125,)*3,(255,119,0)],x=161,y=111,w=15,h=35): g.col,g.x,g.y,g.h=col,x//dim,y//dim,h//dim g.rkt=toPol([(-w//4,h),(w//4,h),(w,h-10),(w,-h),(-w,-h),(-w,h-10)]) h-=1 g.pCol={'Earth':'blue','Moon':'gray'} g.motor=toPol([(w-3,-h),(3*w//4-3,-h-7),(w//2-3,-h-7),(w-5,-h-20),(5-w,-h-20),(3-w//2,-h-7),(3-3*w//4,-h-7),(3-w,-h)]) g.rktMap=toPol([(8,-5),(0,10),(-8,-4)]) g.fs=(30,w-5,-h-20) g.r={'Earth':6_378,'Moon':3_474} g.newFlames(0) g.size=1 g.bgCol(0);g.draw(pi/2);rect(0,y+h+20,320,h+25,ground) def bgCol(g,y):g.col[0]=(0,0,150-(y//1000)) def draw(g,θ): rect(0,15,320,217,g.col[0]) g.drawRkt(θ) def drawRkt(g,θ): poly(toCart(g.rkt,g.x,g.y,θ),g.col[1]) poly(toCart(g.motor,g.x,g.y,θ),g.col[2]) poly(toCart(g.flames,g.x,g.y,θ),g.col[3]) def newFlames(g,th):g.flames=toPol([(-g.fs[1],g.fs[2]),(g.fs[1],g.fs[2]),(0,g.fs[2]-int(g.fs[0]*th))]) def map(g,t,tf,θ,x,y,pnt): rect(0,15,320,207,(0,)*3) fcircle(g.x-int(x(t))//g.r[pnt],g.y+int(y(t)//g.r[pnt]+83//g.size),int(83//g.size),g.pCol[pnt]) poly(toCart(g.rktMap,g.x,g.y,θ),g.col[1]) # for t in range(tf): # set_pixel(int(x(t))//6378+161,int(y(t))//6378+111,gray) class Physics(): def __init__(phy,m,T,fuel): phy.m,phy.T,phy.fuel,phy.g,phy.ng,phy.x,phy.y,phy.vx,phy.vy,phy.ax,phy.ay=m,T,fuel,9.81,3.983324e14,0,0,0,0,0,0 phy.v0,phy.p0=(0,0),(0,0) phy.skip=1 phy.moonPos,phy.planet=(0,384_400_000),'Earth' phy.r={'Earth':6378e3,'Moon':3474600} phy.tf=lambda:(phy.y()-phy.p0[1])/(1/2*phy.vy()) def start(phy): phy.s=monotonic() phy.t=lambda: phy.skip*(monotonic()-phy.s) phy.vx=lambda:phy.ax*phy.t()+phy.v0[0] phy.vy=lambda:phy.ay*phy.t()+phy.v0[1] phy.nx=lambda t:.5*phy.ax*(t**2)+phy.v0[0]*t+phy.p0[0] phy.ny=lambda t:.5*phy.ay*(t**2)+phy.v0[1]*t+phy.p0[1] phy.x=lambda:.5*phy.ax*(phy.t()**2)+phy.v0[0]*phy.t()+phy.p0[0] phy.y=lambda:.5*phy.ay*(phy.t()**2)+phy.v0[1]*phy.t()+phy.p0[1] def refresh(phy): phy.g=round(phy.ng/((phy.y()+phy.r[phy.planet])**2),3) phy.fuel-=phy.th*phy.skip*.1 def new(phy,θ,th): phy.v0=(phy.vx(),phy.vy()) #if phy.planet!='Moon' and phy.moonPos[0]-10_000<phy.x()<phy.moonPos[0]+10_000 and phy.moonPos[1]-10_000<phy.y()<phy.moonPos[1]+10_000: # sfs.phy.planet,sfs.phy.ng='Moon',4.897114e12 phy.p0=(phy.x(),phy.y()) phy.th=th phy.s=monotonic() phy.ax=(phy.T*th/phy.m)*cos(θ) phy.ay=(phy.T*th/phy.m)*sin(θ)-phy.g class SFS(): def __init__(sfs,m=1,T=18,fuel=500,mode='None'): print('Duh') sfs.col=[(120,160,200),(125,)*3,(10,)*3,(0,0,50)] # THEME, PRINT, BG, BG GAME sfs.phy=Physics(m,T,fuel) if mode=='To Earth': sfs.phy.p0=(randint(100_000,250_000),randint(2_500,15_000)) sfs.phy.v0=(randint(-750,750),randint(-750,0)) sfs.g=Graphics() sfs.fuel=fuel sfs.map=lambda θ:sfs.g.map(sfs.phy.t(),sfs.phy.tf(),θ,sfs.phy.nx,sfs.phy.ny,sfs.phy.planet) sfs.pol=lambda x,y: 2*atan(y/(x+ab(x,y)+1))-pi/2 rect(0,0,320,15,sfs.col[0]) txt('PRESS UP TO LAUNCH !',2,17,'white',sfs.g.col[0],1) sfs.play() def stats(sfs,θ,th): rect(38,205,100,10,sfs.g.col[0]) rect(38,205,int(th*100),10,'white') txt(str(int(th*100))+'%',7,206,'white',sfs.g.col[0],1) txt('FUEL'+str(int(100*sfs.phy.fuel/sfs.fuel))+'% ALT.: '+str(int(sfs.phy.y()))+'m Vx: '+str(int(sfs.phy.vx()))+'ms Vy: '+str(int(sfs.phy.vy()))+'ms θ: '+str(int(degrees(θ)))+'deg',7,0,'white',Upsilon,1) # txt(str(sfs.phy.g),7,15,'white',Upsilon,1) def refresh(sfs,θ,th): sfs.phy.refresh() if not sfs.nav: a=sfs.pol(sfs.phy.vy(),sfs.phy.vx()) line(161+int(75*cos(a)),111+int(75*sin(a)),161+int(79*cos(a)),111+int(79*sin(a)),'white') sfs.stats(θ,th) def play(sfs): θ,th,sfs.nav=pi/2,1,False while not key(1):sleep(.1) sfs.phy.start() sfs.phy.new(θ,th) ti=int(monotonic()) while 1: if key(4): sfs.nav=not sfs.nav if not sfs.nav:sfs.g.draw(θ) sfs.refresh(θ,th) for k in [0,3]: if key(k): θ=(θ+[5*deg,-5*deg][k!=0])%(2*pi) sfs.phy.new(θ,th) if sfs.nav:sfs.map(θ) else:sfs.g.draw(θ) sfs.refresh(θ,th) for k in [33,34]: if key(k): iVal=((sfs.phy.x(),sfs.phy.y()),(sfs.phy.vx(),sfs.phy.vy())) sfs.phy.skip=max(1,sfs.phy.skip+[-5,5][k-33]) txt('TIME:'+str(sfs.phy.skip)+'x',7,0,(0,)*3,Upsilon,1) sleep(1) sfs.phy.new(θ,th) sfs.phy.p0,sfs.phy.v0=iVal[0],iVal[1] for k in [1,2]: if key(k): th=min(1,max(0,th+[.05,-.05][k-1])) sfs.phy.new(θ,th) if not sfs.nav:sfs.g.newFlames(th);sfs.g.draw(θ) if sfs.nav: for k in [45,46]: if key(k): sfs.g.size=max(.25,sfs.g.size+[-.25,.25][k-45]) sfs.map(θ) else: sfs.g.bgCol(sfs.phy.y()) if sfs.phy.y()<75:sfs.g.draw(θ);rect(0,int(sfs.phy.y())+166,320,111,ground) if sfs.phy.y()<0: if ab(sfs.phy.vx(),sfs.phy.vy())<25: sfs.stats(θ,th) sfs.phy=Physics(sfs.phy.m,sfs.phy.T,sfs.phy.fuel) txt('Landed on Earth !',7,25,'white',sfs.g.col[0],1) sfs.play() else:break elif sfs.phy.fuel<=0:sfs.phy.T=sfs.phy.th=0;sfs.phy.new(pi/2,0)#txt('!!! OUT OF FUEL !!!',7,15,'red',sfs.g.col[0],) sfs.refresh(θ,th) sleep(0.1) txt('U CRASHED :(',130,25,'red',sfs.g.col[0]) txt('FLIGHT TIME: '+str(int(monotonic()-ti))+'s',130,50,'white',sfs.g.col[0],1) print(' --- FINAL STATS ---\n','Vx',sfs.phy.vx(),' Vy',sfs.phy.vy()) SFS(1,23,750)