/**
* Copyright tomop ( http://wonderfl.net/user/tomop )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/xmnB
*/
package
{
import flash.display.*;
import flash.events.*
import flash.events.*
import flash.ui.*
import flash.utils.Timer;
import flash.text.*;
import flash.geom.*;
[SWF(backgroundColor = 0x000000, width = 550, height = 400, frameRate = 30)]
public class Main extends Sprite
{
//左右キーで方向転換
//上キーで前方に加速
//下キーで後方に加速
//スペースキーでショット
//コードの書き方超適当だ。
//プロパティの設定
//自機
private var ship:Ship;
//マネージャー系
private var jiki_tama_manager:JikiTamaManager;
private var teki_manager:TekiManager;
//敵の配列
private var teki_arr:Array;
//自機のタマの配列
private var shot_arr:Array;
//タイマー系
private var teki_timer:Timer;
private var point_text:TextField;
//効果
private var effect:Effect;
private var fire_work:FireWork;
//コンストラクタ
public function Main()
{
init();
var bmp_data:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xffffff);
var bmp:Bitmap = addChild(new Bitmap(bmp_data)) as Bitmap;
effect = new Effect(bmp_data, ship, shot_arr);
var bmp_data_2:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0xffffff);
var bmp_2:Bitmap = addChild(new Bitmap(bmp_data_2)) as Bitmap;
fire_work = new FireWork(bmp_data_2);
}
//初期化
private function init():void {
//インスタンス初期化
initInstance();
//イベントリスナー初期化
initEventListener();
}
//インスタンスの初期化
private function initInstance():void {
stage.frameRate = 30;
ship = new Ship();
ship.x = stage.stageWidth / 2;
ship.y = stage.stageHeight / 2;
ship.moveStart();
//自機のタマの管理
jiki_tama_manager = new JikiTamaManager();
shot_arr = new Array();
shot_arr = jiki_tama_manager.getArray();
//敵の管理
teki_manager = new TekiManager();
teki_arr = new Array();
teki_arr = teki_manager.getArray();
addChild(ship);
teki_timer = new Timer(700, 0);
teki_timer.addEventListener(TimerEvent.TIMER , tekiTimerListener);
teki_timer.start();
point_text = new TextField();
point_text.border = true;
point_text.borderColor = 0xffffff;
point_text.selectable = false;
point_text.textColor = 0xffffff;
point_text.autoSize = TextFieldAutoSize.LEFT;
point_text.x = 10;
point_text.y = 10;
point_text.width = 200;
point_text.text = "0"
addChild(point_text);
}
//敵の出現
private function tekiTimerListener(e:TimerEvent):void {
var teki1:Teki1 = new Teki1(teki_manager.getCountIndex());
teki_manager.countIndex();
teki_manager.setTeki(teki1);
addChild(teki1);
Teki1(teki1).moveStart();
}
//イベントリスナーの登録
private function enterFrameListener(e:Event):void {
//敵と自機のショットとのヒット判定
for (var i:* in teki_arr)
{
var teki1:Teki1 = teki_arr[i];
for (var j:* in shot_arr)
{
if (Teki1(teki1).hitTestObject(shot_arr[j]))
{
Teki1(teki1).damage();
if (Teki1(teki1).getShield() <= 0)
{
//爆発
fire_work.explode(new Point(Teki1(teki1).x, Teki1(teki1).y), 30, 0xffffff, 2);
//敵の消去
Teki1(teki1).killListener();
removeChild(teki1);
teki_manager.removeTeki(teki1);
Shot1(shot_arr[j]).killTimer();
removeTama(Shot1(shot_arr[j]));
jiki_tama_manager.deShotNum();
//ポイントの追加
var point:int = int(point_text.text) + 100;
point_text.text = String(point);
}
}
}
}
effect.effect();
}
private function initEventListener():void {
stage.addEventListener(KeyboardEvent.KEY_DOWN , keyDownListener);
stage.addEventListener(KeyboardEvent.KEY_UP , keyUpListener);
//毎フレーム実行
addEventListener(Event.ENTER_FRAME , enterFrameListener);
}
private var left_flag:Boolean = false;
private var right_flag:Boolean = false;
private var up_flag:Boolean = false;
private var down_flag:Boolean = false;
private function keyDownListener(e:KeyboardEvent):void {
switch(e.keyCode)
{
case Keyboard.LEFT:
left_flag = true;
right_flag = false;
break;
case Keyboard.RIGHT:
right_flag = true;
left_flag = false;
break;
case Keyboard.UP:
down_flag = false;
up_flag = true;
break;
case Keyboard.DOWN:
down_flag = true;
up_flag = false;
break;
case Keyboard.SPACE:
shot();
break;
}
updateShip();
}
private function updateShip():void {
if (left_flag) {
ship.vr = -5;
}else if (right_flag) {
ship.vr = 5;
}
if (up_flag) {
ship.thrust = 0.2;
ship.draw(true);
}else if(down_flag){
ship.thrust = -0.2;
ship.draw(false);
}
}
private function keyUpListener(e:KeyboardEvent):void {
left_flag = right_flag = up_flag = down_flag = false;
ship.thrust = ship.vr = 0;
ship.draw(false);
}
//タマを撃つ
private function shot():void
{
//最大発射数に現在達していないならタマを発射
if (jiki_tama_manager.getNowTamaNum() < jiki_tama_manager.getMaxTamaNum())
{
var tama:Shot1 = new Shot1();
tama.x = ship.x;
tama.y = ship.y;
tama.mt = new Matrix();
tama.mt.translate(ship.x, ship.y);
var radian:Number = ship.rotation * Math.PI / 180;
addChild(tama);
tama.moveStart(radian);
jiki_tama_manager.addTama(tama);
}
}
//発射しているタマの数を増やす
public function addShotNum():void {
if (jiki_tama_manager.getNowTamaNum() < jiki_tama_manager.getMaxTamaNum())
{
jiki_tama_manager.addShotNum();
}
}
//発射しているタマの数を減らす
public function deShotNum():void {
if (jiki_tama_manager.getNowTamaNum() > 0)
{
jiki_tama_manager.deShotNum();
}
}
//タマを削除
public function removeTama(ref:Shot1):void {
removeChild(ref);
jiki_tama_manager.removeTama(ref);
}
//敵を削除
public function removeTeki(ref:Teki1):void
{
removeChild(ref);
teki_manager.removeTeki(ref);
//trace("delete")
}
}
}
import flash.display.*;
import flash.filters.*;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
class Effect {
private var buffer:BitmapData;
private var canvas:BitmapData;
private var ship:Ship;
private var tama_arr:Array;
private var blur:BlurFilter = new BlurFilter(2,2)
private var blur2:BlurFilter = new BlurFilter(1.5,1.5)
private var ct:ColorTransform = new ColorTransform();
public function Effect(bmp:BitmapData, _ship:Ship, _tama_arr:Array) {
canvas = bmp;
buffer = bmp.clone();
ship = _ship;
tama_arr = _tama_arr;
}
private var pt:Point = new Point();
public function effect():void {
for (var i:* in tama_arr) {
var tama:Shot1 = tama_arr[i] as Shot1;
buffer.draw(tama, tama.mt);
}
ct.alphaMultiplier = 0.95;
buffer.applyFilter(buffer, buffer.rect, pt,blur);
buffer.applyFilter(buffer, buffer.rect, pt,blur2);
buffer.colorTransform(canvas.rect, ct);
canvas.copyPixels(buffer, buffer.rect, pt);
}
}
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.8;
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 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;
}
}
}
import flash.display.Sprite;
import flash.events.*;
import flash.utils.*;
class Ship extends Sprite
{
//プロパティの設定
public var vr:Number = 0;
public var thrust:Number = 0; //推進力
public var vx:Number = 0;
public var vy:Number = 0;
public var max_v:Number = 10;
private var friction:Number = 0.99;
//コンストラクタ
public function Ship()
{
draw(false);
}
public function draw(ShowFlame:Boolean):void
{
graphics.clear();
graphics.lineStyle(1, 0xffffff);
graphics.moveTo(10, 0);
graphics.lineTo( -10 , 10);
graphics.lineTo( - 5, 0);
graphics.lineTo( -10 , -10);
graphics.lineTo(10, 0);
if (ShowFlame)
{
graphics.moveTo( -7.5, -5);
graphics.lineTo( -15, 0);
graphics.lineTo( -7.5 , 5);
}
}
public function moveStart():void {
addEventListener(Event.ENTER_FRAME, enterFrameListener);
}
private function enterFrameListener(e:Event):void {
setRotation(vr);
var angle:Number = this.rotation * Math.PI / 180 ;
var ax:Number = Math.cos(angle) * thrust;
var ay:Number = Math.sin(angle) * thrust;
vx += ax;
vy += ay;
if (vx >= max_v) {
vx = max_v;
}
if (vy >= max_v) {
vy = max_v;
}
if (vx <= -max_v) {
vx = -max_v;
}
if (vy <= -max_v) {
vy = -max_v;
}
this.x += vx;
this.y += vy;
vx *= friction;
vy *= friction;
//スクリーンラッピング
checkWalls();
}
private function setRotation(vr:Number):void {
this.rotation += vr;
}
private function checkWalls():void {
if (this.x >= stage.stageWidth ) {
this.x -= stage.stageWidth ;
}else if (this.x<= 0)
{
this.x += stage.stageWidth ;
}
if (this.y >= stage.stageHeight )
{
this.y -= stage.stageHeight ;
}else if (this.y <= 0)
{
this.y += stage.stageHeight ;
}
}
}
import flash.display.*;
import flash.events.*
import flash.utils.*;
class Shot1 extends Sprite
{
//プロパティの設定
private var vx:Number = 9;
private var vy:Number = 9;
private var fps:Number = 1000 / 30;
private var timer:Timer;
private var radian:Number = 0;
private var index:uint = 0;//一意のインデックス番号
public var mt:Matrix;
//コンストラクタ
public function Shot1()
{
init();
}
//初期化関数
private function init():void {
timer = new Timer(fps);
//グラフィックの作成
graphics.lineStyle(1, 0xffffff);
graphics.moveTo( 0, 0);
graphics.drawCircle(0, 0, 3);
}
//移動開始
public function moveStart(radian:Number):void {
this.radian = radian;
//タマが発射された
addShotNum()
timer.addEventListener(TimerEvent.TIMER, timerListener);
timer.start();
}
//移動用関数
private function timerListener(e:TimerEvent):void {
this.x += Math.cos(radian) * vx;
this.y += Math.sin(radian) * vy;
mt.translate(Math.cos(radian) * vx, Math.sin(radian) * vy);
//ステージから消えたら消去
checkWalls();
}
//ステージ外に出たかどうか判定
private function checkWalls():void {
if (this.x < 0 || this.x > stage.stageWidth)
{
deShotNum();
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, timerListener);
Main(this.parent).removeTama(this);
}else if (this.y < 0 || this.y > stage.stageHeight)
{
deShotNum();
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, timerListener);
Main(this.parent).removeTama(this);
}
}
//インデックスの設定
public function setIndex(num:uint):void {
//trace(num);
this.index = num;
}
//インデックスの取得
public function getIndex():uint
{
return index;
}
//発射しているタマの数を増やす
private function addShotNum():void {
Main(this.parent).addShotNum();
}
//発射しているタマの数を減らす
private function deShotNum():void {
Main(this.parent).deShotNum();
}
//タイマーの削除
public function killTimer():void {
timer.removeEventListener(TimerEvent.TIMER, timerListener);
}
}
import flash.display.*;
import flash.events.*;
class Teki1 extends Sprite
{
//プロパティ
private var shield:int = 1;
private var attack_power:int = 1;
private var vx:int = 4;
private var vy:int = 4;
private var radian:Number = 0;
public var index:uint = 0;
//コンストラクタ
public function Teki1(newIndex:uint)
{
init(newIndex);
}
//初期化関数
private function init(newIndex:uint):void {
graphics.lineStyle(1, 0xffffff);
graphics.moveTo(0, 0);
graphics.drawCircle(0 , 0, 8);
this.index = newIndex;
}
//耐久力の取得
public function getShield():int {
return shield;
}
public function randRange(min:int, max:int):int {
var randomNum:int = Math.floor(Math.random() * (max - min + 1)) + min;
return randomNum;
}
//移動開始
public function moveStart():void {
var random:int = randRange(0 , 3);
switch(random)
{
case 0:
x = stage.stageWidth/2 +((Math.random() * 100) -50);
y = -20;
radian = Math.random() * 3.14;
break;
case 1:
x = stage.stageWidth/2 +((Math.random() * 100) -50);
y = stage.stageHeight + 20;
radian = Math.random() * -3.14;
break;
case 2:
x = -20
y = stage.stageHeight/2 +((Math.random() * 100) -50);
radian = Math.random() * 1;
break;
case 3:
x = stage.stageWidth + 20;
y = stage.stageHeight/2 +((Math.random() * 100) -50);
radian = Math.random() * -3.14;
break;
}
addEventListener(Event.ENTER_FRAME, moveListener);
}
//移動
public function moveListener(e:Event):void {
x += Math.cos(radian) * vx;
y += Math.sin(radian) * vy;
checkWalls();
}
//インデックスの取得
public function getIndex():uint {
return index;
}
//ダメージ
public function damage():void {
shield -= 1;
}
public function killListener():void {
removeEventListener(Event.ENTER_FRAME, moveListener);
}
//ステージ外に出たかどうか判定
private function checkWalls():void {
if (this.x < -100 || this.x > stage.stageWidth + 100)
{
Main(this.parent).removeTeki(this);
removeEventListener(Event.ENTER_FRAME, moveListener);
}else if (this.y < -100 || this.y > stage.stageHeight + 100)
{
Main(this.parent).removeTeki(this);
removeEventListener(Event.ENTER_FRAME, moveListener);
}
}
}
import flash.display.Sprite;
class TekiManager
{
private var teki_arr:Array
private var index:uint = 0;
//コンストラクタ
public function TekiManager()
{
init();
}
//初期化
private function init():void {
teki_arr = new Array();
}
//敵配列の取得
public function getArray():Array
{
return teki_arr;
}
//全体敵インデックスのカウント
public function countIndex():void {
index += 1;
}
//全体敵インデックスの取得
public function getCountIndex():uint
{
return index;
}
//敵配列のセット
public function setTeki(teki:Teki1):void
{
teki_arr["teki" + Teki1(teki).getIndex()] = teki;
}
//配列の削除
public function removeTeki(teki:Teki1):void
{
delete teki_arr["teki" + Teki1(teki).getIndex()];
}
}
import flash.events.*;
import flash.utils.*;
class JikiTamaManager
{
//プロパティの設定
private var index:uint = 0;
private var tama_arr:Array;
private var fps:Number = 1000 / 30;
private var max_shot_num:uint = 3;//最大ショット数
private var now_shot_num:uint = 0; //現在撃っている弾の数
//コンストラクタ
public function JikiTamaManager()
{
init();
}
//初期化関数
private function init():void {
tama_arr = new Array();
}
//タマの配列を取得
public function getArray():Array
{
return tama_arr;
}
//タマの配列の長さを取得
/*public function getArrayLength():uint
{
return tama_arr.length;
}*/
//タマの発射
public function addTama(ref:Shot1):void {
tama_arr["shot" + index] = ref;
ref.setIndex(index);
index += 1;
}
//タマの参照の削除
public function removeTama(ref:Shot1):void {
delete tama_arr["shot" + ref.getIndex()];
/*for(var i in tama_arr)
{
trace(tama_arr[i]);
}*/
}
//発射しているタマの数を増やす
public function addShotNum():void {
now_shot_num += 1;
}
//発射しているタマの数を減らす
public function deShotNum():void {
now_shot_num -= 1;
}
//現在発射しているタマの数を取得
public function getNowTamaNum():uint
{
return now_shot_num;
}
//マックスの発射数を取得
public function getMaxTamaNum():uint
{
return max_shot_num;
}
//削除されるタマを返す
public function getRemoveTama(ref:Shot1):Shot1
{
return tama_arr["shot" + ref.getIndex()];
}
}
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;
}
}