diff --git a/files/doom.m5r b/files/doom.m5r deleted file mode 100644 index 32eda88..0000000 --- a/files/doom.m5r +++ /dev/null @@ -1,504 +0,0 @@ -',self._resize) - - self._mouse_locked=False - self._game_state="main" - self._rt.bind('',self._mousebtn) - self._rt.bind('',self._esc) - self._rt.bind('',self._kd) - self._rt.bind('',self._ku) - self._rt.bind('',self._mouse_look) - - self._px,self._py=1.5,1.5 - self._pa=0.0 - self._hp=100 - self._ammo=60 - self._armor=0 - self._score=0 - self._weapon_frame=0 - self._muzzle_flash=0 - self._pain_flash=0 - - self._doors={} - self._enemies=[] - self._pickups=[] - self._init_world() - - self._keys=set() - self._last_mouse_x=int(self._width//2) - self._run() - self._rt.mainloop() - - def _init_world(self): - self._doors.clear() - self._enemies.clear() - self._pickups.clear() - for y in range(_MH): - for x in range(_MW): - if _MAP[y][x]==2: - self._doors[(x,y)]={'open':0.0,'opening':False} - elif _MAP[y][x]==3: - self._enemies.append({ - 'x':x+0.5,'y':y+0.5,'hp':75, - 'ai_timer':0,'type':_r.randint(0,2), - 'moving':False,'target_x':x+0.5,'target_y':y+0.5 - }) - elif _MAP[y][x]==4: - ptype=_r.choice(['health','ammo','armor']) - self._pickups.append({ - 'x':x+0.5,'y':y+0.5,'type':ptype, - 'bob':0,'collected':False - }) - - def _resize(self, e): - self._width=e.width - self._height=e.height - - def _mousebtn(self, e): - if self._game_state=="main": - self._game_state="play" - self._lock_mouse(e) - elif self._game_state=="pause": - self._lock_mouse(e) - self._game_state="play" - elif self._game_state=="play" and self._mouse_locked: - self._shoot() - - def _esc(self, e): - if self._game_state=="play" and self._mouse_locked: - self._unlock_mouse() - self._game_state="pause" - elif self._game_state=="pause": - self._game_state="main" - elif self._game_state=="main": - self._rt.destroy() - - def _lock_mouse(self,e=None): - if not self._mouse_locked: - self._cv.grab_set() - self._rt.config(cursor="none") - self._mouse_locked=True - if e: self._last_mouse_x=e.x - - def _unlock_mouse(self): - self._cv.grab_release() - self._rt.config(cursor="") - self._mouse_locked=False - - def _kd(self,e): self._keys.add(e.keysym.lower()) - def _ku(self,e): self._keys.discard(e.keysym.lower()) - - def _mouse_look(self,e): - if self._game_state=="play" and self._mouse_locked: - dx=e.x-self._last_mouse_x - self._pa+=dx*0.003 - self._last_mouse_x=e.x - - def _shoot(self): - if self._ammo<=0: return - self._ammo-=1 - self._weapon_frame=8 - self._muzzle_flash=6 - - # Hitscan shooting - for enemy in self._enemies[:]: - dx,dy=enemy['x']-self._px,enemy['y']-self._py - dist=_m.sqrt(dx*dx+dy*dy) - if dist<10: - angle_to=_m.atan2(dy,dx) - angle_diff=abs(angle_to-self._pa) - if angle_diff>_m.pi: angle_diff=2*_m.pi-angle_diff - if angle_diff<0.3: # In crosshair - damage=_r.randint(25,45) - enemy['hp']-=damage - if enemy['hp']<=0: - self._enemies.remove(enemy) - self._score+=100 - - def _move(self): - s=0.05*max(1,self._width/800) - nx,ny=self._px,self._py - if 'w' in self._keys: - nx=self._px+_m.cos(self._pa)*s - ny=self._py+_m.sin(self._pa)*s - if 's' in self._keys: - nx=self._px-_m.cos(self._pa)*s - ny=self._py-_m.sin(self._pa)*s - if 'a' in self._keys: - nx=self._px+_m.cos(self._pa-_m.pi/2)*s - ny=self._py+_m.sin(self._pa-_m.pi/2)*s - if 'd' in self._keys: - nx=self._px+_m.cos(self._pa+_m.pi/2)*s - ny=self._py+_m.sin(self._pa+_m.pi/2)*s - - if self._can_walk(nx, ny): - self._px,self._py=nx,ny - if 'left' in self._keys: self._pa-=0.06 - if 'right' in self._keys: self._pa+=0.06 - - def _can_walk(self,x,y): - mx,my=int(x),int(y) - if mx<0 or mx>=_MW or my<0 or my>=_MH: return False - cell=_MAP[my][mx] - if cell==0: return True - if cell==2 and self._doors.get((mx,my),{'open':0.0})['open']>0.7: - return True - return False - - def _update_doors(self): - mx,my=int(self._px),int(self._py) - for dx in [-1,0,1]: - for dy in [-1,0,1]: - cx,cy=mx+dx,my+dy - if (cx,cy) in self._doors: - dist=_m.sqrt((self._px-(cx+0.5))**2+(self._py-(cy+0.5))**2) - if dist<2.0: - self._doors[(cx,cy)]['opening']=True - for pos,door in self._doors.items(): - if door['opening'] and door['open']<1.0: - door['open']+=0.04 - elif not door['opening'] and door['open']>0.0: - door['open']-=0.01 - door['open']=max(0,min(1,door['open'])) - - def _update_enemies(self): - for enemy in self._enemies: - enemy['ai_timer']+=1 - if enemy['ai_timer']>80: - enemy['ai_timer']=0 - dx,dy=self._px-enemy['x'],self._py-enemy['y'] - dist=_m.sqrt(dx*dx+dy*dy) - if dist<8: - enemy['target_x']=enemy['x']+dx*0.08 - enemy['target_y']=enemy['y']+dy*0.08 - enemy['moving']=True - if dist<2 and _r.random()<0.15: - damage=_r.randint(8,18) - if self._armor>0: - self._armor-=damage//2 - self._hp-=damage//2 - else: - self._hp-=damage - self._pain_flash=8 - if enemy['moving']: - dx,dy=enemy['target_x']-enemy['x'],enemy['target_y']-enemy['y'] - spd=0.015 - enemy['x']+=dx*spd - enemy['y']+=dy*spd - if abs(dx)<0.1 and abs(dy)<0.1: - enemy['moving']=False - - def _update_pickups(self): - for pickup in self._pickups[:]: - if pickup['collected']: continue - pickup['bob']+=0.1 - dx,dy=self._px-pickup['x'],self._py-pickup['y'] - if _m.sqrt(dx*dx+dy*dy)<0.6: - pickup['collected']=True - if pickup['type']=='health': - self._hp=min(100,self._hp+30) - elif pickup['type']=='ammo': - self._ammo+=25 - elif pickup['type']=='armor': - self._armor=min(100,self._armor+30) - self._score+=50 - self._pickups.remove(pickup) - - def _raycast(self,angle): - x,y=self._px,self._py - dx,dy=_m.cos(angle),_m.sin(angle) - dist=0 - while dist<25: - x+=dx*0.06;y+=dy*0.06;dist+=0.06 - mx,my=int(x),int(y) - if mx<0 or mx>=_MW or my<0 or my>=_MH: return dist - cell=_MAP[my][mx] - if cell==1: return dist - if cell==2 and self._doors.get((mx,my),{'open':0.0})['open']<0.7: - return dist - return dist - - def _draw_3d_box(self,x,y,w,h,d,color,outline='#000'): - # 2.5D isometric box - pts_front=[(x,y),(x+w,y),(x+w,y+h),(x,y+h)] - pts_top=[(x,y),(x+d,y-d),(x+w+d,y-d),(x+w,y)] - pts_right=[(x+w,y),(x+w+d,y-d),(x+w+d,y+h-d),(x+w,y+h)] - self._cv.create_polygon(pts_front,fill=color,outline=outline,width=2) - self._cv.create_polygon(pts_top,fill=self._brighten(color,1.3),outline=outline,width=1) - self._cv.create_polygon(pts_right,fill=self._darken(color,0.7),outline=outline,width=1) - - def _brighten(self,color,factor): - if color.startswith('#'): - r,g,b=int(color[1:3],16),int(color[3:5],16),int(color[5:7],16) - r,g,b=min(255,int(r*factor)),min(255,int(g*factor)),min(255,int(b*factor)) - return f'#{r:02x}{g:02x}{b:02x}' - return color - - def _darken(self,color,factor): - if color.startswith('#'): - r,g,b=int(color[1:3],16),int(color[3:5],16),int(color[5:7],16) - r,g,b=int(r*factor),int(g*factor),int(b*factor) - return f'#{r:02x}{g:02x}{b:02x}' - return color - - def _render_menu(self): - cv=self._cv - ww,wh=self._width,self._height - cv.delete('all') - # 2.5D background - cv.create_rectangle(0,0,ww,wh,fill="#0a0a15",outline="") - for i in range(0,ww,60): - for j in range(0,wh,60): - cv.create_rectangle(i,j,i+30,j+30,fill="#151525",outline="#333",width=1) - - # 2.5D title - self._draw_3d_box(ww//2-180,wh//2-100,360,80,20,"#cc2222","#881111") - cv.create_text(ww//2,wh//2-60,text="DOOM 2.5D",fill="#fff",font=("Consolas",32,"bold")) - - # 2.5D start button - self._draw_3d_box(ww//2-100,wh//2+20,200,60,15,"#224422","#112211") - cv.create_text(ww//2,wh//2+50,text="START GAME",fill="#fff",font=("Consolas",18,"bold")) - - cv.create_text(ww//2,wh-40,text="Click to Start | ESC to Quit",fill="#88f",font=("Consolas",14)) - - def _render_pause(self): - cv=self._cv - ww,wh=self._width,self._height - cv.create_rectangle(0,0,ww,wh,fill="#000",stipple="gray50") - - # 2.5D pause box - self._draw_3d_box(ww//2-150,wh//2-80,300,120,25,"#333366","#111133") - cv.create_text(ww//2,wh//2-40,text="PAUSED",fill="#ff4",font=("Consolas",28,"bold")) - cv.create_text(ww//2,wh//2+10,text="Click to Resume",fill="#fff",font=("Consolas",16)) - cv.create_text(ww//2,wh//2+35,text="ESC for Main Menu",fill="#aaf",font=("Consolas",14)) - - def _render_game(self): - cv=self._cv - ww,wh=self._width,self._height - rays=int(_RAYS*ww/800) - cv.delete('all') - - # Sky/floor - for i in range(wh//2): - brightness=int(50+i*0.2) - color=f'#{brightness//4:02x}{brightness//3:02x}{brightness//2:02x}' - cv.create_line(0,i,ww,i,fill=color) - for i in range(wh//2,wh): - brightness=int(80-(i-wh//2)*0.15) - color=f'#{brightness//3:02x}{brightness//2:02x}{brightness//4:02x}' - cv.create_line(0,i,ww,i,fill=color) - - # Walls - for i in range(rays): - angle=self._pa-_FOV/2+(_FOV*i/rays) - dist=self._raycast(angle) - dist*=_m.cos(angle-self._pa) - h=int((wh*0.6)/max(0.2,dist)) - top=wh//2-h//2 - bright=max(20,min(255,int(255/max(1.2,dist)))) - col=f'#{bright//3:02x}{bright//4:02x}{bright//5:02x}' - x=int(i*(ww/rays)) - cv.create_rectangle(x,top,x+max(1,int(ww/rays)),top+h,fill=col,outline='') - - # Render sprites - sprite_list=[] - for enemy in self._enemies: - dx,dy=enemy['x']-self._px,enemy['y']-self._py - dist=_m.sqrt(dx*dx+dy*dy) - angle=_m.atan2(dy,dx)-self._pa - while angle<-_m.pi: angle+=2*_m.pi - while angle>_m.pi: angle-=2*_m.pi - if abs(angle)<_FOV/2+0.5: - sprite_list.append((dist,'enemy',angle,enemy)) - - for pickup in self._pickups: - if pickup['collected']: continue - dx,dy=pickup['x']-self._px,pickup['y']-self._py - dist=_m.sqrt(dx*dx+dy*dy) - angle=_m.atan2(dy,dx)-self._pa - while angle<-_m.pi: angle+=2*_m.pi - while angle>_m.pi: angle-=2*_m.pi - if abs(angle)<_FOV/2+0.5: - sprite_list.append((dist,'pickup',angle,pickup)) - - sprite_list.sort(reverse=True) - for dist,stype,angle,obj in sprite_list: - screen_x=ww//2+int(angle*ww/_FOV) - size=max(15,min(180,int((wh*0.5)/max(0.3,dist)))) - left=screen_x-size//2 - top=wh//2-size//2 - - if stype=='enemy': - if obj['hp']>50: ecolor='#ff3333' - elif obj['hp']>25: ecolor='#ff6666' - else: ecolor='#ff9999' - - # 2.5D enemy - d=size//8 - self._draw_3d_box(left,top,size,size,d,ecolor,'#aa0000') - # Eyes - eye_size=max(3,size//12) - cv.create_rectangle(left+size//3,top+size//4,left+size//3+eye_size,top+size//4+eye_size,fill='#ff0',outline='#aa0') - cv.create_rectangle(left+2*size//3,top+size//4,left+2*size//3+eye_size,top+size//4+eye_size,fill='#ff0',outline='#aa0') - - elif stype=='pickup': - bob=_m.sin(obj['bob'])*size//8 - if obj['type']=='health': pcolor,symbol='#ff4444','+' - elif obj['type']=='ammo': pcolor,symbol='#ffff44','A' - else: pcolor,symbol='#4444ff','S' - - # 2.5D pickup - d=size//6 - self._draw_3d_box(left,top+bob,size//2,size//2,d,pcolor,'#666') - cv.create_text(screen_x,wh//2+bob,text=symbol,fill='#fff',font=('Courier',max(12,size//4),'bold')) - - # 2.5D weapon - weapon_w,weapon_h=int(ww/6),int(wh/2.5) - weapon_x=ww-weapon_w-40 - weapon_y=wh-weapon_h-40+self._weapon_frame*3 - weapon_d=20 - - self._draw_3d_box(weapon_x,weapon_y,weapon_w,weapon_h,weapon_d,'#666666','#333') - # Barrel - self._draw_3d_box(weapon_x+weapon_w//4,weapon_y+20,weapon_w//2,30,10,'#444444','#222') - - # Muzzle flash - if self._muzzle_flash>0: - flash_size=40+self._muzzle_flash*5 - cv.create_oval(weapon_x+weapon_w//2-flash_size//2,weapon_y+10, - weapon_x+weapon_w//2+flash_size//2,weapon_y+50, - fill='#ffff00',outline='#ffaa00',width=3) - self._muzzle_flash-=1 - - # 2.5D HUD - hud_h=80 - self._draw_3d_box(0,wh-hud_h,ww,hud_h,8,'#222244','#444') - - # Health bar (2.5D) - health_w=int(200*self._hp/100) - self._draw_3d_box(20,wh-60,200,30,6,'#330000','#660000') - if health_w>0: - self._draw_3d_box(20,wh-60,health_w,30,6,'#ff4444','#aa0000') - cv.create_text(120,wh-45,text=f'HP: {self._hp}',fill='#fff',font=('Courier',14,'bold')) - - # Armor bar - if self._armor>0: - armor_w=int(150*self._armor/100) - self._draw_3d_box(250,wh-60,150,30,6,'#000033','#000066') - self._draw_3d_box(250,wh-60,armor_w,30,6,'#4444ff','#0000aa') - cv.create_text(325,wh-45,text=f'ARM: {self._armor}',fill='#fff',font=('Courier',12,'bold')) - - # Ammo and score - cv.create_text(ww-200,wh-55,text=f'AMMO: {self._ammo}',fill='#ff4',font=('Courier',14,'bold')) - cv.create_text(ww-200,wh-35,text=f'SCORE: {self._score}',fill='#4f4',font=('Courier',14,'bold')) - cv.create_text(ww-200,wh-15,text=f'ENEMIES: {len(self._enemies)}',fill='#f84',font=('Courier',12,'bold')) - - # Crosshair - cx,cy=ww//2,wh//2 - cv.create_line(cx-15,cy,cx+15,cy,fill='#fff',width=3) - cv.create_line(cx,cy-15,cx,cy+15,fill='#fff',width=3) - cv.create_oval(cx-5,cy-5,cx+5,cy+5,outline='#fff',width=2) - - # Pain flash - if self._pain_flash>0: - cv.create_rectangle(0,0,ww,wh,fill='#ff0000',stipple='gray25') - self._pain_flash-=1 - - if self._weapon_frame>0: self._weapon_frame-=1 - - def _run(self): - if self._game_state=="main": - self._render_menu() - elif self._game_state=="pause": - self._render_game() - self._render_pause() - elif self._game_state=="play": - self._move() - self._update_doors() - self._update_enemies() - self._update_pickups() - self._render_game() - self._rt.after(28,self._run) - -_DOOM25D() -?> - - -(char)c))); - } -} -?> - -int main() { - int _a[]={68,79,79,77,32,50,46,53,68,32,70,117,108,108,32,71,97,109,101}; - for(int i=0;i<19;i++) std::cout<<(char)_a[i]; - std::cout< - diff --git a/files/maze.m5r b/files/maze.m5r new file mode 100644 index 0000000..2c2ef53 --- /dev/null +++ b/files/maze.m5r @@ -0,0 +1,327 @@ +",self._resize) + self._rt.bind("",self._kd) + self._rt.bind("",self._ku) + self._rt.bind("", self._mouse_btn) + self._rt.bind("",self._esc) + self._rt.bind("", self._mouse_move) + self._mouse_locked = False + self._last_mouse_x = None + self._reset_game() + self._keys=set() + self._tick() + self._rt.mainloop() + + def _reset_game(self,level=1): + self._level=level + self._map=_gen_maze(level) + self._sz=len(self._map) + self._px,self._py=1.5,1.5 # start position + self._pa=_m.pi/4 + self._levelup_msg=0 + + def _resize(self,e):self._W,self._H=e.width,e.height + + def _mouse_btn(self,e): + if self._game_state=="main": + self._game_state="play" + self._lock_mouse(e) + elif self._game_state=="pause": + self._lock_mouse(e) + self._game_state="play" + + def _lock_mouse(self,e=None): + self._mouse_locked=True + self._rt.config(cursor="none") + self._cv.grab_set() + if e:self._last_mouse_x=e.x + + def _unlock_mouse(self,e=None): + self._mouse_locked=False + self._rt.config(cursor="") + self._cv.grab_release() + self._last_mouse_x=None + + def _mouse_move(self,e): + if self._mouse_locked and self._game_state=="play": + if self._last_mouse_x: + self._pa+=(e.x-self._last_mouse_x)*0.005 + self._last_mouse_x=e.x + + def _esc(self,e): + if self._game_state=="play" and self._mouse_locked: + self._unlock_mouse() + self._game_state="pause" + elif self._game_state=="pause": + self._game_state="main" + elif self._game_state=="main": + self._rt.destroy() + + def _brighten(self, col, factor): + if col.startswith('#') and len(col)==7: + r,g,b=int(col[1:3],16),int(col[3:5],16),int(col[5:7],16) + r,g,b=min(255,int(r*factor)),min(255,int(g*factor)),min(255,int(b*factor)) + return f'#{r:02x}{g:02x}{b:02x}' + return col + + def _darken(self, col, factor): + if col.startswith('#') and len(col)==7: + r,g,b=int(col[1:3],16),int(col[3:5],16),int(col[5:7],16) + r,g,b=int(r*factor),int(g*factor),int(b*factor) + return f'#{r:02x}{g:02x}{b:02x}' + return col + + def _draw_3d_box(self,x,y,w,h,d,col,ol='#000000'): + self._cv.create_rectangle(x,y,x+w,y+h,fill=col,outline=ol,width=2) + pts_top=[(x,y),(x+d,y-d),(x+w+d,y-d),(x+w,y)] + self._cv.create_polygon(pts_top,fill=self._brighten(col,1.22),outline=ol,width=1) + pts_r=[(x+w,y),(x+w+d,y-d),(x+w+d,y+h-d),(x+w,y+h)] + self._cv.create_polygon(pts_r,fill=self._darken(col,0.75),outline=ol,width=1) + + def _draw_hud(self): + y = self._H-80 + self._draw_3d_box(0,y,self._W,80,6,"#161b28","#313c32") + + # Level display + self._cv.create_text(120,y+25,text=f"LEVEL: {self._level}",font=("Consolas",24,"bold"),fill="#00ffcc") + + # Instructions + self._cv.create_text(self._W//2,y+25,text="FIND THE BLUE EXIT!",font=("Consolas",20,"bold"),fill="#ffff44") + + # Size info + self._cv.create_text(self._W-150,y+25,text=f"MAZE SIZE: {self._sz}x{self._sz}",font=("Consolas",16,"bold"),fill="#ff6644") + + def _raycast(self,a): + x,y = self._px,self._py + dx,dy = _m.cos(a)*.05,_m.sin(a)*.05 + for d in range(1,400): + x+=dx; y+=dy + mx,my=int(x),int(y) + if mx<0 or my<0 or mx>=self._sz or my>=self._sz: + return d/20,1,'#666666' + cell = self._map[my][mx] + if cell==1: + return d/20,1,'#888888' + elif cell==2: # Blue exit wall + return d/20,1,'#0066ff' + return 18,0,'#000000' + + def _render_game(self): + w,h = self._W,self._H + self._cv.delete('all') + + # Sky gradient + for i in range(h//2): + b=45+i//12 + sh=f"#{b:02x}{b:02x}{b//2+20:02x}" + self._cv.create_line(0,i,w,i,fill=sh) + + # Floor gradient + for i in range(h//2,h): + b=70-(i-h//2)//10 + sh=f"#{b:02x}{b//3:02x}{b//4:02x}" + self._cv.create_line(0,i,w,i,fill=sh) + + # Render walls + rays=250 + for i in range(rays): + a=self._pa-_m.pi/2.3 + (_m.pi/1.15*i)/(rays-1) + d,wall,wall_color=self._raycast(a) + d = max(.08, d*_m.cos(a-self._pa)) + hwall=int(h*0.8/d) + + if wall: + # Apply distance shading to wall color + if wall_color == '#0066ff': # Blue exit wall + shade_factor = max(0.3, min(1.0, 1.0/d)) + r,g,b = 0, int(102*shade_factor), int(255*shade_factor) + cc = f"#{r:02x}{g:02x}{b:02x}" + else: # Regular walls + shade=min(255,max(30,int(200/(d+0.8)))) + cc=f"#{shade:02x}{shade:02x}{shade:02x}" + else: + cc="#000000" + + x=int(i*w/rays) + self._cv.create_rectangle(x,h//2-hwall//2-10,x+int(w/rays+1),h//2+hwall//2,fill=cc,outline="") + + self._draw_hud() + + # Compass/minimap indicator + cx,cy=w-80,80 + self._cv.create_oval(cx-30,cy-30,cx+30,cy+30,fill="#333333",outline="#ffffff",width=2) + # Direction arrow + arrow_x = cx + 20*_m.cos(self._pa) + arrow_y = cy + 20*_m.sin(self._pa) + self._cv.create_line(cx,cy,arrow_x,arrow_y,fill="#00ff00",width=3) + self._cv.create_text(cx,cy+45,text="N",font=("Consolas",12,"bold"),fill="#ffffff") + + if self._game_state=="pause": + self._draw_3d_box(w//2-150,h//2-70,300,69,10,"#333333","#242424") + self._cv.create_text(w//2,h//2-37,text="PAUSED",font=("Consolas",28,"bold"),fill="#ffff44") + self._cv.create_text(w//2,h//2+7,text="ESC to resume",font=("Consolas",13,"bold"),fill="#66ccdd") + + if self._levelup_msg>0: + self._draw_3d_box(w//2-180,h//2-60,360,50,12,"#0066ff","#ffffff") + self._cv.create_text(w//2,h//2-35,text=f"LEVEL {self._level-1} COMPLETE!",font=("Consolas",18,"bold"),fill="#ffffff") + self._levelup_msg-=1 + + def _tick(self): + if self._game_state=="play": + self._step() + self._render_game() + elif self._game_state=="main": + self._render_menu() + elif self._game_state=="pause": + self._render_game() + self._rt.after(30,self._tick) + + def _render_menu(self): + w,h=self._W,self._H + self._cv.delete('all') + + # Checkered background + for y in range(0,h,80): + for x in range(0,w,80): + cc="#2a3344" if (x//80+y//80)%2==0 else "#1a2233" + self._cv.create_rectangle(x,y,x+80,y+80,fill=cc,width=0) + + # Title + self._draw_3d_box(w//2-200,h//3-100,400,80,25,"#0066ff","#003388") + self._cv.create_text(w//2,h//3-60,text="MAZE ESCAPE",fill="#ffffff",font=("Consolas",36,"bold")) + + # Subtitle + self._draw_3d_box(w//2-180,h//3,360,50,15,"#44aa44","#226622") + self._cv.create_text(w//2,h//3+25,text="2.5D ADVENTURE",fill="#ffffff",font=("Consolas",20,"bold")) + + # Start button + self._draw_3d_box(w//2-120,h//2+80,240,55,12,"#ff6644","#ffffff") + self._cv.create_text(w//2,h//2+107,text="START MAZE",fill="#ffffff",font=("Consolas",18,"bold")) + + # Instructions + self._cv.create_text(w//2,h-80,text="Find the BLUE WALL to escape each level!",font=("Consolas",16),fill="#aaccff") + self._cv.create_text(w//2,h-50,text="WASD: Move | Mouse: Look | Click: Lock Camera",font=("Consolas",14),fill="#88aacc") + + def _move_smooth(self,dx,dy): + def is_blocked(x,y): + mx,my=int(x),int(y) + return mx<0 or my<0 or mx>=self._sz or my>=self._sz or self._map[my][mx]==1 + + nx,ny = self._px+dx, self._py+dy + if not is_blocked(nx,ny): + self._px, self._py = nx,ny + else: + # Try sliding along walls + if not is_blocked(self._px,ny): + self._py=ny + elif not is_blocked(nx,self._py): + self._px=nx + + def _step(self): + # Movement + spd,dx,dy=0.12,0,0 + if 'w' in self._keys: + dx+=_m.cos(self._pa)*spd + dy+=_m.sin(self._pa)*spd + if 's' in self._keys: + dx-=_m.cos(self._pa)*spd*.8 + dy-=_m.sin(self._pa)*spd*.8 + if 'a' in self._keys: + dx+=_m.cos(self._pa-_m.pi/2)*spd*.7 + dy+=_m.sin(self._pa-_m.pi/2)*spd*.7 + if 'd' in self._keys: + dx+=_m.cos(self._pa+_m.pi/2)*spd*.7 + dy+=_m.sin(self._pa+_m.pi/2)*spd*.7 + + self._move_smooth(dx,dy) + + # Check if player reached the blue exit wall + mx, my = int(self._px), int(self._py) + + # Check surrounding cells for the exit (blue wall) + for check_x in range(max(0, mx-1), min(self._sz, mx+2)): + for check_y in range(max(0, my-1), min(self._sz, my+2)): + if self._map[check_y][check_x] == 2: + # Close enough to exit + distance = _m.sqrt((self._px - (check_x+0.5))**2 + (self._py - (check_y+0.5))**2) + if distance < 1.2: + self._reset_game(self._level + 1) + self._levelup_msg = 60 + return + + def _kd(self,e): + if self._game_state=="play" and self._mouse_locked: + self._keys.add(e.keysym.lower()) + if e.keysym.lower()=='left': + self._pa-=_m.pi/20 + if e.keysym.lower()=='right': + self._pa+=_m.pi/20 + + def _ku(self,e): + self._keys.discard(e.keysym.lower()) + +_MAZE25D() +?> + + + + + + + + +int main(){ std::cout<<"MAZE ESCAPE 2.5D M5RCode"< + +