xna方法不接受null

时间:2012-10-30 20:15:29

标签: c# xna

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。 参数名称:texture

2 个答案:

答案 0 :(得分:3)

在XNA中,最好在需要之前加载所有资源,这就是你拥有的LoadContent()方法。您应该在那里加载项目符号纹理,然后在必要时在Update()中使用它。

每个图像只需要一个Texture2D对象,即使您想要多次绘制它也是如此。 你不需要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()。当你读它时,它返回当前按下的键,所以你需要每帧刷新它。

你应该将它添加到Update()方法的开头:

state = Keyboard.GetState();

答案 1 :(得分: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);
    }