Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / AI Help Part 2

Author
Message
NoviceNate333
11
Years of Service
User Offline
Joined: 7th Dec 2012
Location: United States
Posted: 12th Jul 2014 11:31
Hello everybody!
I have been stuck on this AI class for the past couple of weeks and need some assistance on solving the brain aching problem. For now I am using basic rotations and primitive shapes for enemy models just for testing until i get this issue solved. So the issue is When there are multiple enemies and i kill one of them the other enemies refuse to die. It is as if some how their health is still shared. The other enemy still updates and still attacks/walks/idles. but the enemy just does not execute the dying method.
Here is my character class which is the base class for my enemy class.



Here is the Enemy class that contains the basic logic for AI until i get the health and dying part to function correctly



Please anyone, if you have the knowledge to help me do not hesitate I have been stuck on this same problem for a long time now with a lot of help from \\\"The Tall Man\\\" and some advice from \\\"mr_d\\\" thanks in advance
TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 12th Jul 2014 19:43 Edited at: 12th Jul 2014 19:46
Yes, because you have exactly one instance of act and you're using it for every enemy.

There are a lot of strange design decisions you've made with your code, and I'm going to help you improve on them so you have some nice, clean C++ code going for you.


The issues

First of all, your character class is an absolute abomination. It doesn't even represent a character, it appears to be managing the creation and deletion of characters, so why call it "character" when it's not a character?

Enemy is inheriting from character, but there's no advantage to it doing so.

charHolder appears to be an array of characters and it's somehow passed in externally?


Character base class

I recommend you create a base class for all characters. This class shares common things that every character in the game can do, such as walk, run, die, update, etc.



Next, you need to think about the different types of characters you want in your game.


Player

The code is self explanatory:


The player character is a Character (which is why we inherit from Character), and it handles everything that has to do with the player.


Enemy

The same goes for the enemy:



Character Manager

The last thing you need is a way to bring it all together. I would create a class that manages creating and deleting characters, and you should instantiate exactly one object from this class to use in the game.

This class should only have methods for managing things that have to do with all characters:
- createCharacter for creating new characters of a specified type (i.e. zombie, player, crab, etc.)
- destroyCharacter for destroying characters
- update for handling things that have to do with all characters, such as collision.

Start with something like this:



Using the CharacterManager class

Like I said, you should have one instance of it in your game, and it is responsible for handling all characters.



NoviceNate333
11
Years of Service
User Offline
Joined: 7th Dec 2012
Location: United States
Posted: 12th Jul 2014 22:01
Hello thank you for your feedback, advice, and help. Although in theory your methods sounds very good, but i find it hard for me to comprehend and follow, for an abundance of these concepts are foreign to my knowledge. For example i have never heard of the map class, but it seems to be similar to the vector class. Also I have never seen or used the virtual term before. With these new terminologies and rules it may take me a while to incorporate this into my project. I am going to perform some research on some more oop practices. Do you happen to know any good web sites where i can learn this information efficiently. I have a couple of books, but none of them delve this far into polymorphism or oop practices. Thank you.
TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 13th Jul 2014 00:53 Edited at: 13th Jul 2014 00:56
It's a pain to learn the concepts and practices of C++ and I fully understand. I don't have a specific website where all of this stuff is explained, but I can explain it some more if you want? Google and stackoverflow is always a good place to get quick answers about things.

I'll try to explain the things as best as possible.

map

The map container is one of the most common containers and is part of the C++ standard template library (STL). You can think of map as a dictionary: You can store complex "values" under specific "keys" so later on you can quickly find a value by only giving a key.

A map has two template arguments:


This means you can choose any type you want for the key, and any type you want for the value. For example, let's say you had to store the age of a bunch of people. You'd choose a string as a key, and an int for the age:



Lets say Jack comes along and states he is 25 years old. You'd like to save this information in your map. You'd do it like this:


If "Jack" wasn't already in the map, a new slot is created internally. If he already existed in the map, then you'd overwrite the old value of "Jack".

Let's say your map has 1000 people in it, and you want to find Maria's age. You could write this:



The good thing about maps: They use successive approximation for the lookup. This means they find the item you're looking for in much less than 1000 loops (O(log n)).

Iterating maps is a little more tricky, but once you understand it it makes sense. "Iterating" means to loop through every item in the map.

Maps basically store a sorted list of std::pairs. An std::pair looks like this:


Because myMap was declared with <std::string, int>, it will store a list of std::pairs that look like this:


The "map" class contains a typedef for an iterator, and it gives you the methods begin() and end() which return the very first item and the very last item+1, respectively.

So in your for loop you have to declare an iterator of type std::map<std::string, int>::iterator, and then assign myMap.begin() to it. The end of the map is at myMap.end().


"it" is a pointer to the current std::pair stored in the map. it->first will contain the current name of the person in the dictionary, it->second will contain the age.

If you want to check if something exists in the map, you can use the find() method. find() returns an iterator.



virtual

The virtual keyword is very easy to understand. If you are using inheritance, you absolutely need to make all methods that are overridden virtual, otherwise disaster happens.

Let's say you have these classes:


And here's how you instantiate them:


This would be the output:


All fine and good, right?

But what if you want to store all animals in a vector (or map)? They all have to be the same type, because a vector can only store items of a single type.

Well, Cow is an Animal so we can also write this:


Great, now animal and cow are both of type Animal* and can be inserted into a vector. But wait, now the output is this:



Oh oh, why is cow->makeSound() calling the function in Animal::makeSound() and not Cow::makeSound()? Because they're not virtual! The variable cow doesn't know it has a subclass called Cow so it doesn't try to find any functions that belong to a subclass.

The fix:


NOTE: It is very important to make base class destructors virtual. If you don't do this, the destructors of your derived class will not be called. This can mean disaster if your class is handling a resource.

Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 15th Jul 2014 05:31
A good resource to learning C++ and the underlying concepts regarding everything from dynamic memory, class inheritance and various other uses would be CProgramming.com or CPlusPlus.com. Just keep in mind that this language is quite complex with lots of concepts and functionality that builds upon other concepts and functionality. Be patient and push on through, that's the best way to learn C++.

NoviceNate333
11
Years of Service
User Offline
Joined: 7th Dec 2012
Location: United States
Posted: 21st Jul 2014 09:58
Thank you for all of the help "TheComet" I have been studying and trying to become familiar with these new techniques and i have integrated them into my brand new Weapon class to support water splash decals along with muzzle flare/smoke and bullet hole decals. However I am still re-writing the character class to contain Way points and limb collision. Path finding is going to be the hard part though XD. again thank you for all of your help! also Thank you "Dar13" for the helpful resources!
NoviceNate333
11
Years of Service
User Offline
Joined: 7th Dec 2012
Location: United States
Posted: 22nd Jul 2014 09:36
I do have a question sorry for the double post in the charactermanager class how does it access the character class. for example...
you wrote


when i tried this it tells me Character is undeclared.
Is the character manager supposed to include the character class or be derived from it?
TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 23rd Jul 2014 04:39 Edited at: 18th Aug 2014 15:56
[EDIT] Code tags aren't working suddenly?

It's not declared, so declaring it will solve your problem. In the header file CharacterManager.hpp you can use a forward declaration:


The source file needs to know about its implementation, so you'll have to include the file in CharacterManager.cpp:


Just in case you're unfamiliar with the difference between declarations and definitions:

A declaration is a statement informing the compiler about a new identifier and its type. These are declarations:


A definition provides a previously declared identifier with a body, that is, information about its implementation. Examples:


The reason why you don't have to include Character.hpp in the header file of CharacterManager is because you only need a pointer (or reference) of Character*.

Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 23rd Jul 2014 05:33 Edited at: 23rd Jul 2014 05:42
I have to admit I had no idea what virtual was for and I've never used it before, but you do a very good job of explaining it, TheComet.

One thing that I'm still not 100% sure about is the naming of C++ files. It's something that's not explained well in any C++ tutorial. Things like, is there a reason to name something ".h" or ".cpp"? Does the compiler handle them differently? Can you substitute one for the other and have it work? What is ".hpp" for? Can you #include a ".cpp", and if so, does is act differently to a ".h"? Are multiple ".cpp"s automatically included? If you have multiple ".cpp"s, is one parsed before the others, and if so, how is it decided? Etc.

The way I've always done it is to just have a single ".cpp" and then #include everything else (which are all ".h") in the order I need them, and that has worked perfectly for me, but I have no idea if it's bad practice of even if it's working the way I expect.





EDIT: Hum, yeah, seems to be broken in this thread. Wonder why?
EDIT2: Ok, so you can break all code boxes in a post by using incorrect syntax for subsequent boxes. That is, I used code & /code for the first box, and code=cpp & /code. The first codebox showed ONLY TEXT, and no tags. The second box showed the text and the incorrect first tag, but the not the second. I edited, removed the tags from the second box so it was just text and the first worked. I opened the beta forums to see what the syntax was for highlighted codeboxes, found my error and fixed the second box. Then both worked.

My theory is that you made a mistake in the syntax of one of your codeboxes and that stuffed up the rest of them. As an example, you may have typed code=cpp instead of code lang=cpp.

Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 23rd Jul 2014 06:06
@Clonkex
C++ ".h" files are 'header' files, used to declare classes/structs/function/etc. Including these files in other files allows the declared types/classes/etc to be used in the other files.

C++'s ".cpp" files are the source files, used to define(flesh out) the classes/structs/functions/etc declared in the header files.

".hpp" files are the same as ".h" files, though can be used to distinguish between a C header file and a C++ header file.

I suppose you could include a ".cpp" though I'm certain the compiler will not be happy with you.


Quote: "The way I've always done it is to just have a single ".cpp" and then #include everything else (which are all ".h") in the order I need them, and that has worked perfectly for me, but I have no idea if it's bad practice of even if it's working the way I expect."

That's perfectly fine C++, though it negates one of C++'s strengths which is its modularity. If you have a class say "Foot" and it is declared in a header file("Foot.h") and defined in a source file("Foot.cpp").

Foot.h:


Foot.cpp:


Now say that you want to use Foot in your main source file("main.cpp"). You can do that by doing this:


If you don't have a "Foot.cpp", you have to define the class within the "main.cpp" or you get a compiler or linker error saying that the function "Foot::getSizeInInches()" isn't defined anywhere.

As to how multiple ".cpp"'s with one header(as I'm assuming that's what you're referring to) it's perfectly do-able. Here's an example:

Hand.h:


Hand_width.cpp:


Hand_thick.cpp:


Hand_length.cpp:


main.cpp:


Now this example is quite wasteful and is not the most practical but it shows how it can be done. I would only recommend doing this if your source files were getting truly outrageously big(1,500 lines+) for only a few functions and you still have a bunch of methods to implement(such as some stub inherited virtual methods or getters/setters).

Hopefully that answers most of your questions.

TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 23rd Jul 2014 06:56 Edited at: 23rd Jul 2014 06:57
Yeah, declarations go in header files and definitions go in source files. The compiler handles them differently in that only source files are compiled and linked, and every source file is compiled once only, outputting an object file.

Quote: "I suppose you could include a ".cpp" though I'm certain the compiler will not be happy with you."


Assuming the .cpp file has definitions in it, you can include it so long it is only included once within the entire project. Otherwise you'll get a multiple definition error.

The only time this should happen in C++ is with templated identifiers, because templates can't be instantiated without knowing about their definitions.

The following code represents a naive generic vector container:
Container.hxx


A lot of people will usually extract the implementation into a separate file for more readability:
Container.hpp


Container.hxx


However, you still have to include Container.hxx and not Container.hpp in order to use the class.

Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 23rd Jul 2014 09:33
Quote: "C++ ".h" files are 'header' files, used to declare classes/structs/function/etc. Including these files in other files allows the declared types/classes/etc to be used in the other files.

C++'s ".cpp" files are the source files, used to define(flesh out) the classes/structs/functions/etc declared in the header files."


Yes, I knew that because that's the definition used by most tutorials. The issue is that the divide is not necessarily clear. I can write functions (runnable code) in either, for example.

Quote: "As to how multiple ".cpp"'s with one header(as I'm assuming that's what you're referring to)"


That's not what I meant. My question was more basic: If I have multiple .cpps, and I put a function in one of them, can I access that function from any other .cpp (that is, in a header, I would have to include them in the right order or use external, but in a source file, you don't include it)? This is not a practical question, but rather a theoretical question; I'm trying to get my head around what actually happens when the compiler compiles, and it's a problem any C++ noob has and rarely gets a proper answer to.

Quote: "Here's an example:"


That helps, I understand a little better.

Quote: "".hpp" files are the same as ".h" files, though can be used to distinguish between a C header file and a C++ header file."


Ah, I think I read that somewhere. In that case I will almost certainly never be using .hpp. It just looks ugly to my eyes.

There's some other things I wanted to note but I don't have time right now.

Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 23rd Jul 2014 13:36
Quote: " That's not what I meant. My question was more basic: If I have multiple .cpps, and I put a function in one of them, can I access that function from any other .cpp (that is, in a header, I would have to include them in the right order or use external, but in a source file, you don't include it)? This is not a practical question, but rather a theoretical question; I'm trying to get my head around what actually happens when the compiler compiles, and it's a problem any C++ noob has and rarely gets a proper answer to."

In order to use a function defined in a different .cpp you would have to include the file where that function is declared. That would usually be a .h file. C++ compilers compile each .cpp into separate compilation units which are then linked together as needed by the linker after compilation is completely finished. Here is a good StackOverflow question regarding the C++ compilation process.

Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 23rd Jul 2014 15:02
Quote: "C++ compilers compile each .cpp into separate compilation units which are then linked together as needed by the linker after compilation is completely finished."


Huh. Sounds to me like C++ programs were originally designed to have just one source file. Or maybe it was specifically designed with the linking phase to simplify compilation...?

Anyway good link, very helpful

Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 23rd Jul 2014 20:33
Quote: "Or maybe it was specifically designed with the linking phase to simplify compilation...?"

That's exactly it.

TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 23rd Jul 2014 23:31
Don't want to re-compile every file every single time, right?

Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 25th Jul 2014 03:22
Quote: "Don't want to re-compile every file every single time, right?"


So THAT'S how it does that...

NoviceNate333
11
Years of Service
User Offline
Joined: 7th Dec 2012
Location: United States
Posted: 25th Jul 2014 13:54 Edited at: 25th Jul 2014 13:57
So... Regaurding the original purpose of this post XD. I was finally able to fix the enemies, character and character manager class. And not receive low fps. I switched from using the stl map container to vectors; how ever I did read that when using objects like enemies it is better to use list. I had to change around a lot of the code you showed me because when trying to piece it together I had over 50 compilation errors. Without your help "thecomet" I don't think I would have understood how to achieve this. I will post my code some time today when I get home so others with the same problem can learn as well. I'm still achieving 60 fps, but with maps I was only getting about 30 with only 2 enemies on the screen.
TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 25th Jul 2014 21:00
Quote: "how ever I did read that when using objects like enemies it is better to use list"


That's strange. You should use std::vector by default, the only time you should use std::list is if you're doing a lot of insertions and deletions. The downside of std::list is iterating over them is slightly slower because it is implemented as a doubly linked list, i.e. it suffers from cache misses because it doesn't store the elements in contiguous memory.

http://stackoverflow.com/questions/2209224/vector-vs-list-in-stl

I'd be interested to see your code.

NoviceNate333
11
Years of Service
User Offline
Joined: 7th Dec 2012
Location: United States
Posted: 1st Aug 2014 10:11
Ok so here is my code. I am starting to believe however that it is more of a polygon issue than a Programming issue...
Enemy.h


Enemy.cpp




Character.h




character.cpp




ChracterManager.h




I hope you can find some bug that is causing a slowdown because the character model i am using for the mutant i would like to keep XD
Clonkex
Forum Vice President
13
Years of Service
User Offline
Joined: 20th May 2010
Location: Northern Tablelands, NSW, Australia
Posted: 1st Aug 2014 15:47
The first thing I notice is that you're calling the GetDist function unnecessarily, though I seriously doubt that's causing any performance issues. You should only need to do this:



Other than that, I see nothing that would cause a major slowdown. I have two questions and an instruction for you:

1) What's your computer like (i.e. give us your specs)?
2) How many polys does this mutant model have? If it's designed for 3D rendering (as in, pre-rendered CG stuff) it'll be way too high-poly.
3) Make certain you're not creating and deleting a model several times a frame, running a function hundreds or thousands of times too many or something else along those lines. Might be good to step through with the debugger or make some global variables to count the number of times each function has been called per frame.

NoviceNate333
11
Years of Service
User Offline
Joined: 7th Dec 2012
Location: United States
Posted: 1st Aug 2014 16:24
My computer has a 1gb nvidia graphics card 3.2 ghz quad core processor and 4gb of ram. I use windows xp the majority of the time.

I was actually using the decayed model from model pack 52. I am not sure of the poly count.

I am only creating the enemy before the main loop and i delete all of them after the level has been deleted only once.

I am thinking about delving more into directX and creating my own .x model importer and learning how to implement animation.
NoviceNate333
11
Years of Service
User Offline
Joined: 7th Dec 2012
Location: United States
Posted: 1st Aug 2014 18:02
Sorry for the double post but i though i would bring this up as well. So there is only lag when both of the enemies are attacking or following the player. when the enemies are idle the fps remain at 60.
WickedX
15
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 5th Aug 2014 02:39 Edited at: 5th Aug 2014 02:46
Sorry off topic, but when I first read TheComet's post above concerning the definitions of a declaration and definition, it didn’t sound right. So, I finally checked my reference material and according to the Turbo C++ Programmer’s Guide; if the compiler allocates memory then it’s a definition.

Int A; // is actually referred to a defining declaration.

A = 6; // is an initializer

class A // is a non-defining declaration of a class
{
public:
void foo();
};

A MyA; // is a definition of the class

Just wanted to clarify or get more clarification if my resources are in error.

Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 16th Aug 2014 23:12
I realize it's late, but I thought I'd point out that WickedX's resources quite possibly are before the first C++ ISO standard and thus are out-of-date and/or incorrect. Borland did make a Turbo C++ in 2006 so perhaps he has that edition of the Programmer's Guide.

Just my two cents.

WickedX
15
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 17th Aug 2014 02:23
Did a quick 5 minute search for; C++ what is the difference between a definition and a declaration. The first five sites seem to concur with the Turbo C++ Programmers Guide.

Dar13
15
Years of Service
User Offline
Joined: 12th May 2008
Location: Microsoft VisualStudio 2010 Professional
Posted: 17th Aug 2014 04:14
Well, now that I have looked at what you said compared to TheComet; you both seem to have said the same thing. But you said it with more specific language I suppose.

WickedX
15
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 17th Aug 2014 04:39
Look a little closer at TheComet’s post. If I am not misinterpreting, seems somewhat backward to me.

TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 18th Aug 2014 15:57 Edited at: 18th Aug 2014 15:58
@NoviceNate333

Profile your code. I'm not sure how to do that with MSVC, but googling it will give you loads of answers.

Profiling your code will give you statistics on which functions are taking the longest to execute. This will help you isolate where the slowdown is occurring.

@WickedX

What's backwards? This is what I said:

Quote: "A declaration is a statement informing the compiler about a new identifier and its type. These are declarations:


A definition provides a previously declared identifier with a body, that is, information about its implementation. Examples:
"


Obviously, you can also have declarations and definitions on the same line. Example:



WickedX
15
Years of Service
User Offline
Joined: 8th Feb 2009
Location: A Mile High
Posted: 19th Aug 2014 01:17
This is what I find online and in my resources. As long as we know how to program in C++, it doesn’t really matter. Anyway, excellent info on class structures.



The Tall Man
10
Years of Service
User Offline
Joined: 16th Nov 2013
Location: Earth
Posted: 20th Aug 2014 01:45
When Visual Studio isn't being inconsistent, a declaration is a prototype. A definition is the implementation.

Judging what we see is the greatest blinder and self-limiter in the universe.

What we perceive is never reality. It is only a story we tell ourselves based on our current perspective, which has far more to do with our beliefs about ourselves than with anything else.

Login to post a reply

Server time is: 2024-03-29 09:06:18
Your offset time is: 2024-03-29 09:06:18