b2Shape is equal to 0xCDCDCDCD and thows an exception at Create Fixture - c++

I am following the manual at http://box2d.org/manual.pdf to try and better understand how Box2D works but I have run into a problem. When I call
m_body->CreateFixture it throws an exception when it tries to access the fixtureDef->shape because fixtureDef->shape is 0xCDCDCDCD. I am very confused because I am still learning Box2D and would love it if anyone could help explain.
Here are some important pieces of code to know from PhysicsEngine.h:
class PhysicsGround{
private:
b2Body* m_body;
b2Fixture* m_fixture;
b2PolygonShape m_shape;
public:
void init(glm::vec2 pos, glm::vec2 size, b2World* world);
b2Body* getBody();
void setBody(b2Body* body);
b2Fixture* getFixture();
};
class PhysicsEngine
{
private:
ICMEM::StackAllocator m_stackAlloc;
std::vector<PhysicsSprite*> m_physObjs;
b2World* m_world;
b2Vec2 m_gravity;
public:
PhysicsEngine() {}
void init(float gravX, float gravY);
void shutDown();
void addPhysicsObject(PhysicsSprite* sprite);
void addGround(glm::vec2 pos, glm::vec2 size);
void setGravity(float gravX, float gravY);
void update(double dt);
b2World* getWorld() { return m_world; }
};
Here is some important info from PhysicsEngine.cpp:
void PhysicsEngine::init(float gravX, float gravY) {
m_stackAlloc.init(200000000);
m_world = (b2World*)m_stackAlloc.allocAligned(sizeof(b2World), alignof(b2World));
m_world = new(m_world)b2World(b2Vec2(gravX, gravY));
}
void PhysicsEngine::addGround(glm::vec2 pos, glm::vec2 size) {
PhysicsGround* physicsGround = (PhysicsGround*)m_stackAlloc.allocAligned(sizeof(PhysicsGround), alignof(PhysicsSprite));
physicsGround->init(pos, size, m_world);
}
void PhysicsGround::init(glm::vec2 pos, glm::vec2 size, b2World* world) {
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(pos.x, pos.y);
m_body = world->CreateBody(&groundBodyDef);
m_shape.SetAsBox(size.x / 2.0f, size.y / 2.0f);
m_fixture = m_body->CreateFixture(&m_shape, 0.0f); // Exception thrown here
}

You have uninitialized values in your objects. This creates in non debug build random values, in this case the pattern 0xCDCDCDCD is a typical Visual Studio debug value for these uninitialized values.
You may want to use C++11 initialization capabilities as you don't provide a custom constructor. For instance:
class PhysicsGround{
private:
b2Body* m_body{nullptr};
b2Fixture* m_fixture{nullptr};
b2PolygonShape m_shape;
//
};

Related

Faster every Frame/Second UnrealEngine C++

MyPawn.cpp
// Called every frame
void AMyPawn::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
// Handle growing and shrinking based on our "Grow" action
{
float CurrentScale = OurVisibleComponent->GetComponentScale().X;
if (bGrowing)
{
// Grow to double size over the course of one second
CurrentScale = CurrentScale + 2;
}
else
{
// Shrink half as fast as we grow
CurrentScale -= (DeltaTime * 0.5f);
}
// Make sure we never drop below our starting size, or increase past double size.
CurrentScale = FMath::Clamp(CurrentScale, 1.0f, 2.0f);
OurVisibleComponent->SetWorldScale3D(FVector(CurrentScale));
}
// Handle movement based on our "MoveX" and "MoveY" axes
{
if (!CurrentVelocity.IsZero())
{
FVector NewLocation = GetActorLocation() + (CurrentVelocity * DeltaTime);
SetActorLocation(NewLocation);
}
}
}
MyPawn.h
#include "GameFramework/Pawn.h"
#include "MyPawn.generated.h"
UCLASS()
class MYPROJECT_API AMyPawn : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AMyPawn();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
UPROPERTY(EditAnywhere)
USceneComponent* OurVisibleComponent;
//Input functions
void Move_XAxis(float AxisValue);
void Move_YAxis(float AxisValue);
void StartGrowing();
void StopGrowing();
//Input variables
FVector CurrentVelocity;
bool bGrowing;
};
I want to add a statement that make my Spawn move faster every Frame or Second while one of the key input pressed (Forward,Backward,Left or Right),
I've tried to add
CurrentVelocity.X += CurrentVelocity.X
or
CurrentVelocity.X += 1
in the AMyPawn::Tick, and tried some more combination with no success, hope u can help me solve this .

C++ Dangling pointer issue

I am using the Raylib GUI framework for a project that displays all the nodes within an iteration of the Collatz Conjecture. In my program, I have a class for a Node object that acts simply as a circle with a labelled number. The variable text in my draw method, however, has an issue; C26815: The pointer is dangling because it points at a temporary instance which was destroyed. I'm new to C++ and don't have access to any books to teach me at the moment, hence I'm not entirely sure what a "dangling" pointer is or what it means, but I'm fairly certain it's the reason I can't display any text on my nodes. Here's my Node class:
class Node {
private:
int x;
int y;
int value;
int radius;
public:
Vector2 get_pos() {
return Vector2{ (float)x, (float)-value * 25 };
}
void set_radius(int newRadius) {
radius = newRadius;
}
void set_value(int newValue) {
value = newValue;
}
void set_x(int newX) {
x = newX;
}
void set_y(int newY) {
y = newY;
}
void draw() {
if (value) {
const char* text = std::to_string(value).c_str();
Vector2 size = MeasureTextEx(GetFontDefault(), text, 32.0f, 0.0f);
Vector2 pos = get_pos();
DrawCircle(pos.x, pos.y, radius, WHITE);
DrawText(text, pos.x - size.x / 2, pos.y - size.y / 2, 32, BLACK);
}
}
};
Any help or explanation as to what's going on would be appreciated.
EDIT: Other people have had similar issues on other questions but none of the answers made sense to me or felt applicable to my situation.
In this line
const char* text = std::to_string(value).c_str();
You are calling c_str() which returns a pointer to the buffer of the temporary returned by std::to_string(value). This temporaries lifetime ends at the end of this line. The pointer returned from c_str is only valid as long as the string is still alive.
If DrawText copies the string (rather than just copying the pointer you pass) you can fix it via
std::string text = std::to_string(value);
Vector2 size = MeasureTextEx(GetFontDefault(), text, 32.0f, 0.0f);
Vector2 pos = get_pos();
DrawCircle(pos.x, pos.y, radius, WHITE);
DrawText(text.c_str(), pos.x - size.x / 2, pos.y - size.y / 2, 32, BLACK);

Access Violation Reading Location when assigning Float (0x0000000000000170)

I'm crashing with a Access Violation reading location. I'm doing this in Unreal Engine, but it's simple and I feel the issue should be universally applicable within C++, though I am new to it.
I am crashing when trying to assign LastDoorOpenTime in OpenDoor() of OpenDoor.cpp (below). I'm able assign to it successfully at the start of the program in UOpenDoor::BeginPlay(), but trying the same thing in OpenDoor() crashes the application with "Access Violation reading location".
OpenDoor.h:
#pragma once
#include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "GameFramework/Actor.h"
#include "Engine/TriggerVolume.h"
#include "Engine/World.h"
#include "OpenDoor.generated.h"
UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
class ESCAPEROOM_API UOpenDoor : public UActorComponent
{
GENERATED_BODY()
public:
// Sets default values for this component's properties
UOpenDoor();
protected:
// Called when the game starts
virtual void BeginPlay() override;
void OpenDoor();
void CloseDoor();
public:
// Called every frame
virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override;
private:
UPROPERTY(VisibleAnywhere)
float OpenAngle = -60.f;
UPROPERTY(EditAnywhere)
ATriggerVolume* PressurePlate;
UPROPERTY(EditAnywhere)
float DoorCloseDelay = 1.f;
float LastDoorOpenTime;
AActor* ActorThatOpens;
AActor* Owner;
bool IsDoorOpen;
UWorld* ThisWorld;
};
OpenDoor.cpp:
#include "OpenDoor.h"
// Sets default values for this component's properties
UOpenDoor::UOpenDoor()
{
// Set this component to be initialized when the game starts, and to be ticked every frame. You can turn these features
// off to improve performance if you don't need them.
PrimaryComponentTick.bCanEverTick = true;
// ...
}
// Called when the game starts
void UOpenDoor::BeginPlay()
{
Super::BeginPlay();
ThisWorld = GetWorld();
ActorThatOpens = ThisWorld->GetFirstPlayerController()->GetPawn();
AActor* Owner = GetOwner();
IsDoorOpen = false;
}
void UOpenDoor::OpenDoor()
{
Owner->SetActorRotation(FRotator(0.f, OpenAngle, 0.f));
int cow = 1 + 1;
LastDoorOpenTime = 0.f; //ACCESS VIOLATION HERE
IsDoorOpen = true;
}
void UOpenDoor::CloseDoor()
{
Owner->SetActorRotation(FRotator(0.f, 0.f, 0.f));
IsDoorOpen = false;
}
// Called every frame
void UOpenDoor::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
{
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
if (PressurePlate->IsOverlappingActor(ActorThatOpens)) {
OpenDoor();
}
if (IsDoorOpen) {
if (ThisWorld->GetTimeSeconds() >= LastDoorOpenTime + DoorCloseDelay) {
CloseDoor();
}
}
}
Changing: "AActor* Owner = GetOwner();" to "Owner = GetOwner();" fixed it.

Cocos2d retain() in inherited classes

So I've had a lot of trouble with Cocos2d's auto-release shenanigans, and (almost) wish that I could just handle all of that myself...
Anyways, the problem I've had is with creating some animations. I've got a class called AnimatedDamageableSprite which inherits from DamageableSprite which inherits from Sprite which inherits from CCSprite etc...
When I create an AnimatedDamageableSprite, I have a successful animation on the screen, which runs as it should.
When I create a Suicider, which (you guessed it) inherits from AnimatedDamageableSprite, the CCArray which contains the frames for animation doesn't survive beyond the first loop, and on the second update attempt, the program gets an AV error.
Here's the code for the two classes:
Sprite.h
// This class works
class AnimatedDamageableSprite :public DamageableSprite {
public:
AnimatedDamageableSprite(int hp, CCPoint pos, CCTexture2D* tex, int rows, int columns, float scaleX, float scaleY);
virtual ~AnimatedDamageableSprite();
virtual void update(float dt);
virtual bool updateFrame(float dt);
virtual SpriteType getType() { return ANIMATED_DAMAGEABLE_SPRITE; };
protected:
float m_frameNum;
CCArray* m_frames;
int m_numOfFrames;
};
// This class doesn't
class Suicider :public AnimatedDamageableSprite {
public:
Suicider(int difficulty);
virtual ~Suicider();
virtual void update(float dt);
virtual SpriteType getType() { return SUICIDER; };
private:
float m_speed;
};
Sprite.cpp
AnimatedDamageableSprite::AnimatedDamageableSprite(int hp, CCPoint pos, CCTexture2D* tex, int rows, int columns, float scaleX, float scaleY)
:DamageableSprite(hp, pos, tex, scaleX, scaleY), m_frameNum(0), m_numOfFrames(rows*columns) {
float texWidth = tex->getContentSize().width / (float)columns;
float texHeight = tex->getContentSize().height / (float)rows;
m_frames = CCArray::createWithCapacity(m_numOfFrames);
m_frames->retain();
for (unsigned int i = 0; i < columns; i++) {
for (unsigned int j = 0; j < rows; j++) {
CCRect r(i*texWidth, j*texHeight, texWidth, texHeight);
m_frames->addObject(new CCSpriteFrame);
((CCSpriteFrame*)m_frames->lastObject())->createWithTexture(tex, r);
((CCSpriteFrame*)m_frames->lastObject())->initWithTexture(tex, r);
m_frames->lastObject()->retain();
}
}
initWithSpriteFrame((CCSpriteFrame*)m_frames->objectAtIndex(m_frameNum));
setTexture(tex);
setPosition(pos);
setScaleX(scaleX);
setScaleY(scaleY);
updateTransform();
}
// This function is called every frame. It returns a boolean for unrelated reasons
bool AnimatedDamageableSprite::updateFrame(float dt) {
bool retVal = false;
// Assume animations are at 30 FPS for now
m_frameNum += dt * 0.03f;
while (m_frameNum >= m_numOfFrames) {
m_frameNum -= m_numOfFrames;
retVal = true;
}
setDisplayFrame((CCSpriteFrame*)m_frames->objectAtIndex(m_frameNum));
updateTransform();
return retVal;
}
// This class calls the constructor of the one that works, and does nothing else relevant to the problem
// It also doesn't override the updateImage() function
Suicider::Suicider(int difficulty)
: AnimatedDamageableSprite(1, CCPoint(10,10), g_textureManager.getTexture("Suicider Sheet"), 6, 10, SCALE_WIDTH, SCALE_HEIGHT) {
// ...
}
EDIT:
Seems I forgot to actually point out the problem.
The CCArray* m_frames declared in AnimatedDamageableSprite is fine when used in that instance, but it is deleted at the end of a frame when used in the Suicider class - i.e. it isn't being retained. Hence the AV error when I try to access an item inside it which no-longer exists
I tried retaining it in the Suicider constructor as well, although that didn't change anything.

Error draw Sprite in cocos2dx v3.6

I'm new in cocos2dx. Followed this tutorial.
I create simple test with cocos2dx v3.6.
Bullet.h:
using namespace cocos2d;
class Bullet : public Sprite{
public:
Bullet();
~Bullet();
static Bullet* createBullet();
void setBullet( Vec2 pos, Vec2 vel , int Lev , float rotate);
private:
void moveFinish();
Vec2 velocity;
// static SpriteFrameCache * fr = SpriteFrameCache::getInstance();
};
Bullet.ccp
#include "Bullet.h"
Bullet::Bullet(){}
Bullet::~Bullet(){}
void Bullet::setBullet( Vec2 pos, Vec2 vel , int Lev , float rotate){
SpriteFrameCache * frc = SpriteFrameCache::getInstance();
frc->addSpriteFramesWithFile("bullet.plist","bullet.png");
SpriteFrame * sf = frc->getSpriteFrameByName("bullet8.png");
setSpriteFrame(sf);
setPosition(pos);
setRotation(rotate);
velocity = vel;
// schedule(update, 0.2);
//
// FiniteTimeAction * actionMove = MoveTo::create(10.0f, Vec2(1000, 1000));
// FiniteTimeAction * actionDone = CallFuncN::create(callfunc_selector(Bullet::moveFinish));
//
// runAction(Sequence::create(actionMove, actionDone, NULL));
}
void Bullet::moveFinish(){
}
Bullet* Bullet::createBullet(){
Bullet* sp = new Bullet();
if (sp->create()) {
sp->autorelease();
return sp;
}
CC_SAFE_DELETE(sp);
return NULL;
}
Main scene :
....
Bullet * bl = Bullet::createBullet();
bl->setBullet(gun->getPosition(), Vec2(5, 5), 2, gun->getRotation());
addChild(bl);
....
When run it show error:
Assert failed: Invalid GLProgramState Assertion failed: (shader),
function init, file
/Users/tuan/zzijkline/cocos2d/cocos/renderer/CCQuadCommand.cpp, line
50.
How can I fix it?
Your createBullet() seems wrong. You should be instantiating the Sprite from it and you should be loading the SpriteFrameCache from outside your Bullet class.
setBullet() should only be handling position, rotation and velocity.
Bullet* Bullet::create() {
Bullet* sp = new Bullet();
if (sp->initWithSpriteFrameName("bullet8.png")) {
sp->autorelease();
return sp;
}
CC_SAFE_DELETE(sp);
return NULL;
}
void Bullet::setBullet( Vec2 pos, Vec2 vel , int Lev , float rotate) {
setSpriteFrame(sf);
setPosition(pos);
setRotation(rotate);
velocity = vel;
}