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 / Creating Sub Files in C++(Dark GDK)

Author
Message
James V
13
Years of Service
User Offline
Joined: 18th Apr 2011
Location: U.S.A.
Posted: 18th Apr 2011 15:54
Hello, I'm rather new to using C++ and Dark GDK. I know the basics, and I've come pretty far on my own, but I'm now stuck... I'm creating an FPS game against zombies. Right now, I only have one zombie chasing me, and I can shoot and kill it. But all the code for the zombie is in my Main.cpp file, which will make it extremely difficult to create multiple zombies. So what I want to do is be able to make a Header File or somthing, that will consist of one zombie, then all I have to do is copy and paist the file, and now I have two zombies. I know there must be a way to do this, but I'm not sure how.
Wikaman1
16
Years of Service
User Offline
Joined: 17th Aug 2008
Location: Scotland
Posted: 18th Apr 2011 20:04
can you post some code? Then I'll be able to provide some advice on how to handle multiple zombies.

I also happen to be making a zombie game
Hassan
15
Years of Service
User Offline
Joined: 4th May 2009
Location: <script> alert(1); </script>
Posted: 18th Apr 2011 20:28
just make a header file like main.h, and use #include "main.h" in the DarkGDK.cpp (or it's main.cpp? can't remember)

anyway - number of files has nothing to do with number of zombies, what you probably want to do is to make a class (usually declared in the header, not methods definitions, and definitions are in a separate .cpp file, e.g. zombies.cpp, you might want to call the .h file zombies.h, not important but it looks more meaningful) that stands for an individual zombie, and make an array (could be in main.cpp) of this class.
note that, above we used a separate file to make code look nicer, but it has totally NOTHING to do with the number of zombies, you can write a million lines in main.cpp and define all classes and zombies and whatever you want there

Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 18th Apr 2011 20:41 Edited at: 18th Apr 2011 20:45
Copy and paste the file? No. How many instances of an object you create has nothing to do with which file the code is in, and copy-pasting the same code in several places is generally a bad idea. Or maybe you meant "include" the header file?

Anyway, there are several ways to make multiple objects. You can use dbCloneObject to copy the zombie model with different ID numbers, then you can loop through the ID numbers to control each zombie. You can store zombie data in a structure or class, and you can use arrays or vectors to store all the data structures. Eventually, you can create a zombie class that controls all behaviour within the class.

Separating the program into different modules is another question. It's true that it is good to put data and functions that logically belong together (like all code related to the zombie) into a separate file and then interface it to the main program using a header file. For a quick introduction to header files, have a look at:

http://www.learncpp.com/cpp-tutorial/18-programs-with-multiple-files/ (chapters 1.8 and 1.9)

Both this site and http://www.cplusplus.com/doc/tutorial/ are good places to read more about C++.

Finally, as Wikaman1 said, if you post the existing code, you can receive more advice on how to proceed from there.
James V
13
Years of Service
User Offline
Joined: 18th Apr 2011
Location: U.S.A.
Posted: 19th Apr 2011 15:14
Ok, thanks for all the replys. Here are the parts of code for the zombie.



Thats the part in the Main Loop...
Here is the 'Zombie' function:



And here is the Compute Distance Function:
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 20th Apr 2011 21:38
I will answer your original question eventually, but I'd like to give you first some general coding advice because there is room for improvement on that code.

Brush up on your math because the distance calculation function is not good. Changing the sign of coordinates to positive gives an incorrect result. Let's say the player's X coordinate is 40 and the zombie's X coordinate is -20. The difference between them is 60 units, but if you change the zombie's coordinate to positive, the calculated difference will be only 20! Furthermore, you don't need to change sign before multiplying numbers because multiplying two negative values gives, by definition, a positive result. Finally, the line "XZ = XX + ZZ" should be "XZ = XXX + ZZZ". Actually, the whole distance calculation function can be much shortened and corrected like this:



In several places you decrement variables like this: ZN = ZN - 1. In C++ there are two more elegant ways to do that. Read about the increment/decrement (++ and --) operators and about the += and -= operators. You can write either this:
or this:


http://www.cplusplus.com/doc/tutorial/operators/

Repeating dbPositionObject no less than eleven times is very ugly. When you repeat code like that, you can be sure that there is a better way. E.g. let's test if ZN can be divided without remainder by 10. Read about the modulo (%) operator. Since there is also a value which cannot be divided by 10 (value 5), we can add that as an extra check, so I would shorten it like this:



This statement means: if ZN is dividable by 10 so that the remainder is zero, or ZN is 5.

In the first code block you have "if (FoundObject == 20)" and in a different "if" statement "if (FoundObject == 21)" but the commands to be executed are exactly the same in both cases. So why not combine the statements like this and write the commands only once:



The ZombTing1, 2, 3 boolean variables could be eliminated. I suppose that the whole purpose of these variables is to execute the dbShowObject and dbHideObject commands only once when the zombie changes from one mode to another, is that so? It would be easier to store the previous zombie mode and compare the two. Supposing that you declare a PrevZombMode variable somewhere, with the same type (probably int) as ZombMode is declared, then you could write this:



Since there are several zombie modes and an "if" is required for each, it would be even more elegant to use a switch statement but I won't confuse you with it if you don't know it yet. However, it's worth to get acquainted with the switch structure in the future.

By the way, testing a boolean variable like "if (ZombTing3 == false)" is completely OK, but you could shorten it with the "not" (!) operator:


An advice about using DarkGDK as well:

I see that if the zombie is walking, you point it towards the camera (the player's position) but then you always rotate it with 180 degrees. If the zombie is facing the wrong way, you can set a new default direction for it after loading. After dbLoadObject, rotate the model once by 180 degrees, then use dbFixObjectPivot(20). That will fix the current rotation as the
new zero rotation, so you hopefully won't need to rotate the model every loop.

Well that's already a lot for you to go through. In the next post I will try to tackle the "how to make more zombies" part.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 20th Apr 2011 23:19
To make more zombies you need to store the data about each zombie in some data structure, then make a collection of those data structures, finally you need to process them somehow, usually with a loop. Another issue is that, as soon as you have more than one of an object, management of the ID numbers of models becomes a problem.

I thought for a while about what would be the best suggestion to give you. On the long run, classes are definitely the way to go, I'm just a bit afraid that the concept of classes is quite a big jump. If you had only one model for each zombie, maybe I would have suggested a simple array of ID numbers for a start, but you have three models per zombie... A data structure where you need to handle data from the outside is easier to understand but eventually more difficult to handle... so well, let's stay with classes.

I must say in advance that there are many ways to design a program and my suggestion here is by no means the only way. Maybe someone else will post soon and suggest something completely different.

Here is a simple class that stores the zombie mode, the ID numbers of the three models that belong to that zombie, and contains two functions.



Then we define how many zombies we need and create an array of them.



To avoid loading models from the disk several times, we load the base models once. Each zombie will have a function that clones the model in memory. Getting a new ID number is solved here by a global variable which is not a very good solution but it was simple to code for an example.



This function will make a new copy of the base models for the current zombie. To make models for all of them you can call the function in a loop:



Then comes the game when the zombies must do something. Here is an example function that calculates distance and sets attack mode for one zombie:



Again, we still rely on global variables (PlyrX and PlyrZ) which is not so good practice but we have to start somewhere. To set the current mode for all zombies, you can call this function in a for loop, as it was done with the setModels function above.

That's how far I got with it. You can see the principle but to be able to use it and code it, read about the usage of classes in a C++ reference.
James V
13
Years of Service
User Offline
Joined: 18th Apr 2011
Location: U.S.A.
Posted: 21st Apr 2011 15:59
Mireben, you have been quite the help! Thank you so much for your time and effort. Your first post about the 'distance calculation' and the 'dbPositionObject' where so helpful. Definitely makes the code a lot more compact.

Before I got your reply though, I did some trial and error of my own. I know that there can be a whole lot of things that can improve the code... but it works.

First, I set a bunch of arrays, at least what I think are arrays:


Then I remade the zombie function:


And rewrote the ComputeDistance function useing your advice:


Now bear in mind that I wrote the code before I read your post, so it’s not as efficient as yours is, and I am going to change it up a bit.
For example, I'm creating a new zombie for each and every one of them, instead of useing 'dbCloneObect()'.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 22nd Apr 2011 11:36 Edited at: 22nd Apr 2011 13:18
It's getting better. So you decided to use several arrays for storing the properties of zombies, that's a good solution too. I have just a few more comments about the usage of those arrays.

Initializing the arrays with listing all the values is usually done when the values are different, for example:



because this kind of array cannot be initialized with a loop. However, when all the numbers are the same, it's better to initialize things with a for loop at the beginning of the game, instead of typing everything and possibly making a mistake in the count of elements.



This structure is very strange:



You shouldn't write code so that you need to repeat the same condition twice. Besides, the N 0-10 doesn't have a real functional meaning here (I return to that in a moment). It would be much simpler to replace the whole thing with this:



Back to that N 0-10... The only meaning I could find for that variable is that you want to avoid creating more than 10 zombies? The easier way to do that is make your arrays size 10 (it's advisable anyway not to allocate more memory for the arrays than what you are really going to use), and then make sure that MaxZombies can never exceed that value, so that the program does not try to write over the end of the arrays. For example:



Notice that if you use a constant for the size of the arrays, then if you want to change the number of zombies later, you only need to change the whole code in one place: the value of the constant. Everything else, like loops and checking conditions will be automatically adjusted to the new value.

(Remark: I see you use += 1 which is very good, but if the increment is only 1, we usually use ++. The += and -= forms are good when the increment is greater than 1, for example -= 5.)

This loop has a similar "beauty problem" than the previous one:



It would be simpler like this:



and no need to increment ZombSync within the loop, since it will be the loop variable itself. If MaxZombies cannot go above 10, then you don't need the N variable here either.

The last thing I noticed in the code is this:



EDIT:
You cannot define a new function within another function. The reason why the compiler doesn't complain is that you put a semicolon at the end of the line, which makes it a forward declaration instead of a function definition, meaning that this line doesn't do anything at all. If you want a new FollowPath function, then move the lines that belong to it outside of the zombie function.
Mireben
16
Years of Service
User Offline
Joined: 5th Aug 2008
Location:
Posted: 23rd Apr 2011 10:37
P.S. On second thoughts I shouldn't have written the remark about substituting += 1 with ++ because it's a question of style, not a problem. The only place I would stick to the ++i form is in a loop header, but otherwise, if you like the other form better then feel free to use it.

Login to post a reply

Server time is: 2024-10-02 17:30:05
Your offset time is: 2024-10-02 17:30:05