コンピュータリテラシーB 131106x

提供: socialakiba wiki
ナビゲーションに移動 検索に移動

復習

新しいタイルを作る

Tile.cs
タイルの種類を増やす
Level.cs
タイルを読み込む。
Player.cs
プレイヤーとタイルの当たり判定。
0.txt
マップにタイルを追加する。

新しいクラスXXXを作る

XXX.cs
XXX.csという新しいファイルにクラスXXXについて書く(普通は既存のクラスを適当にコピペして適当に名前を変え、パラメータをいじる)。
Tile.cs
タイルの種類を増やす。
Level.cs
タイルを読み込む。Updateメソッドをいじる。Drawメソッドをいじる。
Player.cs
プレイヤーとXXXとの当たり判定。プレイヤーが死んだときのメソッドを追加。
0.txt
マップにタイルを追加する。

すべるタイル

氷のテクスチャのタイルを描く。 2、3種類描いて水平・垂直反転させたりして使い回して種類を増やす。

Tile.cs で Ice というタイルを増やす。

        Ice = 4, // 121107 追加

Level.cs で氷のテクスチャを読み込む。

                case 'I': // 氷 121107追加
                    return LoadVarietyTile("BlockI", 6, TileCollision.Ice);

Player.cs で氷の上に乗っているかどうかを判定し、氷の上にいる場合は、X方向の動きを止めないようにする。

        bool isOnIce;

Class Player { ...の直後に isOnIce という変数を宣言する。 bool は true (真)か false (偽) かのどちらかの値を取る変数。 if文などで使われることが多い(if(isOnIce)など)。

Updateメソッドの中の

            movement = 0.0f;

という部分を

            if(!isOnIce) movement = 0.0f; //121107

に変更。 !isOnIce は isOnIce の否定なので、「氷の上ではないとき」という意味になる。 氷の上にいるときは movement は 0 にリセットされないので、動き続ける。

            //// Get analog horizontal movement.
            //movement = gamePadState.ThumbSticks.Left.X * MoveStickScale;

            //// Ignore small movements to prevent running in place.
            //if (Math.Abs(movement) < 0.5f)
            //    movement = 0.0f;

GetInput メソッドの中のゲームパッドのアナログスティックからの入力の部分をごそっとコメントアウト。 この授業ではゲームパッドを使う予定はないので特に困らない。 アナログスティックからの入力がないと movement (X方向の移動量)が 0にリセットされてしまうため。

                    isOnIce = (collision == TileCollision.Ice || collision == TileCollision.Passable);// 121107追加

isOnIce とは TileCollision.Ice (氷の上にいるとき)、または TileCollision.Passable (空中にいるとき)、 という意味になる。 TileCollision.Passable は要らないようにも思えるが、氷の端で勝手に止まってしまわないようにするために必要。

IcePlatform.png

はねるタイル

バネのタイルを描く。

BlockJ0.png

Tile.cs で Jump というタイルを増やす。

        Jump = 5, // 121107 追加

Level.cs でバネのテクスチャを読み込む。

                case 'J':
                    return LoadVarietyTile("BlockJ", 1, TileCollision.Jump);// 121107

Player.cs で 上方向(Y < 0)の速度の範囲を広げる。

Class Player { の直後に

        const float SpringFactor = 2.0f;

という定数宣言を加える。const というのは定数なので、宣言した後で値を変更できません、という意味。 float というのは浮動小数点 (整数ではなく、小数点より細かな値も表せる) で、 数値の後ろに f を付ける。XNAでは良く使われる。 2.0f というのはバネの上では(だいたい)2倍の速度で跳ねる、ということ。

ApplyPhysicsメソッドの中の

            velocity.Y = MathHelper.Clamp(velocity.Y + GravityAcceleration * elapsed, -MaxFallSpeed, MaxFallSpeed);

            velocity.Y = MathHelper.Clamp(velocity.Y + GravityAcceleration * elapsed, - SpringFactor * MaxFallSpeed, MaxFallSpeed);

に変更。 velocity.Y とは Y方向の速度。 Y方向にあまり速く動かないように制限している部分だが、より高く飛ぶために上方向だけ速度の範囲を広げる。

バネの上に乗ったらジャンプする(上方向の速度を増やす)。

                    if (collision == TileCollision.Jump) // 121107
                    {
                        velocity.Y = JumpLaunchVelocity * SpringFactor;
                        continue;
                    }

JumpLaunchVelocity はジャンプするときの Y方向の初速度である。

JumpPlatform.png

宝石を取ると通れるようになるタイル

ドアのテクスチャを描く。

BlockD0.png

Tile.cs で Door というタイルを追加する。

        Door = 6, // 121107 追加

Level.cs でドアのテクスチャを読み込む。

                case 'd':
                    return LoadVarietyTile("BlockD", 1, TileCollision.Door);// 121107

Level.cs の class Level : IDisposable { の直後に(: IDisposable の意味は今は知らなくてもよい)

        public bool isLocked = true;// 121107

という変数宣言を追加する。 isLocked というフラグはドアがロックされているかどうかというフラグ。 最初はロックされている。 public というのは他のクラスからもこの変数が見えるようにするためのもの。 たとえば、Level というクラスの中からはこの変数は isLocked で参照できるが、 Player というクラスの中からは Level.isLocked で参照できる。

Tileという二次元の配列(マップのタイルの配置が格納されている)も private から public に変えておく(理由は後述)。

      public Tile[,] tiles; // 121107 private から public へ

ちなみに、private 宣言された変数はそのクラスの外から参照できない。 明示的に public 宣言しない変数(Player の isOnIceなど)は private になる(Java では明示的に宣言しない変数は public になる)。

宝石を取ったときにロックを解除するために、OnGemCollectedメソッドの中に

            isLocked = false;// 121107

を追加。

Player.cs いつもの衝突判定のあたり。

ドアがロックされていてば通れない(Impassable)。 そうでないときは通れる(Passable)。

                    if (collision == TileCollision.Door)
                    {
                        if (Level.isLocked)
                        {
                            collision = TileCollision.Impassable;
                        }
                        else
                        {
                            collision = TileCollision.Passable;
                            Level.tiles[x, y] = new Tile(null, TileCollision.Passable);// ドアを消す
                            Level.isLocked = true;// 再び鍵がかかった状態に
                        }
                    }

ドアとプレイヤーが接触したときに、ドアを通過可能にしたあと、ドアのテクスチャを null に、 TileCollision を Passable にしておく。 これでドアは以後描かれなくなる。

ドアは縦2個分のタイルを使うので、マップの中で上下二個のタイルのうちの上の方に配置する。 下に配置すると埋もれてしまう。

....................
............G.......
....................
....................
...........###......
....................
....................
....................
.........#J#........
....................
.....1..........E...
....###.......######
...............d....
..................X.
%%%IIII%%KKK%%######

DoorPlatform.png

ドアを複数作ることもできる。

##########..........
...d....d...........
.X..................
#####.####..........
.........#..........
.....A...#..###.....
..########..........
..#.................
G.#.................
###......#J#........
...............GE...
....###.......######
....#...............
.1..#...............
#####KKKKKKKKKKKKKKK

Platformer dangeon.png

課題

宝石を取ると乗れるようになるタイルを作ってみる。

たとえば、Magical というタイルを作る。 isEnabled というフラグ(bool) を作り、最初は false にしておく。 宝石を取る前(Level.isEnabled == false)はPassableにして、 取った後(Level.isEnabled == true)はImpassableにする。

InvisiblePlatform.png

追記

Enemy.cs もしくは Rider.cs の 137行目あたりに

                if (Level.GetCollision(tileX + (int)direction, tileY - 1) == TileCollision.Impassable ||
                    Level.GetCollision(tileX + (int)direction, tileY - 2) == TileCollision.Door || // 121107
                    Level.GetCollision(tileX + (int)direction, tileY) == TileCollision.Passable)
                {
                    waitTime = MaxWaitTime;
                }
                else
                {
                    // Move in the current direction.
                    Vector2 velocity = new Vector2((int)direction * MoveSpeed * elapsed, 0.0f);
                    position = position + velocity;
                }

と一行追加するとEnemyもRiderもDoorを通過できなくなります。


東京工芸大学 芸術学部 インタラクティブメディア学科 nagaelab