beamShooting
matacatさんのスクリプトからかなり変更を加えてしまいましたが、WaveSilkを見ていたらビームが美しいシューティングゲームを作りたくなったので製作中です。
/**
* Copyright hryk_m ( http://wonderfl.net/user/hryk_m )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/4UMk
*/
// forked from matacat's WaveSilk
package
{
import flash.events.TextEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.text.TextFieldAutoSize;
import flash.display.AVM1Movie;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import frocessing.color.ColorHSV;
import flash.utils.Dictionary;
import com.bit101.components.Label;
import com.bit101.components.Component;
import com.bit101.components.PushButton;
import net.wonderfl.score.basic.BasicScoreForm;
import net.wonderfl.score.basic.BasicScoreRecordViewer;
import net.wonderfl.utils.WonderflAPI;
[SWF(backgroundColor = "#000000")]
public class BeamShooting extends Sprite
{
private var logoBody:Shape = new Shape();
private var logoCircle:Shape = new Shape();
public var lifeField:TextField;
public var logoField:TextField;
public var startField:TextField;
public var overField:TextField;
public var tmpFormat:TextFormat;
public var scoreField:TextField;
public var score:int;
private const WIND_H:Number = 0;
private const WIND_V:Number = -20;
private const THICK:Number = 2;
private var alp:Number = 0.1;
private var beam:Shape = new Shape();
private var beamR:int;
private var chargeFlag:Boolean = true;
private var pts:Vector.<Number> = new Vector.<Number>();
private var hsv:ColorHSV = new ColorHSV(0, 0.5, 1);
public var myShip:MyShip;
public var beamCenter:int = -500;
public var beamCollisionR:int;
private var _roundCount:int;
private var _nextRoundCount:int;
public var mainTimer:Timer;
private var _stageData:StageData = new StageData();
private var _enemyList:Dictionary;
private var _tfStatus:TextField;
private var _form:BasicScoreForm;
private var rank:BasicScoreRecordViewer;
public function BeamShooting()
{
Component.initStage(stage);
logoBody.graphics.beginFill(0x666666);
var vertices:Vector.<Number>=Vector.<Number>([stage.stageWidth/2,stage.stageHeight/2-100, stage.stageWidth/2 - 50,stage.stageHeight/2, stage.stageWidth/2 + 50,stage.stageHeight/2]);
logoBody.graphics.drawTriangles(vertices);
logoBody.graphics.endFill();
addChild(logoBody);
hsv.h = 360 * Math.random();
logoCircle.graphics.lineStyle(THICK, hsv.value);
logoCircle.graphics.drawCircle(stage.stageWidth/2, stage.stageHeight/2-40,62);
addChild(logoCircle);
logoField = new TextField();
logoField.text = "BEAM SHOOTING";
tmpFormat = new TextFormat("",30,hsv.value);
logoField.autoSize = TextFieldAutoSize.LEFT;
logoField.setTextFormat(tmpFormat);
logoField.x = stage.stageWidth/2 - logoField.width/2;
logoField.y = stage.stageHeight/2 + 30;
addChild(logoField);
startField = new TextField();
startField.text = "CLICK to START";
startField.autoSize = TextFieldAutoSize.LEFT;
tmpFormat.color = 0x666666;
tmpFormat.size = 20;
startField.setTextFormat(tmpFormat);
startField.x = stage.stageWidth/2 - startField.width/2;
startField.y = stage.stageHeight/2 + 80;
addChild(startField);
stage.addEventListener(MouseEvent.CLICK, startGame);
}
public function startGame(e:MouseEvent):void{
var obj: Object = loaderInfo.parameters;
ScoreWindowLoader.init(this, new WonderflAPI(obj));
stage.removeEventListener(MouseEvent.CLICK, startGame);
removeChild(logoBody);
removeChild(logoCircle);
removeChild(logoField);
removeChild(startField);
myShip = new MyShip(0,430);
myShip.life = 50;
score = 0;
_roundCount = 0;
_nextRoundCount = 50;
mainTimer = new Timer(40,0);
mainTimer.addEventListener(TimerEvent.TIMER,onMainTimer);
mainTimer.start();
addEventListener(Event.ENTER_FRAME,drawGame);
addChild(myShip.body);
addChild(beam);
_enemyList = new Dictionary();
lifeField = new TextField();
lifeField.textColor = 0xFF0000;
lifeField.text = "LIFE:" + myShip.life;
lifeField.x = 10;
lifeField.y = 450;
addChild(lifeField);
scoreField = new TextField();
scoreField.textColor = 0xFF0000;
scoreField.text = "SCORE:" + score;
scoreField.x = 100;
scoreField.y = 450;
addChild(scoreField);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
}
private function onMainTimer(event:TimerEvent):void{
if(_roundCount++ > _nextRoundCount){
excuseCommand();
_roundCount = 0;
}
}
private function excuseCommand():void{
var command:Array = _stageData.getNext();
switch(command[0]){
case "wait":
_nextRoundCount = int(command[1]);
break;
case "end":
clearStage();
break;
default:
var useClass:Class = getUseClass(command[0]);
addEnemy(useClass, int(command[1]), int(command[2]));
excuseCommand();
}
}
private function getUseClass(className:String):Class{
switch(className){
case "EnemyA": return EnemyA;
case "EnemyB": return EnemyB;
case "EnemyC": return EnemyC;
default: return EnemyA;
}
}
private function drawGame(event:Event):void{
checkCollision();
myShip.action();
myShip.draw();
lifeField.text = "LIFE:" + myShip.life;
scoreField.text = "SCORE:" + score;
}
private function resetParams():void
{
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
beam.graphics.clear();
beamR = 1;
beamCollisionR = 0;
beamCenter = -500;
hsv.h = 360 * Math.random();
hsv.v = 1;
}
private function onMouseDown(e:MouseEvent):void
{
stage.addEventListener(Event.ENTER_FRAME, onMouseDownEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_UP, onChargeMouseUp);
}
private function onMouseDownEnterFrame(e:Event):void
{
if(chargeFlag){
if(beamR == 1){
resetParams();
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
beam.graphics.clear();
beam.graphics.lineStyle(THICK, hsv.value);
beamR++;
beam.graphics.drawCircle(stage.mouseX, 430,beamR);
}
}
private function onMouseUp(e:MouseEvent):void
{
chargeFlag = false;
beam.graphics.clear();
stage.removeEventListener(Event.ENTER_FRAME, onMouseDownEnterFrame);
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
beamCenter = stage.mouseX;
beamCollisionR = beamR;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onChargeMouseUp(e:MouseEvent):void
{
stage.removeEventListener(Event.ENTER_FRAME, onMouseDownEnterFrame);
}
private function onEnterFrame(e:Event):void
{
for (var i:int = 0; i < stage.stageHeight/10; i++) {
beam.graphics.lineStyle(THICK, hsv.value, alp);
beam.graphics.drawCircle(beamCenter + Math.random() * beamR*0.2,430-i*10*Math.random(),beamR);
}
hsv.h +=15;
hsv.v -= 0.08;
if (hsv.v <= 0) {
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
resetParams();
chargeFlag = true;
}
}
private function addEnemy(unitClass:Class, newX:int, newY:int) :void{
var enemy:Unit;
if(unitClass == EnemyC){
enemy = new unitClass(myShip,newX,newY);
}else{
enemy = new unitClass(newX,newY);
}
addChild(enemy.body);
enemy.draw();
_enemyList[enemy] = enemy;
}
public function removeEnemy(enemy:Unit):void{
removeChild(enemy.body);
delete _enemyList[enemy];
}
private function checkCollision():void{
for each (var enemy:Unit in _enemyList){
if (isCollision(enemy, myShip, 20)){
enemy.remove();
myShip.setDamage(10);
}
if (onChargeBeamCollision(stage.mouseX, enemy, beamR + 20)){
score += enemy.getScore();
enemy.remove();
resetParams();
beam.graphics.clear();
chargeFlag = false;
stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
var chargeBreakTimer:Timer = new Timer(1000,1);
chargeBreakTimer.addEventListener(TimerEvent.TIMER_COMPLETE,function():void{chargeFlag = true;});
chargeBreakTimer.start();
}
if (isBeamCollision(beamCenter, enemy, beamCollisionR + 20)){
score += enemy.getScore();
/* var removeEnemyTimer:Timer = new Timer(100,1);
removeEnemyTimer.addEventListener(TimerEvent.TIMER_COMPLETE,function():void{enemy.remove();});
removeEnemyTimer.start(); */
enemy.remove();
if(enemy == null || enemy.body.stage == null){
break;
}
}
enemy.action();
enemy.draw();
}
}
private function isCollision(baseUnit:Unit,checkUnit:Unit,size:int):Boolean{
var dx:int = baseUnit.x - checkUnit.x;
var dy:int = baseUnit.y - checkUnit.y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
var result:Boolean = dist <= size;
return result;
}
private function onChargeBeamCollision(onChargeBeamCenter:int,checkUnit:Unit,size:int):Boolean{
var dx:int = onChargeBeamCenter - checkUnit.x;
var dy:int = 430 - checkUnit.y;
var dist:Number = Math.sqrt(dx * dx + dy * dy);
var result:Boolean = dist <= size;
return result;
}
private function isBeamCollision(beamCenter:int,checkUnit:Unit,size:int):Boolean{
var dx:int = (beamCenter > checkUnit.x) ? beamCenter - checkUnit.x : checkUnit.x - beamCenter;
var result:Boolean = dx <= size;
return result;
}
public function clearStage():void{
mainTimer.stop();
removeChild(myShip.body);
removeChild(beam);
removeChild(lifeField);
removeChild(scoreField);
for each (var enemy:Unit in _enemyList) enemy.remove();
ScoreWindowLoader.show(score, onCloseEndWindow);
}
public function gameOver():void{
mainTimer.stop();
overField = new TextField();
overField.text = "GAME OVER ...";
overField.autoSize = TextFieldAutoSize.LEFT;
overField.setTextFormat(tmpFormat);
overField.x = stage.stageWidth/2 - startField.width/2;
overField.y = stage.stageHeight/2 - startField.height/2;
addChild(overField);
stage.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
var overTimer:Timer = new Timer(3000,1);
overTimer.addEventListener(TimerEvent.TIMER_COMPLETE,gameOverToStart);
overTimer.start();
}
private function gameOverToStart(event:Event):void
{
removeChild(overField);
removeChild(myShip.body);
removeChild(beam);
removeChild(lifeField);
removeChild(scoreField);
for each (var enemy:Unit in _enemyList) enemy.remove();
addChild(logoBody);
addChild(logoCircle);
addChild(logoField);
addChild(startField);
_stageData = new StageData();
stage.addEventListener(MouseEvent.CLICK, startGame);
}
private function onCloseEndWindow():void
{
addChild(logoBody);
addChild(logoCircle);
addChild(logoField);
addChild(startField);
_stageData = new StageData();
stage.addEventListener(MouseEvent.CLICK, startGame);
}
}
}
import flash.display.DisplayObject;
import flash.display.Shape;
class Unit{
public var body:DisplayObject;
public var x:int;
public var y:int;
public var score:int;
public function Unit(disp:DisplayObject,newX:int,newY:int):void{
body = disp;
x = newX;
y = newY;
}
public function getScore():int{
return score;
}
public function action():void{
}
public function draw():void{
body.x = x;
body.y = y;
}
public function remove():void{
var beamShooting:BeamShooting = body.parent as BeamShooting;
beamShooting.removeChild(body);
}
}
import flash.display.DisplayObject;
class MyShip extends Unit{
public var bodyShape:Shape = new Shape();
public var newShipCenter:int;
public var rotation:int = 0;
private var _rightFlag:Boolean;
private var _leftFlag:Boolean;
public var life:int;
public function MyShip(newX:int,newY:int):void{
bodyShape.graphics.beginFill(0x666666);
var vertices:Vector.<Number>=Vector.<Number>([0,0, 10,20, -10,20]);
bodyShape.graphics.drawTriangles(vertices);
bodyShape.graphics.endFill();
super(bodyShape,newX,newY);
_rightFlag = false;
_leftFlag = false;
life = 50;
}
override public function action():void {
var beamShooting:BeamShooting = body.parent as BeamShooting;
x = beamShooting.stage.mouseX;
if(x > newShipCenter){
_rightFlag = true;
_leftFlag = false;
}else if(x < newShipCenter){
_rightFlag = false;
_leftFlag = true;
}else{
_rightFlag = false;
_leftFlag = false;
}
if(_rightFlag){
rotation+=2;
}else if(_leftFlag){
rotation-=2;
}else{
rotation = 0;
}
newShipCenter = x;
}
override public function draw():void{
super.draw();
body.rotation = rotation;
}
public function setDamage(damage:int):void{
life -= damage;
if(life <= 0){
var beamShooting:BeamShooting = body.parent as BeamShooting;
beamShooting.gameOver();
}
}
}
import flash.display.Sprite;
import flash.display.DisplayObject;
class EnemyA extends Unit {
public var enemyShape:EnemyShape;
public const MAX_Y:int = 500;
public var speed:int;
function EnemyA(newX:int, newY:int, newSpeed:int=5):void {
enemyShape = new EnemyShape(0x006600);
super(enemyShape, newX, newY);
score = 10;
speed = newSpeed;
}
override public function action():void {
y += speed;
if (y>MAX_Y) {
remove();
}
}
override public function remove():void {
var beamShooting:BeamShooting = body.parent as BeamShooting;
beamShooting.removeEnemy(this);
}
}
import flash.display.Sprite;
import flash.display.DisplayObject;
class EnemyB extends Unit {
public var enemyShape:EnemyShape;
public const MIN_Y:int = 0;
public const MAX_Y:int = 500;
public var speed:int;
private var _baseX:int;
private var _r:int;
private var _rad:Number;
function EnemyB(newX:int, newY:int, newSpeed:int=2):void {
enemyShape = new EnemyShape(0x3333FF);
super(enemyShape, newX, newY);
score = 30;
speed = newSpeed;
_baseX = x;
_r = 100;
_rad = 0;
}
override public function action():void {
y += speed+ Math.sin(_rad += 0.1);
x = _baseX + Math.sin(_rad += 0.05)*_r;
if (y < MIN_Y || y >MAX_Y) {
remove();
}
}
override public function remove():void {
var beamShooting:BeamShooting = body.parent as BeamShooting;
beamShooting.removeEnemy(this);
}
}
import flash.display.DisplayObject;
class EnemyC extends Unit {
public var enemyShape:EnemyShape;
public const MAX_Y:int = 500;
public var speed:int;
private var _target:Unit;
function EnemyC(newTarget:Unit, newX:int, newY:int, newSpeed:int=1):void {
enemyShape = new EnemyShape(0x660066);
super(enemyShape, newX, newY);
score = 50;
speed = newSpeed;
_target = newTarget;
}
override public function action():void {
y += speed * 3;
if(x < _target.x -2){
x += speed*2;
}else if(x > _target.x +2){
x -= speed*2;
}
if (y >MAX_Y) {
remove();
}
}
override public function remove():void {
var beamShooting:BeamShooting = body.parent as BeamShooting;
beamShooting.removeEnemy(this);
}
}
import flash.display.Sprite;
import flash.display.DisplayObject;
class EnemyShape extends Sprite {
public var enemyShape:Shape = new Shape();
function EnemyShape(color:uint):void {
enemyShape.graphics.beginFill(color);
enemyShape.graphics.moveTo(-3,8);
enemyShape.graphics.lineTo(-8,0);
enemyShape.graphics.lineTo(-7,8);
enemyShape.graphics.lineTo(-10,8);
enemyShape.graphics.lineTo(-20,20);
enemyShape.graphics.lineTo(-10,20);
enemyShape.graphics.lineTo(-20,28);
enemyShape.graphics.lineTo(0,20);
enemyShape.graphics.lineTo(20,28);
enemyShape.graphics.lineTo(10,20);
enemyShape.graphics.lineTo(20,20);
enemyShape.graphics.lineTo(10,8);
enemyShape.graphics.lineTo(7,8);
enemyShape.graphics.lineTo(8,0);
enemyShape.graphics.lineTo(3,8);
enemyShape.graphics.endFill();
addChild(enemyShape);
}
}
class StageData{
private var _commandList:Array;
function StageData(){
_commandList = new Array();
with(_commandList){
push(["EnemyA",50,0]);
push(["EnemyA",230,0]);
push(["wait",10]);
push(["EnemyA",100,0]);
push(["EnemyA",200,0]);
push(["EnemyA",300,0]);
push(["EnemyA",400,0]);
push(["wait",50]);
push(["EnemyA",300,0]);
push(["EnemyA",350,0]);
push(["EnemyA",400,0]);
push(["EnemyA",450,0]);
push(["wait",50]);
push(["EnemyA",200,0]);
push(["EnemyA",250,0]);
push(["EnemyA",300,0]);
push(["EnemyA",350,0]);
push(["wait",50]);
push(["EnemyA",300,0]);
push(["wait",1]);
push(["EnemyA",260,0]);
push(["wait",1]);
push(["EnemyA",220,0]);
push(["wait",1]);
push(["EnemyA",180,0]);
push(["wait",1]);
push(["EnemyA",140,0]);
push(["wait",1]);
push(["EnemyA",100,0]);
push(["EnemyA",200,0]);
push(["wait",1]);
push(["EnemyA",60,0]);
push(["EnemyA",240,0]);
push(["wait",1]);
push(["EnemyA",20,0]);
push(["EnemyA",280,0]);
push(["wait",1]);
push(["EnemyA",320,0]);
push(["wait",1]);
push(["EnemyA",360,0]);
push(["wait",1]);
push(["EnemyA",120,0]);
push(["EnemyA",270,0]);
push(["wait",5]);
push(["EnemyA",20,0]);
push(["EnemyA",70,0]);
push(["EnemyA",170,0]);
push(["EnemyA",220,0]);
push(["EnemyA",320,0]);
push(["EnemyA",400,0]);
push(["wait",50]);
push(["EnemyA",300,0]);
push(["wait",1]);
push(["EnemyA",260,0]);
push(["wait",1]);
push(["EnemyA",220,0]);
push(["wait",1]);
push(["EnemyA",180,0]);
push(["wait",1]);
push(["EnemyA",140,0]);
push(["wait",1]);
push(["EnemyA",100,0]);
push(["EnemyA",200,0]);
push(["wait",1]);
push(["EnemyA",60,0]);
push(["EnemyA",240,0]);
push(["wait",1]);
push(["EnemyA",20,0]);
push(["EnemyA",280,0]);
push(["wait",1]);
push(["EnemyA",320,0]);
push(["wait",1]);
push(["EnemyA",360,0]);
push(["wait",100]);
push(["EnemyA",250,0]);
push(["wait",1]);
push(["EnemyA",210,0]);
push(["EnemyA",290,0]);
push(["wait",1]);
push(["EnemyA",170,0]);
push(["EnemyA",330,0]);
push(["wait",1]);
push(["EnemyA",130,0]);
push(["EnemyA",370,0]);
push(["wait",1]);
push(["EnemyA",90,0]);
push(["EnemyA",410,0]);
push(["wait",50]);
push(["EnemyB",30,0]);
push(["EnemyB",270,0]);
push(["wait",50]);
push(["EnemyC",30,0]);
push(["wait",150]);
push(["end"]);
}
}
function getNext():Array {
return _commandList.shift();
}
}
import flash.display.DisplayObjectContainer;
import net.wonderfl.utils.WonderflAPI;
import flash.events.Event;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
class ScoreWindowLoader
{
private static var _top: DisplayObjectContainer;
private static var _api: WonderflAPI;
private static var _content: Object;
//private static const URL: String = "wonderflScore.swf";
private static const URL: String = "http://swf.wonderfl.net/swf/usercode/5/57/579a/579a46e1306b5770d429a3738349291f05fec4f3.swf";
private static const TWEET: String = "beamShooting score: %SCORE% http://wonderfl.net/c/4UMk #wonderfl";
public static function init(top: DisplayObjectContainer, api: WonderflAPI): void
{
_top = top, _api = api;
var loader: Loader = new Loader();
var comp: Function = function(e: Event): void
{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, comp);
_content = loader.content;
}
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, comp);
loader.load(new URLRequest(URL), new LoaderContext(true));
}
/**
* Wonderfl の Score API 用
* ランキング表示から Tweet までをひとまとめにしたSWF素材を使う
* @param score : 取得スコア
* @param closeHandler : Window が閉じるイベントハンドら
*/
public static function show( score: int, closeHandler: Function): void
{
var window: DisplayObject = _content.makeScoreWindow(_api, score, "beamShooting", 1, TWEET);
var close: Function = function(e: Event): void
{
window.removeEventListener(Event.CLOSE, close);
closeHandler();
}
window.addEventListener(Event.CLOSE, close);
_top.addChild(window);
}
}