I'm a scholar for Computer Games Programming, currently studying C++. I'm trying to access a private Texture2D and Vector 2 type in a .h file from a .cpp file in order to give an object position and image.
This is the Player.cpp file
#include "Player.h"
#include <sstream>
Player::Player(int argc, char* argv[]) : Game(argc, argv), _cPlayerSpeed(0.1f), _cPlayerFrameTime(250)
{
//Player Inits
_playerDirection;
_playerFrame = 0;
_playerCurrentFrameTime = 0;
_playerSpeedMultiplier = 1.0f;
//Init of Important Game Aspects
Graphics::Initialise(argc, argv, this, 1024, 768, false, 25, 25, "Genocide: Remastered", 60);
Input::Initialise();
Graphics::StartGameLoop(); //Start of Game Loop, calls Update and Draw in game loop.
}
Player::~Player()
{
}
void Player::Input(int elapsedTime, Input::KeyboardState* state)
{
// Checks for directional keys pressed
if (state->IsKeyDown(Input::Keys::D))
{
_playerPosition->X += _cPlayerSpeed * elapsedTime;
}
}
/// <summary> All content should be loaded in this method. </summary>
void Player::LoadContent()
{
_playerPosition = new Vector2();
_playerTexture = new Texture2D();
_playerTexture->Load(" ", false);
_playerSourceRect = new Rect(0.0f, 0.0f, 0, 0);
}
/// <summary> Called every frame - update game logic here. </summary>
void Player::Update(int elapsedTime)
{
}
/// <summary> Called every frame - draw game here. </summary>
void Player::Draw(int elapsedTime)
{
}
This is the Player.h
#pragma once
#ifdef WIN32
#ifndef _DEBUG
#pragma comment(linker, "/SUBSYSTEM:windows /ENTRY:mainCRTStartup")
#endif
#endif
#include "S2D/S2D.h"
using namespace S2D;
class Player : public Game
{
public:
Player(int argc, char* argv[]);
~Player();
/// <summary> All content should be loaded in this method. </summary>
void virtual LoadContent();
/// <summary> Called every frame - update game logic here. </summary>
void virtual Update(int elapsedTime);
/// <summary> Called every frame - draw game here. </summary>
void virtual Draw(int elapsedTime);
private:
Vector2* _playerPostion;
Rect* _playerSourceRect;
Texture2D* _pacmanTexture;
const float _cPlayerSpeed;
const int _cPlayerFrameTime;
int _playerDirection;
int _playerFrame;
int _playerCurrentFrameTime;
float _playerSpeedMultiplier;
void Input(int elapsedTime, Input::KeyboardState* state);
void CheckPaused(Input::KeyboardState* state, Input::Keys pauseKey);
void CheckViewportCollision();
void UpdatePlayer();
};
I've literally copied and pasted something I've been working on with my Lecturer and changed variable, type and instantiation declaration and his works. Curious as to why mine isn't. Help will be much appreciated.
Many thanks,
Ryan.
In the header, your Texture2D* is called _pacmanTexture, whereas in your implementation, you've called it _playerTexture. Similarly, you've misspelled _playerPosition in the header.
Usual way to give access to private resources of a class to another class is to add public accessor methods (getter, setter).
Related
I am having trouble figuring out how to use UPawnMovementComponent instead of UFloatingPawnMovement to move a pawn. Every time I implemented UPawnMovementComponent and hit play, the editor crashed. Here's the code.
PlayerCharacter.h
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "Camera/CameraComponent.h"
#include "GameFramework/SpringArmComponent.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/PawnMovementComponent.h"
#include "PlayerCharacter.generated.h"
UCLASS()
class LEARNING_API APlayerCharacter : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
APlayerCharacter();
UPROPERTY(EditAnywhere, Category = "Components")
UStaticMeshComponent* PlayerMesh;
UPROPERTY(EditAnywhere, Category = "Components")
UCameraComponent* Camera;
UPROPERTY(EditAnywhere, Category = "Components")
USpringArmComponent* CameraArm;
UPROPERTY(EditAnywhere, Category = "Components")
UCapsuleComponent* CapsuleComponent;
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
void MoveForward(float Amount);
void MoveRight(float Amount);
void Turn(float Amount);
void LookUp(float Amount);
PawnMovementComponent* PawnMovement;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
PlayerCharacter.cpp
// Fill out your copyright notice in the Description page of Project Settings.
#include "PlayerCharacter.h"
// Sets default values
APlayerCharacter::APlayerCharacter()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
// Default to Player 0
AutoPossessPlayer = EAutoReceiveInput::Player0;
// Player Mesh and make it a root component
PlayerMesh = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Player Mesh"));
RootComponent = PlayerMesh;
// Capsule Component
CapsuleComponent = CreateDefaultSubobject<UCapsuleComponent>(TEXT("Capsule Component"));
float capsule_radius = 40.f;
float capsule_height = 80.f;
CapsuleComponent->InitCapsuleSize(capsule_radius, capsule_height);
CapsuleComponent->SetupAttachment(RootComponent);
// Spring Arm Component
CameraArm = CreateDefaultSubobject<USpringArmComponent>(TEXT("Camera Arm"));
CameraArm->SetRelativeRotation(FRotator(0.f, 0.f, 0.f));
CameraArm->TargetArmLength = 500.f;
CameraArm->bEnableCameraLag = true;
CameraArm->CameraLagSpeed = 3.f;
CameraArm->SetupAttachment(RootComponent);
// Camera
Camera = CreateDefaultSubobject<UCameraComponent>(TEXT("Camera Component"));
Camera->SetupAttachment(CameraArm, USpringArmComponent::SocketName);
// Player Movement Component
PawnMovement= CreateDefaultSubobject<UPawnMovementComponent>(TEXT("Pawn Movement"));
}
// Called when the game starts or when spawned
void APlayerCharacter::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void APlayerCharacter::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveForward", this, &APlayerCharacter::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &APlayerCharacter::MoveRight);
PlayerInputComponent->BindAxis("Turn", this, &APlayerCharacter::Turn);
PlayerInputComponent->BindAxis("LookUp", this, &APlayerCharacter::LookUp);
}
void APlayerCharacter::MoveForward(float Amount)
{
PawnMovement->AddInputVector(GetActorForwardVector() * Amount);
}
void APlayerCharacter::MoveRight(float Amount)
{
PawnMovement->AddInputVector(GetActorRightVector() * Amount);
}
void APlayerCharacter::Turn(float Amount)
{
AddControllerYawInput(Amount);
}
void APlayerCharacter::LookUp(float Amount)
{
AddControllerPitchInput(Amount);
}
The reason I want to implement UPawnMovementComponent rather than UFloatingPawnMovement is because I don't want a floating pawn that moves around in the air, I want the pawn to only move on the ground. I reckon that the UPawnMovementComponent will allow me to do that. Like I said, every time I implemented, compile it, and the ran it, the editor crashed. So is there any way to implement it without the editor crashing.
Not sure if you ever solved this or not (the question is pretty old) but I believe that you can't initialize a UPawnMovementComponent directly, you need to derive your own. If you look at the class declaration you can see that the UPawnMovementComponent is marked as UCLASS(abstract). See the declaration here
Also, if you try checking that PawnMovement is not a nullptr before making any calls to it you'll prevent a crash.
So I am a beginner with game programming in UE4, just starting out with c++. The code below worked perfectly before I attached a springcomponent to my mesh. This is a simple Pawn class that I created. I should also mention that once I included the spring component and tested it and it did not work, my computer shut down accidently. It give the same error repeatedly for any class I create, I have tried making a new class and applying the code.
Please see Image for the error VS 2017 gives when I try to debug
Below is the RollingStone.cpp file code.
#include "RollingStone.h"
#include "Classes/Components/InputComponent.h"
#include "Classes/GameFramework/FloatingPawnMovement.h"
#include "Classes/Camera/CameraComponent.h"
// Sets default values
ARollingStone::ARollingStone()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
FloatingPawnMovement = CreateDefaultSubobject<UFloatingPawnMovement>("PawnMoevement");
StaticMesh = CreateDefaultSubobject<UStaticMeshComponent>("StaticMeshComponeent");
Camera = CreateDefaultSubobject<UCameraComponent>("CameraComponeent");
Camera->SetRelativeLocation(FVector(-500.f, 0.f, 0.f));
Camera->SetupAttachment(StaticMesh);
SetRootComponent(StaticMesh);
bUseControllerRotationYaw = true;
bUseControllerRotationPitch = true;
}
// Called when the game starts or when spawned
void ARollingStone::BeginPlay()
{
Super::BeginPlay();
}
void ARollingStone::MoveForward(float Amount)
{
FloatingPawnMovement->AddInputVector(GetActorForwardVector()* Amount);
}
void ARollingStone::MoveRight(float Amount)
{
FloatingPawnMovement->AddInputVector(GetActorRightVector()* Amount);
}
void ARollingStone::Turn(float Amount)
{
AddControllerYawInput(Amount);
}
void ARollingStone::Lookup(float Amount)
{
AddControllerPitchInput(Amount);
}
// Called every frame
void ARollingStone::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
// Called to bind functionality to input
void ARollingStone::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
PlayerInputComponent->BindAxis("MoveForward", this, &ARollingStone::MoveForward);
PlayerInputComponent->BindAxis("MoveRight", this, &ARollingStone::MoveRight);
PlayerInputComponent->BindAxis("Turn", this, &ARollingStone::Turn);
PlayerInputComponent->BindAxis("LookUp", this, &ARollingStone::Lookup);
}
Below is the RollingStone.h file code:
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "RollingStone.generated.h"
UCLASS()
class MYPROJECT_API ARollingStone : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
ARollingStone();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
void MoveForward(float Amount);
void MoveRight(float Amount);
void Turn(float Amount);
void Lookup(float Amount);
class UFloatingPawnMovement* FloatingPawnMovement;
UPROPERTY(EditAnywhere, Category = "Components")
UStaticMeshComponent* StaticMesh;
UPROPERTY(EditAnywhere, Category = "Components")
class UCameraComponent* Camera;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
// Called to bind functionality to input
virtual void SetupPlayerInputComponent(class UInputComponent* PlayerInputComponent) override;
};
Will appreciate you taking the time to help me. I am now very sure that the accidental shutdown caused this since its not working even after I stop using the springarmcomponent, you can see it is not there in the code and this previously working code now does not even debug.
I am using visual studio 2017 by the way!
Thank you!
Looking forward to a solution.
I am currently learning Unreal and working with C++ and when creating a collision box I am receiving an 'Error C2248: 'UPrimitiveComponent::bGenerateOverlapEvents': cannot access private member declared in class 'UPrimitiveComponent'
The error is showing at line 18 in the ShipController.cpp file.
When reading around it was suggested that instead of using 'bGenerateOverlapEvents' to use 'SetGenerateOverlapEvents' instead however whilst this compiled correctly the collision box didn't not function properly.
Ship Controller Header File:
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Pawn.h"
#include "ShipController.generated.h"
UCLASS()
class BASICSHOOTER_API AShipController : public APawn
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AShipController();
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)
UShapeComponent* CollisionBox;
UPROPERTY(EditAnywhere)
float Speed = 10.0f;
UPROPERTY(EditAnywhere, Category="Spawning")
TSubclassOf<class ABulletController> BulletBlueprint;
void Move_XAxis(float AxisValue);
void Move_YAxis(float AxisValue);
void OnShoot();
FVector CurrentVelocity;
bool Died;
UFUNCTION()
void OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult);
};
Ship Controller Cpp file
// Fill out your copyright notice in the Description page of Project Settings.
#include "ShipController.h"
#include "BulletController.h"
#include "EnemyController.h"
#include "Components/BoxComponent.h"
#include "Kismet/GameplayStatics.h"
// Sets default values
AShipController::AShipController()
{
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
CollisionBox = CreateDefaultSubobject<UBoxComponent>(TEXT("Root"));
CollisionBox->bGenerateOverlapEvents = true;
CollisionBox->OnComponentBeginOverlap.AddDynamic(this, &AShipController::OnOverlap);
AutoPossessPlayer = EAutoReceiveInput::Player0;
}
// Called when the game starts or when spawned
void AShipController::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AShipController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
if (!CurrentVelocity.IsZero())
{
FVector NewLocation = GetActorLocation() + Speed * CurrentVelocity * DeltaTime;
SetActorLocation(NewLocation);
}
}
// Called to bind functionality to input
void AShipController::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
Super::SetupPlayerInputComponent(PlayerInputComponent);
InputComponent->BindAxis("MoveX", this, &AShipController::Move_XAxis);
InputComponent->BindAxis("MoveY", this, &AShipController::Move_YAxis);
InputComponent->BindAction("Shoot", IE_Pressed, this, &AShipController::OnShoot);
}
void AShipController::Move_XAxis(float AxisValue)
{
CurrentVelocity.X = AxisValue * 100.0f;
}
void AShipController::Move_YAxis(float AxisValue)
{
CurrentVelocity.Y = AxisValue * 100.0f;
}
void AShipController::OnShoot()
{
UWorld* World = GetWorld();
if (World)
{
FVector Location = GetActorLocation();
World->SpawnActor<ABulletController>(BulletBlueprint, Location, FRotator::ZeroRotator);
}
}
void AShipController::OnOverlap(UPrimitiveComponent* OverlappedComponent, AActor* OtherActor, UPrimitiveComponent* OtherComponent, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult)
{
if (OtherActor->IsA(AEnemyController::StaticClass()))
{
Died = true;
this->SetActorHiddenInGame(true);
UGameplayStatics::SetGamePaused(GetWorld(), true);
}
}
Enemy Controller Header File
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "EnemyController.generated.h"
UCLASS()
class BASICSHOOTER_API AEnemyController : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
AEnemyController();
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
UPROPERTY(EditAnywhere)
UShapeComponent* RootBox;
UPROPERTY(EditAnywhere)
float Speed = -200.0f;
};
Enemy Controller Cpp File
// Fill out your copyright notice in the Description page of Project Settings.
#include "EnemyController.h"
#include "Components/BoxComponent.h"
// Sets default values
AEnemyController::AEnemyController()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
RootBox = CreateDefaultSubobject<UBoxComponent>(TEXT("Root"));
}
// Called when the game starts or when spawned
void AEnemyController::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void AEnemyController::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
FVector NewLocation = GetActorLocation();
NewLocation.X += Speed * DeltaTime;
SetActorLocation(NewLocation);
if (NewLocation.X < -600.0f)
{
this->Destroy();
}
}
I expect the output to be when an object of class EnemyController touches an object of class ShipController that the game will pause and that the object of class ShipController will be hidden in game.
Using SetGenerateOverlapEvents(true); instead of bGenerateOverlapEvents = true; did work.
For some reason I had set the objects at different heights and the collision boxes were not colliding which is why it didn't appear to work.
Thanks for the comments and advice!
So i've been trying to process audio using JUCE and followed a tutorial and there he used override on one of the functions but when i do it it says "Expected function body after function declarator". The goal is to play random white noise as explained by the video.
Video link: https://www.youtube.com/watch?v=GjNeYI6-uNE&index=11&list=PLLgJJsrdwhPxa6-02-CeHW8ocwSwl2jnu
Code:
/*
==============================================================================
This file was auto-generated!
==============================================================================
*/
#include "MainComponent.h"
//==============================================================================
MainComponent::MainComponent()
{
// Make sure you set the size of the component after
// you add any child components.
setSize (800, 600);
// specify the number of input and output channels that we want to open
setAudioChannels (2, 2);
}
MainComponent::~MainComponent()
{
// This shuts down the audio device and clears the audio source.
shutdownAudio();
}
//==============================================================================
void MainComponent::prepareToPlay (int samplesPerBlockExpected, double sampleRate)
{
// This function will be called when the audio device is started, or when
// its settings (i.e. sample rate, block size, etc) are changed.
// You can use this function to initialise any resources you might need,
// but be careful - it will be called on the audio thread, not the GUI thread.
// For more details, see the help for AudioProcessor::prepareToPlay()
}
void MainComponent::getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override /*this one gets the error*/
{
for (int channel = 0; channel < bufferToFill.buffer->getNumChannels(); ++channel)
{
float* const buffer = bufferToFill.buffer->getWritePointer(channel, bufferToFill.startSample);
for (int sample = 0; sample < bufferToFill.numSamples; ++sample)
{
buffer[sample] = (random.nextFloat() * 2.0f - 1.0f) * 0.25;
}
}
bufferToFill.clearActiveBufferRegion();
}
void MainComponent::releaseResources()
{
// This will be called when the audio device stops, or when it is being
// restarted due to a setting change.
// For more details, see the help for AudioProcessor::releaseResources()
}
//==============================================================================
void MainComponent::paint (Graphics& g)
{
// (Our component is opaque, so we must completely fill the background with a solid colour)
g.fillAll (getLookAndFeel().findColour (ResizableWindow::backgroundColourId));
// You can add your drawing code here!
}
void MainComponent::resized()
{
// This is called when the MainContentComponent is resized.
// If you add any child components, this is where you should
// update their positions.
}
.h file:
/*
==============================================================================
This file was auto-generated!
==============================================================================
*/
#pragma once
#include "../JuceLibraryCode/JuceHeader.h"
//==============================================================================
/*
This component lives inside our window, and this is where you should put all
your controls and content.
*/
class MainComponent : public AudioAppComponent
{
public:
//==============================================================================
MainComponent();
~MainComponent();
//==============================================================================
void prepareToPlay (int samplesPerBlockExpected, double sampleRate) override;
void getNextAudioBlock (const AudioSourceChannelInfo& bufferToFill) override;
void releaseResources() override;
//==============================================================================
void paint (Graphics& g) override;
void resized() override;
private:
//==============================================================================
// Your private member variables go here...
Random random;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainComponent)
};
Main.cpp
/*
==============================================================================
This file was auto-generated!
It contains the basic startup code for a JUCE application.
==============================================================================
*/
#include "../JuceLibraryCode/JuceHeader.h"
#include "MainComponent.h"
//==============================================================================
class AudioOutApplication : public JUCEApplication
{
public:
//==============================================================================
AudioOutApplication() {}
const String getApplicationName() override { return ProjectInfo::projectName; }
const String getApplicationVersion() override { return ProjectInfo::versionString; }
bool moreThanOneInstanceAllowed() override { return true; }
//==============================================================================
void initialise (const String& commandLine) override
{
// This method is where you should put your application's initialisation code..
mainWindow.reset (new MainWindow (getApplicationName()));
}
void shutdown() override
{
// Add your application's shutdown code here..
mainWindow = nullptr; // (deletes our window)
}
//==============================================================================
void systemRequestedQuit() override
{
// This is called when the app is being asked to quit: you can ignore this
// request and let the app carry on running, or call quit() to allow the app to close.
quit();
}
void anotherInstanceStarted (const String& commandLine) override
{
// When another instance of the app is launched while this one is running,
// this method is invoked, and the commandLine parameter tells you what
// the other instance's command-line arguments were.
}
//==============================================================================
/*
This class implements the desktop window that contains an instance of
our MainComponent class.
*/
class MainWindow : public DocumentWindow
{
public:
MainWindow (String name) : DocumentWindow (name,
Desktop::getInstance().getDefaultLookAndFeel()
.findColour (ResizableWindow::backgroundColourId),
DocumentWindow::allButtons)
{
setUsingNativeTitleBar (true);
setContentOwned (new MainComponent(), true);
#if JUCE_IOS || JUCE_ANDROID
setFullScreen (true);
#else
setResizable (true, true);
centreWithSize (getWidth(), getHeight());
#endif
setVisible (true);
}
void closeButtonPressed() override
{
// This is called when the user tries to close this window. Here, we'll just
// ask the app to quit when this happens, but you can change this to do
// whatever you need.
JUCEApplication::getInstance()->systemRequestedQuit();
}
/* Note: Be careful if you override any DocumentWindow methods - the base
class uses a lot of them, so by overriding you might break its functionality.
It's best to do all your work in your content component instead, but if
you really have to override any DocumentWindow methods, make sure your
subclass also calls the superclass's method.
*/
private:
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (MainWindow)
};
private:
std::unique_ptr<MainWindow> mainWindow;
};
//==============================================================================
// This macro generates the main() routine that launches the app.
START_JUCE_APPLICATION (AudioOutApplication)
You need to remove the override from the function definition in the .cpp file. This specifier can only appear in a member function declaration (i.e., in the header file), unless you're defining the function inside the header file, in which case it can appear just before the function body.
This question already has answers here:
Circular C++ Header Includes
(6 answers)
Closed 9 years ago.
So I am making a game trying to use OOP but visual studio isn't happy I am using VC++ 2010 express as my IDE, I decided to "Objectify" SDL into reusable components but now I went from 0 errors to 122 and some of them really aren't errors like when it says window is not defined and i click to go to the error the error disappears... so I am having a bit of trouble
#ifndef GUARD_WINDOWSTATE_H
#define GUARD_WINDOWSTATE_H
#include<SDL.h>
#include"Window.h"
#include"Graphics.h"
/*
WindowSate is a component to a window class, a windowstate is a seperate
frame of a window, it could be a menu or a level or something
a windowstate handles its events through a window and draws via graphics buffer to
the window's surface it will hold the components of the window(graphics, GUI components, etc.)
and the window will hold it
*/
class WindowState {
public:
WindowState(Window* window)
:m_window(window)
{
m_window->add_state(this);
}
virtual void load() = 0;
virtual void update( SDL_Event* e) = 0;
virtual void logic() = 0;
virtual void render(Graphics g) = 0;
virtual void unload() = 0;
protected:
Window* m_window;
};
#endif
it tells me that window is undefined when it is defined in window.h which is included
here is window.h:
#ifndef GUARD_WINDOW_H
#define GUARD_WINDOW_H
#include"SDL.h"
#include<vector>
#include<string>
#include"WindowState.h"
#include"Graphics.h"
/*The window class is the interface to the user,
it displays everything and is the top layer of the interactive application
it recieves events and passes them down the chain to states and components
it holds states and enumerates through them
*/
class Window {
private:
//width and height of the window
int m_width, m_height;
//graphics handler of the window
Graphics m_g;
//window surface
SDL_Surface* m_surface;
//event to hold all events
SDL_Event m_events;
//current and qeued states
int m_current_state;
int m_queued_state;
//Current WindowState
WindowState* m_window_state;
//is the window open?
bool m_running;
//title of the window
std::string m_title;
//vector to hold all the window states
std::vector<WindowState*> m_states;
public:
//Basic constructor
Window(int width, int height);
//constructor with title
Window(int width, int height, std::string title);
//returns the windows events
virtual SDL_Event& get_events() { return m_events; }
SDL_Surface* surface() { return m_surface; }
bool is_running() { return m_running; }
virtual void run(); //starts the window
virtual void update(); //updates the events
virtual void update_state(); //checks for a change in state
virtual void draw(); //draws current state
virtual void close(); // closes the window
void queue_window_state(int state); //sets up a window state to be activated
void add_state(WindowState* state); //adds a state to the window
void set_caption(std::string caption);
//destructor
~Window();
};
#endif
you have a circular include. Notice how WindowState.h includes Window.h and Window.h includes WindowState.h? It's a never ending dependency cycle that the compiler doesn't like.
If it were my money, I'd remove the #include <Window.h form WindowState.h and before the class somewhere do what is called a forward declaration: class Window;.
Keep in mind, you can' t use this class in this file. You can, however, include it and use it in the corresponding WindowState.cpp file.
In WindowsState.h both Window and Graphics do not need a complete definition, just a forward declaration, so change:
#include"Window.h"
#include"Graphics.h"
to:
class Window;
class Graphics;
In Window.h, WindowState only needs a forward declaration, so change:
#include "WindowsState.h"
to:
class WindowState;
Graphics cannot be forward-declared in Window.h because the full size of the type must be computed to compile Window successfully.
Using forward declarations minimizes compilation dependencies between files and makes your code compile faster. Changing the Graphics.h and Window.h files, for example, will not require recompiling all files that include only WindowState.h, for example.