Sprite
2007年07月27日
【講座004】書き加えたコードの意味
まず、最初に加えたインスタンス変数たちを紹介します。
Texture2D myTexture;
SpriteBatch spriteBatch;
Vector2 spritePosition = Vector2.Zero;
Vector2 spriteSpeed = new Vector2(50.0f, 50.0f);
はじめに、Texure2Dというクラスは何か、ということを説明します。このクラスは、グラフィックチップが読み書きできる平面グリッド、を意味していまして、簡単に言うと、画面の上に貼る透明な板だと思った方がいいです。
昔々にMSXとか、ファミコンベーシックでプログラムを組んだことがある方はSPRITE関数なんてのがあって、背景画像の上にスプライトでキャラクタを動かして、あれやこれやと、ゲームを作ったりしていたと思うのですが、サイズが自由に設定できる透明な板(スプライト)と考えるのが、理解しやすいと思います。
で、このクラスへのインスタンス変数をmyTextureという名前にしたわけですが、お気づきの方もいらっしゃると思いますが、複数の絵を動かしたい場合などには、このインスタンス変数を必要な分だけ定義しなければならない、ということですね。
プログラムの中を読み取るときには、先に一気に読み取ってしまった方がわかりやすいときもあるので、このmyTextureが、どう使われているのか、もうちょっと見てみましょう。
LoadGraphicsContentメソッドの中では、絵を読み込ましています。
myTexture = content.Load<Texture2D>("face");
という形ですね。この、content.Loadというのは、右側のソリューションエクスプローラで一覧されている、様々なデータと、ひも付けを行うメソッドです。ですから、今回はTexture2Dクラスのデータを読み込むよ、ってことで<>内に、Texture2Dと書いてありまして、その後、ファイル名(拡張子無し)を設定します。
Drawメソッドの中では、実際に絵を描くのに、次のようなコードを使っています。
spriteBatch.Draw(myTexture, spritePosition, Color.White);
このような形で使われるわけです。
さて、次は、SpriteBatchです。これは、GraphicsDeviceへスプライトのグループを描画し表示させるクラスです。習うより慣れろってこともありますから、このクラスについては、今は「おまじない」だと思って使っていた方がいいでしょう。後の回で、いろいろと実験をしてみたいと思います。
ちなみに、このインスタンス変数 spriteBatchは、LoadGraphicsContentメソッドの中で、
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
とgraphics.GraphicsDeviceとのやりとりでインスタンスを作るときに使われ、Drawメソッドの中で、
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();
と使われて、さっきのmyTextureを使って、絵を描いています。ここのspritePositionというのは、どこに表示するのか、を意味していますが、
spritePositionとspriteSpeedは、Vector2の変数として宣言されています。
2次元の座標を表すのに、このクラスを用いるのがC#っぽいところ。C言語などでも構造体とかで、座標を表したりもしましたので、プログラミングをやっている人にはわかりやすいかも。ところで、2次元の座標はX軸とY軸でできていて、画面の左上が(X,Y)=(0,0)で、右に行くほどXの値が大きくなり、下に行くほどYの値がおおきくなります。
そこで、spritePositionには当初(0,0)を設定し、spriteSpeedには当初(50.0, 50.0)を設定する、と書かれています。「50.0f」っていう風に最後に「f」が付いていない?と思われるかもしれません。これは、この「50.0」という値がfloat型なんだよってことを意味しています。単に「50.0」と書いてビルドしてみるとわかりますが、50.0と表示すると、それはdouble型であることになってしまい、ビルドエラーになってしまいます。
なんだか、よく分らない気持ちになるかもしれません。こういうところで、よく分らないからプログラム嫌いってなっちゃう人も多くて、すごく残念なんですが、私ははっきりと言い切っておきます。「こんなこと、気にせず先に進んでください」と。いろいろな本で「型」の考え方が大切だ、とかいろいろ書いてあるかもしれませんが、それが理解できるようになるのは、結構先ですし、ある種、専門的にコンピュータ数値解析のことをやらないとわかりません。いろいろなプログラミング言語で特徴がありますが、C#(C言語系,Javaも)特有の問題ですから、深く悩まず、こういうエラーにぶつかったら、「あ、f、付け忘れちゃった」くらいの気持ちで進んでください。
今回も長くなってきたので、これでおしまい。次回は、動かしている部分のコードを読み取っていきましょう。
Texture2D myTexture;
SpriteBatch spriteBatch;
Vector2 spritePosition = Vector2.Zero;
Vector2 spriteSpeed = new Vector2(50.0f, 50.0f);
はじめに、Texure2Dというクラスは何か、ということを説明します。このクラスは、グラフィックチップが読み書きできる平面グリッド、を意味していまして、簡単に言うと、画面の上に貼る透明な板だと思った方がいいです。
昔々にMSXとか、ファミコンベーシックでプログラムを組んだことがある方はSPRITE関数なんてのがあって、背景画像の上にスプライトでキャラクタを動かして、あれやこれやと、ゲームを作ったりしていたと思うのですが、サイズが自由に設定できる透明な板(スプライト)と考えるのが、理解しやすいと思います。
で、このクラスへのインスタンス変数をmyTextureという名前にしたわけですが、お気づきの方もいらっしゃると思いますが、複数の絵を動かしたい場合などには、このインスタンス変数を必要な分だけ定義しなければならない、ということですね。
プログラムの中を読み取るときには、先に一気に読み取ってしまった方がわかりやすいときもあるので、このmyTextureが、どう使われているのか、もうちょっと見てみましょう。
LoadGraphicsContentメソッドの中では、絵を読み込ましています。
myTexture = content.Load<Texture2D>("face");
という形ですね。この、content.Loadというのは、右側のソリューションエクスプローラで一覧されている、様々なデータと、ひも付けを行うメソッドです。ですから、今回はTexture2Dクラスのデータを読み込むよ、ってことで<>内に、Texture2Dと書いてありまして、その後、ファイル名(拡張子無し)を設定します。
Drawメソッドの中では、実際に絵を描くのに、次のようなコードを使っています。
spriteBatch.Draw(myTexture, spritePosition, Color.White);
このような形で使われるわけです。
さて、次は、SpriteBatchです。これは、GraphicsDeviceへスプライトのグループを描画し表示させるクラスです。習うより慣れろってこともありますから、このクラスについては、今は「おまじない」だと思って使っていた方がいいでしょう。後の回で、いろいろと実験をしてみたいと思います。
ちなみに、このインスタンス変数 spriteBatchは、LoadGraphicsContentメソッドの中で、
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
とgraphics.GraphicsDeviceとのやりとりでインスタンスを作るときに使われ、Drawメソッドの中で、
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();
と使われて、さっきのmyTextureを使って、絵を描いています。ここのspritePositionというのは、どこに表示するのか、を意味していますが、
spritePositionとspriteSpeedは、Vector2の変数として宣言されています。
2次元の座標を表すのに、このクラスを用いるのがC#っぽいところ。C言語などでも構造体とかで、座標を表したりもしましたので、プログラミングをやっている人にはわかりやすいかも。ところで、2次元の座標はX軸とY軸でできていて、画面の左上が(X,Y)=(0,0)で、右に行くほどXの値が大きくなり、下に行くほどYの値がおおきくなります。
そこで、spritePositionには当初(0,0)を設定し、spriteSpeedには当初(50.0, 50.0)を設定する、と書かれています。「50.0f」っていう風に最後に「f」が付いていない?と思われるかもしれません。これは、この「50.0」という値がfloat型なんだよってことを意味しています。単に「50.0」と書いてビルドしてみるとわかりますが、50.0と表示すると、それはdouble型であることになってしまい、ビルドエラーになってしまいます。
なんだか、よく分らない気持ちになるかもしれません。こういうところで、よく分らないからプログラム嫌いってなっちゃう人も多くて、すごく残念なんですが、私ははっきりと言い切っておきます。「こんなこと、気にせず先に進んでください」と。いろいろな本で「型」の考え方が大切だ、とかいろいろ書いてあるかもしれませんが、それが理解できるようになるのは、結構先ですし、ある種、専門的にコンピュータ数値解析のことをやらないとわかりません。いろいろなプログラミング言語で特徴がありますが、C#(C言語系,Javaも)特有の問題ですから、深く悩まず、こういうエラーにぶつかったら、「あ、f、付け忘れちゃった」くらいの気持ちで進んでください。
今回も長くなってきたので、これでおしまい。次回は、動かしている部分のコードを読み取っていきましょう。
2007年07月26日
【講座003】貼った絵を動かしてみる
今日は、Help「Your First Game: Microsoft XNA Game Studio Express in
2D」のStep 5に進んでみます。
予告したとおり、Step 5は貼った絵を動かすプログラムです。
今回は「Update」のところに、まず次の「赤字」の部分を加えます。
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
UpdateSprite(gameTime);
base.Update(gameTime);
}
このUpdateSpriteというのは、自分で作るメソッドです。ですので、今度は、このメソッドを足さなければなりません。「Draw」の下に書き加えましょう。あくまで書き加えるところが「赤字」ですよ。
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
void UpdateSprite(GameTime gameTime)
{
// Move the sprite by speed, scaled by elapsed time.
spritePosition += spriteSpeed *
(float)gameTime.ElapsedGameTime.TotalSeconds;
int MaxX = graphics.GraphicsDevice.Viewport.Width -
myTexture.Width;
int MinX = 0;
int MaxY = graphics.GraphicsDevice.Viewport.Height -
myTexture.Height;
int MinY = 0;
// Check for bounce.
if (spritePosition.X > MaxX)
{
spriteSpeed.X *= -1;
spritePosition.X = MaxX;
}
else if (spritePosition.X < MinX)
{
spriteSpeed.X *= -1;
spritePosition.X = MinX;
}
if (spritePosition.Y > MaxY)
{
spriteSpeed.Y *= -1;
spritePosition.Y = MaxY;
}
else if (spritePosition.Y < MinY)
{
spriteSpeed.Y *= -1;
spritePosition.Y = MinY;
}
}
これでOKです。さて、どうなるでしょうか? いつも[F5]なので、本来のビルドの仕方、[F6]を押しましょう。これでビルドが行われて、「ビルド正常終了」となったら、[F5]で実行(本当はデバッグ開始)です。
動き始めましたよね。Step 6は、この先はいろいろな改造方法があるよっていう話が書かれていますので、ここでは直接内容には触れませんが、実際、これを使って、いろいろとやってみたいなぁと考えています。
次回は、とりあえず、改造する前に、それぞれのプログラムコードが、何を意味しているのか、詳細に分析して行こうと思います。
予告したとおり、Step 5は貼った絵を動かすプログラムです。
今回は「Update」のところに、まず次の「赤字」の部分を加えます。
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
UpdateSprite(gameTime);
base.Update(gameTime);
}
このUpdateSpriteというのは、自分で作るメソッドです。ですので、今度は、このメソッドを足さなければなりません。「Draw」の下に書き加えましょう。あくまで書き加えるところが「赤字」ですよ。
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
void UpdateSprite(GameTime gameTime)
{
// Move the sprite by speed, scaled by elapsed time.
spritePosition += spriteSpeed *
(float)gameTime.ElapsedGameTime.TotalSeconds;
int MaxX = graphics.GraphicsDevice.Viewport.Width -
myTexture.Width;
int MinX = 0;
int MaxY = graphics.GraphicsDevice.Viewport.Height -
myTexture.Height;
int MinY = 0;
// Check for bounce.
if (spritePosition.X > MaxX)
{
spriteSpeed.X *= -1;
spritePosition.X = MaxX;
}
else if (spritePosition.X < MinX)
{
spriteSpeed.X *= -1;
spritePosition.X = MinX;
}
if (spritePosition.Y > MaxY)
{
spriteSpeed.Y *= -1;
spritePosition.Y = MaxY;
}
else if (spritePosition.Y < MinY)
{
spriteSpeed.Y *= -1;
spritePosition.Y = MinY;
}
}
これでOKです。さて、どうなるでしょうか? いつも[F5]なので、本来のビルドの仕方、[F6]を押しましょう。これでビルドが行われて、「ビルド正常終了」となったら、[F5]で実行(本当はデバッグ開始)です。
動き始めましたよね。Step 6は、この先はいろいろな改造方法があるよっていう話が書かれていますので、ここでは直接内容には触れませんが、実際、これを使って、いろいろとやってみたいなぁと考えています。
次回は、とりあえず、改造する前に、それぞれのプログラムコードが、何を意味しているのか、詳細に分析して行こうと思います。
2007年07月25日
【講座002】スプライトを動かす
では、昨日に続いて、Helpに書いてあった先に進んでみたいと思います。
英語の和約ばかりしていても仕方がないので、要約します。
Step 4
まず、小さな画像ファイル(.bmp でも .jpg でも、.png でもいいけど)を用意しましょう。あとで、これが動きますので、だいたい100×100ピクセルサイズから、300×300ピクセルサイズの間がいいでしょうね。別に正方形でなくてもかまいません。
僕は、こんな絵をペイントで書きました。ファイル名は「face.png」です。
そのあと、Visual C#の画面の右側にある、「ソリューションエクスプローラ」のところで、右クリックして、[追加]→[既存の項目]を選択します。
そうすると、「既存項目の追加」というファイル選択ウィンドウが開きます。最初に一番下の「ファイルの種類」を「すべてのファイル (*.*)」にしてしまった方が便利かもしれません。なぜだかよく分りませんが、JPEG画像は.jpeが拡張子に設定されているみたいで、非常に使いづらいので。
僕はここで、ペイントでさっき作った「face.png」を選択しました。
これで、Visual C#のこのプロジェクトで、この画像ファイルを利用できるようになりました。
そうしたら、プログラムを書いていきましょう。
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
ContentManager content;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
}
と書かれている部分があります。この、「ContentManager content;」と、「public Game1()」の間に次の項目を入れます。
Texture2D myTexture;
SpriteBatch spriteBatch;
Vector2 spritePosition = Vector2.Zero;
Vector2 spriteSpeed = new Vector2(50.0f, 50.0f);
あとで、詳しい説明をすることにして、とりあえず先に進みます。
今度は、さっき折りたたんだ中で、「LoadGraphicsContent」のところを開きなおして、中身を次のようにします。ちなみに書き加えるところは「赤く」しておきました。
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
// TODO: Load any ResourceManagementMode.Automatic content
myTexture = content.Load<Texture2D>("face");
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
}
// TODO: Load any ResourceManagementMode.Manual content
}
ちなみに、この中で、「face」と書かれたところがあります。僕は、さっきペイントで「face.png」というのを作って、ソリューションエクスプローラに入れたわけですが、この拡張子の部分を取って、「face」となっています。作った画像が「body.jpg」であれば、ここは「body」になりますし、「ball.bmp」であれば、「ball」になります。
さて、この後は、折りたたまれた「Draw」を書き換えます。さっきと同じように書き加えるところは「赤字」にしています。
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
さぁ、これで、もう実行は可能です。[F5]キーを押して、ビルド&実行をしてみましょう。
左上の方に、さっき作った画像が貼られています。とりあえず、Step 4では、ここまでです。終わりにする時にはウィンドウ右上の×ボタンを押しましょう。(XBOXのゲームパッドがUSBで接続されているときは、Backボタンを押してもプログラムは終了します。)
今日のところはここまで。次は、当然ながら、この絵を動かすってことをやってみたいと思います。
英語の和約ばかりしていても仕方がないので、要約します。
Step 4
まず、小さな画像ファイル(.bmp でも .jpg でも、.png でもいいけど)を用意しましょう。あとで、これが動きますので、だいたい100×100ピクセルサイズから、300×300ピクセルサイズの間がいいでしょうね。別に正方形でなくてもかまいません。
僕は、こんな絵をペイントで書きました。ファイル名は「face.png」です。
そのあと、Visual C#の画面の右側にある、「ソリューションエクスプローラ」のところで、右クリックして、[追加]→[既存の項目]を選択します。
そうすると、「既存項目の追加」というファイル選択ウィンドウが開きます。最初に一番下の「ファイルの種類」を「すべてのファイル (*.*)」にしてしまった方が便利かもしれません。なぜだかよく分りませんが、JPEG画像は.jpeが拡張子に設定されているみたいで、非常に使いづらいので。
僕はここで、ペイントでさっき作った「face.png」を選択しました。
これで、Visual C#のこのプロジェクトで、この画像ファイルを利用できるようになりました。
そうしたら、プログラムを書いていきましょう。
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
ContentManager content;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
content = new ContentManager(Services);
}
と書かれている部分があります。この、「ContentManager content;」と、「public Game1()」の間に次の項目を入れます。
Texture2D myTexture;
SpriteBatch spriteBatch;
Vector2 spritePosition = Vector2.Zero;
Vector2 spriteSpeed = new Vector2(50.0f, 50.0f);
あとで、詳しい説明をすることにして、とりあえず先に進みます。
今度は、さっき折りたたんだ中で、「LoadGraphicsContent」のところを開きなおして、中身を次のようにします。ちなみに書き加えるところは「赤く」しておきました。
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
// TODO: Load any ResourceManagementMode.Automatic content
myTexture = content.Load<Texture2D>("face");
spriteBatch = new SpriteBatch(graphics.GraphicsDevice);
}
// TODO: Load any ResourceManagementMode.Manual content
}
ちなみに、この中で、「face」と書かれたところがあります。僕は、さっきペイントで「face.png」というのを作って、ソリューションエクスプローラに入れたわけですが、この拡張子の部分を取って、「face」となっています。作った画像が「body.jpg」であれば、ここは「body」になりますし、「ball.bmp」であれば、「ball」になります。
さて、この後は、折りたたまれた「Draw」を書き換えます。さっきと同じように書き加えるところは「赤字」にしています。
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// TODO: Add your drawing code here
spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
spriteBatch.Draw(myTexture, spritePosition, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
さぁ、これで、もう実行は可能です。[F5]キーを押して、ビルド&実行をしてみましょう。
左上の方に、さっき作った画像が貼られています。とりあえず、Step 4では、ここまでです。終わりにする時にはウィンドウ右上の×ボタンを押しましょう。(XBOXのゲームパッドがUSBで接続されているときは、Backボタンを押してもプログラムは終了します。)
今日のところはここまで。次は、当然ながら、この絵を動かすってことをやってみたいと思います。