[英]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.