Attack on the Forest

The Partridge Family were neither partridges nor a family. Discuss.
albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Attack on the Forest

Post by albinopapa » February 28th, 2018, 10:42 pm

user.StateOfMovement = StandingState();
StateOfMovement is an enum class: enum class MOVSTATE
StandingState is a class, not an enum class.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Attack on the Forest

Post by albinopapa » March 1st, 2018, 1:29 am

There are other issues I didn't notice also.

Your inheritance with classes without specifying which type is always private inheritance.

Code: Select all

class RunningState : UserState
This means the same as class RunningState : private UserState
Private inheritance means that base class functions cannot be called from child class pointers
Also, none of your UserState classes have any public members, classes are private by default.
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Attack on the Forest

Post by albinopapa » March 1st, 2018, 1:43 am

About private inheritance:
You have some virtual functions in UserState: Update, HandleInput, Move and Draw.
You have override for all functions except Draw.

Code: Select all

	RunningState* state = new RunningState;
	state->Update( 0.f, user, win );	// Overridden so is callable
	state->Draw();				// Not overridden so isn't callable
Since the pointer is a RunningState pointer, calling overridden functions like Update is fine. However, calling the base Draw will produce an error saying it is not accessible.
It also restricts implicit conversion, you aren't able to pass a child to a function requiring a parent pointer/reference.

Code: Select all

void Implicit( UserState* pState )
{

}

RunningState* state;
Implicit( state );  		// Fails: "Conversion to inaccessible base class 'UserState' is not allowed"
You are able to call parent functions from within the child class though.

Code: Select all

class A
{
public:
	void DoFunctionCall();	// Is only callable from base object or within child functions
private:

};
class B : A // or private A
{
public:
	void DoThisFunction()
	{
		DoFunctionCall();	// Is callable from within child function
	}
};
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Attack on the Forest

Post by albinopapa » March 1st, 2018, 1:58 am

And, something I believe is important, is:

Code: Select all

class RunningState : public UserState
{
public:
	virtual void Update(float dt, User& user, MainWindow& wnd)
	{
		// ...
	};
	virtual void HandleInput(MainWindow& wnd, User& user)
	{
		// ...
	}
	virtual void Move(User& user, float dt)
	{
		// ...
	}
};
For child classes, this is something that has always bugged me, and I suppose it's because I started programming after C++ 11 standards. Child class functions are virtual by default, so no need to redeclare them virtual. It doesn't change anything and they are ignored, but when I see this, I think their are going to be classes deriving from this child class also. I find it better to leave off the virtual keyword for child classes in favor for either tagging it as override or final.

Code: Select all

// When you are overriding a function use override
class RunningState : public UserState
{
public:
	void Update(float dt, User& user, MainWindow& wnd) override
	{
		// ...
	};
	void HandleInput(MainWindow& wnd, User& user) override
	{
		// ...
	}
	void Move(User& user, float dt) override
	{
		// ...
	}
};

Code: Select all

// When you want to prevent or indicate no other classes can or will inherit from this class
class RunningState : public UserState
{
public:
	void Update(float dt, User& user, MainWindow& wnd) final
	{
		// ...
	};
	void HandleInput(MainWindow& wnd, User& user) final
	{
		// ...
	}
	void Move(User& user, float dt) final
	{
		// ...
	}
};
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

User avatar
Zedtho
Posts: 189
Joined: February 14th, 2017, 7:32 pm

Re: Attack on the Forest

Post by Zedtho » March 1st, 2018, 3:39 pm

Thank you so much for helping! I'll be sure to fix all of the problems! I'll make sure to watch Chili's video on inheritance too now that I think of it :P

User avatar
Zedtho
Posts: 189
Joined: February 14th, 2017, 7:32 pm

Re: Attack on the Forest

Post by Zedtho » March 2nd, 2018, 7:46 pm

Just been working on some stuff under the hood, but I soon got a conflict between my RectF class and apparently a RectF class in Rect.h. It's probably a better idea just to use the RectF class in Rect.h, though, right?

Edit: Just did that, seems to be working fine, I'll delete My RectF class

Edit2: Since I made a useless post anyways, I might as well ask a question: currently I've got a largish blob in my user.h class dedicated to graphics (just initializations of Alphasprites, etc), is there some way to possibly move them out? Is that even a good design decision? I'd think the animation controller should stay local to user, but I'm not sure if the same should be for the others?

Edit3: should I push .shh files to the github too or should I ignore those?

albinopapa
Posts: 4373
Joined: February 28th, 2013, 3:23 am
Location: Oklahoma, United States

Re: Attack on the Forest

Post by albinopapa » March 2nd, 2018, 11:58 pm

I seem to always want to respond bottom up:

shh files will be recompiled each time someone compiles the chili framework, so you can safely ignore them.

One method of separating the sprite stuff is to put that in some resource manager class. It's one way you can use the same sprite for multiple entities in the game. Basically, you'd just pass around a reference or pointer to the class or use a singleton class. A singleton is a class that can only ever have one instance of itself and is global to any file that includes it's header file.

Code: Select all

class SpriteResource
{
public:
     // probably not ever going to need to change what's inside this class
     static const SpriteResource* Instance()
     {
          if( !_this )
               _this = std::make_unique<SpriteResource>();

          return _this.get();
     }
private:
     // Have to keep constructors private so you can't accidentally create more than one copy.
     SpriteResource() = default;
     SpriteResource(const SpriteResource& ) = delete;  // Don't need copies
     SpriteResource& operator=(const SpriteResource&) = delete; 

// Load all sprite resources here as you did in Unit.h
private:
     static std::unique_ptr<SpriteResource> _this;
};

// static class members must be initialized outside the declaration
std::unique_ptr<SpriteResource> SpriteResource::_this;
If you think paging some data from disk into RAM is slow, try paging it into a simian cerebrum over a pair of optical nerves. - gameprogrammingpatterns.com

User avatar
Zedtho
Posts: 189
Joined: February 14th, 2017, 7:32 pm

Re: Attack on the Forest

Post by Zedtho » March 3rd, 2018, 8:36 pm

Thanks for answering :D

Post Reply