let w,h,g,my={};function dartsMain(){let version='0.51';my.bdSz=400 w=my.bdSz h=my.bdSz my.scoreWd=70 my.opts={gameN:0} my.vals=[20,1,18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12,5] my.rads={bullIn:12.7/2,bullOut:31.8/2,tripleIn:99,tripleOut:107,doubleIn:162,doubleOut:170,txt:196,bd:451/2} my.mouse={dnQ:false} my.anims=[] my.animClearQ=true my.gameN=optGet('gameN') my.games=[{name:'301',throwsPerRound:3,tgtScore:301,radExtra:0},{name:'501',throwsPerRound:3,tgtScore:501,radExtra:0},{name:'31',throwsPerRound:3,tgtScore:31,radExtra:10},] my.game=my.games[my.gameN] my.mates=[{id:'a',name:'Blue',clr:'blue',score:my.game.tgtScore,side:'left',x:0,y:0},{id:'b',name:'Red',clr:'red',score:my.game.tgtScore,side:'right',x:w-my.scoreWd-4,y:0}] my.mateN=0 let s='';my.sndHome=(document.domain=='localhost')?'/mathsisfun/images/sounds/':'/images/sounds/' s+='';s+='';s+='';s+='';my.snds=[];my.soundQ=true s+='
';s+='';s+=optPopHTML();s+='
' s+='Message
' s+='
' s+='
' my.mates.map(mate=>{s+=`
` s+=`
`}) s+='';s+='
';s+='
© 2021 MathsIsFun.com v'+version+'
';s+='
';s+='
';document.write(s);let el=document.getElementById('canvas1');let ratio=3;el.width=w*ratio;el.height=h*ratio;el.style.width=w+"px";el.style.height=h+"px";g=el.getContext("2d");g.setTransform(ratio,0,0,ratio,0,0);msg('Click and Drag','black',w/2-140,w/2) drawDartboard() my.aimer=new Anim() let div=document.getElementById('canvas1') div.onmousedown=function(ev){let rtn=bdHit(ev.offsetX,ev.offsetY) my.mouse.dnQ=true my.mouse.sttx=ev.offsetX my.mouse.stty=ev.offsetY console.log('down',rtn,my.animClearQ) if(!my.animClearQ)animsClear() let mate=my.mates[my.mateN] mate.dartN-- document.getElementById('mateDartN'+mate.id).innerHTML='*'.repeat(mate.dartN) msg('',mate.clr,-500,0)};div.onmousemove=function(ev){if(!my.mouse.dnQ)return let rtn=bdHit(ev.offsetX,ev.offsetY) my.mouse.endx=ev.offsetX my.mouse.endy=ev.offsetY if(my.mouse.dnQ){let dx=my.mouse.endx-my.mouse.sttx let dy=my.mouse.endy-my.mouse.stty let ang=Math.atan2(dx,-dy)+Math.PI/2 let mate=my.mates[my.mateN] my.aimer.drawAt(my.mouse.sttx,my.mouse.stty,ang) my.aimer.drawLine(0,0,my.mouse.endx-my.mouse.sttx,my.mouse.endy-my.mouse.stty,mate.clr)}};div.onmouseup=function(ev){let rtn=bdHit(ev.offsetX,ev.offsetY) console.log('up',rtn) my.aimer.clear() my.mouse.dnQ=false my.mouse.endx=ev.offsetX my.mouse.endy=ev.offsetY fire()};gameNew()} function gameNew(){my.mates.map(mate=>{mate.score=my.game.tgtScore document.getElementById('mateScore'+mate.id).innerHTML=mate.score}) my.mateN=0 roundNew()} function roundNew(){let mate=my.mates[my.mateN] document.getElementById('mateDartN'+mate.id).innerHTML='' my.mateN=1-my.mateN mate=my.mates[my.mateN] mate.dartN=3 document.getElementById('mateDartN'+mate.id).innerHTML='*'.repeat(mate.dartN) mate.roundScoreStt=mate.score let currId=mate.id my.mates.map(mate=>{let div=document.getElementById('mateScore'+mate.id) div.style.borderColor=mate.clr if(mate.id==currId){div.style.backgroundColor='hsla(120,100%,90%,0.6)'}else{div.style.backgroundColor='hsla(120,100%,90%,0.0)'}}) my.animClearQ=false} function animsClear(){my.anims.map(anim=>{anim.clear()}) my.anims=[] my.animClearQ=true} function fire(){console.log('fire',my.mouse) doTraj() let anim=new Anim(my.pts) my.anims.push(anim) anim.stt()} function doTraj(){let dx=my.mouse.endx-my.mouse.sttx let dy=my.mouse.endy-my.mouse.stty console.log('doTraj dx,dy',dx,dy) dx*=my.rads.bd/(my.bdSz/2) dy*=my.rads.bd/(my.bdSz/2) console.log('doTraj dx,dy',dx,dy) let ang=Math.atan2(dx,-dy) let px=my.mouse.sttx let py=my.mouse.stty let pz=0 let vx=dx let vy=dy let vz=Math.sqrt(dx*dx+dy*dy)*0.01 let ax=0 let ay=9 let az=0 let drag=0 console.log('doTraj',vx,vy) let dt=0.1 let pts=[] for(let i=0;i<=Math.ceil(10/dt);i++){pts.push({t:i*dt,x:fmt2(px),y:fmt2(py),z:fmt2(pz),ang:ang+Math.PI/2}) if(pz>2.37)break vx+=ax*dt vy+=ay*dt vz+=az*dt vx-=vx*vx*drag*dt vy-=vy*vy*drag*dt vz-=vz*vz*drag*dt px+=vx*dt py+=vy*dt pz+=vz*dt ang=Math.atan2(vx,-vy)} my.pts=pts console.log('doTraj',my.pts)} function fmt2(x){return((x*100)<<0)/100} class Anim{constructor(pts){this.pts=pts this.rad=200 this.canvas=document.createElement("canvas");document.getElementById('drg').appendChild(this.canvas);this.canvas.setAttribute("id","ammo");this.canvas.setAttribute("style","position:absolute;");this.canvas.setAttribute("width",this.rad*2);this.canvas.setAttribute("height",this.rad*2);this.canvas.style.setProperty("top",0+"px");this.canvas.style.setProperty("left",0+"px");this.g=this.canvas.getContext('2d');} stt(){this.frameN=0 this.frame()} frame(){let pt=this.pts[this.frameN] let finalQ=false if(pt.y<0){finalQ=true} this.canvas.style.setProperty("left",pt.x-this.rad+"px");this.canvas.style.setProperty("top",pt.y-this.rad+"px");this.g.clearRect(0,0,g.canvas.width,g.canvas.height) this.g.dart(this.rad,this.rad,pt.ang) this.frameN++ if(this.frameN>=this.pts.length)finalQ=true if(finalQ){hit(pt)}else{requestAnimationFrame(this.frame.bind(this));}} drawAt(x,y,ang){this.canvas.style.setProperty("left",x-this.rad+"px");this.canvas.style.setProperty("top",y-this.rad+"px");this.g.clearRect(0,0,g.canvas.width,g.canvas.height) this.g.dart(this.rad,this.rad,ang)} drawLine(x0,y0,x1,y1,clr){let g=this.g g.strokeStyle=clr g.lineWidth=3 g.beginPath() g.moveTo(this.rad+x0,this.rad+y0) g.lineTo(this.rad+x1,this.rad+y1) g.stroke()} clear(){this.g.clearRect(0,0,g.canvas.width,g.canvas.height)}} function hit(pt){let result=bdHit(pt.x,pt.y) console.log('Landed!',pt,result) let mate=my.mates[my.mateN] msg(result.score,mate.clr,pt.x,pt.y) console.log('score',mate) let currScore=mate.score-result.score if(currScore==0&&(result.type=="double"||result.type=="triple"||result.type=="bullIn"||result.type=="bullOut")){document.getElementById('mateScore'+mate.id).innerHTML=currScore win() return} if(currScore<0||currScore==1){mate.score=mate.roundScoreStt document.getElementById('mateScore'+mate.id).innerHTML=mate.score roundNew() return} mate.score=currScore document.getElementById('mateScore'+mate.id).innerHTML=mate.score if(mate.dartN==0){roundNew()}} function win(){let mate=my.mates[my.mateN] msg(mate.name+' Wins!',mate.clr,w/2-100,w/2)} function bdHit(x,y){let dx=x-my.bdSz/2 let dy=y-my.bdSz/2 let rad=Math.sqrt(dx*dx+dy*dy) rad=rad*my.rads.bd/(my.bdSz/2) let ang=Math.atan2(dx,-dy) if(ang<0)ang+=2*Math.PI let sectN=(ang/(2*Math.PI)*my.vals.length+0.5)<<0 if(sectN>=my.vals.length)sectN=0 let rx=my.game.radExtra console.log('bdHit',rx);if(radmy.rads.doubleOut+rx)return{type:'out',score:0} let score=my.vals[sectN] if(rad>my.rads.doubleIn-rx&&radmy.rads.tripleIn-rx&&rad0){let div=document.getElementById(name) if(div.currentTime>0&&div.currentTime0)soundPlayQueue();};} function soundToggle(){let btn='sound' if(my.soundQ){my.soundQ=false document.getElementById(btn).classList.add("mute")}else{my.soundQ=true document.getElementById(btn).classList.remove("mute")}} function radioHTML(prompt,id,lbls,checkN,func){let s='';s+='
';s+='
';s+=prompt;s+='
';s+='
';for(let i=0;i';s+='';} s+='
';s+='
';return s;} function radioNGet(name){var div=document.querySelector('input[name="'+name+'"]:checked') var id=div.id var n=(id.match(/\d+$/)||[]).pop();return n} function optPopHTML(){let s='';s+='
';s+='';s+=radioHTML('Game','game',my.games,my.gameN,'radioClick');s+='
';s+='New game? ' s+='';s+=' ' s+='';s+='
';s+='
';return s;} function radioClick(n){} function toggleBtn(btn,onq){if(onq){document.getElementById(btn).classList.add("hi");document.getElementById(btn).classList.remove("lo");}else{document.getElementById(btn).classList.add("lo");document.getElementById(btn).classList.remove("hi");}} CanvasRenderingContext2D.prototype.roundRect=function(x,y,w,h,r){if(w<2*r)r=w/2;if(h<2*r)r=h/2;this.beginPath();this.moveTo(x+r,y);this.arcTo(x+w,y,x+w,y+h,r);this.arcTo(x+w,y+h,x,y+h,r);this.arcTo(x,y+h,x,y,r);this.arcTo(x,y,x+w,y,r);this.closePath();return this;} CanvasRenderingContext2D.prototype.drawPoly=function(pts){let g=this;g.moveTo(pts[0].x,pts[0].y);for(let i=1;i{if(shape.mirrorQ){pts=mirror(shape.pts) pts=toxy(pts)}else{pts=toxy(shape.pts)} pts=trans(pts,x,y,ang,3,3) g.strokeStyle='#000' g.lineWidth=0.5 g.fillStyle=shape.clr g.beginPath() g.drawPoly(pts) g.fill();g.stroke()})} function mirror(pts){let len=pts.length for(let i=len-1;i>=0;i--){let pt=pts[i];pts.push([pt[0],-pt[1]])} return pts} function toxy(pts){let ptsxy=pts.map(pt=>{return{x:pt[0],y:pt[1]}}) return ptsxy} function trans(pts,xStt,yStt,ang,xFact,yFact){let a=Math.cos(ang) let b=-Math.sin(ang) let c=Math.sin(ang) let d=Math.cos(ang) let pts2=[] for(let i=0;i{return{x:xStt+pt.x,y:yStt+pt.y}}) return pts3} function polarToCartesian(centerX,centerY,radius,angle){let x=centerX+(radius*Math.cos(angle));let y=centerY+(radius*Math.sin(angle));return{x:x,y:y}} function optPop(){console.log("optpop");var pop=document.getElementById('optpop');pop.style.transitionDuration="0.3s";pop.style.opacity=1;pop.style.zIndex=102;pop.style.left=(w-340)/2+'px';} function optYes(){var pop=document.getElementById('optpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-999px';my.gameN=radioNGet('game') console.log('optYes',my.gameN) optSet('gameN',my.gameN) my.game=my.games[my.gameN] gameNew()} function optNo(){var pop=document.getElementById('optpop');pop.style.opacity=0;pop.style.zIndex=1;pop.style.left='-999px';} function optGet(name){var val=localStorage.getItem(`yacht.${name}`) if(val==null)val=my.opts[name] return val} function optSet(name,val){localStorage.setItem(`yacht.${name}`,val) my.opts[name]=val}