tower_defense_v_1.py

Created by fixem

Created on May 14, 2025

9.23 KB

V 1.0 de mon jeu de Tower defense. 100% Fait main sur calculatrice Numworks N0110. 5 Tours différentes disponible avec 8 amélioration chacune !! 4 types d’ennemis différents avec niveaux. (+1 niveau toutes les 20 vagues) Curseur déplacable avec les flèches. FPS affichables avec [shift] PV affichables avec [cut] Stats des tours avec [alpha] lorsque le curseur est sur la tour Zone de tir des tours représenté par un cercle autour de la tour si le curseur est dessus. Amélioration avec [OK] Lancer la vague avec [EXE] Tours plaçables avec les touches de [1] à [5] Possibilité de mettre sur pause avec [0] (La calculatrice peut être éteinte sans quitter le jeu si en pause). Bon jeu à tous !!!


from kandinsky import*
from ion import*
from time import*
from random import*
from math import sqrt
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)
tower=[]
Epos=[]
Tpos=[]
wave=0
money=50
path=[(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=False
def init(ready,wave,money):
 fill_rect(0,0,320,222,gr);Info(ready,wave,money);draw(path)
 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():
  global wave,alive,money
  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]
  init(ready,wave,money)
  co=get_pixel(x,y)
  cursor(x,y,ro)
  while 1:
    if PV<=0:draw_string("Game Over",240,91,ro,no);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)
      draw_string(" "*32,0,202,no,gr)
    elif keydown(12):
      while keydown(12):
        draw_string(str(fps)+" fps",280-10*len(str(fps)),202,bl,gr)
      draw_string(" "*32,0,202,no,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)
            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,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: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):
  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(money),260-10*len(str(money)),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):
    global Epos
    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():
  global reset
  reset=True
  wav=wave-20*int(wave//20);global alive
  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
    ra=stats[3];draw_string(str(name[t.n])+"/Level: "+str(t.Lvl),0,100);draw_string("Upgrade: "+str(stats[0]),0,120);draw_string("Damage: "+str(stats[1])+"-->"+str(T[t.n][t.Lvl+1][1]),0,140);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 Menu():
  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: 1.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)
# 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,10,12,3),("--",10,15,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]
]
Menu()
Play()

During your visit to our site, NumWorks needs to install "cookies" or use other technologies to collect data about you in order to:

With the exception of Cookies essential to the operation of the site, NumWorks leaves you the choice: you can accept Cookies for audience measurement by clicking on the "Accept and continue" button, or refuse these Cookies by clicking on the "Continue without accepting" button or by continuing your browsing. You can update your choice at any time by clicking on the link "Manage my cookies" at the bottom of the page. For more information, please consult our cookies policy.