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工具包教程中,我建议使用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++名称空间的整个目的。应该只将using namespace
语句放在.cpp文件中,然后在标头中使用完全限定的名称。
从您发布的代码中没有明显的原因可以解释为什么会出现异常。我建议您进入代码,看看异常的真正来源。如果您正在使用NuGet,那么您可能希望使用项目到项目引用。有关详细信息,请参阅DirectX工具包wiki。
您可以尝试使用Fonts\Arial.spritefont
而不是Fonts/Arial.spritefont
,看看这是否有区别。
对于现代编译器来说,如果
#ifndef FONT_H #define FONT_H .. #endif
不一定是老派的C风格。只需使用#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") );
相关文章:
- 警告处理为错误这里有什么问题
- "error: no matching function for call to"构造函数错误
- boost::进程间消息队列引发错误
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- QT在错误的班级中寻找空位
- vector.resize()中的分配错误
- 代码在main()中运行,但在函数中出现错误
- 释放错误后堆使用
- wx通用目录控制错误"wxTheFileIconsTable was nullptr"
- 在类中将不完整类型的unique_ptr初始化为 nullptr 时编译 gcc 错误
- 读取访问冲突. _Mycont 在 C++ 中将 udp 数据放入向量时出现 nullptr 错误
- 当我尝试"make"时,出现错误:标识符"nullptr"未定义
- Win32 CreateWindow() 错误,这是 nullptr
- 数组越界或错误等于 nullptr?C++
- 使用 nullptr 会在代码块 IDE 中出现错误
- 具有显式定义的默认构造函数的 unique_ptr 到 nullptr 错误的类内成员初始值设定项
- C++DirectX11:使用DirectX工具包时出现NullPtr错误
- 编译错误'nullptr'未声明的标识符
- 未声明错误 Nullptr