V2.0 de mon jeu de tower defense. MAJ majeure: mise en place d’un menu. /!\ Un bug -> si vous quittez la partie au milieu d’une vague vous ne pourrez pas en relancez une depuis le menu et vous devrez quitter le jeu et le relancer. (en gros vous ne pourrez lancer que une seule vague sinon).
from kandinsky import* from ion import* from time import* from random import* from math import sqrt pdb=[25,75,150,450,2500] lVl=0 Wave=[0,0,0,0] Perso=0 gr1=(75,)*3 gr2=(175,)*3 ro,ja,bc,gr,no,bl,be=(255,0,0),(252,216,0),(0,255,255),(125,)*3,(0,)*3,(255,)*3,(255,204,115) enemy=[] tower=[];Epos=[];Tpos=[];wave=0;money=50 path1=[(0,42,100,10,be),(90,52,10,80,be),(10,122,80,10,be),(10,132,10,60,be),(10,192,140,10,be),(150,62,10,140,be),(160,62,120,10,be),(280,62,10,120,be),(290,172,30,10,be)] reset=True def init(ready,wave,money): fill_rect(0,0,320,222,gr);Info(ready,wave,money);draw(path1) for t in tower:t.Draw() def cursor(x,y,c):c2=get_pixel(x+2,y);fill_rect(x,y,10,1,c);fill_rect(x,y,1,10,c);fill_rect(x+9,y,1,10,c);fill_rect(x,y+9,10,1,c);fill_rect(x+2,y,6,1,c2);fill_rect(x,y+2,1,6,c2);fill_rect(x+9,y+2,1,6,c2);fill_rect(x+2,y+9,6,1,c2) def Play(tm=0,Wave=[0,0,0,0]): global wave,Perso,alive,money,Tpos,tower,enemy,Epos money=10**1000 if tm else 50 if tm:Perso=1 else:Perso=0 eff,efff,x,y,ready,PV,rd,can_place=0,0,40,42,0,100,0,0 pt={42:0,43:1,44:2,36:3,37:4};prt={42:25,43:75,44:125,36:450,37:2500} ts=1 de=[-10,-10,10,10] wave=0;tower=[];Epos=[];Tpos=[];enemy=[] init(ready,wave,money) co=get_pixel(x,y) cursor(x,y,ro) while 1: if PV<=0:break fps=int(1/ts) Time=monotonic() if keydown(14): while keydown(14): draw_string(str(PV)+" PV",290-10*len(str(PV)),202,bl,gr) elif keydown(12): while keydown(12): draw_string(str(fps)+" fps",280-10*len(str(fps)),202,bl,gr) elif keydown(13) and (x,y) in Tpos: while keydown(13): col=Info2(x,y) init(ready,wave,money) cursor(x,y,col) rd+=1 if rd==5: rd=0 for k in [0,1,2,3,52]: if keydown(k): if k==52 and not ready: ready=1 Info(ready,wave,money) if Perso:Remplir(Wave) else:Remplir() cursor(x,y,co) if k in [0,3]: x+=de[k] elif k in [1,2]: y+=de[k] if x>300:x=0 elif x<0:x=310 if y>202:y=22 elif y<22:y=212 co=get_pixel(x,y) if co==get_pixel(0,42) or len(tower)>=30 or (x,y) in Tpos:can_place=0 else:can_place=1 cursor(x,y,bc) if can_place else cursor(x,y,ro) efff=1 while keydown(k): pass if (x,y) in Tpos: ID=Tpos.index((x,y)) for t in tower: if t.ID==ID: eff=1;to=t;ra=t.Stats[3];cercle(x+5,y+5,ra*10,ro,1) if keydown(4) and to.Lvl<7: if money>=to.Stats[0]:to.Lvl+=1;money-=to.Stats[0];to.Stats=T[to.n][to.Lvl];Info(ready,wave,money) while keydown(4):pass elif keydown(17): a=to.ID;money+=int(3*((to.Lvl+1)*(to.n+1))**2.5);tower.remove(to);Tpos.remove((x,y)) for t in tower: if t.ID>a:t.ID-=1 fill_rect(x,y,10,10,gr) elif eff:init(ready,wave,money);eff=0;cursor(x,y,bc) if can_place else cursor(x,y,ro) if efff and eff:init(ready,wave,money);efff=0;cursor(x,y,ro) if keydown(48):input();init(ready,wave,money) if can_place: for k in [42,43,44,36,37]: if keydown(k): if money>=prt[k]: tower.append(Tower(pt[k])) Tpos.append((x,y)) money-=prt[k] for t in tower:t.Draw() else:draw_string("Money:"+str(money),260-10*len(str(money)),1,ro,gr) if co==get_pixel(0,42) or len(tower)>=30 or (x,y) in Tpos:can_place=0 else:can_place=1 cursor(x,y,bc) if can_place else cursor(x,y,ro) for t in tower: cible=t.Attack(Tpos,enemy,Epos,ready,wave) for e in enemy: e.Move(Epos) if Epos[e.ID][0]==322: PV-=e.HP;e.HP=0;alive-=1 if e.Ef==1:fill_rect(int(Epos[e.ID][0]),int(Epos[e.ID][1]),6,6,be);e.Ef=0 if alive==0 and ready: if tm: tower.clear() Tpos.clear() Epos.clear() enemy.clear() while not keydown(52):pass break else: wave+=1;money+=5*wave;ready=0;Epos.clear();enemy.clear();Info(ready,wave,money) ts=monotonic()-Time def draw(o): for i in range(len(o)):fill_rect(o[i][0],o[i][1],o[i][2],o[i][3],o[i][4]) def Info(ready,wave,money): mo="∞" if money>10**999 else money if ready:draw_string("Wave:"+str(wave)+"-In progress",0,1,no,gr) else:draw_string("Wave:"+str(wave)+" "*12,0,1,no,gr) draw_string("Money:"+str(mo),260-10*len(str(mo)),1,ja,gr);fill_rect(0,21,320,1,bl) name=["Soldat","Sniper","Lance-flamme","Minigunner","Anihilateur"] class Tower: def __init__(sf,n,lvl=0):sf.ID=len(tower);sf.n=n;sf.Lvl=lvl;sf.Stats=T[n][sf.Lvl];sf.T=0 def Draw(sf): ct=[(255,255,0),(255,0,255),(0,255,255),(255,255,255),(0,0,0)] fill_rect(Tpos[sf.ID][0]+2,Tpos[sf.ID][1]+2,6,6,ct[sf.n]) def Attack(sf,Tpos,enemy,Epos,ready,wave): global reset,alive,money;dM=0;cible=None;x,y=Tpos[sf.ID];x+=5;y+=5 if reset:reset=False;sf.T=0 for i in range(len(Epos)): ex,ey=Epos[i];ex+=3;ey+=3;dist=sqrt((x-ex)**2+(y-ey)**2) if dist<=sf.Stats[3]*10 and enemy[i].HP>0 and enemy[i].Tr>dM:dM=enemy[i].Tr;cible=i if cible!=None and sf.T>=sf.Stats[2]: sf.T=0 try: enemy[cible].dam=5;enemy[cible].HP-=sf.Stats[1] if enemy[cible].HP<=0: ID=enemy[cible].ID;money+=enemy[cible].R;alive-=1;Info(ready,wave,money);fill_rect(int(Epos[cible][0]),int(Epos[cible][1]),6,6,be);enemy.remove(enemy[cible]);Epos.remove(Epos[ID]) for e in enemy: if e.ID>ID:e.ID-=1 except TypeError:pass else:sf.T+=1 # Health,Speed,Reward # lent,boss,normal,rapide E=[(10,.5,3),(50,.5,15),(5,1,1),(3,2,2)] turn=[(92,2),(172,0),(252,2),(322,3),(462,1),(592,3),(722,2),(832,3)] class Enemy: def __init__(sf,n,lvl): sf.dam=0 sf.n=n sf.ID=len(enemy) sf.Lvl=lvl sf.HP=int(E[n][0]*(1+(2.5*lvl))) sf.V=E[n][1] sf.R=int(E[n][2]*2*(sf.Lvl+1)) sf.Tr=-10*(sf.ID+1) sf.D=3 sf.Ef=0 def Move(sf,Epos): if sf.dam>0:ce=[(255,0,0),(255,0,0),(255,0,0),(255,0,0)];sf.dam-=1 else:ce=[(0,150,0),(50,)*3,(100,200,100),(0,150,255)] v=sf.V;de=[-v,-v,v,v] for i in turn: if sf.Tr==i[0]:sf.D=i[1] fill_rect(int(Epos[sf.ID][0]),int(Epos[sf.ID][1]),6,6,be) if sf.D in [1,2]:Epos[sf.ID]=(Epos[sf.ID][0],Epos[sf.ID][1]+de[sf.D]) elif sf.D in [0,3]:Epos[sf.ID]=(Epos[sf.ID][0]+de[sf.D],Epos[sf.ID][1]) fill_rect(int(Epos[sf.ID][0]),int(Epos[sf.ID][1]),6,6,ce[sf.n]);sf.Tr+=v enemy=[];alive=0 def Remplir(Wave=[0,0,0,0]): global alive,reset,Perso,Epos,enemy,lVl,wave reset=True if Perso:Perso=0 else: wav=wave-20*int(wave//20) lVl=int(wave//20) if wav==0:Wave=[0,0,2,0] elif wav==1:Wave=[0,0,0,2] elif wav==2:Wave=[2,0,0,0] else:Wave=[int(wav//4+lVl//3),int(wav//10+1*wave//50),int(wav//2+lVl/3),int(wav//2-1+lVl/3)] j1,j=0,-1 for i in Wave: j+=1 for f in range(i): alive+=1;j1+=1 Epos.append((0-10*j1,44)) enemy.append(Enemy(j,lVl)) def Info2(x,y): if (x,y) in Tpos: ID=Tpos.index((x,y));stats=None for t in tower: if t.ID==ID:stats=t.Stats;break if stats==None:return bc d1=stats[1];d2=T[t.n][t.Lvl+1][1] if d1>10000: d1,d2="∞","∞" ra=stats[3] draw_string("Damage: "+str(d1)+"-->"+str(d2),0,140) draw_string(str(name[t.n])+"/Level: "+str(t.Lvl),0,100);draw_string("Upgrade: "+str(stats[0]),0,120);draw_string("Reload delay: "+str(stats[2])+"-->"+str(T[t.n][t.Lvl+1][2]),0,160);draw_string("Range: "+str(ra)+"-->"+str(T[t.n][t.Lvl+1][3]),0,180);return ro else:return bc def cercle(x0,y0,r,c1,e): for i in range(e): xd=x0-int((r-i)/sqrt(2)) xf=x0+int((r-i)/sqrt(2)) for x in range(xd,xf+1): x1=x y1=y0+int(sqrt((r-i)**2-(x-x0)**2)) set_pixel(x,y1,c1) for j in range(3): x2=x0+y1-y0 y2=y0+x0-x1 set_pixel(x2,y2,c1) x1,y1=x2,y2 def Help(): tp=1 col=[0,255,255] fill_rect(0,0,320,222,gr) while 1-keydown(4): if col[2]>150 and tp==1:col[2]-=1 else: col[2]+=1 if col[2]<255:tp=0 else:tp=1 draw_string("Tower Defense",95,91,bl,gr) draw_string("Par FIXEM",2,2,bl,gr) draw_string("Version: 2.0",200,2,bl,gr) draw_string("[OK] pour continuer",65,202,col,gr) while keydown(4):pass fill_rect(0,0,320,222,gr) while 1-keydown(4): if col[2]>150 and tp==1:col[2]-=1 else: col[2]+=1 if col[2]<255:tp=0 else:tp=1 draw_string("[shift] -> Voir les FPS\n[alpha] -> Voir les stats sur\n\t\t une tour\n[cut] -> Voir les PV\n[OK] -> Ameliorer les tours\nFleches -> Deplacer le curseur\n[EXE] -> Lancer une vague\n1-5 -> Placer des tours",0,2,bl,gr) draw_string("[OK] pour continuer",65,202,col,gr) while keydown(4):pass fill_rect(0,0,320,222,gr) while 1-keydown(4): if col[2]>150 and tp==1:col[2]-=1 else: col[2]+=1 if col[2]<255:tp=0 else:tp=1 draw_string("Tour 1 -> Soldat (25)\nTour 2 -> Sniper (75)\nTour 3 -> Lance-Flamme (125)\nTour 4 -> Minigunner (450)\nTour 5 -> Anihilateur(2500)",0,2,bl,gr) draw_string("[OK] pour continuer",65,202,col,gr) while keydown(4):pass def Train(): global tower fill_rect(0,0,320,222,gr) Wave=Choose() Play(1,Wave) # Cost,Damage,Delay,Range T=[ [(50,2,25,2),(100,3,25,2),(200,3,17,2.25),(400,3,17,2.5),(800,5,17,2.5),(1600,10,15,2.5),(3200,12,12,2.5),("--",15,12,3),("--",)*4], [(150,10,150,3),(300,20,150,3),(600,50,150,4),(1200,100,150,4),(2400,100,75,5),(4800,150,75,5),(9600,150,65,5),("--",200,65,5),("--",)*4], [(250,1,5,1.5),(500,2,5,1.5),(1000,2,3,1.5),(2000,3,3,1.5),(4000,3,3,1.75),(8000,4,3,2),(16000,5,3,2),("--",5,2,2.25),("--",)*4], [(900,2,10,1.5),(1800,3,10,1.5),(3600,3,7,2.5),(7200,4,7,2.5),(14400,5,7,3),(28800,6,7,3),(47600,6,7,3.5),("--",6,5,3.5),("--",)*4], [(5000,10**100,1000,5),(10000,10**100,950,5.1),(20000,10**100,900,5.2),(40000,10**100,800,5.5),(80000,10**100,700,5.75),(160000,10**100,600,6),(320000,10**100,500,6),("--",10**100,500,10),("--",)*4]] def Choose(): global lVl,Perso Wave=[0,0,0,0] Perso=1 pos=0 ne=["Lent: ","Boss: ","Normal: ","Rapide: ","Niveau: "] while 1-keydown(4): for i in range(5): draw_string(ne[i],25,2+30*i,gr1,gr) try: tx=str(Wave[i]) except IndexError: tx=str(lVl) draw_string(tx,25+10*len(ne[i]),2+30*i,gr1,gr) if keydown(1) and pos!=0: draw_string(" ",2,2+30*pos,gr1,gr);pos-=1 while keydown(1):pass elif keydown(2) and pos!=3: draw_string(" ",2,2+30*pos,gr1,gr);pos+=1 while keydown(2):pass if keydown(0) and Wave[pos]!=0: Wave[pos]-=1 while keydown(0):pass if keydown(3) and sum(Wave)!=40: Wave[pos]+=1 while keydown(3):pass if keydown(46) and lVl!=0: lVl-=1 while keydown(46):pass elif keydown(45): lVl+=1 while keydown(45):pass if keydown(52):Wave=[0,0,0,0];lVl=0 draw_string("->",2,2+30*pos,gr1,gr) return Wave def Inventory(): global tower ct=[(255,255,0),(255,0,255),(0,255,255),(255,255,255),(0,0,0)] fill_rect(0,0,320,222,gr) pos=0 for i in range(5): tower.append(Tower(i)) while 1: draw_string(name[pos],2,2,gr1,gr) if keydown(0): pos=pos-1 if pos!=0 else 4 while keydown(0):pass fill_rect(0,0,320,222,gr) elif keydown(3): pos=pos+1 if pos!=4 else 0 while keydown(3):pass fill_rect(0,0,320,222,gr) if keydown(1) and t.Lvl!=7: t.Lvl+=1 while keydown(1):pass elif keydown(2) and t.Lvl!=0: t.Lvl-=1 while keydown(2):pass t=tower[pos] t.Stats=T[t.n][t.Lvl] stats=t.Stats if stats[1]>100000:stats=(stats[0],"∞",stats[2],stats[3]) draw_string("Niveau: "+str(t.Lvl)+" "*9,12+10*len(name[pos]),2,gr2,gr) draw_string("Prix vers niveau "+str(t.Lvl+1)+":",2,42,gr2,gr);draw_string(str(stats[0])+" "*9,190+10*len(str(t.Lvl)),42,gr1,gr) draw_string("Prix de base: ",2,62,gr2,gr);draw_string(str(pdb[pos])+" "*9,142,62,gr1,gr) draw_string("Attaque: ",2,82,gr2,gr);draw_string(str(stats[1])+" "*9,92,82,gr1,gr) draw_string("Delai: ",2,102,gr2,gr);draw_string(str(stats[2])+" "*9,72,102,gr1,gr) draw_string("Portee: ",2,122,gr2,gr);draw_string(str(stats[3])+" "*9,82,122,gr1,gr) draw_string("Symbole:",2,152,gr2,gr);fill_rect(92,147,30,30,ct[pos]) def Menu(): global Perso,Wave action=[Play,Train,Inventory,Help] txt=["Play","Training","Towers","Help"] xy=[(35,22),(15,57),(25,77),(35,97)] pos=0 def info(): fill_rect(0,0,320,222,gr) fill_rect(5,7,100,120,gr1) fill_rect(10,12,90,110,gr) draw_string("TOWER DEFENSE",188,2,gr2,gr) draw_string("V2.0",278,22,gr2,gr) draw_string("Par FIXEM",2,200,gr2,gr) info() while 1: if keydown(1): pos=pos-1 if pos!=0 else len(xy)-1 while keydown(1):pass elif keydown(2): pos=pos+1 if pos!=len(xy)-1 else 0 while keydown(2):pass for i in range(len(txt)): c1=gr1 if pos==i else gr2 draw_string(txt[i],xy[i][0],xy[i][1],c1,gr) if keydown(4): try: while keydown(4):pass wave=0 action[pos]() info() except KeyboardInterrupt or NameError:sleep(0.4);info();tower.clear();Tpos.clear();Epos.clear(),enemy.clear();Perso=0;Wave=[0,0,0,0] try: Menu() except KeyboardInterrupt:pass