// ワンコは犬ですから package { import flash.display.*; import flash.events.*; import flash.utils.*; import flash.net.*; import flash.system.*; import jp.progression.commands.*; import jp.progression.commands.lists.*; import jp.progression.commands.display.*; import jp.progression.commands.net.*; import jp.progression.commands.tweens.*; import jp.progression.events.*; import flash.text.*; // 背景とかインターフェースとか作り込む余裕がなかった。 // いろいろやっつけすぎ。 public class Amateur extends Sprite { public static var GRAPHICS_URL:String = "http://swf.wonderfl.net/static/assets/checkmate05/wancoAmateur.swf"; public var stayMotion:MovieClip; public var jumpMotion:MovieClip; public var highJumpMotion:MovieClip; public var walkMotion:MovieClip; public var runMotion:MovieClip; public var squatMotion:MovieClip; public var questionMotion:MovieClip; public var exclamationMotion:MovieClip; public var heartMotion:MovieClip; public var poutMotion:MovieClip; public var starMotion:MovieClip; public var singMotion:MovieClip; public var sleepMotion:MovieClip; public var wakeMotion:MovieClip; public function Amateur(){ super(); stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; var com:SerialList = new SerialList(); com.addCommand( new LoadSWF( new URLRequest( GRAPHICS_URL ) ), function():void { var loader:Loader = Loader( this.latestData ); var domain:ApplicationDomain = loader.contentLoaderInfo.applicationDomain; stayMotion = new ( domain.getDefinition( "StayMotion" ) as Class ); jumpMotion = new ( domain.getDefinition( "JumpMotion" ) as Class ); highJumpMotion = new ( domain.getDefinition( "HighJumpMotion" ) as Class ); walkMotion = new ( domain.getDefinition( "WalkMotion" ) as Class ); runMotion = new ( domain.getDefinition( "RunMotion" ) as Class ); squatMotion = new ( domain.getDefinition( "SquatMotion" ) as Class ); questionMotion = new ( domain.getDefinition( "QuestionMotion" ) as Class ); exclamationMotion = new ( domain.getDefinition( "ExclamationMotion" ) as Class ); heartMotion = new ( domain.getDefinition( "HeartMotion" ) as Class ); poutMotion = new ( domain.getDefinition( "PoutMotion" ) as Class ); starMotion = new ( domain.getDefinition( "StarMotion" ) as Class ); singMotion = new ( domain.getDefinition( "SingMotion" ) as Class ); sleepMotion = new ( domain.getDefinition( "SleepMotion" ) as Class ); wakeMotion = new ( domain.getDefinition( "WakeMotion" ) as Class ); } ); com.addEventListener(ExecuteEvent.EXECUTE_COMPLETE,onLoadSWF); com.execute(); _tf = new TextField(); addChild(_tf); _tf.width = 200; _tf.height = 100; var g : Graphics = graphics; g.lineStyle(4, 0x111111); g.beginFill(0x993300); g.drawRect(-5, 250, 475, 250); g.endFill(); g.beginFill(0x33aaff); g.drawRect(-5, -10, 475, 260); g.endFill(); } private var _tf : TextField; private function onLoadSWF(e:Event):void { _motion = new Sprite(); addChild(_motion); _mc = walkMotion; _motion.addChild(_mc); _motion.x = 465 / 2; _motion.y = 370; _motion.z = 0; addEventListener(Event.ENTER_FRAME, onEnterFrame); stage.addEventListener(MouseEvent.CLICK, onClick); this.mouseEnabled = true; _d = new Disc(); addChild(_d); _state = 0; _rtx = _motion.x; _rtz = _motion.z; } private function onClick(e : MouseEvent) : void { if(_state == 0){ _d.doThrowing(); _t = 0; changeMotion(exclamationMotion); _state = 1; }else if(_state == 3){ _d.init(); changeMotion(walkMotion); _state = 0; _rtx = _motion.x; _rtz = _motion.z; } } private var _d : Disc; private var _motion : Sprite; private var _mc : MovieClip; // 0 : 投擲待ち // 1 : フリスビーを取りに行っている // 2 : フリスビーをくわえて戻っている // 3 : 戻った private var _state : int; private const RETX : Number = 465 / 2; private const RETZ : Number = 0; private var _t : int = -1; private var _tb : int = 0; private var _rtx : Number; private var _rtz : Number; private function onEnterFrame(e : Event) : void { if(_state == 0){ if( (_motion.x - _rtx) * (_motion.x - _rtx) + (_motion.z - _rtz) * (_motion.z - _rtz) < 10 * 10){ _rtx = Math.random() * 465; _rtz = Math.random() * 200; } moveWanko(_rtx, _rtz, 4); dirWanko(_motion.x + _prevX, _motion.z + _prevZ); }else if(_state == 1){ _d.move(); _t--; if(_t == -24){ changeMotion(runMotion); } if(_t == _tb){ _state = 2; return; } // _tf.text = "" + (_d.y - _d.vy * 13); dirWanko(_d.x, _d.z); if(_t < -24){ moveWanko(_d.x, _d.z, 7); var d2 : Number = (_motion.x - _d.x) * (_motion.x - _d.x) + (_motion.z - _d.z) * (_motion.z - _d.z); if(_d.vy < 0 && Math.abs(_d.y - _d.vy * 13 - (350 - 165)) < 10 && d2 < 20 * 20){ _t = 27; _tb = 14; changeMotion(highJumpMotion); return; } if(_d.y >= 350 && d2 < 30 * 30){ _state = 2; } } }else if(_state == 2){ _t--; var at : Number = dirWanko(RETX, RETZ); if(_t == 0){ changeMotion(runMotion); } if(_t > 0){ // _tf.appendText("" + _t + "\t" + _mc.currentFrame + "\n"); _d.y = 360 - _t * 13; }else{ moveWanko(RETX, RETZ, 7); _d.y = 350; _d.y += [0, 6, 0, -6, -6, 6][_mc.currentFrame]; // runMotionと同期 } _d.x = _motion.x + 30 * Math.cos(at); _d.z = _motion.z + 30 * Math.sin(at); _d.rotationY = 0; _d.rotationX = -75; if( (_motion.x - RETX) * (_motion.x - RETX) + (_motion.z - RETZ) * (_motion.z - RETZ) < 10 * 10){ changeMotion(MovieClip(selectR([wakeMotion, heartMotion, starMotion]))); dirWanko(RETX, RETZ); _d.y = 360; _state = 3; } }else if(_state == 3){ } // Z-sort if(getChildAt(1).z < getChildAt(2).z){ swapChildrenAt(1, 2); } } private function selectR(a : Array) : Object { return a[int(Math.random() * a.length)]; } private function changeMotion(mc : MovieClip) : void { if(_mc === mc)return; _motion.removeChild(_mc); _mc = mc; _mc.gotoAndPlay(1); _motion.addChild(_mc); } // ワンコを(tx, tz)のほうに向ける private function dirWanko(tx : Number, tz : Number) : Number { var at : Number = Math.atan2(tz - _motion.z, tx - _motion.x); var t : Number = ((Math.PI / 2 + 2 * Math.PI / 20 * 2.5) + 2 * Math.PI + at) % (2 * Math.PI); // _tf.text = "" + _t + "\t" + int(t / (Math.PI * 2) * 20) + "\n"; _mc.wc2.wc3.gotoAndStop(int(t / (Math.PI * 2) * 20)); return at; } private var _prevX : Number = 0.0; private var _prevZ : Number = -1.0; // ワンコを(tx, tz)のほうに動かす。 // 直前とくらべてあまりに向きの角が急すぎるときは一定角まで回転する。 private function moveWanko(tx : Number, tz : Number, v : Number) : void { var mdr : Number = Math.sqrt( (tx - _motion.x) * (tx - _motion.x) + (tz - _motion.z) * (tz - _motion.z) ); var dx : Number, dz : Number; if(mdr > 10){ dx = (tx - _motion.x) / mdr; dz = (tz - _motion.z) / mdr; if(_prevX * dx + _prevZ * dz < Math.cos(20 * Math.PI / 180)){ // 角度変化の上限 var sgn : Number = _prevX * dz - _prevZ * dx; var nc : Number = Math.cos(20 * Math.PI / 180); var ns : Number = Math.sin(20 * Math.PI / 180); var nz : Number = _prevZ * nc + _prevX * ns * (sgn > 0 ? 1 : -1); var nx : Number = _prevX * nc + _prevZ * ns * (sgn > 0 ? -1 : 1); dx = nx; dz = nz; } _prevX = dx; _prevZ = dz; }else{ dx = 0; dz = 0; } // 等速移動 _motion.x += dx * v; _motion.z += dz * v; } } } import flash.display.*; import flash.geom.*; class Disc extends Sprite { private const R : Number = 30; public var vxz : Number; public var vy : Number; public var dir : Number; public var vdir : Number; public var omega : Number; // フリスビーの回転角速度(揚力以外の移動には関係ない) public function Disc() { var mat : Matrix = new Matrix(); mat.scale(1/1638*R*2, 1/1638*R*2); var g : Graphics = this.graphics; g.lineStyle(1, 0x000000); g.beginGradientFill(GradientType.RADIAL, [0x00ee00, 0x005500], [1, 1], [225, 255], mat); g.drawCircle(0, 0, R); g.endFill(); // g.beginGradientFill(GradientType.RADIAL, [0x00ee00, 0x005500], [1, 1], [200, 255], mat); g.beginFill(0x00ee00); g.drawCircle(0, 0, 0.9 * R); g.endFill(); g.beginFill(0x00ff00); g.drawCircle(0, 0, 0.5 * R); g.moveTo(0, 0); g.lineTo(0, 0.5 * R); this.rotationX = -90; makeBound(16); init(); } private function makeBound(n : int) : void { var L : Number = R * Math.sin(Math.PI / n); for(var i : int = 0;i < n;i++){ var theta : Number = Math.PI * 2 / n * i; var s : Shape = new Shape(); var g : Graphics = s.graphics; g.lineStyle(1, 0x005500 + 0x001100 * (i % 2)); g.beginFill(0x005500 + 0x001100 * (i % 2)); g.drawRect(-L, 0, 2 * L, 3); g.endFill(); s.x = R * Math.cos(theta); s.y = R * Math.sin(theta); s.rotationX = 90; s.rotationZ = 90+theta / Math.PI * 180; addChild(s); } } public function init() : void { x = 465 / 2; y = 120; z = -200; rotationX = -90; rotationZ = 0; rotationY = 0; } public function doThrowing() : void { vxz = 9.0 + triRandom() * 2.0; vy = 1.0 + triRandom() * 1.5; omega = 50 + triRandom() * 20; vdir = triRandom() * 0.01; dir = -vdir * 5 + triRandom() * 0.1; rotationX = -90 + (Math.random() + Math.random()) * 15 - 15; } private static function triRandom() : Number { return Math.random() + Math.random() - 1; } private const T : Number = 0.1; private const SCALE : Number = 10; private const MU : Number = Math.pow(0.95, T); private const OMU : Number = Math.pow(0.7, T); private const G : Number = 9.8; // フリスビーを移動 public function move() : void { var theta : Number = Math.atan2(vy, vxz) / Math.PI * 180; var v2 : Number = vy * vy + vxz * vxz; // いんちき揚力 var L : Number = (1.0 - 1 / omega) * vxz / Math.sqrt(v2); // 加速と減衰 omega *= OMU; rotationY += omega; if(omega < 1.0)omega = 1.0; vxz *= MU; vy += (L - 1.0) * G * T * T; vy *= MU; // 飛行中だけ移動 if(y < 350){ x += vxz * Math.sin(dir) * T * SCALE; z += vxz * Math.cos(dir) * T * SCALE; y -= vy * T * SCALE; dir += vdir; } } } フリスビー投げるよ!