forked from: FireWorksGame

by tomop
♥0 | Line 360 | Modified 2010-01-03 23:51:04 | MIT License
play

ActionScript3 source code

/**
 * Copyright tomop ( http://wonderfl.net/user/tomop )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/ediY
 */

package 
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;
	[SWF(backgroundColor = 0x000000, width = 550, height = 600, frameRate = 30)] 
	public class Main extends MovieClip
	{
		
		//画面クリックで狙った場所に花火を打ち上げる。
		//花火を連鎖させて高得点を競い合うゲームになる予定。
		//動きが重い...
		//だいぶ連鎖するようになった
		
		public static const WIDTH:Number = 550;
		public static const HEIGHT:Number = 600;
		private var fire_work:FireWork;
		private var tilt:Tilt;
		private var canvas_bmp:Bitmap;
		private var t_canvas_bmp:Bitmap;
		
		public function Main() {
			var canvas:BitmapData = new BitmapData(WIDTH, HEIGHT, true, 0xffffff);
			t_canvas_bmp = addChild(new Bitmap(canvas)) as Bitmap;
			canvas_bmp = addChild(new Bitmap(canvas.clone())) as Bitmap;
			
			fire_work = new FireWork(canvas_bmp.bitmapData);
			
			tilt = addChild(new Tilt(t_canvas_bmp.bitmapData,fire_work)) as Tilt;
		}	
	}	
}

import flash.display.*;
import flash.filters.*;
import flash.geom.*;
import flash.events.*;
import flash.utils.*;

class Tilt extends Sprite {
	
	private var canvas:BitmapData;
	private var buffer:BitmapData;
	private var u_particles:Array = new Array();
	private var target_pt:Point;
	private var particles:Array = new Array();
	private var ct:ColorTransform = new ColorTransform;
	private var pt:Point = new Point();
	private var fire_work:FireWork;
	
	//ターゲット発射
	private var timer:Timer;
	private var interval:Number = 5000;
	private var wave_num:int = 40;
	
	private var wave_count:uint = 0;
	private var u_particle_count:int = 0;
	private var max_u_particle_count:int = 6;
	
	public function Tilt(_canvas:BitmapData, _fire_work:FireWork) {
		canvas = _canvas;
		fire_work = _fire_work;
		buffer = canvas.clone();
		addEventListener(Event.ADDED_TO_STAGE, init);
	}
	
	private function init(e:Event):void {
		stage.addEventListener(MouseEvent.MOUSE_UP, addUserTilt);
		startRoop();
		startGame();
	}
	
	private function startGame():void {
		wave();
		timer = new Timer(interval);
		timer.addEventListener(TimerEvent.TIMER, wave);
		timer.start();
	}
	
	private function wave(e:TimerEvent = null):void {
		for (var i:int = wave_count* wave_num; i < (wave_num * wave_count) + wave_num; i++) {
			var rx:Number = Main.WIDTH * Math.random();
			var ry:Number = Main.HEIGHT;
			var mt:Matrix = new Matrix();
			mt.translate(rx, ry);
			var tx:Number = Shuffles.randRange( 50, Main.WIDTH -50);
			var ty:Number = Shuffles.randRange(0, 100);
			var dis_x:Number = tx -rx;
			var dis_y:Number = ty - ry;
			var rot:Number = Math.atan2(dis_y, dis_x) * (180 / Math.PI);
			var vel:Number = Shuffles.randRange(10, 12);
			var p:TiltParticle = new TiltParticle(mt, rot, vel, 0xffffff * Math.random(),2,new Point(rx, ry), 0.1);
			particles["p_" + i] = p;
		}
		//波のカウント追加,発射カウントのリセット
		wave_count += 1;
		u_particle_count = 0;
	}
	private function addUserTilt(e:MouseEvent):void {
		if (u_particle_count < max_u_particle_count) {
			var mt:Matrix = new Matrix();
			mt.translate(Main.WIDTH / 2, Main.HEIGHT);
			var mouse_pt:Point = new Point(e.stageX, e.stageY);
			var dis_x:Number = e.stageX - (Main.WIDTH / 2);
			var dis_y:Number = e.stageY -(Main.HEIGHT);
			var rot:Number = Math.atan2(dis_y, dis_x) * (180 / Math.PI);
			u_particle_count += 1;//カウント追加
			u_particles["u_p_" + u_particle_count] = new UserTiltParticle(mt, rot, 6, 0xffffff, 2, new Point(e.stageX, e.stageY));
		}
	}
	
	private function stopRoop():void {	
		this.removeEventListener(Event.ENTER_FRAME, roop);
	}
		
	private function startRoop():void {
		this.addEventListener(Event.ENTER_FRAME, roop);
	}
	
	private function roop(e:Event = null):void {
		
		for (var u_p_name:String in u_particles) {
			var u_p:Particle = u_particles[u_p_name] as Particle;
			
			if (u_p != null) {
				u_p.update();
				buffer.draw(u_p.bmp_data, u_p.mt);
			}
		}
		
		for (var p_name:String in particles) {
			var p:Particle = particles[p_name];
			
			if (p != null) {
				p.update(); 
				buffer.draw(p.bmp_data, p.mt);
			}
		}
		
		canvas.copyPixels(buffer, canvas.rect, pt);
		ct.alphaMultiplier = 0.9;
		buffer.colorTransform(canvas.rect, ct);
	
		removeParticles();
	}
	
	private var check_distance:Number = 40;
	private function checkHitDetection(user_p:UserTiltParticle):void {	
		for (var p_name:String in particles) {
			var tilt_p:TiltParticle = particles[p_name] as TiltParticle;
			
			if (tilt_p != null) {
				var dis_x:Number = user_p.pos_pt.x - tilt_p.pos_pt.x;
				var dis_y:Number = user_p.pos_pt.y - tilt_p.pos_pt.y;
			
				if (Math.abs(dis_x) < check_distance && Math.abs(dis_y) < check_distance) {
					//花火爆発
					fire_work.explode(tilt_p.pos_pt, 10, tilt_p.color,2.5);
					//連鎖チェック
					tilt_p.exploded = true;
					checkHitDetection2(tilt_p);
					//データ削除
					tilt_p.destroy();
					particles[p_name] = null;
					
				}	
			}
		}
	}
	private function checkHitDetection2(select_p:TiltParticle):void {
		for (var p_name:String in particles) {
			
			var tilt_p_2:TiltParticle = particles[p_name] as TiltParticle;
			
			if (tilt_p_2 != null) {
				var dis_x:Number = select_p.pos_pt.x - tilt_p_2.pos_pt.x;
				var dis_y:Number = select_p.pos_pt.y - tilt_p_2.pos_pt.y;
			
				if (Math.abs(dis_x) < check_distance && Math.abs(dis_y) < check_distance) {
					//花火爆発
					fire_work.explode(tilt_p_2.pos_pt, 10, tilt_p_2.color,2.5);
					//連鎖チェック
					if (!tilt_p_2.exploded) {
						//既に爆発済み
						tilt_p_2.exploded = true;
						checkHitDetection2(tilt_p_2);
						//データ削除
						tilt_p_2.destroy();
						particles[p_name] = null;
					}
				}
			}
		}
	}

	private function removeParticles():void {
		for (var p_name:String in particles) {
			var p:TiltParticle = particles[p_name] as TiltParticle;
			
			if (p != null) {
				if (p.pos_pt.y >= Main.HEIGHT) {
				p.destroy();
				particles[p_name] = null;
				}
			}
		}
		
		for (var u_p_name:String in u_particles) {
			
			var u_p:UserTiltParticle = u_particles[u_p_name] as UserTiltParticle;
			
			if (u_p != null) {
				var dis_x:Number = u_p.target_pos_pt.x - u_p.pos_pt.x;
				var dis_y:Number = u_p.target_pos_pt.y - u_p.pos_pt.y;
			
				if (Math.abs(dis_x) < 7 && Math.abs(dis_y) < 7) {
					//連鎖爆発チェック
					checkHitDetection(u_p);
					//花火爆発
					fire_work.explode(u_p.pos_pt, 20, 0xffffff,2.5);
					//データ削除
					u_particles[u_p_name] = null;
				}
			}
		}
	}
}

import flash.display.*;
import flash.filters.*;
import flash.geom.*;
import flash.events.*;

class FireWork extends Sprite{
	
	private var canvas:BitmapData;
	private var buffer:BitmapData;
	
	private var particles:Vector.<Particle> = new Vector.<Particle>();
	private var ct:ColorTransform = new ColorTransform;
	
	public function FireWork(_canvas:BitmapData) {
		canvas = _canvas;
		buffer = canvas.clone();
	}
	
	public function explode(center_pt:Point, particle_num:uint, color:Number, scale:Number = 2):void {
		var vector:Vector.<Number> = setKakudo(particle_num);
		var	zure:Number = 10; //爆発の広がり
		
		for (var i:int = 0; i < particle_num; i++ ) {
			var rx:Number = Shuffles.randRange(center_pt.x - zure, center_pt.x +zure);
			var ry:Number = Shuffles.randRange(center_pt.y - zure, center_pt.y +zure);
			var rv:Number = 3;
			var mt:Matrix = new Matrix();
			mt.translate(rx, ry);
			var particle:Particle = new Particle(mt, vector[i], rv, color, scale);
			particles.push(particle);
		}
		startRoop();
	}
	//角度
	private function setKakudo(_particle_num:uint):Vector.<Number> {
		var vec_num:Vector.<Number> = new Vector.<Number>();
		
		for (var i:uint = 0; i < (_particle_num/2); i++) {	
			vec_num.push(i * (180 / (_particle_num / 2)));
		}
			
		for (i = 1; i < (_particle_num/2) + 1; i++) {
			vec_num.push(i * -(180 / (_particle_num / 2)));
		}
			
		return vec_num;
	}
	
	private function stopRoop():void {	
		this.removeEventListener(Event.ENTER_FRAME, roop);
	}
		
	private function startRoop():void {
		this.addEventListener(Event.ENTER_FRAME, roop);
	}
	
	private var pt:Point = new Point(0, 0);
	
	private function roop(e:Event = null):void {
		for (var i:int = 0; i < particles.length; i++ ) {
			var p:Particle = particles[i] as Particle;
			p.update();
			buffer.draw(p.bmp_data, p.mt);
		}
		
		canvas.copyPixels(buffer, canvas.rect, pt);
		ct.alphaMultiplier = 0.9;
		buffer.colorTransform(canvas.rect, ct);
		
		removeParticles();
	}
	
	private function removeParticles():void {
		for (var i:int = 0; i < particles.length; i++ ) {
			var p:Particle = particles[i] as Particle;
			if (p.alpha <= 0.05) {
				p.destroy();
				particles.splice(i, 1);
			}
		}
	}
	
}

import flash.display.*;
import flash.filters.*;
import flash.geom.*;
	
class Particle extends EventDispatcher{
	
	public static const TARGET_TILT:String = "target_tilt";
	public static const FIRE:String = "fire";
	public static const USER_TILT:String = "user_tilte";
	public static const DESTROY:String = "destroy";
	public var particle_kind:String;
	
	public var velocity:Number = 6; //元速度
	public var xVel:Number = 0;// x速度
	public var yVel:Number = 0;//y速度
	public var gravitiy:Number = 0.95; //重力
	public var radian:Number = 0; //ラジアン
	public var mt:Matrix;//マトリックス
	public var alpha:Number = 1;
	public var pt:Point = new Point(0, 0);
	public var color:uint;//
	public var scale:Number; //大きさ
	public var grow:GlowFilter;
	public var blur:BlurFilter;
	public var bmp_data:BitmapData;
	public var ct:ColorTransform = new ColorTransform;
	
	public var exploded:Boolean = false; //既に爆発したかどうか
	
	public function Particle(_mt:Matrix,rot:Number, vel:Number, _color:uint,_scale:Number,_gravity:Number = 0.95) {
		velocity = vel;
		mt = _mt;
		radian = rot * Math.PI / 180;
			
		xVel = velocity * Math.cos(radian);
		yVel = velocity * Math.sin(radian);
			
		color = _color;
		scale = _scale;
		gravitiy = _gravity;
		
		drawShape(scale, color);
	}	
	
	protected function drawShape(scale:Number, color:Number):void {
		bmp_data = new BitmapData(scale, scale, true, 0xffffff);
		var sp:Sprite = new Sprite();
		sp.graphics.moveTo(0, 0);
		sp.graphics.lineStyle(0, 0, 0);
		sp.graphics.beginFill(color);
		sp.graphics.drawRect( 0, 0, scale, scale);
		sp.graphics.endFill();
		bmp_data.draw(sp);
	}
	
	//データの更新
	public function update():void {
		yVel *= gravitiy;
		xVel *= gravitiy;
		mt.translate(xVel, yVel);
		
		if (Math.abs(yVel) < 0.5 && Math.abs(xVel) < 0.5) {
			ct.alphaMultiplier = 0.9;
			alpha *= 0.9;
			bmp_data.colorTransform(bmp_data.rect, ct);
		}
		
	}
	
	//破壊
	public function destroy():void {
		if (bmp_data != null) {
			bmp_data.dispose();
			bmp_data = null;
		}
	}
}

//tilt partilce
class TiltParticle extends Particle {
	
	public var pos_pt:Point;
	
	public function TiltParticle(_mt:Matrix, rot:Number, vel:Number, _color:uint, _scale:Number,_pos_pt:Point,_gravity:Number = 0.95) {
		super(_mt, rot, vel, _color, _scale, _gravity);
		pos_pt = _pos_pt;
	}
	/*override protected function drawShape(scale:Number, color:Number):void {
		
	}*/
	override public function update():void {
		yVel += 0.1;
		xVel *= 0.99;
		mt.translate(xVel, yVel);
		pos_pt.x += xVel;
		pos_pt.y += yVel;
	}
}

//user tilt particle
class UserTiltParticle extends Particle {
	
	public var pos_pt:Point = new Point(Main.WIDTH/2,Main.HEIGHT);
	public var target_pos_pt:Point = new Point();
	
	public function UserTiltParticle(_mt:Matrix, rot:Number, vel:Number, _color:uint, _scale:Number,_target_pos:Point, _gravity:Number = 0.95) {
		super(_mt, rot, vel, _color, _scale, _gravity);
		target_pos_pt = _target_pos;
	}
	/*override protected function drawShape(scale:Number, color:Number):void {
		
	}*/
	override public function update():void {
		mt.translate(xVel, yVel);
		pos_pt.x += xVel;
		pos_pt.y += yVel;
	}
}
class Shuffles {
	//コンストラクタ
	public function Shuffles() { }
	//配列のシャッフル
	static public function shuffle(l_arr:Array):Array
	{
		var tmp_arr:Array = l_arr;
		var i:int = tmp_arr.length;
	
		while (i--) {
			var j:int = Math.floor(Math.random()*(i+1));  //ランダムなインデックスを計算
			var t:* = tmp_arr[i];
			tmp_arr[i] = tmp_arr[j];
			tmp_arr[j] = t;
		}
		return tmp_arr;	
	}
	//ベクターのシャッフル
	static public function shuffleVInt(l_arr:Vector.<Particle>):Vector.<Particle> {
		var tmp_arr:Vector.<Particle> = l_arr;
		var i:int = tmp_arr.length;
	
		while (i--) {
			var j:int = Math.floor(Math.random()*(i+1));  //ランダムなインデックスを計算
			var t:* = tmp_arr[i];
			tmp_arr[i] = tmp_arr[j];
			tmp_arr[j] = t;
		}
		return tmp_arr;	
	}
	//ランダムな数値の取り出し
	static public function randRange(min:Number, max:Number):Number {
		var randomNum:Number = Math.floor(Math.random() * (max - min + 1)) + min;
		return randomNum; 
	}
}