1
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace WindowsGame3
{
    public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Texture2D ship, bullet, alien;

    Texture2D[] aliens = new Texture2D[20];
    Texture2D[] bullets = new Texture2D[10];

    Vector2 shipPos = new Vector2(200, 540);
    Vector2 alienPos = new Vector2(200, 400);
    Vector2 bulletPos = new Vector2(200, 450);

    Vector2[] aliensPos = new Vector2[20];
    Vector2[] bulletsPos = new Vector2[10];

    int alienCount = 0;
    int bulletCount = 0;

    KeyboardState state = Keyboard.GetState();

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";

        graphics.PreferredBackBufferWidth = 400;
        graphics.PreferredBackBufferHeight = 600;
    }

    protected override void Initialize()
    {
        base.Initialize();
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);

        alien = Content.Load<Texture2D>("alien");
        ship = Content.Load<Texture2D>("ship");

        for (int x = 0; x < 5; x++)
        {
            for (int y = 0; y < 4; y++)
            {
                aliens[alienCount] = Content.Load<Texture2D>("alien");
                aliensPos[alienCount].X = 100 + (x * 40);
                aliensPos[alienCount].Y = 20 + (y * 40);
                alienCount++;
            }  
        }
    }

    protected override void UnloadContent()
    {

    }

    protected override void Update(GameTime gameTime)
    {
        if (state.IsKeyDown(Keys.Right) && shipPos.X < 360)
        {
            shipPos.X += 5;
        }

        if (state.IsKeyDown(Keys.Left) && shipPos.X > 0)
        {
            shipPos.X -= 5;
        }

        if (state.IsKeyDown(Keys.Space))
        {
                bullets[bulletCount] = Content.Load<Texture2D>("bullet");
                bulletsPos[bulletCount].X = shipPos.X;
                bulletsPos[bulletCount].Y = shipPos.Y;
                bulletCount++;
        }

        base.Update(gameTime);
    }

    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Black);

        spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

        spriteBatch.Draw(ship, shipPos, Color.White);
        spriteBatch.Draw(alien, alienPos, Color.White);

        for (int alienCount = 0; alienCount < 20; alienCount++)
        {
            spriteBatch.Draw(aliens[alienCount], aliensPos[alienCount], Color.White);
        }

        for (int bulletCount = 0; bulletCount < 10; bulletCount++)
        {
            spriteBatch.Draw(bullets[bulletCount], bulletsPos[bulletCount], Color.White);
        }

        spriteBatch.End();
        base.Draw(gameTime);
    }
}
}

船の位置に弾丸を作成し、その弾丸を配列に格納したいのですが、描画メソッドで配列から弾丸を描画すると、エラーメッセージが表示されます このメソッドは、このパラメーターに null を受け入れません。パラメータ名:テクスチャ

4

2 に答える 2

3

XNAでは、必要になる前にすべてのリソースをロードすることをお勧めします。これは、LoadContent()メソッドの目的です。そこに弾丸テクスチャをロードし、必要に応じてUpdate()で使用する必要があります。

何度も描画したい場合でも、画像ごとに必要なTexture2Dオブジェクトは1つだけです。まったく同じ画像でいっぱいのTexture2D配列は必要ありません。

だから、あなたの例のために:

protected override void LoadContent()
{
    spriteBatch = new SpriteBatch(GraphicsDevice);

    alien = Content.Load<Texture2D>("alien"); //only one texture needed
    ship = Content.Load<Texture2D>("ship");
    bullet = Content.Load<Texture2D>("bullet"); //only one texture needed

    //set initial positions as before
    for (int x = 0; x < 5; x++)
    {
        for (int y = 0; y < 4; y++)
        {
            aliensPos[alienCount].X = 100 + (x * 40);
            aliensPos[alienCount].Y = 20 + (y * 40);
            alienCount++;
        }  
    }
}

新しいエイリアンや弾丸を作りたいときは、画像がすでにロードされているので、それらの位置を設定するだけです。

if (state.IsKeyDown(Keys.Space))
{
        bulletsPos[bulletCount].X = shipPos.X;
        bulletsPos[bulletCount].Y = shipPos.Y;
        bulletCount++;
}

次に、すべてのテクスチャをロードして準備ができたら、次のように描画できます。

protected override void Draw(GameTime gameTime)
{
    GraphicsDevice.Clear(Color.Black);

    spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend);

    spriteBatch.Draw(ship, shipPos, Color.White);

    for (int alienCount = 0; alienCount < 20; alienCount++)
    {
        //draw alien texture for every aliensPos
        spriteBatch.Draw(alien, aliensPos[alienCount], Color.White);
    }

    for (int bulletCount = 0; bulletCount < 10; bulletCount++)
    {
        //draw bullet texture for every bulletsPos
        spriteBatch.Draw(bullet, bulletsPos[bulletCount], Color.White);
    }

    spriteBatch.End();
    base.Draw(gameTime);
}

そして最後に、船を動かすには、フレームごとにキーボードを読む必要があります。Keyboard.GetState()を呼び出すのは1回だけです。読むと、現在押されているキーが返されるので、フレームごとに更新する必要があります。

Update()メソッドの最初にこれを追加する必要があります。

state = Keyboard.GetState();
于 2012-10-31T10:18:58.457 に答える
0

それは、弾丸を作る前に弾丸を描こうとしているからです。解決策は、弾丸を作成する前に弾丸を描画しないことです。

これを行う方法はいくつもありますが、最も速くて汚い方法を次に示します。

変化する

    for (int bulletCount = 0; bulletCount < 10; bulletCount++)
    {
        spriteBatch.Draw(bullets[bulletCount], bulletsPos[bulletCount], Color.White);
    }

    for (int bulletCount = 0; bulletCount < 10; bulletCount++)
    {
        if(bullets[bulletCount] != null)
            spriteBatch.Draw(bullets[bulletCount], bulletsPos[bulletCount], Color.White);
    }
于 2012-10-30T20:20:18.090 に答える