解決済み

actionscript 3.0 初心者です

  • すぐに回答を!
  • 質問No.7338121
  • 閲覧数259
  • ありがとう数2
  • 気になる数0
  • 回答数4
  • コメント数0

お礼率 66% (58/87)

以下の3つの質問にご回答いただければ幸いです。

以下の参考にさせていただいている、スクリプトにて

1、random関数の()の後に来る数字はどのような範囲を意味しているのでしょうか?
2、sList[i].vx = Math.random() -0.5;という記述について、これはあるオブジェクトの
落下(進行)の速度を示しているらしいのですが、その手前の記述で、
private var vx:Number = 0;という記述があります。自分で定義したものをプロパティーとして使い事はできるのでしょうか?(もしくわこのvxはarrayのプロパティとして使われていると考えてよろしいのしょうか?)
3、なぜ速度をわざわざ配列で記入する必要があるのでしょうか?

多岐にわたっておりますが、是非よろしくお願い致します。


package{

import flash.display.Sprite;

import flash.display.MovieClip;

import flash.geom.Matrix;

import flash.events.Event;

import flash.filters.BlurFilter;


public class Main extends Sprite {



private var snow:Ball;
    private var num:int = 200;
private var sList:Array = [];
private var vx:Number = 0;



public function Main(){

for(var i:int = 0; i < num; i++){

var snow:Ball = new Ball(2,0xaaffff)


//初期位値

snow.x = Math.random() * stage.stageWidth;

snow.y = Math.random() * stage.stageHeight;

//大きさを生成順に小さく

snow.scaleX = snow.scaleY = 1 / (0.02 * i + 1);





//配置して配列に入れる

addChild(snow);

sList.push(snow);

//それぞれのx方向の速度設定

sList[i].vx = Math.random() -0.5;

}

addEventListener(Event.ENTER_FRAME,go1);

}

private function go1(evt:Event):void{

for(var i = 0; i < num; i++){

//x方向とy方向の動き設定(奥のものほど遅くなる)

sList[i].x += sList[i].vx / (0.02 * i + 1);

sList[i].y += 4 / (0.02 * i + 1);

//ステージ外(下)に出たら移動

if(sList[i].y > 400){

sList[i].x = Math.random() * stage.stageWidth;

sList[i].y = 0;

}

}

}

}

}

質問者が選んだベストアンサー

  • 回答No.4

ベストアンサー率 80% (21/26)

連投申し訳ございません。
回答No.3のコードにおけるSnowクラスのコンストラクタ、Snow.Snow()に
誤りがありました。正しくは以下の通りです。

 /**
  * コンストラクタ。
  * @param id 通し番号。(番号が小さいほど大きく、速くなります)
  */
 public function Snow(id:int)
 {
  var amount:Number = id / LIMIT;
  coefficient = amount + 0.1;
  cacheAsBitmap = true;
  addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

  // ↓ Flashで予めシェイプを作ってリンケージする場合、ここからの処理は不要
  var shape:Shape = new Shape();
  var r:int = 0xFF * (0.2 + amount * 0.8);
  var g:int = 0xFF * (0.5 + amount * 0.5);
  var b:int = 0xFF * (0.5 + amount * 0.5);
  shape.graphics.beginFill((r << 16) + (g << 8) + b);
  shape.graphics.drawCircle(0, 0, SIZE_MIN + (SIZE_MAX - SIZE_MIN) * amount);
  shape.graphics.endFill();
  addChild(shape);
  // ↑ Flashで予めシェイプを作ってリンケージする場合、ここまでの処理は不要
 }
お礼コメント
naonao321

お礼率 66% (58/87)

このたびはありがとうございました。

とても読み応えのある文章を大変うれしく思っております。
しばらく検証しましたが、なかなか概念的な所が難しいです。
引き続き検証を続けたいと思いますが、これ以上お礼が長引くのは
よくないと思い、書かせていただきした。
後日また質問をさせていただきますので、お見かけになりましたら
是非お願い致します。ありがとうございました。
投稿日時 - 2012-03-18 18:40:40
感謝経済

その他の回答 (全3件)

  • 回答No.3

ベストアンサー率 80% (21/26)

※ この回答はNo.2の補足に対するものです。
>B.メイン側はSnowを作るだけで何もせず、Snowに勝手に(自律的に)動いてもらう方法
>について非常に興味があります

Flashに限らずどのゲーム制作もそうですが、基本的に子の動きに親が関わっては
いけません。親はただ「動け」と命令するだけです。子は「動け」の命令に反応して、
その子が雪なら落下するよう座標を書き換えますし、
その子が鳥なら(もしいたら)雪を避けるようにして飛んでいくでしょう。
その際、雪は風に流されるかもしれませんし、鳥は飛ぶために翼(孫)に
「動け」と命令するかもしれませんが、そんなこと親は知る必要もありません。
そうすると親のプログラムコードはビックリするくらいシンプルに作ることができます。

このように「動け」、と言うだけで各自がまるで生きているかのように勝手な
動きをすることを「多態性(Polymorphism)」と言います。これが理解できると、
Flashを使った複雑なゲームとかが簡単に作れるようになる、最短ルートとなるでしょう。

下記にコードを提示します。何の変哲もない雪を降らせるだけのアニメーションですが、
Mainは雪を一度作って、それ以降は何もしていないことに気づくと思われます。
幸いなことに、Flashには毎フレーム発生するイベント"enterFrame"があるため、
Mainは逐一「動け」と命令することさえもサボることができます。

// ■■■ Main.as
package
{
 import flash.display.Sprite;

 [SWF(width="320",height="240",backgroundColor="0x000033",frameRate="60")]
 /** ドキュメント クラス。 */
 public final class Main extends Sprite
 {
  /** コンストラクタ。 */
  public function Main()
  {
   var field:Sprite = new Sprite();
   for (var i:int = Snow.LIMIT; --i >= 0; )
   {
    field.addChildAt(new Snow(i), 0);
    // 別に間にfieldを挟まなくても構わないが、これでfieldのscale調整してやると
    // 画面の一部に雪を降らせたり、fieldを増やして3箇所に雪を降らせたり
    // field.rotationを弄ることで雪を降らせる画面をぐるぐる回したりもできる
    // SnowみたいにfieldもSpriteを継承してやることで複雑な動きを作ることも
   }
   addChild(field);
  } // これ以降はSnowが勝手に動くので何もしない(あるいはほかの仕事をやらせる)
 }
}

// ■■■ Snow.as
package
{
 import flash.display.Shape;
 import flash.display.Sprite;
 import flash.events.Event;
 import flash.geom.Point;

 /** 雪(単体)。 */
 public final class Snow extends Sprite
 {
  /** 限界数量。(これを変えることで雪の数を増減できます) */
  public static const LIMIT:int = 500;

  /** 最小サイズ。 */
  private static const SIZE_MIN:Number = 1;

  /** 最大サイズ。 */
  private static const SIZE_MAX:Number = 5;

  /** 移動速度・方角。 */
  private var vector:Point = new Point();

  /** 速度を変えるための係数。 */
  private var coefficient:Number;

  /**
   * コンストラクタ。
   * @param id 通し番号。(番号が小さいほど大きく、速くなります)
   */
  public function Snow(id:int)
  {
   coefficient = amount + 0.1;
   cacheAsBitmap = true;
   addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

   // ↓ Flashで予めシェイプを作ってリンケージする場合、ここからの処理は不要
   var shape:Shape = new Shape();
   var amount:Number = id / LIMIT;
   var r:int = 0xFF * (0.2 + amount * 0.8);
   var g:int = 0xFF * (0.5 + amount * 0.5);
   var b:int = 0xFF * (0.5 + amount * 0.5);
   shape.graphics.beginFill((r << 16) + (g << 8) + b);
   shape.graphics.drawCircle(0, 0, SIZE_MIN + (SIZE_MAX - SIZE_MIN) * amount);
   shape.graphics.endFill();
   addChild(shape);
   // ↑ Flashで予めシェイプを作ってリンケージする場合、ここまでの処理は不要
  }

  /** 位置情報をリセットします。 */
  private function reset():void
  {
   x = stage.stageWidth * Math.random();
   y = -SIZE_MAX;
   vector.x = 0.1 * Math.random() * coefficient;
   vector.y = 1.5 * coefficient;
  }

  /**
   * ステージに登録されたイベントによって呼び出されます。
   * @param evt イベント情報。
   */
  private function onAddedToStage(e:Event):void
  {
   addEventListener(Event.ENTER_FRAME, onEnterFrame);
   reset();
   y = stage.stageHeight * Math.random();
  }

  /**
   * 毎フレーム開始時のイベントによって呼び出されます。
   * @param evt イベント情報。
   */
  private function onEnterFrame(e:Event):void
  {
   x += vector.x;
   y += vector.y;
   if (y > stage.stageHeight + SIZE_MAX)
   {
    reset();
   }
  }
 }
}
お礼コメント
naonao321

お礼率 66% (58/87)

詳細なご回答ありがとうございます。
なかなか手強そうです。まだまだなぜそのメソッドが必要かが
わかるまでに至っておりませんが、いただいた記述をもとに
しつこくやっていきたいと思います。
投稿日時 - 2012-03-18 18:45:35
  • 回答No.2

ベストアンサー率 80% (21/26)

前回回答で言いそびれてしまいましたが、質問のタイトルには何がどう
わからないかを簡潔に書くと皆がちゃんと質問を見てくれるようになりますよ?
(初心者です、とか解りません、だけだとページすら見てくれない人が結構多いです)

1.前回のコードを含めて総合的にみると、フレームごとのX増加量のように思えます。
sList[i].x = 100とすると画面左端によった状態での降下となる現象に
ついては、このソースから把握するのは困難しいです。前回ソースの
//x方向とy方向の動き設定(奥のものほど遅くなる)
に該当する部分はどこに行ってしまったのでしょうか?Snow.as、なければSnowと言う
名前でリンケージされているシンボルにアクションが含まれていないでしょうか?

2.一言で言うと、「Snowを動かすため」です。方法として、大きく2通りがあります。
A.Snowを配列に登録して、メイン側が一つ一つ監視、操作していく方法
 (入門者向け。ごく簡単なムービーによく使われます。今回はこちらですね)
B.メイン側はSnowを作るだけで何もせず、Snowに勝手に(自律的に)動いてもらう方法
 (中~上級者向け。本格的なFlashムービー制作には絶対外せない方法です)

ソースを見る限り前者Aの作りになっているようなので、Aの動きについて解説します。
・メインはSnowを220個作り、表示のためステージに登録するが、さらにメインが監視を
 するため作った220個のSnowを配列に登録する。(この登録するメソッドがpushです)
・配列の中身を総なめして、一つ一つ移動量に応じてXY座標を操作する。
 300より下に行き過ぎたやつは画面上に引き上げる。
自律して動いてもらうのでしたら、配列に登録(push)は要らないですが、メインが
Snowを監視するのでしたらSnowがメインから見れる場所にいないとだめです。
補足コメント
naonao321

お礼率 66% (58/87)

度重なるご回答ありがとうございます。

お話にあった、B.メイン側はSnowを作るだけで何もせず、Snowに勝手に(自律的に)動いてもらう方法について非常に興味があります。大まかにどのような考え方なのかご説明いただけませんでしょうか?
是非よろしくお願い致します。
投稿日時 - 2012-03-09 05:42:57
  • 回答No.1

ベストアンサー率 80% (21/26)

ソースを30秒眺めて、雪を降らせるムービーと推測しました。

1.Math.random()は0以上1未満の値を取得します。そこから-0.5しているので、
 結果的に-0.5以上0.5未満となります。

2.このvxは使われていません。消しても問題ありません。sListのBall.vxと
 混同されているようですが、たまたま名前が同じなだけで関係ありません。

3.この「雪」は左右に流れていきます。バラバラに流れさせるために配列を
 使っています。配列じゃないと、全部の雪が一方向に流れていきます。また、
 都度ランダムで左右の速度を決めると、雪がブルブル震えだして不自然となります。
補足コメント
naonao321

お礼率 66% (58/87)

dmq様

ご回答ありがとうございます。

掲載させていただいた参考スクリプトは
今回の質問の場合少し不適切でしたので、
以下のスクリプトについて、再度ご回答といただけないでしょうか。
よろしくお願い致します。

以下のスクリプトにて
1、中段に sList[i].xv = Math.random()-0.6;という記述
をご覧になられると思いますが、このxvを消すと動かずにエラーがおきます。
xvからxのみにすると今度は最初はランダムに配置されたオブジェクトが、しかしすぐに左端に大集合してしまいます。このvxは毎フレームごとのxの増加量と考えてよろしいのでしょうか?
また、sList[i].xv = Math.random()-0.6;について、
これをsList[i].x = 100とするとすべてのオブジェクトがx座標100のまま降下していくと考えたのですが、画面左端によった状態での降下でした。どうしてこのようになるのでしょうか?
2、同じく中盤の sList.push(snow);という記述について、
なぜこのような操作が必要なのでしょうか?恐らく、必要な事は間違いないと思いますが、どのような考え方によってこれが記述されたかがあまりよくわかりません。

//数
var num:int = 220;
//いれる配列
var sList:Array = [];

for (var i:int = 0; i<num; i++) {
//作成
var snow:Snow = new Snow();
//初期位置
snow.x = Math.random()*stage.stageWidth;
snow.y = Math.random()*stage.stageHeight;
//大きさを生成順に小さくしていく
snow.scaleX = snow.scaleY = 1/(0.02*i+1);

//配置して配列にいれる
addChildAt(snow, 1);
sList.push(snow);
//それぞれのX方向の速度設定
sList[i].xv = Math.random()-0.6;
}

//動きのイベント
addEventListener(Event.ENTER_FRAME,parallax);
function parallax(e:Event):void {
for (i=0; i<num; i++) {

//画面の下にでたら上に移動
if (sList[i].y>300) {
sList[i].x = Math.random()*stage.stageWidth;
sList[i].y = 0;
}
}
}

長文に渡り恐縮です。
是非よろしくお願い致します。
投稿日時 - 2012-03-03 17:55:11
AIエージェント「あい」

こんにちは。AIエージェントの「あい」です。
あなたの悩みに、OKWAVE 3,500万件のQ&Aを分析して最適な回答をご提案します。

関連するQ&A
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する

特集


感謝指数によるOK-チップ配布スタート!

ピックアップ

ページ先頭へ