ソースコードが1000行を越えてきたので、念のためこちらにも保存。
enchant(); game_size=320; dt=1/10000.0; dt2=0.5*dt*dt; scale=32.0/1.0; //dots/meter Gravity=-9.8; num_frame=0; var EARTH = enchant.Class.create(Sprite,{ initialize:function(){ enchant.Sprite.call(this, game_size, game_size); this.hl=3.0; this.hr=1.0; this.w=game_size/scale; this.hc=0.2; var surface=new Surface(game_size,game_size); surface.context.strokeStyle="SaddleBrown"; surface.context.fillStyle="SaddleBrown"; surface.context.lineWidth=2; surface.context.beginPath(); surface.context.moveTo(0,game_size); surface.context.lineTo(0,game_size-this.hl*scale); var h=this.hl-(this.hl-this.hr)/(this.w)*(this.w*0.48); surface.context.lineTo(this.w*0.48*scale,game_size-h*scale); surface.context.lineTo(this.w*0.48*scale,game_size-(h+this.hc)*scale); h=this.hl-(this.hl-this.hr)/(this.w)*(this.w*0.52)+this.hc; surface.context.lineTo(this.w*0.52*scale,game_size-h*scale); surface.context.lineTo(this.w*0.52*scale,game_size-(h-this.hc)*scale); surface.context.lineTo(this.w*scale,game_size-this.hr*scale); surface.context.lineTo(this.w*scale,game_size); surface.context.fill(); this.image=surface; game.rootScene.addChild(this); }, change:function(hl,hc,hr){ this.hl=hl; this.hr=hr; this.hc=hc; var surface=new Surface(game_size,game_size); surface.context.strokeStyle="SaddleBrown"; surface.context.fillStyle="SaddleBrown"; surface.context.lineWidth=2; surface.context.beginPath(); surface.context.moveTo(0,game_size); surface.context.lineTo(0,game_size-this.hl*scale); var h=this.hl-(this.hl-this.hr)/(this.w)*(this.w*0.48); surface.context.lineTo(this.w*0.48*scale,game_size-h*scale); surface.context.lineTo(this.w*0.48*scale,game_size-(h+this.hc)*scale); h=this.hl-(this.hl-this.hr)/(this.w)*(this.w*0.52)+this.hc; surface.context.lineTo(this.w*0.52*scale,game_size-h*scale); surface.context.lineTo(this.w*0.52*scale,game_size-(h-this.hc)*scale); surface.context.lineTo(this.w*scale,game_size-this.hr*scale); surface.context.lineTo(this.w*scale,game_size); surface.context.fill(); this.image=surface; }, touch:function(x,y){ var h=this.hl-(this.hl-this.hr)/(this.w)*x; if(this.w*0.48 <=x && x<=this.w*0.52) h+=this.hc; if(y<h) return(true); else return(false); } }); FRAME_NODE=enchant.Class.create({ initialize: function(parent,x,y,mass){ this.parent=parent; this.x=x/1000; this.y=y/1000; this.mass=mass; }, force: function() { var force={x:0.0, y:0.0, m:0.0}; if(this.wheel!==undefined) { force=this.wheel.force(); force.y+=Gravity*this.mass; force.m+=this.x*Gravity*this.mass; } else if(this.suspention!==undefined) { force=this.suspention.force(); force.y+=Gravity*this.mass; force.m+=this.x*Gravity*this.mass; } else{ force.y=Gravity*this.mass; force.m=this.x*force.y-this.y*force.x; } return(force); }, redraw_sprite:function(){ var X,Y; if(this.wheel!==undefined) this.wheel.redraw_sprite(); else if(this.suspention!==undefined) this.suspention.redraw_sprite(); }, remove: function() { if(this.wheel!==undefined) this.wheel.remove(); else if(this.suspention!==undefined) this.suspention.remove(); } }); WHEEL_NODE=enchant.Class.create({ initialize: function(parent,radius,mass) { this.dt=dt; this.dt2=dt2; this.parent=parent; this.x=parent.x; this.y=parent.y; this.radius=radius/1000; this.I=this.radius*this.radius*mass; this.pressure=2.0*1024*100; this.width=2.1*25.4/1000*0.5; this.theta=0.0; this.theta_=0.0; this.omega=0.0; var rad=this.radius*scale; var is=Math.floor(rad*2.0*1.1); this.is=is; this.sprite=new Sprite(is, is); var surface=new Surface(is,is); surface.context.lineWidth=2; surface.context.strokeStyle="Gray"; surface.context.beginPath(); surface.context.moveTo(0,is/2); surface.context.lineTo(is,is/2); surface.context.stroke(); surface.context.beginPath(); surface.context.moveTo(is/2,0); surface.context.lineTo(is/2,is); surface.context.stroke(); surface.context.strokeStyle="black"; surface.context.beginPath(); surface.context.arc(is/2,is/2,rad,0.0,Math.PI*2); surface.context.stroke(); this.sprite.image=surface; var X,Y; if(this.parent.parent instanceof BICYCLE) { X=this.parent.parent.X; Y=this.parent.parent.Y; } else if(this.parent.parent.parent instanceof BICYCLE){ X=this.parent.parent.parent.X; Y=this.parent.parent.parent.Y; } this.sprite.x=-is/2+(this.x+X)*scale; this.sprite.y=-is/2-(this.y+Y)*scale+game_size; game.rootScene.addChild(this.sprite); }, redraw_sprite:function(){ var X,Y; if(this.parent.parent instanceof BICYCLE) { X=this.parent.parent.X; Y=this.parent.parent.Y; } else if(this.parent.parent.parent instanceof BICYCLE){ X=this.parent.parent.parent.X; Y=this.parent.parent.parent.Y; } this.sprite.x=-this.is/2+(this.x+X)*scale; this.sprite.y=-this.is/2-(this.y+Y)*scale+game_size; this.x=this.parent.x; this.y=this.parent.y; var dtheta=180.0/Math.PI*(this.theta-this.theta_); this.sprite.rotate(dtheta); this.theta_=this.theta; }, remove: function() { game.rootScene.removeChild(this.sprite); }, force:function(){ var damp_coef=10.0/5e-4;//単位面積あたりのダンピングレート 10.0s^-1/5cm^-2を仮定 var force={x:0.0, y:0.0, m:0.0}; var m=0.0; var S=0; var X,Y,Vx,Vy,Omega; var PI=Math.PI; if(this.parent.parent instanceof BICYCLE) { X=this.parent.parent.X; Y=this.parent.parent.Y; Vx=this.parent.parent.Vx; Vy=this.parent.parent.Vy; Omega=this.parent.parent.Omega; } else if(this.parent.parent.parent instanceof BICYCLE){ X=this.parent.parent.parent.X; Y=this.parent.parent.parent.Y; Vx=this.parent.parent.parent.Vx; Vy=this.parent.parent.parent.Vy; Omega=this.parent.parent.parent.Omega; } var px=this.parent.x; var py=this.parent.y; var radius=this.radius; var wv=this.radius*this.omega; var dTheta=PI/50.0; var theta1=PI; for(var i=0;i<50;i++){ var theta=dTheta*i; // console.log(theta); var cos=Math.cos(theta); var sin=Math.sin(theta); var x=px-radius*cos+X; var y=py-radius*sin+Y; if(earth.touch(x,y)===true) { theta1=theta-dTheta; break; } } var theta2=0; for(i=50;i>=0;i--){ theta=dTheta*i; cos=Math.cos(theta); sin=Math.sin(theta); x=px-radius*cos+X; y=py-radius*sin+Y; if(earth.touch(x,y)===true) { theta2=theta+dTheta; break; } } dTheta=PI/1000; var dS=this.width * radius * dTheta; var damp=damp_coef*dS; var force_abs=this.pressure*dS; L=Math.floor((theta2-theta1)/dTheta); for(i=0;i<L;i++){ theta=theta1+dTheta*i; cos=Math.cos(theta); sin=Math.sin(theta); x=px-radius*cos y=py-radius*sin; var vx=-y*Omega+Vx-wv*sin; var vy=x*Omega+Vy+wv*cos; x+=X; y+=Y; if(earth.touch(x,y)===true){ // S+=1; var fx=force_abs*cos-vx*damp;//転がり抵抗 var fy=force_abs*sin-vy*damp;//転がり抵抗 force.x+=fx-wv*damp*sin/10.0; force.y+=fy-wv*damp*cos/10.0; // m+=this.radius*(cos*(fy+wv*damp*cos/10.0)-sin*(fx+wv*damp*sin/10.0)); m+=radius*(cos*fy-sin*fx); } } // force.y+=Gravity*this.parent.mass; this.theta +=this.omega*this.dt; if(this.theta>=PI*2) this.theta-=PI*2; if(this.theta<=-PI*2) this.theta+=PI*2; this.omega +=m/this.I*this.dt; force.m=this.parent.x*force.y-this.parent.y*force.x; /* if(Math.floor(this.sprite.age/100)*100===this.sprite.age) { // if(this.parent instanceof SUSPENTION_NODE) { console.log("forceY", this.x,S,wv,force.y); //} }*/ return(force); } }); function abs(r){ return(Math.sqrt(r.x*r.x+r.y*r.y)); } function normalize(r){ l=abs(r); var rr={x:r.x/l, y:r.y/l}; return(rr); } function project(r,e){ var l=mul(r,e); var rr={x:e.x*l, y:e.y*l}; return(rr); } function mul(a,b){ return(a.x*b.x+a.y*b.y); } SUSPENTION_NODE=enchant.Class.create({ initialize: function(parent,x,y,mass) { this.parent=parent; this.dt=dt; this.dt2=dt2; x=x/1000-parent.parent.X; y=y/1000-parent.parent.Y; this.x=x; this.y=y; var e0={x:x-parent.x, y:y-parent.y}; this.is_x=Math.floor(Math.abs(e0.x)*scale); this.is_y=Math.floor(Math.abs(e0.y)*scale); this.l0=abs(e0); this.vl=0.0; this.mass=mass; this.shrink=0.0; this.sprite=new Sprite(this.is_x, this.is_y); var surface=new Surface(this.is_x,this.is_y); surface.context.lineWidth=2; surface.context.strokeStyle="Red"; surface.context.beginPath(); surface.context.moveTo(0,0); surface.context.lineTo(this.is_x/2,this.is_y/2); surface.context.stroke(); surface.context.beginPath(); surface.context.strokeStyle="Gray"; surface.context.lineWidth=4; surface.context.moveTo(this.is_x/2,this.is_y/2); surface.context.lineTo(this.is_x,this.is_y); surface.context.stroke(); this.sprite.image=surface; var X,Y; X=this.parent.parent.X; Y=this.parent.parent.Y; this.sprite.x=(this.parent.x+X)*scale; this.sprite.y=-(this.parent.y+Y)*scale+game_size; this.sprite.originX=0; this.sprite.originY=0;//this.is_y; game.rootScene.addChild(this.sprite); }, redraw_sprite:function(){ if(this.wheel!==undefined) this.wheel.redraw_sprite(); var X,Y; X=this.parent.parent.X; Y=this.parent.parent.Y; this.sprite.x=(this.parent.x+X)*scale; this.sprite.y=-(this.parent.y+Y)*scale+game_size; var theta=180.0/Math.PI*this.parent.parent.Theta; this.sprite.rotation=-theta; }, remove:function(){ if(this.wheel!==undefined) this.wheel.remove(); game.rootScene.removeChild(this.sprite); }, force:function(){ var stroke=10.0e-2;//ストローク10cm var P0=4100.0e2/60*55; //60psi=4100HPaサスペンション圧力 メータ読み つまり実際は+1atm var Patm=1024.0e2;//大気圧 var S=Math.PI*1.5e-2*1.5e-2; //直径3cmのピストン var damp_c=250;//250.0;//1m/sの速度の時25kg重のダンピング、コンプレッション側 var damp_r=500;//500.0;//1m/sの速度の時50kg重のダンピング、リバウンド側 var rigid=1000.0/1e-3;//底付きしたとき、および伸びきったときのばね定数 var r={x:this.x-this.parent.x, y:this.y-this.parent.y}; var l=abs(r); var eT=normalize(r); var eH={x:-eT.y, y:eT.x}; var T; var shrink=this.l0-l; this.shrink=shrink; if (shrink <= 0.0) {//伸びきったとき T=rigid*shrink; }else if (shrink >= stroke*0.99) {//底付きしたとき T=rigid*(shrink-stroke); }else{ var P=(P0+Patm)*stroke/(stroke-shrink); if(this.vl<0.0) T=(P-Patm)*S -damp_c*this.vl; else T=(P-Patm)*S -damp_r*this.vl; } var wheel_force=this.wheel.force(); wheel_force.y+=Gravity*this.mass; var fT=mul(wheel_force,eT); var fH=mul(wheel_force,eH); var x1={x:this.x, y:this.y}; var x1T=mul(x1,eT); var x1H=mul(x1,eH); // if(Math.floor(this.sprite.age/1000)*1000===this.sprite.age) console.log(x1H,x1T); var force={x:0.0, y:0.0, m:0.0}; var x2={x:this.parent.x, y:this.parent.y}; var x2H=mul(x2,eH); var Omega=this.parent.parent.Omega; var I=this.parent.parent.I; var M=this.parent.parent.M; var A={x:this.parent.parent.Ax, y:this.parent.parent.Ay}; var AT=mul(A,eT); var AH=mul(A,eH); var Ao=this.parent.parent.Ao; /* var tmp1=1.0/this.mass+1.0/M+x1T*x1T/I; var tmp2=-fH/this.mass + x2H*x1T/I*T -Omega*Omega*x1H + Omega*this.vl; var H=tmp2/tmp1; var a=fT/this.mass+(1.0/this.mass+1.0/M+x2H*x1H/I)*T-x1T*x1H/I*H+Omega*Omega*x1T; */ var a=(fT+T)/this.mass-AT/M +Ao*x1H +Omega*Omega*x1T; var H=-fH+this.mass*(AH/M +Ao*x1T -Omega*Omega*x1H + Omega*this.vl); x1T+=this.vl*this.dt+a*this.dt2; this.vl+=a*this.dt; this.x=x1T*eT.x+x1H*eH.x; this.y=x1T*eT.y+x1H*eH.y; force.x=-T*eT.x-H*eH.x; force.y=-T*eT.y-H*eH.y; force.m=x2H*T-x1T*H; // if(Math.floor(this.sprite.age/1000)*1000===this.sprite.age) console.log(Omega,I,M); // if(Math.floor(this.sprite.age/1000)*1000===this.sprite.age) console.log(shrink,T); // if(Math.floor(this.sprite.age/100)*100===this.sprite.age) { // var P=(P0+Patm)*stroke/(stroke-shrink); // console.log("l, vl, p., d: ",-fH/this.mass,x2H*x1T/I*T,-Omega*Omega*x1H, Omega*this.vl); // console.log("Tx,Hx, deff: ",-T*eT.x,-H*eH.x, force.x); // console.log("Tx,Hx, deff: ",force.x,force.y); // console.log("w: ",wheel_force.x,wheel_force.y); // } return(force); } }); HUMAN = enchant.Class.create(Sprite,{ initialize: function(bicycle){ this.parent=bicycle; this.dt=dt; this.dt2=dt2; this.X=bicycle.frame_node[1].x-0.1+bicycle.X; this.Y=bicycle.frame_node[1].y+0.8+bicycle.Y; this.Theta=Math.PI*0.24; this.Theta_=Math.PI*0.24; this.Vx=0.0; this.Vy=0.0; this.Omega=0.0; this.Ax=0.0; this.Ay=0.0; this.Ao=0.0; this.x1=0.0; this.y1=0.0; this.x2=0.8; this.y2=0.2; this.M=68.0; this.I=this.M*this.x2*this.x2/4; this.force={x:0.0, y:0.0, m:0.0}; this.image_size_x=Math.floor(this.x2*scale); this.image_size_y=Math.floor(this.y2*scale); enchant.Sprite.call(this,this.image_size_x +15, this.image_size_y+10); var surface=new Surface(this.image_size_x +15, this.image_size_y+10); surface.context.fillStyle="Peru"; surface.context.strokeStyle="Peru"; surface.context.lineWidth=2; surface.context.beginPath(); surface.context.rect(this.x1*scale,this.y1*scale,this.x2*scale,this.y2*scale); surface.context.fill(); surface.context.fillStyle="Black"; surface.context.beginPath(); surface.context.arc(this.image_size_x+7,5,5,0,Math.PI*2); surface.context.fill(); this.image=surface; this.originX=this.image_size_x/2; this.originY=this.image_size_y/2; this.x=-this.image_size_x/2+this.X*scale; this.y=-this.image_size_y/2+game_size-this.Y*scale; this.rotation=-180/Math.PI*this.Theta; game.rootScene.addChild(this); this.arm={length:0.5, x:this.x2, y:(this.y1+this.y2)/2, theta:-Math.PI/2, connect:bicycle.frame_node[5]}; this.arm.x=this.arm.x-(this.x1+this.x2)/2; this.arm.y=this.arm.y-(this.y1+this.y2)/2; var cos=Math.cos(this.Theta); var sin=Math.sin(this.Theta); var x=this.arm.x*cos-this.arm.y*sin; var y=this.arm.y*cos+this.arm.x*sin; this.arm.x=x; this.arm.y=y; var dx=this.arm.connect.x+this.parent.X-(this.arm.x+this.X); var dy=this.arm.connect.y+this.parent.Y-(this.arm.y+this.Y); this.arm.theta=Math.atan2(dy*cos-dx*sin,dx*cos+dy*sin); this.arm.theta0=this.arm.theta; this.arm.length=Math.sqrt(dx*dx+dy*dy); this.arm.length0=this.arm.length; this.arm.sprite=new Sprite(Math.floor(this.arm.length*scale),3); this.arm.sprite.originX=0; this.arm.sprite.originY=2; surface=new Surface(Math.floor(this.arm.length*scale),3); surface.context.fillStyle="black"; surface.context.strokeStyle="black"; surface.context.lineWidth=2; surface.context.beginPath(); surface.context.rect(0,0,this.arm.length*scale,3); surface.context.fill(); this.arm.sprite.image=surface; this.arm.sprite.x=(this.X+this.arm.x)*scale; this.arm.sprite.y=game_size-(this.Y+this.arm.y)*scale; this.arm.sprite.rotation=-180/Math.PI*(this.Theta+this.arm.theta); game.rootScene.addChild(this.arm.sprite); this.leg={length:0.75, x:this.x1+0.1, y:(this.y1+this.y2)/2, theta:-0.55*Math.PI, connect:bicycle.frame_node[1]}; this.leg.x=this.leg.x-(this.x1+this.x2)/2; this.leg.y=this.leg.y-(this.y1+this.y2)/2; x=this.leg.x*cos-this.leg.y*sin; y=this.leg.y*cos+this.leg.x*sin; this.leg.x=x; this.leg.y=y; dx=this.leg.connect.x+this.parent.X-(this.leg.x+this.X); dy=this.leg.connect.y+this.parent.Y-(this.leg.y+this.Y); this.leg.theta=Math.atan2(dy*cos-dx*sin,dx*cos+dy*sin); this.leg.theta0=this.leg.theta; this.leg.length=Math.sqrt(dx*dx+dy*dy); this.leg.length0=this.leg.length; this.leg.sprite=new Sprite(Math.floor(this.leg.length*scale),4); this.leg.sprite.originX=0; this.leg.sprite.originY=2; surface=new Surface(Math.floor(this.leg.length*scale),3); surface.context.fillStyle="Peru"; surface.context.strokeStyle="Peru"; surface.context.lineWidth=2; surface.context.beginPath(); surface.context.rect(0,0,this.leg.length*scale,3); surface.context.fill(); this.leg.sprite.image=surface; this.leg.sprite.x=(this.X+this.leg.x)*scale; this.leg.sprite.y=game_size-(this.Y+this.leg.y)*scale; this.leg.sprite.rotation=-180/Math.PI*(this.Theta+this.leg.theta); game.rootScene.addChild(this.leg.sprite); }, redraw_sprite:function(){ this.x=-this.image_size_x/2+this.X*scale; this.y=-this.image_size_y/2+game_size-this.Y*scale; this.rotation=-180/Math.PI*this.Theta; this.arm.sprite.scaleX=this.arm.length/this.arm.length0; this.arm.sprite.x=(this.X+this.arm.x)*scale; this.arm.sprite.y=game_size-(this.Y+this.arm.y)*scale; this.arm.sprite.rotation=-180/Math.PI*(this.Theta+this.arm.theta); this.leg.sprite.scaleX=this.leg.length/this.leg.length0; this.leg.sprite.x=(this.X+this.leg.x)*scale; this.leg.sprite.y=game_size-(this.Y+this.leg.y)*scale; this.leg.sprite.rotation=-180/Math.PI*(this.Theta+this.leg.theta); }, new_force:function(){ this.force.x=0; this.force.y=0; this.force.m=0; var force={x:0, y:0, m:0}; var KTA=100/1e-2; var KTL=200/1e-2; var KM=300/(Math.PI/180*5); var dampT=100; var dampM=100; var dx=this.arm.connect.x+this.parent.X-(this.arm.x+this.X); var dy=this.arm.connect.y+this.parent.Y-(this.arm.y+this.Y); var length=Math.sqrt(dx*dx+dy*dy); var vt=(length-this.arm.length)/this.dt; this.arm.length=length; var Theta_=this.Theta+this.arm.theta0; var cos=Math.cos(Theta_); var sin=Math.sin(Theta_); var theta=Math.atan2(dy*cos-dx*sin,dx*cos+dy*sin)+this.arm.theta0; var vm=(theta-this.arm.theta)/dt; this.arm.theta=theta; var T=(this.arm.length-this.arm.length0)*KTA+vt*dampT; var M=(this.arm.theta-this.arm.theta0)*KM+vm*dampM; var Tx=T*dx/length; var Ty=T*dy/length; this.force.x+=Tx-M/length*dy/length; this.force.y+=Ty+M/length*dx/length; this.force.m+=M+this.arm.x*Ty-this.arm.y*Tx; var fx=-Tx-(-M)/length*dy/length; force.x+=fx; var fy=-Ty+(-M)/length*dx/length; force.y+=fy; force.m+=this.arm.connect.x*fy-this.arm.connect.y*fx; // console.log("T",(this.arm.length-this.arm.length0)*KT,-vt*dampT); // console.log("M",(this.arm.theta-this.arm.theta0)*KM,-vm*dampM); // console.log("M",this.arm.theta,this.arm.theta0,this.arm.theta-this.arm.theta0); // console.log("arm",Tx,Ty,T,dx,dy,length); dx=this.leg.connect.x+this.parent.X-(this.leg.x+this.X); dy=this.leg.connect.y+this.parent.Y-(this.leg.y+this.Y); length=Math.sqrt(dx*dx+dy*dy); vt=(length-this.leg.length)/this.dt; this.leg.length=length; Theta_=this.Theta+this.leg.theta0; cos=Math.cos(Theta_); sin=Math.sin(Theta_); theta=Math.atan2(dy*cos-dx*sin,dx*cos+dy*sin)+this.leg.theta0; vm=(theta-this.leg.theta)/dt; this.leg.theta=theta; T=(this.leg.length-this.leg.length0)*KTL+vt*dampT; M=(this.leg.theta-this.leg.theta0)*KM+vm*dampM; Tx=T*dx/length; Ty=T*dy/length; // console.log("leg",Tx,Ty,T,dx,dy,length); this.force.m+=M+this.leg.x*Ty-this.leg.y*Tx; this.force.x+=Tx-M/length*dy/length; this.force.y+=Ty+M/length*dx/length; fx=-Tx-(-M)/length*dy/length; force.x+=fx; fy=-Ty+(-M)/length*dx/length; force.y+=fy; force.m+=this.leg.connect.x*fy-this.leg.connect.y*fx; //console.log("F", this.force); this.force.y+=this.M*Gravity; //console.log(this.M*Gravity); // console.log(this.force); return(force); }, new_accel:function(){ this.Ax=this.force.x/this.M; this.Ay=this.force.y/this.M; this.Ao=this.force.m/this.I; // console.log("A", this.Ax,this.Ay,this.Ao); }, new_velocity:function(){ var dt=this.dt; this.Vx+=this.Ax*dt; this.Vy+=this.Ay*dt; this.Omega+=this.Ao*dt; // console.log("V ", this.Vx,this.Vy,this.Omega); }, new_position:function(){ var dt=this.dt; var dt2=this.dt2; this.X+=this.Vx*dt+this.Ax*dt2; this.Y+=this.Vy*dt+this.Ay*dt2; var dTheta=this.Omega*dt+this.Ao*dt2; this.Theta+=dTheta; var cos=Math.cos(dTheta); var sin=Math.sin(dTheta); var x_=this.arm.x*cos-this.arm.y*sin; var y_=this.arm.y*cos+this.arm.x*sin; this.arm.x=x_; this.arm.y=y_; x_=this.leg.x*cos-this.leg.y*sin; y_=this.leg.y*cos+this.leg.x*sin; this.leg.x=x_; this.leg.y=y_; // console.log("X", this.X,this.Y,this.Theta); } /* new_position:function(X,Y,dTheta){ var cos=Math.cos(dTheta); var sin=Math.sin(dTheta); var dx=this.X-X; var dy=this.Y-Y; this.X=this.parent.X+dx*cos-dy*sin; this.Y=this.parent.Y+dy*cos+dx*sin; this.Theta+=dTheta; var x_=this.arm.x*cos-this.arm.y*sin; var y_=this.arm.y*cos+this.arm.x*sin; this.arm.x=x_; this.arm.y=y_; dx=this.arm.connect.x+this.parent.X-(this.arm.x+this.X); dy=this.arm.connect.y+this.parent.Y-(this.arm.y+this.Y); this.arm.theta=Math.atan2(dy,dx)-this.Theta; this.arm.length=Math.sqrt(dx*dx+dy*dy); x_=this.leg.x*cos-this.leg.y*sin; y_=this.leg.y*cos+this.leg.x*sin; this.leg.x=x_; this.leg.y=y_; dx=this.leg.connect.x+this.parent.X-(this.leg.x+this.X); dy=this.leg.connect.y+this.parent.Y-(this.leg.y+this.Y); this.leg.theta=Math.atan2(dy,dx)-this.Theta; this.leg.length=Math.sqrt(dx*dx+dy*dy); }*/ }); BICYCLE = enchant.Class.create(Sprite,{ initialize: function(){ this.ID=num_frame; num_frame++; this.dt=dt; this.dt2=dt2; this.Vx=0.0; this.Vy=0.0; this.Ax=0.0; this.Ay=0.0; this.Theta=0.0; this.Theta_=0.0; this.Omega=0.0; this.Ao=0.0; this.frame_node=Array(this.num_node); this.frame_node[0]=new FRAME_NODE(this,0.0, 0.0, 3.0);//"RearEnd" x,y, mass this.frame_node[1]=new FRAME_NODE(this,425, -20, 1.8);//BB this.frame_node[2]=new FRAME_NODE(this,302, 333, 0.5);//"TopChainSeat" this.frame_node[3]=new FRAME_NODE(this,814, 582, 1.0);//Head this.frame_node[4]=new FRAME_NODE(this,210, 582, 0.4);//Saddle this.frame_node[5]=new FRAME_NODE(this,924, 600, 0.8);//Handle // this.frame_node[6]=new FRAME_NODE(this,1085,0.0, 2.8);//ForkEnd this.set_parameters(); this.frame_node[0].wheel=new WHEEL_NODE(this.frame_node[0],315,1.5); // this.frame_node[6].wheel=new WHEEL_NODE(this.frame_node[6],315,1.5); this.frame_node[3].suspention=new SUSPENTION_NODE(this.frame_node[3],1085, 0.0, 2.8); this.frame_node[3].suspention.wheel=new WHEEL_NODE(this.frame_node[3].suspention,315,1.5); this.X=0.8; this.Y=earth.hl+1.0; this.human=new HUMAN(this); this.set_sprite(); this.redraw_sprite(); this.set_speed_label(); game.rootScene.addChild(this); }, onenterframe:function(){ var D=Math.floor((1.0/100)/dt); for(var i=0;i<D;i++){ var force=this.new_force(); this.new_accel(force); this.new_position(); this.new_velocity(); } if(this.X*scale > game_size+this.image_size_x/2 && this.Vx>0.0){ this.X =-this.image_size_x/2/scale; this.Y += (earth.hl-earth.hr)*1.2; this.human.X =-this.image_size_x/2/scale; this.human.Y += (earth.hl-earth.hr)*1.2; } if(this.X*scale < -this.image_size_x/2 && this.Vx<0.0){ this.X =(game_size+this.image_size_x/2)/scale; this.Y -= (earth.hl-earth.hr)*1.2; this.human.X =(game_size+this.image_size_x/2)/scale; this.human.Y -= (earth.hl-earth.hr)*1.2; } this.redraw_sprite(); if(Math.floor(this.age/5)*5===this.age) this.new_speed(); }, ontouchstart: function(){ for(var i=0;i<this.frame_node.length;i++) { this.frame_node[i].remove(); } game.rootScene.removeChild(this.speed); game.rootScene.removeChild(this); }, set_parameters: function(){ this.X=0.0; this.Y=0.0; this.M=0.0; this.I=0.0; for(var i=0;i<this.frame_node.length;i++) { this.X+=this.frame_node[i].x*this.frame_node[i].mass; this.Y+=this.frame_node[i].y*this.frame_node[i].mass; this.M+=this.frame_node[i].mass; } this.X/=this.M; this.Y/=this.M; for(i=0;i<this.frame_node.length;i++) { var dx=this.frame_node[i].x-this.X; var dy=this.frame_node[i].y-this.Y; this.I+=(dx*dx+dy*dy)*this.frame_node[i].mass; this.frame_node[i].x=dx; this.frame_node[i].y=dy; } }, set_sprite: function(){ var x_size=0.0,y_size=0.0; for(var i=0;i<this.frame_node.length;i++) { var absx=Math.abs(this.frame_node[i].x); if(absx>x_size) x_size=absx; var absy=Math.abs(this.frame_node[i].y); if(absy>y_size) y_size=absy; } this.image_size_x=Math.floor(2*x_size*scale*1.2); this.image_size_y=Math.floor(2*y_size*scale*1.2); enchant.Sprite.call(this, this.image_size_x, this.image_size_y); var surface=new Surface(this.image_size_x,this.image_size_y); surface.context.fillStyle="Blue"; surface.context.strokeStyle="Blue"; surface.context.lineWidth=2; for(i=0;i<this.frame_node.length;i++) { var x=this.in_sprite_x(i); var y=this.in_sprite_y(i); surface.context.beginPath(); surface.context.arc(x,y,1.5,0,Math.PI*2); surface.context.fill(); } this.connect(0,1,surface); this.connect(0,2,surface); this.connect(1,2,surface); this.connect(1,3,surface); this.connect(2,3,surface); this.connect(2,4,surface); this.connect(3,5,surface); // this.connect(3,6,surface); this.image=surface; }, redraw_sprite:function(){ this.x=-this.image_size_x/2+this.X*scale; this.y=-this.image_size_y/2+game_size-this.Y*scale; this.rotation=-180/Math.PI*this.Theta; for(var i=0;i<this.frame_node.length;i++) { this.frame_node[i].redraw_sprite(); } if(this.human !== undefined) this.human.redraw_sprite(); }, set_speed_label:function(){ this.speed=new Label(); this.speed.x=0; this.speed.y=16+5+14*(this.ID); this.speed.color="black"; this.speed.font="12px areal"; this.speed.width=120; game.rootScene.addChild(this.speed); }, new_speed:function(){ var value=Math.floor(Math.sqrt(this.Vx*this.Vx+this.Vy*this.Vy)*3600/1000); if(value <10) value="0"+value; // this.speed.text="ID"+this.ID+": "+value+"(km/s), "+Math.floor(this.frame_node[0].wheel.omega*10/Math.PI/2)/10+"(rps)"; var shrink=this.frame_node[3].suspention.shrink*100; if(shrink<0.0) shrink=0.0; this.speed.text="ID"+this.ID+": "+value+"(km/s), "+shrink.toFixed(1)+"(cm)"; }, connect: function(i,j,surf){ var x1=this.in_sprite_x(i); var y1=this.in_sprite_y(i); var x2=this.in_sprite_x(j); var y2=this.in_sprite_y(j); surf.context.beginPath(); surf.context.moveTo(x1,y1); surf.context.lineTo(x2,y2); surf.context.stroke(); }, in_sprite_x: function(i){ return(this.frame_node[i].x*scale+this.image_size_x/2); }, in_sprite_y: function(i){ return(this.image_size_y/2-this.frame_node[i].y*scale); }, new_force: function(){ var force={x:0.0, y:0.0, m:0.0}; var L=this.frame_node.length; for(var i=0;i<L;i++){ var force_=this.frame_node[i].force(); force.x+=force_.x; force.y+=force_.y; force.m+=force_.m; } force_=this.human.new_force(); force.x+=force_.x; force.y+=force_.y; force.m+=force_.m; return(force); }, new_accel: function(force){ this.Ax=force.x/this.M; this.Ay=force.y/this.M; this.Ao=force.m/this.I; this.human.new_accel(); }, new_velocity: function(){ var dt=this.dt; this.Vx+=this.Ax*dt; this.Vy+=this.Ay*dt; this.Omega+=this.Ao*dt; this.human.new_velocity(); }, new_position: function(){ var dt=this.dt; var dt2=this.dt2; var X=this.X; var Y=this.Y; this.X+=this.Vx*dt+this.Ax*dt2; this.Y+=this.Vy*dt+this.Ay*dt2; var dTheta=this.Omega*dt+this.Ao*dt2; var cos=Math.cos(dTheta); var sin=Math.sin(dTheta); var L=this.frame_node.length; for(var i=0;i<L;i++){ var dx=this.frame_node[i].x; var dy=this.frame_node[i].y; this.frame_node[i].x=dx*cos-dy*sin; this.frame_node[i].y=dy*cos+dx*sin; if(this.frame_node[i].suspention !== undefined){ dx=this.frame_node[i].suspention.x; dy=this.frame_node[i].suspention.y; this.frame_node[i].suspention.x=dx*cos-dy*sin; this.frame_node[i].suspention.y=dy*cos+dx*sin; } } this.human.new_position(); this.Theta+=dTheta; } }); var create_slope_hl_label=function(){ var button_width=30; var textbox_width=15; var x0=game_size-button_width-textbox_width; var height=10; var y0=2+height*1.5*0; var label=new Label("スロープ左高さ(m)");//スロープ高さ用テキストボックスを作成 label.x=x0-label._boundWidth+20; label.y=y0+(height-label._boundHeight)/2; label.font='10px helvetica'; label.color='black'; // label.textAlign='left'; game.rootScene.addChild(label); var textbox = new InputTextBox(); textbox.x = x0; textbox.y = y0; textbox.width=textbox_width; textbox.height=height; textbox.placeholder=(earth.hl.toString(10)); // textbox.backgroundColor='LightGray'; game.rootScene.addChild(textbox); var button=new Button('set'); button.x=x0+textbox.width; button.y=y0; button.width=button_width; button.height=height; button.ontouchend = function() { earth.change(Number(textbox.value),earth.hc,earth.hr); }; game.rootScene.addChild(button); }; var create_slope_hr_label=function(){ var button_width=30; var textbox_width=15; var x0=game_size-button_width-textbox_width; var height=10; var y0=2+height*1.5; var label=new Label("スロープ右高さ(m)");//スロープ高さ用テキストボックスを作成 label.x=x0-label._boundWidth+20; label.y=y0+(height-label._boundHeight)/2; label.font='10px helvetica'; label.color='black'; // label.textAlign='left'; game.rootScene.addChild(label); var textbox = new InputTextBox(); textbox.x = x0; textbox.y = y0; textbox.width=textbox_width; textbox.height=height; textbox.placeholder=(earth.hr.toString(10)); // textbox.backgroundColor='LightGray'; game.rootScene.addChild(textbox); var button=new Button('set'); button.x=x0+textbox.width; button.y=y0; button.width=button_width; button.height=height; button.ontouchend = function() { earth.change(earth.hl,earth.hc,Number(textbox.value)); }; game.rootScene.addChild(button); }; var create_slope_hc_label=function(){ var button_width=30; var textbox_width=20; var x0=game_size-button_width-textbox_width; var height=10; var y0=2+height*1.5*2; var label=new Label("障害物高さ(m)"); label.x=x0-label._boundWidth+15; label.y=y0+(height-label._boundHeight)/2; label.font='10px helvetica'; label.color='black'; // label.textAlign='left'; game.rootScene.addChild(label); var textbox = new InputTextBox(); textbox.x = x0; textbox.y = y0; textbox.width=textbox_width; textbox.height=height; textbox.placeholder=(earth.hc.toString(10)); // textbox.backgroundColor='LightGray'; game.rootScene.addChild(textbox); var button=new Button('set'); button.x=x0+textbox.width; button.y=y0; button.width=button_width; button.height=height; button.ontouchend = function() { earth.change(earth.hl,Number(textbox.value),earth.hr); }; game.rootScene.addChild(button); }; var create_addbicycle_button=function(){ var height=10; var button=new Button('自転車追加'); button.x=250; button.y=2+height*1.5*3; button.height=height; button.width=70; button.ontouchend = function() { new BICYCLE(); }; game.rootScene.addChild(button); }; var create_time_display=function(a){ var time=new Label(); time.x=2; time.y=2; time.color="black"; time.font="16px areal"; time.width=120; time.addEventListener("enterframe", function(){ time.text="時刻= "+Math.floor(time.age/game.fps)+" (s)"; }); game.rootScene.addChild(time); }; window.onload = function(){ game = new Core(game_size, game_size); game.fps = 100; game.onload = function(){ game.rootScene.backgroundColor = "WhiteSmoke"; earth=new EARTH(); create_time_display(earth); enchant.widget._env.buttonFont='10px helvetica'; create_slope_hl_label(); create_slope_hr_label(); create_slope_hc_label(); create_addbicycle_button(); }; game.start(); };