繁体   English   中英

C ++ DirectX11:使用DirectX工具包的NullPtr错误

[英]C++ DirectX11: NullPtr error using DirectX tool kit

我正在尝试为我的游戏实现字体类,并且在运行时不断出现以下错误

引发异常:写访问冲突。 这是nullptr。

在我的Font.cpp init函数中

void Font::Init(ID3D11Device* device, ID3D11DeviceContext* deviceContext)
{
    if (device != NULL && deviceContext != NULL)
    {
        m_spriteBatch = new SpriteBatch(deviceContext);//<----This line
        m_spriteFont = new SpriteFont(device, L"Fonts/Arial.spritefont");
    }
}

这是我的Font.h

#ifndef FONT_H
#define FONT_H


#include <d3d11.h>
#include <directxmath.h>
#include <fstream>
#include "SpriteBatch.h"
#include "SpriteFont.h"

using namespace std;
using namespace DirectX;

class Font
{

public:
    Font();
    ~Font();
    void Init(ID3D11Device* device, ID3D11DeviceContext* deviceContext);
    void Render();

private:
    SpriteFont* m_spriteFont;
    SpriteBatch* m_spriteBatch;
};

#endif

这是我的Font.cpp

#include "Font.h"
#include "SimpleMath.h"

Font::Font()
{
    m_spriteFont = NULL;
    m_spriteBatch = NULL;
}


Font::~Font()
{
    if (m_spriteFont)
    {
        delete m_spriteFont;
        m_spriteFont = NULL;

    }
    if (m_spriteBatch)
    {
        delete m_spriteBatch;
        m_spriteBatch = NULL;

    }
}
void Font::Init(ID3D11Device* device, ID3D11DeviceContext* deviceContext)
{
    if (device != NULL && deviceContext != NULL)
    {
        m_spriteBatch = new SpriteBatch(deviceContext);
        m_spriteFont = new SpriteFont(device, L"Fonts/Arial.spritefont");
    }
}
void Font::Render()
{
    m_spriteBatch->Begin();
    m_spriteFont->DrawString(m_spriteBatch, L"TEST", SimpleMath::Vector2(300, 300));
    m_spriteBatch->End();
}

这是我的GameScene.cpp

#include "GameScene.h"
#include "TextureShader.h"


GameScene::GameScene(void)
{
    prevtime = 0;
    collision = false;
    Sprite_Box_Height = 0;
    Sprite_Box_Width = 0;
}


GameScene::~GameScene(void)
{
    if(m_player)
    {
        delete m_player;
    }

    if (m_enemy)
    {
        delete m_enemy;
    }

    if (m_ball)
    {
        delete m_ball;
    }
    if (m_timer)
    {
        delete m_timer;
    }
}

bool GameScene::Initialize()
{
    TextureShader* shader = (TextureShader*)ResourceManager::GetInstance()->GetShaderByName("texture.fx");
    if(shader == NULL)
    {
        return false;
    }
    //create objects for all entities and initialize them
    m_ball = new Ball();
    m_ball->Initialize(Engine::GetEngine()->GetGraphics()->GetDevice(), Engine::GetEngine()->GetGraphics()->GetDeviceContext(), shader);
    m_player = new Player();
    m_player->Initialize(Engine::GetEngine()->GetGraphics()->GetDevice(), Engine::GetEngine()->GetGraphics()->GetDeviceContext(), shader);
    m_enemy = new Enemy();
    m_enemy->Initialize(Engine::GetEngine()->GetGraphics()->GetDevice(), Engine::GetEngine()->GetGraphics()->GetDeviceContext(), shader);
    m_font->Init(Engine::GetEngine()->GetGraphics()->GetDevice(), Engine::GetEngine()->GetGraphics()->GetDeviceContext());

    return true;
}

void GameScene::Update()
{
    //Updade all Entities collision
    m_player->Update();
    m_enemy->Update();
    m_ball->Update();
    Collision();
}

void GameScene::Render(ID3D11DeviceContext* deviceContext, XMFLOAT4X4 viewMatrix, XMFLOAT4X4 projectionMatrix)
{
    m_font->Render();
}
void GameScene::Collision()
{
    //Get the current position of the ball and the player
    BallPos = m_ball->GetBallPosition();
    PlayerPos = m_player->GetPlayerPosition();
    EnemyPos = m_enemy->GetPlayerPosition();
    BallVel = m_ball->GetBallVelocity();
    ballVelX = BallVel.m128_f32[0];
    ballVelY = BallVel.m128_f32[1];


    //Set the size of the sprite
    Sprite_Box_Height = 50;
    Sprite_Box_Width = 20;

    //if there is a collision between the ball and a paddle get the current time
    //and reverse the ball's velocity.
    if (m_collision)
    {
        float currentTime = m_timer->GetTime();
        //Wait for the ball to exit the area before setting collison back to false
        //to prevent the ball from getting stuck
        if (prevtime > currentTime - 100)
        {
            m_collision = true;
        }
        else
        {
            m_collision = false;
        }
    }
    else
    {
        //#################################################################//
        //set collision to true when the ball is in the area of the Paddle //
        //check if ball is in the player's x vecinity                      //
        //#################################################################//

        //check if ball has near the same position player's paddle
        if (BallPos.m128_f32[0] < PlayerPos.m128_f32[0] + Sprite_Box_Width && BallPos.m128_f32[0] > PlayerPos.m128_f32[0] - Sprite_Box_Width)
        {
            //check if ball hits the top of the player's paddle
            if (BallPos.m128_f32[1] < PlayerPos.m128_f32[1] + Sprite_Box_Height && BallPos.m128_f32[1] > PlayerPos.m128_f32[1] - Sprite_Box_Height)
            {
                prevtime = m_timer->GetTime();
                m_ball->SetBallVelocity(-ballVelX, ballVelY);
                m_collision = true;
            }
        }
        else if (BallPos.m128_f32[0] < PlayerPos.m128_f32[0] + Sprite_Box_Width && BallPos.m128_f32[0] > PlayerPos.m128_f32[0] - Sprite_Box_Width)
        {
            //check if ball is in the player's y vecinity
            if (BallPos.m128_f32[1] < PlayerPos.m128_f32[1] + Sprite_Box_Height && BallPos.m128_f32[1] > PlayerPos.m128_f32[1] - Sprite_Box_Height)
            {
                prevtime = m_timer->GetTime();
                m_ball->SetBallVelocity(-ballVelX, ballVelY);
                m_collision = true;
            }
        }

        else if (BallPos.m128_f32[0] < EnemyPos.m128_f32[0] + Sprite_Box_Width && BallPos.m128_f32[0] > EnemyPos.m128_f32[0] - Sprite_Box_Width)
        {
            //check if ball is in the player's y vecinity
            if (BallPos.m128_f32[1] < EnemyPos.m128_f32[1] + Sprite_Box_Height && BallPos.m128_f32[1] > EnemyPos.m128_f32[1] - Sprite_Box_Height)
            {
                prevtime = m_timer->GetTime();
                m_ball->SetBallVelocity(-ballVelX, ballVelY);
                m_collision = true;
            }
        }
        //###################################################################//
        //set collision to true when the ball hits the edge of the screen    //
        //by checking if ball's position is passed the edge and sets it back //
        //to  a position just inside the screen                              //
        //###################################################################//
        //if the ball hits the TOP edge of the screen change ball's velocity
        if (BallPos.m128_f32[1] > 300.0f)
        {
            prevtime = m_timer->GetTime();
            m_ball->SetBallVelocity(ballVelX, -ballVelY);
            m_collision = true;
        }
        //if the ball hits the BOTTOM edge of the screen change ball's velocity
        else if (BallPos.m128_f32[1] < -300.0f)
        {
            prevtime = m_timer->GetTime();
            m_ball->SetBallVelocity(ballVelX, -ballVelY);
            m_collision = true;
        }
        //if the ball hits the RIGHT edge of the screen change ball's velocity
        else if (BallPos.m128_f32[0] > 400.0f)
        {
            prevtime = m_timer->GetTime();
            m_ball->SetBallVelocity(-ballVelX, ballVelY);
            m_collision = true;
        }
        //if the ball hits the LEFT edge of the screen change ball's velocity
        else if (BallPos.m128_f32[0] < -400.0f)
        {
            prevtime = m_timer->GetTime();
            m_ball->SetBallVelocity(-ballVelX, ballVelY);
            m_collision = true;
        }
    }
}

提前谢谢你的帮助!!!

我建议在DirectX Tool Kit 教程中使用std::unique_ptr而不是原始指针的原因之一是它确实简化了代码。

// Font.h

#pragma once

#include <d3d11.h>
#include <directxmath.h>
#include <fstream>
#include <memory>
#include "SpriteBatch.h"
#include "SpriteFont.h"

class Font
{

public:
    Font() {}
    void Init(ID3D11Device* device, ID3D11DeviceContext* deviceContext);
    void Render();

private:
    std::unique_ptr<DirectX::SpriteFont> m_spriteFont;
    std::unique_ptr<DirectX::SpriteBatch> m_spriteBatch;
};

// Font.cpp
#include "Font.h"
#include "SimpleMath.h"

using namespace std;
using namespace DirectX;

void Font::Init(ID3D11Device* device, ID3D11DeviceContext* deviceContext)
{
    if (device != NULL && deviceContext != NULL)
    {
        m_spriteBatch = std::make_unique<SpriteBatch>(deviceContext);
        m_spriteFont = std::make_unique<SpriteFont>(device, L"Fonts/Arial.spritefont");
    }
}

void Font::Render()
{
    m_spriteBatch->Begin();
    m_spriteFont->DrawString(m_spriteBatch.get(), L"TEST", SimpleMath::Vector2(300, 300));
    m_spriteBatch->End();
}

您应该避免在.h文件中using namespace语句,因为它基本上破坏了首先使用C ++名称空间的全部目的。 您应该只在.cpp文件中using namespace语句,然后在标头中使用完全限定的名称。

从您发布的代码来看,没有什么明显的原因可以解释为什么您会遇到异常。 我建议您进入代码以查看异常的真正来源。 如果您使用的是NuGet,则可能要使用项目间引用。 有关详细信息,请参见DirectX Tool Kit Wiki。

您可以尝试使用Fonts\\\\Arial.spritefont而不是Fonts/Arial.spritefont来查看是否有所不同。

对于现代编译器,不一定要使用老式的C样式if #ifndef FONT_H #define FONT_H .. #endif 只需使用#pragma once

注意:如果您使用的是VS 2012而不是VS 2013或VS 2015,则无法使用std::make_unique 您可以执行以下操作:

m_spriteBatch.reset( new SpriteBatch(deviceContext) );
m_spriteFont.reset( new SpriteFont(device, L"Fonts/Arial.spritefont") );

暂无
暂无

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

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