前回ソースからZボタン押すだけの戦闘機能を追加しました
/**
* Copyright siouxcitizen ( http://wonderfl.net/user/siouxcitizen )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/djv4
*/
// forked from siouxcitizen's forked from: ワンダフルクエスト
// forked from osamX's ワンダフルクエスト
// forked from nengafl's nengafl
/**=====================================================
* 前回ソースからZボタン押すだけの戦闘機能を追加しました
*
* [遊び方]
* はじめに、マップをクリックして...
* ↑ , w : 上に移動
* ↓ , s : 下に移動
* ← , a : 左に移動
* → , d : 右に移動
* , , z : 戦闘
*
* ↓コーディングにあたっては以下のソースを参考にさせて頂きました
* Enemy
* http://wonderfl.net/c/pImw/
* GYAOS_sample
* http://wonderfl.net/c/f6f2
* ===================================================== */
package
{
import flash.display.*;
import flash.events.*;
import flash.geom.Point;
import flash.net.URLRequest;
import flash.system.LoaderContext;
import flash.utils.Timer;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
[SWF(width="465", height="465", frameRate="30", backgroundColor="0x000000")]
public class WonderflQuest extends Sprite
{
private const SIZE:Number = 465;//ステージの大きさ
private const SCALE:Number = 3; //勇者やフィールドの拡大率
private const SPEED:Number = 6; //勇者が歩くスピード FLDSIZEの約数にしてください
private const MAPSIZE:uint = 16;//マップの横・縦のマスの個数
private const FLDSIZE:uint = 48;//フィールド(マップ上の1マス)の横・縦のドット数
private var yuusha:MovingFigure; //勇者
private var yuushaPos:Point; //勇者のマップ上の座標
private var shikabane:MovingFigure;
private var map:Sprite; //マップ本体 これを動かして勇者が移動しているように見せる
private var bMapData:Array = [];//フィールドが障害物か否かを記憶
private var frameCount:Number = 0; //onEnterFrameで使用
private var keyFlags:Array = [false, false, false, false]; //下上左右のキーが押されているか
private var walkDirection:int = 4; //歩いていく方向 (0~3:下上左右 4:止)
private var loaded:int = 0; //読み込み完了した画像の個数
private var isInit:Boolean = false; //初期化されているか onEnterFrameで使用
private var prgSpr:Sprite; //ロード画面表示用
private var isBattle:Boolean = false; //バトル状態か
private var battleSpr:Sprite; //バトル画面表示用
private var hpView:HpView; // HP表示
private var blinkTimer:Timer; // 攻撃エフェクト用のタイマー
private var hp:int=100; // モンスターのHP
private var winText:TextField; // 「win」表示用テキスト
/**-----------------------------------------------------
* マップの1マス(フィールド)のリストです。
* ここをいじると好きな画像をマップ上に貼ることができます。
* 画像のサイズは、基本的に16*16ピクセルです。
* 形式はjpeg,gif,pngのどれかにしてください。
* Twitterのアイコン画像取得は、こちらのAPIを使わせてもらってます。
* http://usericons.relucks.org/
* ----------------------------------------------------- */
private const fieldList:Array = [
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map0.png", false), //[ 0]: 芝生
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map1.png", false), //[ 1]: 砂
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map2.png", false), //[ 2]: 石畳
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map3.png", false), //[ 3]: フローリング
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map4.png", false), //[ 4]: 橋(縦)
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map5.png", false), //[ 5]: 橋(横)
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map6.png", true), //[ 6]: 木(小)
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map7.png", true), //[ 7]: 木(大)
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map8.png", true), //[ 8]: サボテン
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map9.png", true), //[ 9]: 水
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map10.png", true), //[10]: 壁(石)
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map11.png", true), //[11]: 壁(木)
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map12.png", true), //[12]: 壁(武器屋)
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map13.png", true), //[13]: 壁(防具屋)
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map14.png", true), //[14]: 壁(宿屋)
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map15.png", true), //[15]: 壺
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map16.png", true), //[16]: タンス
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map17.png", true), //[17]: 石像
new Field("http://flash-scope.com/wonderfl/WonderflQuest/map/map18.png", true), //[18]: 真っ暗
new Field("http://usericons.relucks.org/twitter/osamX", false) //[19]: Twitterアイコン
];
/**-----------------------------------------------------
木で、あそこが芝生で...ってやつ)が入ってます。
* ここをいじると、マップが変わります。上のfieldListのコメント参照。
* ----------------------------------------------------- */
//private const mapData:Array =
// [[ 0, 6, 9,18,10,10,10,10,10,18, 2,18,11,11,11,11],
// [ 0, 0, 9,18,16,16, 2, 2, 2,18, 2,18, 3, 3,15,16],
// [ 0, 0, 9,18, 2, 2, 2, 2, 2,18, 2,18, 3, 3, 3, 3],
// [ 7, 0, 9,18, 2, 2, 2, 2, 2,18, 2,18, 3, 3, 3, 3],
// [ 0, 0, 9,18,10,10,10,10, 2,13, 2,14, 3,11,11,11],
// [ 0, 0, 9,18, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
// [ 0, 0, 9,18, 2, 2, 2, 2, 2, 2, 2,12,10,10,10,10],
// [ 0, 0, 9,18, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,16],
// [ 0, 0, 9,18, 2, 2, 2, 2, 2, 2, 2,18, 2, 2, 2, 2],
// [ 1, 0, 9,18,19,15, 2,17, 2, 2,17,18, 2, 2, 2, 2],
// [ 1, 1, 9,10,10,10,10,10, 2, 2,10,10,10,10,10,10],
// [ 1, 1, 9, 9, 9, 9, 9, 9, 4, 4, 9, 9, 9, 9, 9, 9],
// [ 1, 1, 0, 0, 0, 9, 9, 0, 0, 0, 0, 6, 0, 0, 0, 7],
// [ 1, 1, 1, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0],
// [ 8, 1, 1, 1, 9, 9, 9, 9, 0, 0, 1, 1, 0, 0, 6, 0],
// [ 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 0]];
private const mapData:Array =
[[ 0, 0, 9, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 9, 0],
[ 0, 0, 9, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 9, 0],
[ 0, 0, 9, 0, 6, 0, 1, 1, 1, 0, 0, 0, 6, 0, 9, 0],
[ 0, 0, 9, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 9, 0],
[ 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0],
[ 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0],
[ 0, 0, 9, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 0, 9, 0],
[ 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0],
[ 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0],
[ 1, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0],
[ 1, 1, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0],
[ 1, 1, 9, 9, 9, 9, 9, 9, 4, 4, 9, 9, 9, 9, 9, 0],
[ 1, 1, 0, 0, 0, 9, 9, 0, 0, 0, 0, 6, 0, 0, 0, 0],
[ 1, 1, 1, 0, 0, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 1, 1, 1, 1, 9, 9, 9, 9, 0, 0, 1, 1, 0, 0, 0, 0],
[ 1, 1, 1, 9, 9, 9, 9, 9, 9, 9, 9, 9, 1, 1, 1, 0]];
/**-----------------------------------------------------
* 勇者の画像のURLリスト
* ----------------------------------------------------- */
private const yuushaImgList:Array = [
"http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaF1.png", //前向き1
"http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaF2.png", //前向き2
"http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaB1.png", //後ろ向き1
"http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaB2.png", //後ろ向き2
"http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaL1.png", //左向き1
"http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaL2.png", //左向き2
"http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaR1.png", //右向き1
"http://flash-scope.com/wonderfl/WonderflQuest/yuusha/yuushaR2.png" //右向き2
];
/**-----------------------------------------------------
* しかばねの画像のURLリスト
* ----------------------------------------------------- */
private const shikabaneImgList:Array = [
"http://flash-scope.com/wonderfl/WonderflQuest/shikabane/shikabaneF1.png", //前向き1
"http://flash-scope.com/wonderfl/WonderflQuest/shikabane/shikabaneF2.png", //前向き2
"http://flash-scope.com/wonderfl/WonderflQuest/shikabane/shikabaneB1.png", //後ろ向き1
"http://flash-scope.com/wonderfl/WonderflQuest/shikabane/shikabaneB2.png", //後ろ向き2
"http://flash-scope.com/wonderfl/WonderflQuest/shikabane/shikabaneL1.png", //左向き1
"http://flash-scope.com/wonderfl/WonderflQuest/shikabane/shikabaneL2.png", //左向き2
"http://flash-scope.com/wonderfl/WonderflQuest/shikabane/shikabaneR1.png", //右向き1
"http://flash-scope.com/wonderfl/WonderflQuest/shikabane/shikabaneR2.png" //右向き2
];
/**-----------------------------------------------------
* コンストラクタ。 ここが最初に処理されます。
* ----------------------------------------------------- */
public function WonderflQuest():void
{
prgSpr = new Sprite();//ロード画面
addChild(prgSpr);
addEventListener(Event.ENTER_FRAME, onEnterFrame);//イベントリスナーの登録
createMap(); //マップを作る
yuusha = new MovingFigure(yuushaImgList); //勇者を作る
yuusha.scaleX = yuusha.scaleY = SCALE; //勇者を拡大表示
yuusha.x = yuusha.y = (SIZE-FLDSIZE)/2; //中央に配置
yuushaPos = new Point(8 * FLDSIZE, 8 * FLDSIZE);//勇者初期位置
moveMap(yuushaPos); //マップ移動
shikabane = new MovingFigure(shikabaneImgList); //敵しかばねを初期化
// バトル画面エフェクト用タイマーを初期化する
blinkTimer=new Timer(80, 4);
blinkTimer.addEventListener("timer", timerHandler);
}
/**-----------------------------------------------------
* 毎フレームの処理。
* ----------------------------------------------------- */
private function onEnterFrame(event:Event):void {
if (loaded < MAPSIZE * MAPSIZE) { //フィールドの画像読み込み未完了なら
drawPrg();
return; //これ以下を処理しない
}
//画像読み込み完了後 1回だけ処理
if (!isInit) {
removeChild(prgSpr);//ロード画面非表示
prgSpr = null;
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown); //イベントリスナーの登録
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp); //イベントリスナーの登録
addChild(map); //マップ表示
addChild(yuusha); //勇者表示
isInit = true;
}
//15フレーム毎に処理する
if (frameCount++ > 10) {
frameCount = 0;
yuusha.walk();
}
//マップ(勇者)をどの方向に動かすか判定
if (yuushaPos.x % FLDSIZE == 0 && yuushaPos.y % FLDSIZE == 0) {
var mapPosX:int = int(yuushaPos.x / FLDSIZE), mapPosY:int = int(yuushaPos.y / FLDSIZE);
walkDirection = 4; //止まる
switch(true) {
case keyFlags[0]: //下
if(yuushaPos.y < (MAPSIZE-1)*FLDSIZE && !bMapData[mapPosY+1][mapPosX]) walkDirection=0;
yuusha.changeDirection(0);
break;
case keyFlags[1]: //上
if(yuushaPos.y > 0 && !bMapData[mapPosY-1][mapPosX]) walkDirection=1;
yuusha.changeDirection(1);
break;
case keyFlags[2]: //左
if(yuushaPos.x > 0 && !bMapData[mapPosY][mapPosX-1]) walkDirection=2;
yuusha.changeDirection(2);
break;
case keyFlags[3]: //右
if(yuushaPos.x < (MAPSIZE-1)*FLDSIZE && !bMapData[mapPosY][mapPosX+1]) walkDirection=3;
yuusha.changeDirection(3);
break;
}
}
//次のマスまで自動的に勇者を歩かせる
switch(walkDirection) {
case 0:
yuushaPos.y += SPEED;
break;
case 1:
yuushaPos.y -= SPEED;
break;
case 2:
yuushaPos.x -= SPEED;
break;
case 3:
yuushaPos.x += SPEED;
break;
}
if (walkDirection < 4) moveMap(yuushaPos);
}
/**-----------------------------------------------------
* キーボードのキーが押された時の処理。
* ----------------------------------------------------- */
private function onKeyDown(event:KeyboardEvent):void {
//if (winText!=null) removeChild(winText); ←switch文のcaseごとに処理しないとうまく動かない???
switch(event.keyCode) {
case 40: case 83: //↓ s
if(isBattle) break; //バトル中の勇者移動は行わない
keyFlags[0] = true;
if (winText!=null) removeChild(winText);
}
switch(event.keyCode) {
case 38: case 87: //↑ w
if(isBattle) break; //バトル中の勇者移動は行わない
keyFlags[1] = true;
if (winText!=null) removeChild(winText);
}
switch(event.keyCode) {
case 37: case 65: //← a
if(isBattle) break; //バトル中の勇者移動は行わない
keyFlags[2] = true;
if (winText!=null) removeChild(winText);
}
switch(event.keyCode) {
case 39: case 68: //→ d
if(isBattle) break; //バトル中の勇者移動は行わない
keyFlags[3] = true;
if (winText!=null) removeChild(winText);
}
switch(event.keyCode) {
case 188: case 90: //, z
if(!isBattle) {
keyFlags[0] = false;
keyFlags[1] = false;
keyFlags[2] = false;
keyFlags[3] = false;
initBattle();
if (winText!=null) removeChild(winText);
} else {
calcBattle();
}
}
}
/**-----------------------------------------------------
* キーボードのキーが離された時の処理。
* ----------------------------------------------------- */
private function onKeyUp(event:KeyboardEvent):void {
switch(event.keyCode) {
case 40: case 83: //↓ s
keyFlags[0] = false;
}
switch(event.keyCode) {
case 38: case 87: //↑ w
keyFlags[1] = false;
}
switch(event.keyCode) {
case 37: case 65: //← a
keyFlags[2] = false;
}
switch(event.keyCode) {
case 39: case 68: //→ d
keyFlags[3] = false;
}
}
/**-----------------------------------------------------
* マップを作ります。
* この実装方法は良くないです。遅いし、何回も同じ画像をロードしてます。
* 画像が別ドメインにある時に、crossdomain.xmlがなくても大丈夫なようにしています。
* ----------------------------------------------------- */
private function createMap():void {
map = new Sprite();
for (var k:uint = 0; k < MAPSIZE; k++) bMapData[k] = []; //bMapDataを2次元配列にする
for (var j:uint = 0; j < MAPSIZE; j++) {
for (var i:uint = 0; i < MAPSIZE; i++) {
var loader:Loader = new Loader();
var field:Field = fieldList[mapData[j][i]];
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, function(e:Event):void{loaded++;}); //ロード完了したらloadedをカウントアップ
loader.load(new URLRequest(field.url), new LoaderContext(true));
loader.x = FLDSIZE * i;
loader.y = FLDSIZE * j;
loader.scaleX = loader.scaleY = SCALE;
if (mapData[j][i] == 19) loader.scaleX = loader.scaleY = FLDSIZE / 73; //Twitterのアイコンの時
map.addChild(loader);
bMapData[j][i] = field.isObstacle;
}
}
}
/**-----------------------------------------------------
* マップの座標計算。
* ----------------------------------------------------- */
private function moveMap(pos:Point):void {
map.x = (SIZE-FLDSIZE)/2 - yuushaPos.x;
map.y = (SIZE-FLDSIZE)/2 - yuushaPos.y;
}
/**-----------------------------------------------------
* ロード画面を描く。
* ----------------------------------------------------- */
private function drawPrg():void {
var side:Number = SIZE / MAPSIZE,
yy:int = int(loaded / MAPSIZE),
xx:int = loaded - yy * MAPSIZE,
max:int = MAPSIZE;
prgSpr.graphics.clear();
prgSpr.graphics.beginFill(0xFFFFFF);
prgSpr.graphics.drawRect(0, 0, SIZE, yy * side);
if(yy%2)prgSpr.graphics.drawRect((MAPSIZE-xx)*side, yy*side, SIZE, side);
else prgSpr.graphics.drawRect(0, yy*side, xx*side, side);
prgSpr.graphics.endFill();
}
/**-----------------------------------------------------
* バトル画面を初期化。
* ----------------------------------------------------- */
private function initBattle():void {
//
isBattle = true;
battleSpr = new Sprite();
battleSpr.graphics.beginFill(0x222222);
battleSpr.graphics.drawRect(100, 50, 300, 350);
battleSpr.graphics.endFill();
addChild(battleSpr);
shikabane.scaleX = shikabane.scaleY = SCALE; //しかばね的を拡大表示
//shikabane.x = shikabane.y = (SIZE-FLDSIZE)/2; //中央に配置
shikabane.x = 220; //とりあえずテキトーに配置
shikabane.y = 150; //とりあえずテキトーに配置
addChild(shikabane);
// モンスターのHPを表示する
hp = 100;
hpView=new HpView(hp, hp);
//hpView.x=stage.stageWidth/2-hpView.width/2;
//hpView.y=attackButton.y - hpView.height;
hpView.x = 200; //とりあえずテキトーに配置
hpView.y = 250; //とりあえずテキトーに配置
addChild(hpView);
}
/**-----------------------------------------------------
* バトル画面処理を行う。
* ----------------------------------------------------- */
private function calcBattle():void {
//ダメージを計算する
var r:int=Math.floor(Math.random() * 10) + 10;
hp-=r;
//攻撃エフェクト
if (hp < 1) { //モンスター死亡時
//win表示
winText = new TextField();
var format:TextFormat=new TextFormat();
format.size = 200;
winText.autoSize = TextFieldAutoSize.CENTER;
winText.defaultTextFormat=format;
winText.text="win";
addChild(winText);
winText.x = 150; //とりあえずテキトーに配置
winText.y = 10; //とりあえずテキトーに配置
hp=0;
//バトル画面の表示・処理を終了する
isBattle = false;
removeChild(hpView);
removeChild(shikabane);
removeChild(battleSpr);
} else { //攻撃成功時
// 攻撃エフェクトを開始する
blinkTimer.reset();
blinkTimer.start();
}
// HP表示を更新する
hpView.update(hp);
}
/**-----------------------------------------------------
* タイマー処理を行う。
* ----------------------------------------------------- */
private function timerHandler(event:TimerEvent):void
{
if (blinkTimer.currentCount % 2 == 1) {
shikabane.visible = false;
}
else {
shikabane.visible = true;
}
}
}
}
import flash.display.Sprite;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.system.LoaderContext;
/**-----------------------------------------------------
* 勇者クラスです。勇者を作ったり、足踏させたり、向きを変えたりします。
* ----------------------------------------------------- */
class MovingFigure extends Sprite {
public var direction:int = 0; //向き (0:前 1:後 2:左 3:右)
private var walkFlag:Boolean = true;//足踏み用
private var yuushaImages:Array = [];//勇者の画像集
private var ImageURL:Array;
/**-----------------------------------------------------
* コンストラクタ。
* ----------------------------------------------------- */
public function MovingFigure(imgList:Array):void {
ImageURL = imgList;
for (var i:uint = 0; i < 8; i++) {
var loader:Loader = new Loader();
loader.load(new URLRequest(ImageURL[i]), new LoaderContext(true));
yuushaImages.push(loader);
if(i) yuushaImages[i].visible = false;
addChild(yuushaImages[i]);
}
}
/**-----------------------------------------------------
* 足踏みさせます。
* ----------------------------------------------------- */
public function walk():void {
walkFlag = !walkFlag;
for (var i:uint = 0; i < 8; i++) {
if (i == 2*direction+int(walkFlag)) yuushaImages[i].visible = true;
else yuushaImages[i].visible = false;
}
}
/**-----------------------------------------------------
* 向きを変更します。
* numは勇者の向きを表します。(0~3)
* ----------------------------------------------------- */
public function changeDirection(num:int):void {
direction = num;
for (var i:uint = 0; i < 8; i++) {
if (i == 2*direction+int(walkFlag)) yuushaImages[i].visible = true;
else yuushaImages[i].visible = false;
}
}
}
/**-----------------------------------------------------
* Fieldクラスです。画像のURLと、そのフィールドが障害物か否かを保存します。
* ----------------------------------------------------- */
class Field {
public var url:String; //画像のURL
public var isObstacle:Boolean; //障害物か否か (true:障害物 false:障害物じゃない(歩ける))
public function Field(s:String, b:Boolean = false):void {
url = s;
isObstacle = b;
}
}
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
// HP表示
class HpView extends Sprite
{
private var _text:TextField;
private var _hpMax:int;
function HpView(hp:int, hpMax:int)
{
_hpMax=hpMax;
_text=new TextField();
var format:TextFormat=new TextFormat();
_text.autoSize = TextFieldAutoSize.LEFT;
format.color = 0xEEEEEE;
format.size = 20;
_text.defaultTextFormat=format;
addChild(_text);
update(hp);
}
// HP表示を更新する
public function update(hp:int):void
{
_text.text="HP : " + String(hp) + "/" + _hpMax;
}
}