""" Doodle Man ! A doodle jump clone (eco +). Written by Fime 08/01/2021 - V1.0 https://workshop.numworks.com/python/fime/doodle_man """ from random import randint from ion import keydown as kDwn from time import monotonic as mntnc,sleep from kandinsky import fill_rect as rect, draw_string as text SCREEN_W=320 SCREEN_H=222 GAME_W=200 SCORE_W=100 GAME_H=200 OFFSET_X=(SCREEN_W-SCORE_W-GAME_W)//2 OFFSET_Y=(SCREEN_H-GAME_H)//2 MID_SCREEN=OFFSET_Y+10 KEYS={"L":0,"R":3,"bk":17} TYPES=["simple","fake","moving","trampo","fantom"] COLOR={"ddl":(255,50,50), "eyes":(255,255,255), "bg":(50,50,50), "bg2":(70,70,70), "font1":(200,200,200), "font2":(255,255,255), "simple":(255,200,0), "fake":(70,70,100), "moving":(50,200,0), "trampo":(0,150,0), "fantom":(50,50,255)} TARG_FPS=30 TARG_FD=1/TARG_FPS#targetted frame during def s(x): """return 's' since 'x'""" return mntnc()-x def drawPauseText(): txt="GAME PAUSED" x=GAME_W//2-len(txt)*5+OFFSET_X y=GAME_H//2-10+OFFSET_Y text(txt,x,y,COLOR["font2"],COLOR["bg2"]) def drawDll(x,y,s,c): rect(int(x),int(y),int(s),int(s),c) if c!=COLOR["bg"]: s_eye=s//4 x_eye=int(x)+s//2+int(ddl["spd_x"]*ddl["size"]/ddl_init_size) c_eyes=COLOR["eyes"] rect(x_eye-s_eye-1,int(y)+s//2-s_eye//2,int(s_eye),int(s_eye),c_eyes) rect(x_eye+1,int(y)+s//2-s_eye//2,int(s_eye),int(s_eye),c_eyes) def drawPlatform(x,y,hs,vs,c): if y>OFFSET_Y+GAME_H-vs: vs-=(y-(OFFSET_Y+GAME_H-vs)) if y<=limits["y"][1]: rect(int(x),int(y),int(hs),int(vs),c) def drawPlatforms(mode=None): x_ddl=ddl_prvs[0] y_ddl=ddl_prvs[1] s_ddl=ddl["size"] for p in platforms: x=p[0] y=p[1] hs=p[2] vs=p[3] t=p[4] c=p[5] lx=p[6] ly=p[7] if t=="moving": drawPlatform(lx,ly,hs,vs,COLOR["bg"]) for p2 in platforms: if hitBox(p2,[lx,ly,hs,vs]) and not p==p2: drawPlatform(p2[0],p2[1],p2[2],p2[3],p2[5]) if mode=="all" or t=="moving": drawPlatform(x,y,hs,vs,c) p[6]=x p[7]=y if hitBox(p,[x_ddl,y_ddl,s_ddl,s_ddl]): drawPlatform(x,y,hs,vs,c) p[6]=x p[7]=y def addPlatform(y): global cf try: cf==0 except:cf=0#consecutive fake while True: np=createPlatform(y) if np!=None: if np[4]=="fake": if cf==1: np[4]="simple" np[5]=COLOR["simple"] cf=0 else:cf+=1 else: cf=0 break platforms.append(np) def createPlatform(y): hs=int(platform_hor_size)-score//2000 #horizontal size vs=hs//6 #vertical size limits_x=[OFFSET_X+5,GAME_W+OFFSET_X-hs-5] x=randint(limits_x[0],limits_x[1]) t=TYPES[randint(0,len(TYPES)-1)] rand=randint(0,100) if rand<=percentages[t]: p=[x,y,hs,vs,t,COLOR[t],x,y,0.5] return p def hitBox(p1,p2): x1=p1[0] y1=p1[1] hs1=p1[2] vs1=p1[3] x2=p2[0] y2=p2[1] hs2=p2[2] vs2=p2[3] if x1 <= x2+hs2 and x1+hs1 >= x2 and y1 <= y2+vs2 and y1+vs1 >= y2: return True else: return False def game_engine(): global ddl,ddl_prvs,ddl_init_size,limits,platforms,percentages,score,best_score,platform_hor_size,platform_vert_size ddl_init_size=20 ddl={ "x":OFFSET_X+GAME_W//2-ddl_init_size//2, "y":MID_SCREEN, "spd_x":0.0, "spd_y":0, "size":ddl_init_size, "color":COLOR["ddl"]} ddl_prvs=[0,0,0,0,(0,0,0)] print(">init game engine...") rect(0,0,SCREEN_W,SCREEN_H,COLOR["bg2"]) speed=0.07 jump_speed=2.4 platform_hor_size=30 score=0 best_score=readBestScore() #init map drawScorePannel() rect(OFFSET_X,OFFSET_Y,GAME_W,GAME_H,COLOR["bg"]) #limit : x[min][max], y[min][max] limits={ "x":[OFFSET_X,OFFSET_X+GAME_W-ddl["size"]+1], "y":[OFFSET_Y,OFFSET_Y+GAME_H]} #init platforms percentages={"simple":50,"fake":40,"moving":40,"trampo":5,"fantom":5} platforms=[[OFFSET_X, limits["y"][1]-5,GAME_W,5,"simple",COLOR["simple"],OFFSET_X,limits["y"][1],0]] for y in range(OFFSET_Y+60,GAME_H+OFFSET_Y-5,60): addPlatform(y) drawPlatforms("all") draw_all=0 draw_timer=mntnc()-TARG_FD fps=TARG_FPS lpf=1 #lapse_per_frame targ_tics=240 targ_lpf=targ_tics/fps spd_corrector=1 print(">launch the game...") while True: if s(draw_timer)>=TARG_FD: fps=int(1/s(draw_timer)) targ_lpf=targ_tics//fps spd_corrector=lpf/targ_lpf lpf=0 if draw_all: rect(OFFSET_X,OFFSET_Y,GAME_W,GAME_H,COLOR["bg"]) drawPlatforms("all") draw_all=0 else: drawDll(ddl_prvs[0],ddl_prvs[1],ddl_prvs[2],COLOR["bg"]) drawPlatforms() if score>=best_score: best_score = score actualizeScore() drawDll(ddl["x"],ddl["y"],ddl["size"],COLOR["ddl"]) ddl_prvs=[ddl["x"],ddl["y"],ddl["size"]] if kDwn(KEYS["bk"]): drawPauseText() while kDwn(KEYS["bk"]): pass while not kDwn(KEYS["bk"]): pass while kDwn(KEYS["bk"]): pass draw_all=1 draw_timer=mntnc() lpf+=1 ddl["x"]+=ddl["spd_x"] if ddl["y"]<=MID_SCREEN and ddl["spd_y"]<0: score-=int(ddl["spd_y"]*spd_corrector)//10 for p in platforms: if p[1]<=limits["y"][1]-5: p[1]-=ddl["spd_y"] draw_all=1 else: platforms.remove(p) addPlatform(OFFSET_Y) else: ddl["y"]+=ddl["spd_y"] if ddl["x"]<limits["x"][0]: ddl["x"]=limits["x"][0] ddl["spd_x"]=0 if ddl["x"]>limits["x"][1]: ddl["x"]=limits["x"][1] ddl["spd_x"]=0 if ddl["y"]+ddl["size"]<=limits["y"][0]: ddl["y"]-=ddl["spd_y"] ddl["spd_y"]=0 if ddl["y"]<=limits["y"][0]: ddl["y"]=limits["y"][0] if ddl["y"]+ddl["size"]>=limits["y"][1]: ddl["y"]=limits["y"][1]-ddl["size"] drawDll(ddl_prvs[0],ddl_prvs[1],ddl_prvs[2],COLOR["bg"]) drawDll(ddl["x"],ddl["y"],ddl["size"],ddl["color"]) print(">game end: dead...") print(">fps : {}".format(fps)) print(">spd_corrector : {}, lpf : {}/{}".format(spd_corrector,lpf,targ_lpf)) saveScore(best_score) deathAnimation() break if kDwn(KEYS["R"]): ddl["spd_x"]+=speed*spd_corrector if kDwn(KEYS["L"]): ddl["spd_x"]-=speed*spd_corrector for p in platforms: if hitBox(p,[ddl["x"],ddl["y"]+ddl["size"]-5,ddl["size"],5]) and ddl["spd_y"]>=0: if p[4]=="trampo": ddl["spd_y"]=-jump_speed*2*spd_corrector elif p[4]=="fantom": p[4]="fake" p[5]=COLOR["fake"] drawPlatform(p[0],p[1],p[2],p[3],p[5]) ddl["spd_y"]=-jump_speed*spd_corrector elif p[4]=="fake": pass else: ddl["spd_y"]=-jump_speed*spd_corrector percentages[p[4]]*=0.01 if p[4]=="moving": if p[0]<=OFFSET_X+1 or p[0]>=OFFSET_X+GAME_W-p[2]-1: p[8]=-p[8] p[0]+=p[8]*spd_corrector ddl["spd_x"]/= 1.02 ddl["spd_y"]+=0.02 * spd_corrector ddl["size"]=ddl_init_size-score//2000 limits={ "x":[OFFSET_X,OFFSET_X+GAME_W-ddl["size"]], "y":[OFFSET_Y,OFFSET_Y+GAME_H]} def transition(): for c in [COLOR["font1"],COLOR["bg"]]: for y in range(OFFSET_Y,OFFSET_Y+GAME_H,10): sleep(0.016) rect(OFFSET_X,y,GAME_W,10,c) def actualizeScore(): x=OFFSET_X+GAME_W+SCORE_W//2 y=OFFSET_Y+score_off text(str(score),x-len(str(score))*5,y+40,COLOR["font2"],COLOR["bg"]) c=COLOR["simple"] if score==best_score else COLOR["font2"] text(str(best_score),x-len(str(best_score))*5,y+100,c,COLOR["bg"]) def drawScorePannel(): global score_off x=OFFSET_X+GAME_W y=OFFSET_Y score_off=5 rect(x+score_off,y,SCORE_W-2*score_off,GAME_H,COLOR["font1"]) rect(x+2*score_off,y+score_off,SCORE_W-4*score_off,GAME_H-2*score_off,COLOR["bg"]) x=OFFSET_X+GAME_W+SCORE_W//2 y=OFFSET_Y+score_off text("SCORE",x-len("SCORE")*5,y+10,COLOR["font1"],COLOR["bg"]) text("BEST",x-len("BEST")*5,y+70,COLOR["font1"],COLOR["bg"]) s=ddl["size"] drawDll(x-s//2,y+140,s,COLOR["ddl"]) def deathAnimation(): transition() game_engine() def readBestScore(): try: file=open("ddl_man.sav","r") best = file.readline() file.close() print(">score loaded !") return int(best) except: print(">failed to read the score...") return 0 def saveScore(score): try : file=open("ddl_man.sav","w") file.truncate(0) file.write(str(score)) file.close() print(">score saved !") except: print(">failed to save the score...") game_engine()