Bay 12 Games Forum

Please login or register.

Login with username, password and session length
Advanced search  
Pages: 1 ... 113 114 [115] 116 117 ... 796

Author Topic: if self.isCoder(): post() #Programming Thread  (Read 882537 times)

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1710 on: February 26, 2012, 11:12:22 am »

I had a general question about C: How would one call functions from different source files? I've got a rough idea for a text-based dungeon crawler floating in my head, and it'd probably be much cleaner to keep things like monsters and loot in separate files.

There's multiple ways to do this. Like fergus said, you can toss all the function prototypes from a file into a header file and #include that, but there's a small gotcha involved. If that header file is included in multiple files in the project, when you go to compile, you'll get a lot of errors about multiple definitions of functions. The simplest workaround is this:

Code: (header.h) [Select]
#ifndef HEADER_H_INCLUDED // Guard word, typically made in the format of NAME_EXTENSION_INCLUDED
#define HEADER_H_INCLUDED

// function prototypes here

#endif

At your point in learning the language, you probably haven't learned much about preprocessor directives like #define and #ifndef, so I'll give you a quick explanation. When this file is included in one of the source files during compilation, it checks to see if the symbol HEADER_H_INCLUDED is defined. If it's not, it defines the symbol, and the rest of the code is included. The next time the compiler tries to include header.h, it sees that HEADER_H_INCLUDED is already defined, so it skips to the #endif at the end of the file. The function prototypes haven't been included in the compiled code again, so no errors.

Gatleos

  • Bay Watcher
  • Mournhold... City of Light... City of MAGIC!
    • View Profile
    • Someone Sig This
Re: if self.isCoder(): post() #Programming Thread
« Reply #1711 on: February 26, 2012, 11:21:12 am »

If you could do a little tutorial, that'd be great.
Okay, how is the slope and box defined and how do you "move" an object?
It's all grid-based, with each node on the grid containing a shape. Each grid can contain a full square, a 1:1 slope (in all four directions), or either half of a 1:2 slope[1] (in all four directions). The grid is used for a coarse collision check, looping through every node that an entity is touching and checking for a collision in that node. As a result, the engine already knows that the entity's AABB is intersecting the node's x and y axes by the time the fine collision detection function is used, so it only needs to check against the slope's axis after that. The objects on the map simply teleport to their new location based on speed every tick, then check for collision. I haven't gotten to the stage where I'm worrying about tunneling through small objects yet.

[1] It could contain either of these (red is a collision):


Hope that was clear enough. :-\
Logged
Think of it like Sim City, except with rival mayors that seek to destroy your citizens by arming legions of homeless people and sending them to attack you.
Quote from: Moonshadow101
it would be funny to see babies spontaneously combust
Gat HQ (Sigtext)
++U+U++ // ,.,.@UUUUUUUU

malloc

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1712 on: February 26, 2012, 11:52:47 am »

Oh, and to add a few extra notes to Mego's already good explanations.
First of all, you can call your guard words whatever you like. In the last project I worked in, we used this naming scheme:
__[First letter in Core Name][Module Name] so, for an example a header for mathematics could look like this __mQUATERNIONS. But yeah, it's just to illustrate that you can name them anything, as long as the naming is consistent. Also, adding underscores will generally keep them away from important code when using code suggestions. (Yes I am a big fan and user of intellisense)
Another thing you should remember when using headers is the guard word #pragma once.
Instead of writing:
Code: [Select]
#ifndef something
#define something
//Interface
#endif
You can write:
Code: [Select]
#pragma once
//Interface

The reason why it's smart to use this keyword is that major compiler actually are optimized to make use of the pragma once keyword. The #ifndef guard will make the compiler scan the file each time to find the #endif. Which, if the file is used in many other files, will slow down compilation.
#pragma once is however not a standard preprocessor directive, and some compilers will not support it. That is why you can, if you want, include both:
Code: [Select]
#pragma once
#ifndef something
#define something

//Here you put your interface.

#endif

This will keep the code portable, but still make use of the pragma keyword if the compiler supports it.


@Gatleos, I think simply adding the slopes max height to the object when it "stands" on a slope is probably the easiest solution with the setup you're using.
I don't really know what else to say, I just don't think I quite understand what you mean. Sorry!
Logged

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #1713 on: February 26, 2012, 11:59:30 am »

Galteos, how are you attempting the conflict resolution at the moment?

My first instinct would be to figure out the equation of the line between the centre of the object and the tile, figure out how much of that line falls within both the object and the 'red' part of the tile and then move the object along the line away from the tile by that much. Do this for either x iterations or until their is no overlap between that object and any red tiles.
« Last Edit: February 26, 2012, 12:07:16 pm by MorleyDev »
Logged

Gatleos

  • Bay Watcher
  • Mournhold... City of Light... City of MAGIC!
    • View Profile
    • Someone Sig This
Re: if self.isCoder(): post() #Programming Thread
« Reply #1714 on: February 26, 2012, 12:09:23 pm »

@Gatleos, I think simply adding the slopes max height to the object when it "stands" on a slope is probably the easiest solution with the setup you're using.
I don't really know what else to say, I just don't think I quite understand what you mean. Sorry!
Really, all you need to know is that all moving objects are AABBs and I need them to detect collision with sloped surfaces properly. You didn't need that detailed explanation I gave.
Galteos, how are you attempting the conflict resolution at the moment?

My first instinct would be to figure out the overlap, figure out the equation of the line between the centre of the object and the tile, figure out how much of that line falls within the overlap and then move the object along the line away from the tile by that much. Do this for either x iterations or until their is no overlap between that object and any tiles.
The main problem is figuring out which axis to push the object out on. If it collides from the bottom, flat edge of the slope, I need it to push the object downward rather than teleporting it above onto the sloped part. I just can't find an efficient way to determine which side it collided from.
Logged
Think of it like Sim City, except with rival mayors that seek to destroy your citizens by arming legions of homeless people and sending them to attack you.
Quote from: Moonshadow101
it would be funny to see babies spontaneously combust
Gat HQ (Sigtext)
++U+U++ // ,.,.@UUUUUUUU

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #1715 on: February 26, 2012, 12:14:20 pm »

The main problem is figuring out which axis to push the object out on. If it collides from the bottom, flat edge of the slope, I need it to push the object downward rather than teleporting it above onto the sloped part. I just can't find an efficient way to determine which side it collided from.

That should only happen with a sufficiently large time-step or fast object where the centre of the object goes past the centre of the tile. If your tiles are 32px wide and you're time step is 1/60th of a second (I assume your timestep for physics is fixed), then this would admittedly be a problem if you had an object moving at 480 pixels or more a second on full tiles and 16px on half-tiles.

You could have some sort of check against the direction of velocity or original position of the object to make sure the object hasn't gone past the centre?
« Last Edit: February 26, 2012, 12:30:35 pm by MorleyDev »
Logged

Nadaka

  • Bay Watcher
    • View Profile
    • http://www.nadaka.us
Re: if self.isCoder(): post() #Programming Thread
« Reply #1716 on: February 26, 2012, 12:19:42 pm »

Yes, you can use the vector of motion of the object, and its fairly simple math the reflect a vector off a flat surface.
Logged
Take me out to the black, tell them I ain't comin' back...
I don't care cause I'm still free, you can't take the sky from me...

I turned myself into a monster, to fight against the monsters of the world.

Sirus

  • Bay Watcher
  • Resident trucker/goddess/ex-president.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1717 on: February 26, 2012, 01:28:08 pm »

Quote from: Mego
-stuff-
Quote from: malloc
-more stuff-
I think I understood maybe 1 in 5 words. Don't worry about it, I've still got a long ways to go.
Logged
Quote from: Max White
And lo! Sirus did drive his mighty party truck unto Vegas, and it was good.

Star Wars: Age of Rebellion OOC Thread

Shadow of the Demon Lord - OOC Thread - IC Thread

Levi

  • Bay Watcher
  • Is a fish.
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1718 on: February 26, 2012, 01:29:03 pm »

Yeesh.  Its crazy how much code I got to write just for infrastructure for this game, and there is still no end in sight.  This certainly has been an educational experience.  If I ever manage to finish I'll feel a lot more confident about building something more complex.   :P

Logged
Avid Gamer | Goldfish Enthusiast | Canadian | Professional Layabout

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1719 on: February 26, 2012, 02:11:30 pm »

Oh, and to add a few extra notes to Mego's already good explanations.
First of all, you can call your guard words whatever you like. In the last project I worked in, we used this naming scheme:
__[First letter in Core Name][Module Name] so, for an example a header for mathematics could look like this __mQUATERNIONS. But yeah, it's just to illustrate that you can name them anything, as long as the naming is consistent. Also, adding underscores will generally keep them away from important code when using code suggestions. (Yes I am a big fan and user of intellisense)
Another thing you should remember when using headers is the guard word #pragma once.
Instead of writing:
Code: [Select]
#ifndef something
#define something
//Interface
#endif
You can write:
Code: [Select]
#pragma once
//Interface

The reason why it's smart to use this keyword is that major compiler actually are optimized to make use of the pragma once keyword. The #ifndef guard will make the compiler scan the file each time to find the #endif. Which, if the file is used in many other files, will slow down compilation.
#pragma once is however not a standard preprocessor directive, and some compilers will not support it. That is why you can, if you want, include both:
Code: [Select]
#pragma once
#ifndef something
#define something

//Here you put your interface.

#endif

This will keep the code portable, but still make use of the pragma keyword if the compiler supports it.


@Gatleos, I think simply adding the slopes max height to the object when it "stands" on a slope is probably the easiest solution with the setup you're using.
I don't really know what else to say, I just don't think I quite understand what you mean. Sorry!

I stayed away from #pragma because it's not in the standard, so not all compilers will support it. If yours does, that's great, take advantage of what it can do. However, as you said, not all compilers support it, so I prefer to stick with the #define method, as that directive is in the standard.

Another way to solve the function-is-defined-elsewhere problem is to still have the function declared as normal in the file you're using it in, but prepend the declaration with extern. That will indicate to the compiler that the definition is in another file.

Code: (a.c) [Select]
#include <stdio.h>

void print(char* msg) {
    printf("%s\n", msg);
}

Code: (main.c) [Select]
extern void print(char*);

int main() {
    print("Hello, world!");
    return 0;
}

EDIT: Forgot to put "void" in the declaration in main.c.
« Last Edit: February 26, 2012, 03:18:48 pm by Mego »
Logged

malloc

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1720 on: February 26, 2012, 02:49:14 pm »

Interesting, I did actually not know you could do that, but I think it makes a lot of sense. I usually use the extern keyword to make global objects, it's much better than using singletons in my opinion.
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1721 on: February 26, 2012, 03:20:50 pm »

For global objects, I typically define them as static in a header file that gets included in every source file. I usually have a file called includes.h that includes all the other headers I create for a project, as well as defines global objects, and include that in every source file.

MorleyDev

  • Bay Watcher
  • "It is not enough for it to just work."
    • View Profile
    • MorleyDev
Re: if self.isCoder(): post() #Programming Thread
« Reply #1722 on: February 26, 2012, 03:34:33 pm »

For global objects, I typically define them as static in a header file that gets included in every source file. I usually have a file called includes.h that includes all the other headers I create for a project, as well as defines global objects, and include that in every source file.

Aren't statics unique to a translation unit? I thought in C (like C++) you declared global variables you want to cross source files as extern...
Logged

Mego

  • Bay Watcher
  • [PREFSTRING:MADNESS]
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1723 on: February 26, 2012, 03:37:07 pm »

Statics are unique to a program, not to a translation unit. That's another way to avoid using guard words in header files: declare everything static.

malloc

  • Bay Watcher
    • View Profile
Re: if self.isCoder(): post() #Programming Thread
« Reply #1724 on: February 26, 2012, 03:38:49 pm »

I thought so too Morley.


It's funny Mego, I usually never bundle headers and global together, other than for the most basic and needed stuff.
(STL, openGL loaders, etc etc.)

I always try to make interfaces as clean as possible. If I can avoid it, I never include anything in my headers, so if I want one component, I can just include that one component, and I don't get anything extra. It is the basic c++ mindset, you should only get what you actually need/use.
Logged
Pages: 1 ... 113 114 [115] 116 117 ... 796