To the time of Russian winter games... a ski man has to reach the finish line, which is hidden after dark and dangerous trees.
_='a.ontouchstart=a.onmousedowndx=0>d.clientX-a.offsetLeft-x?x-15:x$5bPbeginPathzlineWidth=g;Style=d;Style=bePcPzzVarc~h`,f,kePVbgpl={w:18:18,c:"#4169E1"initzpts=0;spd=3;lpVYSYreturn{x:,y:A,s:Math.ceil(3} initvar d,b;%S;b++)sY[b]=YSYzend={w:/3):3/3),y:A-25%T;b++)d=["#BDB76B","#556B2F"iC=d,J[b]={w:24:3224),y:(A-232)$0c:d[iC]x=(-w-50)+50;y=5cPclosePathVfTText() shp,k~b,g,kfor(g=0;g<d;g++)b=d[gO0]!=nl&&movU0][0O0][1]),3<b?quadraticCurvU3O4O1O2]):linU1O2]ePV lp~@d,@dQRect(gtcPzvar j,n,pJb=J[dgw,kxh`y,f=K/2j+h-15,f`kjKjkj$K-2j,f h-7]),f-1j+5f-1j$3]^^5b=pl;p=l@hh;f=K/2;l=f-5;n=f+5;h+h;g=[[[[l 8l 21][n 6n 19][f-1 b.h-3f-4$2][n-3f+2$2]]]gshp(g[dp,p,2f 3,3,2*pi,f 3f-5f, e$0l 11f 10n 8
-3+5
+3+5]f 4,3,pi,csk,csk,2ac=[[f-2 5[f+2 5]]acac[d][0ac[d][11,pi,@y,@yQbndf=k$0;l=K;n=K/2;h-120;d-80;k`fl`f+g]^^3fk+6,d,kl+8,d,n`-70l$2jf,n$0]blk,wtQ~@y,@yitalic bold 24_FINISH",n-3e-90)sY.y+=3,.y>= A&&(=YSYV),.x,.y,.s,2*pi,csn,csnQ~cr,crbold 20_Points: "+pts,-1830cPzy+=spd;b=x;g=y;k=x+w;f=y+hJif(e=J[d(k>.y||b>g>)&&k<f<bgzreturn}b>ndnd.y&&k<nd.x+end.w?(initV,spd++,pts+=5lpV):f>A?bgV:setTimeout(lp,20)nl=null;fnt="px GeorgiaZwCl8B4513ZwtfffZcbgCCCCBBZ@y333Zl@999Zblk000ZcsneeeZ cr="redZcskFFD39BZm=Math;rd=m.random;flr=m.floor;pi=m.PI;=a.th;A=a.height;@d=createLinearGradient(1511190wt1,cbgmxS=/3mxT=/50sY=[];J=[];bgz=function(],;d++);for(d=0;d<*rdV));flr(pl. `+sY[d]d,b,gshp([[[,hwid=b..length@d.addColorStop([[b.c,b.c,2c.="#};=e0,arc(fill[nl,;gw;kx;ey;){$+1%for(b=0;b<mx@grAhgtJaTrKk+gOb[Q,1UeTo(b[V()YnwZ";^wCl,_"+fnt;fT("`,ej,lz(~bP(.x+e.w&&Qfont="stroke.x&&f>.y+e.h,x:(-
f-5f,k`,f$5+20';for(Y in $='
~zj`_^ZYVUQOKJA@%$ ')with(_.split($[Y]))_=join(pop());eval(_)
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
a.ontouchstart=a.onmousedown=function(e){ // appends mouse and touch (mobile devices) event for player handling
if(e.clientX-a.offsetLeft-pl.x<0)pl.x-=15;
else pl.x+=15;
}
bP=function(sk,fl,lw){ // begins a canvas path - helper function
c.beginPath();
c.lineWidth=lw;
c.strokeStyle=sk;
c.fillStyle=fl;
}
eP=function(){ // ands, strokes and fills a canvas path - helper function
cP();
c.stroke();
c.fill();
}
arc=function(x,y,sz,ln,sk,fl,lw){ // draws a canvas arc -helper function
bP(sk,fl,lw);
c.arc(x,y,sz,0,ln);
eP();
}
bg=function(){ // begins a new game
pl={w:18,h:18,c:"#4169E1"};
init();
pts=0;
spd=3;
lp()
}
nwSnw=function(){ // returns a new snow object
var o={'x':flr(wid*rd()),'y':flr(hgt*rd()),'s':Math.ceil(3*rd())};
return o;
}
init=function(){ // resets game values
var aC,i;
for (i=0;i<mxS;i++) snw[i]=nwSnw();
end={w:flr(wid/3),h:3,x:flr((wid-wid/3)*rd()),y:hgt-25};
for(i=0;i<mxT;i++){
aC=['#BDB76B','#556B2F'];
iC=flr(aC.length*rd());
aTr[i]={w:24,h:32,x:flr((wid-24)*rd()),y:flr((hgt-232)*rd())+100,c:aC[iC]};
};
pl.x=flr((wid-pl.w-50)*rd())+50;pl.y=5;
}
cP=function(){c.closePath()} // helper function to close a path
fT=function(t,x,y){c.fillText(t,x,y)} // helper function to draw a custom text
shp=function(cd,sk,fl,lw){ // draw a custom canvas shape by points - helper function
bP(sk,fl,lw);
var o;
for(var i=0;i<cd.length;i++){
o=cd[i];
if(o[0]!=nl)c.moveTo(o[0][0],o[0][1]);
if(o.length>3)c.quadraticCurveTo(o[3],o[4],o[1],o[2])
else c.lineTo(o[1],o[2]);
}
eP();
}
lp=function(){ // main game loop function for drawing and all handling (saves space)
bP(grd,grd,1);
c.fillRect(0,0,wid,hgt); // refresh background
cP();
var i,p,w,x,h,y,xf,yf,x1,x2,x3,y1,y2,cl;
for(i=0;i<aTr.length;i++){ // draw trees
p=aTr[i];
w=p.w;
x=p.x;
h=p.h;
y=p.y;
xf=x+w/2;
yf=y+h-15;
shp([[[xf,y],x,yf],[nl,x+w,yf],[[x,yf+1],x+w-2,yf,xf,y+h-7]],p.c,p.c,2);
shp([[[xf-1,yf+5],xf-1,yf+13]],wCl,wCl,5);
}
p=pl;cl=lgr;w=p.w;x=p.x;y=p.y;h=p.h;x1=x+w/2;x2=x1-5;x3=x1+5;y1=y+h; // draw player
var cs=[[[[x2,y+8],x2,y+21]],[[[x3,y+6],x3,y+19]],[[[x1-1,y+p.h-3],x1-4,y1+12]],[[[x3,y1-3],x1+2,y1+12]]];
for (i=0;i<cs.length;i++)shp(cs[i],cl,cl,2);
arc(x1,y+3,3,2*pi,p.c,p.c,2);
shp([[[x1,y+3],x1,y1-5],[[x1,y+10],x2,y+11],[[x1,y+10],x3,y+8],[[x1,y1-5],x1-3,y1+5],[[x1,y1-5],x1+3,y1+5]],p.c,p.c,2);
arc(x1,y+4,3,pi,csk,csk,2);
ac=[[x1-2,y+5],[x1+2,y+5]];
for (i=0;i<ac.length;i++) arc(ac[i][0],ac[i][1],1,pi,gry,gry,1);
p=end;w=p.w;x=p.x;y=p.y;x1=x+10;x2=x+w;x3=x+w/2;y1=y-120;y2=y-80; // draw finish line
shp([[[x,y],x1,y1],[[x2,y],x1+w,y1]],wCl,wCl,3);
shp([[[x1,y1],x+6,y2,x+15,y1+20],[nl,x2+8,y2,x3,y-70],[nl,x2+12,y1,x2+15,y1+20],[nl,x1,y1,x3,y1+10]],blk,wt,1);
bP(gry,gry,1);
c.font="italic bold 24"+fnt;
fT("FINISH",x3-30,y-90);
for (i=0;i<snw.length;i++){ // draw snow
snw[i].y+=3;
if (snw[i].y>=hgt) snw[i]=nwSnw();
arc(snw[i].x,snw[i].y,snw[i].s,2*pi,csn,csn,1);
}
bP(cr,cr,1); // draw points
c.font="bold 20"+fnt;
fT("Points: "+pts,wid-180,30);
cP();
pl.y+=spd;
var o,pX=pl.x,pY=pl.y,pW=pl.x+pl.w,pH=pl.y+pl.h;
for(i=0;i<aTr.length;i++){ // player collides with a tree
o=aTr[i];
if(((pW>=o.x&&pH>=o.y)||(pX>=o.x+o.w&&pY>=o.y+o.h))&&(pW<=o.x+o.w&&pH<=o.y+o.h)){bg();return}
}
if(pX>=end.x&&pH>=end.y&&pW<=end.x+end.w){ // player has reached the finish line
init();
spd++;
pts+=50;
lp();
}
else if(pH>hgt) bg() // player drove away
else setTimeout(lp,20);
}
nl=null; // init game variables,constants and pointers
fnt="px Georgia";
wCl="#8B4513";wt="#fff";cbg="#CCCCBB";gry="#333";lgr="#999";blk="#000";csn="#eee";cr="red";csk="#FFD39B"; // game colors
m=Math;
rd=m.random;
flr=m.floor;
pi=m.PI;
wid=a.width;
hgt=a.height;
grd=c.createLinearGradient(0,150,10,10,10,90); // background gradient
grd.addColorStop(0,wt);
grd.addColorStop(1,cbg);
mxS=flr(wid/3); // max snow
mxT=flr(wid/50); // max trees
snw=[];
aTr=[];
bg();