繁体   English   中英

XNA soundEffect在主类中加载并在另一个类中调用时为null

[英]XNA soundEffect is null in when loaded in main class and called in another class

我已经将声音效果文件加载到xna的主类中,但是当我尝试在另一个类中运行它时,出现此错误

{“你调用的对象是空的。”}

我是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 BreakingOut
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Ball ball;
    Paddle paddle;
    Rectangle screenRectangle;
    bool is1P = true;

    int lives = 3;

    Texture2D startButtonTexture;
    Vector2 buttonVec;

    Texture2D exitButtonTexture;
    Vector2 button2Vec;

    int bricksWide = 10;
    int bricksHigh = 7;
    Texture2D brickImage;
    Brick[,] bricks;

    //rec for menu
    Texture2D menuTexture;
    Rectangle menuRec = new Rectangle(0, 0, 960, 640);
    //rec for pause
    Texture2D pauseTexture;
    Rectangle pauseRec = new Rectangle(0, 0, 960, 640);
    //lose
    Texture2D loseTexture;
    Rectangle loseRec = new Rectangle(0, 0, 960, 640);

    Texture2D winTexture;
    Rectangle winRec = new Rectangle(0, 0, 960, 640);

    //sound effects
    public  SoundEffect BallHitSE;
    SoundEffect WallHitSE;
    SoundEffect StartSE;
    //BGM
    Song menuMusic;
    Song gameMusic;

    bool isGameMusicPlaying = false;
    bool isMenuMusicPlaying = false;

    float pauseTimer;
    float exitTimer;
    float muteTimer;
    float SEmuteTimer;

    //public int brickCount = 70;

    SpriteFont font;

    Vector2 mousePos;

    enum gameStates
    {
        MENU,
        GAME1P,
        LOSE,
        PAUSE,
        WIN,
    }

    gameStates currentState = gameStates.MENU;
    gameStates prevState = gameStates.MENU;

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

        IsMouseVisible = true;

        graphics.PreferredBackBufferWidth = 960;
        graphics.PreferredBackBufferHeight = 640;

        screenRectangle = new Rectangle(
            0,
            0,
            graphics.PreferredBackBufferWidth,
            graphics.PreferredBackBufferHeight);
    }

    /// <summary>
    /// Allows the game to perform any initialization it needs to before starting to run.
    /// This is where it can query for any required services and load any non-graphic
    /// related content.  Calling base.Initialize will enumerate through any components
    /// and initialize them as well.
    /// </summary>
    protected override void Initialize()
    {
        // TODO: Add your initialization logic here

        base.Initialize();
    }

    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);

        Texture2D tempTexture = Content.Load<Texture2D>("paddle");
        paddle = new Paddle(tempTexture, screenRectangle);

        BallHitSE = Content.Load<SoundEffect>("BallHit");
        WallHitSE = Content.Load<SoundEffect>("WallHit2");
        StartSE = Content.Load<SoundEffect>("Start");
        gameMusic = Content.Load<Song>("gameMusic");
        menuMusic = Content.Load<Song>("menuMusic");

这是球课

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace BreakingOut
{
class Ball
{
    Vector2 motion;
    Vector2 position;
    Rectangle bounds;
    bool collided;

    public int brickCount = 70;

    const float ballStartSpeed = 6.4f;
    public float ballSpeed;

    Texture2D texture;
    Rectangle screenBounds;


    SoundEffect BallHitSE;
    //BallHitSE = new SoundEffect

    public Rectangle Bounds
    {
        get 
        {
            bounds.X = (int)position.X;
            bounds.Y = (int)position.Y;
            return bounds;
        }
    }

    public Ball(Texture2D texture, Rectangle screenBounds)
    {
        bounds = new Rectangle(0, 0, texture.Width, texture.Height);
        this.texture = texture;
        this.screenBounds = screenBounds;
        //Different things we tried
        //BallHitSE = Content.Load<SoundEffect>("BallHit");
        //BallHitSE =  new soundeffect(what goes in here?);
        //BallHitSE = Content.Manager.Load("path")

    }

    public void Update()
    {
        collided = false;
        position += motion * ballSpeed;
        ballSpeed += 0.001f;

        CheckWallCollision();
    }

    public void CheckWallCollision()
    {
        if (position.X < 0)
        {
            position.X = 0;
            motion.X *= -1;
            //if (BallHitSE != null)
            //{
                BallHitSE.Play();
            //}
        }
        if (position.X + texture.Width > screenBounds.Width)
        {
            position.X = screenBounds.Width - texture.Width;
            motion.X *= -1;
            //if (BallHitSE != null)
            //{
                BallHitSE.Play();
            //}
        }
        if (position.Y < 0)
        {
            position.Y = 0;
            motion.Y *= -1;
            //if (BallHitSE != null)
            //{
                BallHitSE.Play();
            //}
        }
    }

    public void SetInStartPosition(Rectangle paddleLocation)
    {
        Random rand = new Random();

        motion = new Vector2(rand.Next(2, 6), -rand.Next(2, 6));
        motion.Normalize();

        ballSpeed = ballStartSpeed;

        position.Y = paddleLocation.Y - texture.Height;
        position.X = paddleLocation.X + (paddleLocation.Width - texture.Width) / 2;
    }

    public bool OffBottom()
    {
        if (position.Y > screenBounds.Height)
            return true;
        return false;
    }

    public void PaddleCollision(Rectangle paddleLocation)
    {
        Rectangle ballLocation = new Rectangle(
            (int)position.X,
            (int)position.Y,
            texture.Width,
            texture.Height);

        if (paddleLocation.Intersects(ballLocation))
        {
            position.Y = paddleLocation.Y - texture.Height;
            motion.Y *= -1;
        }
    }

    public void Deflection(Brick brick)
    {
        if (!collided)
        {
            motion.Y *= -1;
            collided = true;
            brickCount -= 1;
        }
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(texture, position, Color.White);
        for (int i = 1; i < 10; i++)
        {
            var drawPosition = position - (i * motion * 3);
            var colour = Color.Lerp(Color.White, Color.Transparent, i * (20 / 100f));
            spriteBatch.Draw(texture, drawPosition, colour);
        }
    }
}
}

XNA类与常规类没有什么不同,请不要让它们欺骗您!

看来您只需要将两个部分设置为彼此相等即可。

在球类中:

public Ball(Texture2D texture, Rectangle screenBounds, SoundEffect ballHit/*NEW*/)
{
    this.BallHitSE = ballHit;// NEW

    bounds = new Rectangle(0, 0, texture.Width, texture.Height);
    this.texture = texture;
    this.screenBounds = screenBounds;
    //Different things we tried
    //BallHitSE = Content.Load<SoundEffect>("BallHit");
    //BallHitSE =  new soundeffect(what goes in here?);
    //BallHitSE = Content.Manager.Load("path")

}

然后将声音效果添加到构造函数中:

 Ball ball = new Ball(texture, bounds, BallHitSE);

如果在Ball类中使用这些SoundEffect ,则应将其加载到Ball类的LoadContent中,而不是在主类中。
这就是为什么当您尝试运行一个错误时会收到该错误的原因,它们在另一个类中初始化并且仍然为空。

当然,如果您必须在Ball类中加载某些内容,则需要传递ContentManager ,或使Ball类继承自GameComponentDrawableGameComponent ,以便以这种方式加载声音效果:

BallHitSE = Game.Content.Load<SoundEffect>("BallHit");
WallHitSE = Game.Content.Load<SoundEffect>("WallHit2");

编辑

通常,我以这种方式管理音频:

public class AudioComponent : GameComponent
{
    public enum LevelEffect { BadCollision, GoodCollision, PopUp }
    public enum GameMusic { GameWin, GameLose, GameStart }

    private Song winSound, loseSound, startSound;
    private SoundEffect badCollSound, goodCollSound, popUp;

    public AudioComponent()
    {
    }


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


    public void loadAudio(
        Song winSound,
        Song loseSound,
        Song startSound,
        SoundEffect badCollSound,
        SoundEffect goodCollSound,
        SoundEffect popUp
        )
    {
        this.winSound = winSound;
        this.loseSound = loseSound;
        this.startSound = startSound;
        this.badCollSound = badCollSound;
        this.goodCollSound = goodCollSound;
        this.popUp = popUp;
    }


    public void PlayGameMusic(GameMusic effType)
    {
        switch (effType)
        {
            case GameMusic.GameWin:
                PlayMusic(winSound);
                break;
            case GameMusic.GameLose:
                PlayMusic(loseSound);
                break;
            case GameMusic.GameStart:
                PlayMusicRepeat(startSound);
                break;
        }
    }


    public void PlayLevelEffect(LevelEffect effType)
    {
        switch (effType)
        {
            case GameMusic.BadCollision:
                PlayEffect(badCollSound);
                break;
            case GameMusic.GoodCollision:
                PlayEffect(goodCollSound);
                break;
            case GameMusic.PopUp:
                PlayEffect(popUp);
                break;
        }
    }


    public void PlayEffect(SoundEffect sound)
    {
        sound.Play();
    }


    public bool CheckAlreadyPlayingMusic()
    {
        return MediaPlayer.State == MediaState.Playing;
    }


    public void PlayMusic(Song song)
    {
        MediaPlayer.Play(song);
        MediaPlayer.IsRepeating = false;
    }


    public void PlayMusicRepeat(Song song)
    {
        MediaPlayer.Play(song);
        MediaPlayer.IsRepeating = true;
    }


    public void StopMusic()
    {
        MediaPlayer.Stop();
    }


    public void PauseMusic()
    {
        MediaPlayer.Pause();
    }


    public void ResumeMusic()
    {
        MediaPlayer.Resume();
    }


    public void ChangeVolume(float volume)
    {
        MediaPlayer.Volume = volume;
    }
}

用户Kai Hartmann轻松轻松地解决了此问题

确保在LoadContent()之前实例化Ball。

然后交换这条线

BallHitSE = Content.Load(“ BallHit”); 有了这个

Ball.BallHitSE = Content.Load(“ BallHit”); 并将Ball类中的变量更改为此

公共静态SoundEffect BallHitSE;

https://gamedev.stackexchange.com/a/66184/36332

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM