At Intermediate Lesson 15...

The Partridge Family were neither partridges nor a family. Discuss.
tribalzero
Posts: 10
Joined: September 20th, 2014, 6:31 pm

At Intermediate Lesson 15...

Post by tribalzero » October 28th, 2014, 2:58 pm

So I;ve been going through these tutorials and they are great! However, recently especially with the last few I've watched I'm not so sure I could implement these things on my own. Like polymorphism type of stuff and so I am wondering if I should take a break from the videos and try creating some stuff on my own that has these concepts or if I will 'learn' it as I keep continuing through the videos?

Pindrought
Posts: 432
Joined: September 26th, 2013, 4:57 pm
Location: Kentucky
Contact:

Re: At Intermediate Lesson 15...

Post by Pindrought » October 28th, 2014, 6:47 pm

I think that's really different depending on each individual. That being said, I wouldn't try to go ahead if there's something you don't understand as it'll just bite you in the ass later and you'll end up wasting even more time going back to relearn it.
PM me if you need to contact me. Thanks to all the helpful people on this forum especially to Chili.

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: At Intermediate Lesson 15...

Post by cameron » October 28th, 2014, 9:10 pm

I would 100% say make something on your own. Many people have watched all the tutorials straight through, and try it on their own and need help. I would make sure you have everything down every 5-10 lessons or so( unless it is a demo ). Not saying this is the right way, but it is what I did and I have a great understanding of the language now.
Computer too slow? Consider running a VM on your toaster.

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

Re: At Intermediate Lesson 15...

Post by albinopapa » October 29th, 2014, 8:27 am

I would say the hardest part is deciding when it's useful. Polymorphism is (if you understand parent and child classes ) passing a child class as a pointer to the parent.

You may have seen this type of example, but I'm going to do it just in case you haven't.

Code: Select all

class Animal
{
   // list functions that all animals can do 
   void Speak();
    char *says;
};

class Dog : public Animal // This is how Dog becomes a child of Animal
{
   // List function that only Dogs do
     void DigHole( int depth );

};

class Cat : public Animal 
{
     void RetractClaws();
};

int GetAge( Animal *pPet )
{
     return pPet->GetAge()
}
void main()
{
     Dog bullDog;
     Cat tabby;

     // Here's one way how  to use polymorphism
     Animal **pet = new Animal*[2];
     pet[0] = &bullDog;
     pet[1] = &tabby;
     for(int i = 0; i < 2; i++)
     {
           pet[ i ]->Speak();
     }

     // Here's another way
     Animal **pets = new Animal*[2];
     pets[0] = new Dog();
     pets[1] = new Cat();

    // And another way
     int dogAge = GetAge( &Dog );    
}
The problem then arises that as long as the functions and data you need is in the parent class such as the Speak() function, everything is fine, but when you need to access functions or data that is only in the child classes, you would actually need to have either a Dog pointer or a Dog object and call the required function such as the DigHole function.

Here's my advice.
- Make a basic program that draws a box. The box will need a position, color and size.
- Make this program using the information you have learned. Look for things that belong together like boxHeight, boxWidth and so on.
- Group all those things into a class, call it class Box.
- Next, have your computer draw a triangle. Triangle has height, width, position, color. You will notice they share some of the same properties, biggest difference is the number of points in each and how things like area are calculated. Since both share the same types of data you could save time by creating parent/child classes.
- Create a class called Shape. Parent this class with the Box and Triangle classes like the example above.
- Move your position variables to the Shape class and remove them from both the other two classes. If done correctly, this shouldn't keep your code from running providing your program ran before this step. Now say you wanted to find the area of the shape. Both shapes have an area, but are computed differently so we can't just put a function in Shape. We could write a ( int BoxArea() ) function and a ( int TriangleArea() ) function, but then your Box will have that function as well, and Box doesn't need to calculate the area of a triangle. Remember, you can't call a function from the child class if the object has been morphed to be a parent class pointer.
- Make a function called Area in the Shape class and have it return an int.
- Add the word "virtual" to the front of it and the word "abstract" a the end of it before the ";". This gives us the function that the child classes will be able to use even if morphed into a parent pointer. The "abstract" at the end means that the class cannot be created, so Shape myShape; won't work. It's just a "heads up" to the compiler that a child class has a definition for the function, use it.
- Make the function "int Area() override" in the two child classes. The name, the parameter list and the return type have to match the virtual function from the parent class.
- Define the function for finding the areas of both the triangle and the box. Make sure to remember to have it return the result.
- Now create a function in Game that returns an int and takes a Shape* shape as the parameter.

From here you can build on this. For example, both shapes need to be drawn, you could make a draw functions, add other shapes etc. At this point you want to experiment and see what else you can do with polymorphism. The best uses I can think of for polymorphism is; 1) you can put them in a loop and write something like

Code: Select all

for( int i = 0; i < nShapes; i++)
{
     int shapeArea = shape[ i ].Area();
}
instead of writing out a call to each shape's area function.

2) You can pass them into functions that take a base pointer no matter which child it is, so you don't have to write so many functions.

Code: Select all

bool CompareSizes( Shape *A, Shape *B )
{
     return A->Area() == B->Area();
}
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

tribalzero
Posts: 10
Joined: September 20th, 2014, 6:31 pm

Re: At Intermediate Lesson 15...

Post by tribalzero » October 31st, 2014, 8:18 pm

Wow, appreciate the post! I'll definitely try to implement that as soon as I have some free time.

This is what I was trying on my own, but I got stuck and am a little confused.

I created 2 classes, and what I am trying to implement atm is that first the Menu class will show up and then after a certain action I will go to the next state which would be the MainMenu class.

Code: Select all

#pragma once
#include "D3DGraphics.h"

// Is this similar to extern?
class Game;

class Menu
{
public:
	// Implementation of state:
	// receive game object in constructor
	Menu(Game &game) 
	{
		LoadFont( &font,surface,"Fonts\\Fixedsys16x28.bmp",16,28,32 );
	}
	const void Draw( D3DGraphics &gfx )
	{
		gfx.DrawString("PONG",368,100,&font,D3DCOLOR_XRGB(255,255,255));
	}
	void OnEnter(Menu* state)
	{
		
	}
private:
	D3DCOLOR surface[ 512 * 84 ];
	Font font;
};

// Child of Menu
class MainMenu : public Menu
{
public:
	MainMenu() 
	{
		LoadFont( &font,surface,"Fonts\\Fixedsys16x28.bmp",16,28,32 );
	}
	const void Draw( D3DGraphics &gfx )
	{
		// 18 chars/2 = half of char string length
		// In order to center text
		gfx.DrawString("Select Your Poison",400-(9*16),100,&font,D3DCOLOR_XRGB(255,255,255));
	}
private:
	D3DCOLOR surface[ 512 * 84 ];
	Font font;

};
SO some questions/problems I am having:

class Game;

Before I tried including "Game.h" so my Menu class would take in a game class in the constructor but that wasnt working (maybe circular ...??) and I tried calling class Game; but I dont remember exactly where he spoke about this. Is this basically like saying: extern var?

My other question is that when I try using Game object as a parameter for the Menu() constructor I am not able to initalize this in game.cpp using something like

m( new Menu(*this) )

So my question I guess is some clarity on why this doesn't work and lastly,

The child class, MainMenu complains now that there is no default constructor for Menu, so does that mean there should always be a default constructor or just something about my implementation being off.

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: At Intermediate Lesson 15...

Post by cameron » October 31st, 2014, 9:11 pm

I would not make any class take a reference to the game object, as the game object should be in control of everything. I would try a work around. If you posted the purpose I could probably help a bit more. As for the default ctor, you may have some code somewhere that is causing it. Try adding one and see what happens.

BTW, why is your return type on draw const void?
Computer too slow? Consider running a VM on your toaster.

User avatar
jkhippie
Posts: 218
Joined: March 24th, 2014, 5:11 pm

Re: At Intermediate Lesson 15...

Post by jkhippie » November 1st, 2014, 1:35 am

No default ctor comes up because the Menu ctor takes a Game& parameter and MainMenu doesn't pass a Game& parameter to this base class so it looks for a plain 'Menu()' version of the ctor and there isn't one.
To strive, to seek, to find, and not to yield.

tribalzero
Posts: 10
Joined: September 20th, 2014, 6:31 pm

Re: At Intermediate Lesson 15...

Post by tribalzero » November 1st, 2014, 7:13 pm

Honestly Idk about const void, I dont understand it too well.

Code: Select all


#pragma once
#include "D3DGraphics.h"

class MainMenu;

class Menu
{
public:

	Menu() 
	{
		LoadFont( &font,surface,"Fonts\\Fixedsys16x28.bmp",16,28,32 );
	}
	void Draw( D3DGraphics &gfx )
	{
		gfx.DrawString("PONG",368,100,&font,D3DCOLOR_XRGB(255,255,255));
	}
	void OnEnter(Menu *state)
	{
		state = new MainMenu();
		delete this;
	}
protected:
	D3DCOLOR surface[ 512 * 84 ];
	Font font;
};

Code: Select all


#pragma once
#include "PongMenu.h"

// Child of Menu
class MainMenu : public Menu
{
public:
	MainMenu() {}

	void Draw( D3DGraphics &gfx )
	{
		// 18 chars/2 = half of char string length
		// In order to center text
		gfx.DrawString("Select Your Poison",400-(9*16),100,&font,D3DCOLOR_XRGB(255,255,255));
	}

};

So I'm declaring a pointer to Menu class in game.h and what I want to do with this is when a certain action takes place, like pressing enter, it will change the pointer to a MainMenu class and delete the Menu class.

Now on the line with

state = new MainMenu();

I get
Error: incomplete type is not allowed

I'm sure theres more problems here that I am not seeing as well

cameron
Posts: 794
Joined: June 26th, 2012, 5:38 pm
Location: USA

Re: At Intermediate Lesson 15...

Post by cameron » November 2nd, 2014, 3:05 am

I really like to have all the code with me, if you would upload that would be nice. I do see a few other problems and I think I see the main problem but I would like to double check.
Computer too slow? Consider running a VM on your toaster.

tribalzero
Posts: 10
Joined: September 20th, 2014, 6:31 pm

Re: At Intermediate Lesson 15...

Post by tribalzero » November 2nd, 2014, 1:11 pm

Ok here you go!
Attachments
Platformer.zip
(96.51 KiB) Downloaded 155 times

Post Reply