Jump to content

Photo

No Name Yet -- CD'awgs Non-ZC Temporary Dev Log

C++

  • Please log in to reply
101 replies to this topic

#61 Saffith

Saffith

    IPv7 user

  • Members

Posted 04 July 2016 - 01:06 PM

It will have to tell the Game Object Manager that it's got an item meant for the other player object and then the Game Object Manager can put it over there.

It's hard to say much without knowing more about how it works, but that sounds suboptimal. Are the tank and soldier totally unaware of each other? It sounds like it would make sense for them to know about each other's inventories, if not simply share one.
 

if I plan on using, say, 50 different .wav files as short sound effects in the game, would it be a massive problem to just load them up all immediately from the hard disk at startup and store them in memory while the game runs?

Load them on demand, I'd say. It may not make much difference in practice, but it's better not to have a bunch of unused data taking up memory.



By the way, relevant book recommendation: http://gameprogrammingpatterns.com/
There's a free web version if you can't/don't want to pay for it.

#62 C-Dawg

C-Dawg

    Magus

  • Members

Posted 04 July 2016 - 11:25 PM

Yeah, the way I set it up, the tank and soldier are both classes.  They inherent from GameObject and PlayerObject.  The Soldier and Tank objects get declared and created by the GameObjectManager class.  So, they can't see each other directly.  They can't even do things like create projectiles themselves, either; they have to tell the GameObjectHandler they want to make one and it takes care of it. 

 

I've been really trying hard to avoid making global variables and functions.  Right now, the only global stuff are some constants, Mappy-related stuff, allegro-related stuff, and the graphics handler.

 

That books looks promising; I'll take a peek!



#63 Anarchy_Balsac

Anarchy_Balsac

    Quest Builder

  • Members

Posted 05 July 2016 - 01:41 AM



I've been really trying hard to avoid making global variables and functions.  Right now, the only global stuff are some constants, Mappy-related stuff, allegro-related stuff, and the graphics handler.

 

The advantage to local variables is that each object gets its own version of the variable.  Globals are extremely useful for when you don't want this to be the case.  You can get around this by passing around locals, but that really is more trouble than it's worth, especially for something as complex is a from-scratch video game (even with canned software).  Avoiding Globals is something they teach you in college, but in the real world, it's not necessary.



#64 Gleeok

Gleeok

    It's dangerous to dough alone, bake this.

  • Members
  • Real Name:Pillsbury
  • Location:Magical Land of Dough

Posted 05 July 2016 - 03:10 AM

The funny part about the guys who say never to use globals, like ever, is that their OS, drivers, software, and libraries they use are built on top of them. Even clib is a global state (heaps, io, etc), and cpp standard libs are basically a templated layer over that. [If you don't believe me then answer this: "int main(argc[], argv)"; Who allocated the memory for the command line args?]

Most games up until the PS2 era I reckon were a whole lot of globals. 2D platformers, puzzlers, arcade games just weren't complex enough to not use them. And by complex I mean they didn't have big-ass game engines back then.

#65 Saffith

Saffith

    IPv7 user

  • Members

Posted 05 July 2016 - 09:38 AM

You can use global variables or not. You just ought to know why you should or shouldn't.
- They're often easier, at least short-term. You don't have to figure out how to get global data to a function that cares about it.
- They create invisible dependencies. You can see what data a function takes as arguments just by looking at the header, but global variables it needs set up can't be determined without looking at the implementations.
- They create static state. Any function may change a variable that affects the rest of the program, so the potential for side effects is huge, and unintended interactions between unrelated areas of code are likely. This is anathema to automated testing.
- They're harder to keep track of. Because they can be changed at any point in the code, there's often no guarantee that they're the same after a given function call.
- They're less flexible. If you ever decide you want another of something, you can't just pass a different variable around.
- They're often good enough. In a small enough codebase or one that will never see major changes, the drawbacks may not matter.

Singletons aren't much better. A Singleton is basically a global variable with more overhead and an uglier interface.
  • grayswandir likes this

#66 C-Dawg

C-Dawg

    Magus

  • Members

Posted 05 July 2016 - 06:51 PM

So, if one were trying to minimize the downside of globals while maximizing the upside, you'd limit their use to things that every game object probably needs to be able to see, but be very diligent about only letting VERY SPECIFIC objects actually change them.  So, for example, the following might be good candidates for being global:

 

Map Tile Data (already global in my code due to how Mappy works)

Graphics Handler (functions and the vector of loaded .pngs)

Sound Handler (functions and the vector of loaded .wavs)

key[8] (the array that holds the keys the player is pushing; I would want to keep the actual modification of this at a high level.)

Game Object Factory (something that any other function can use to spawn GameObjects)

Game Object Vectors (currently, they live in the GameObjectManager, but if they were global anything could create them.  The GameObjectManager would have sole responsibility for updating, rendering, and destroying them)

 

Something like that? 


  • Anarchy_Balsac likes this

#67 Anthus

Anthus

    Lord of Liquids

  • Members
  • Location:Ohio

Posted 05 July 2016 - 08:45 PM

This looks really neat. It takes a lot of will power and motivation to sit in front of a blank screen, and code a game, and make graphics. I support this, and hope to see it finished, and you should really consider trying to get it green-lit on Steam or something. :)

 

Question time! lol

 

Will this have 'levels' or be more like Metroid, and focus on exploring/ finding upgrades to advance? Do you have a lot of ideas for designs, or are you just kind of winging it as the project goes along? End Question time. :P



#68 Gleeok

Gleeok

    It's dangerous to dough alone, bake this.

  • Members
  • Real Name:Pillsbury
  • Location:Magical Land of Dough

Posted 05 July 2016 - 08:55 PM

I'm still working on an rpg (whenever I can make time for it that is--which is apparently never :/ ) and it has very few globals. For example: gameData, database, game, assetManager, soundManager, gameMemory. Technically it doesn't need to have any, but the more you work on games the more crazy pants you realize the dependencies are; everything at some point needs to get info about everything else and it's hard to get around it. You can pass everything by pointers and/or just have everything hold local pointers but I don't like doing it so I don't. Eventually you might have something that looks like this:

Foo* foo = context->GetInstance()->GetWorld()->GetSpatialTree()->GetBucketCollisionResult(context->GetInstance()->GetPlayer()->GetX(), context->GetInstance()->GetPlayer()->GetY())->GetClosestFoo(context->GetInstance()->GetPlayer()->GetX(), context->GetInstance()->GetPlayer()->GetY());
if(foo) ...
If you ever get to this point you should just stop whatever you are doing and take a good long break. Maybe go fishing, bang your head into a wall, see how many toothpicks you can cram into your nose or whatever. :P


I'm also working on a 2D shmup, which has a shit ton of globals. The reason for this is because it started out as a prototype, which means I had a lot of gameplay ideas and needed to get them out as fast as possible. As I get new ideas and put more stuff in I refactor relevant code to remove them, but to be honest it's not really a problem. The main problems from globals is probably state and multithreading.


I'd say as long as your interface looks sane by the time you get to the gameplay stuff then you're doing pretty good and I wouldn't worry about every little detail too much.

Example:
void CockPuncher() {
  Foo* foo = GetClosestFoo(player->position); //compare to above
  foo->Die();
  CreateParticleSystem(mega_explode_with_blood, foo->position);
  PlaySoundFX(someSfxID);
}
If you can easily type your game logic without much fuss and can also instantly read what you wrote last month withot straining your eyes I'd say you're winning.

Also good luck with this! I've written some shitty game prototypes that I've hated and just scrapped let me tell you...

#69 Twilight Knight

Twilight Knight

    Tell all with glee, Argon's on PureZC

  • Members
  • Real Name:Sven
  • Location:Rotterdam, NL

Posted 06 July 2016 - 05:36 AM

Globals? Why no static classes? AssetsManager and such globally used models can be made static so you can access 'em by "Assets.getTexture()" or such. I may just be rambling here though, since I haven't read everything.

 

Are you doing this with a game engine like XNA or from scratch?

 

Anyway it looks good and rather unique, at least I haven't seen anything like it. Good luck!



#70 grayswandir

grayswandir

    semi-genius

  • Members

Posted 06 July 2016 - 08:11 AM

Globals? Why no static classes? AssetsManager and such globally used models can be made static so you can access 'em by "Assets.getTexture()" or such. I may just be rambling here though, since I haven't read everything.

There's not really much difference between the two, functionally. :shrug:


If you really wanted to go all out, you could make the globals actually be read-only views of the actual data, and only let the specific classes that handle them have access to the modifiable versions. That's probably overkill for a project with a single developer, though.

#71 C-Dawg

C-Dawg

    Magus

  • Members

Posted 06 July 2016 - 10:49 AM

Will this have 'levels' or be more like Metroid, and focus on exploring/ finding upgrades to advance? Do you have a lot of ideas for designs, or are you just kind of winging it as the project goes along? End Question time. :P

 

 

Well, the general idea is that this game is to Blaster Master what Zodiac was to the Guardian Legend.  So, yeah, a metroidvania style exploration system where you go in and out of your tank.  I have the item and equipment set planned, different areas planned out in general terms, and the high points of the plot worked out.  The soldier gets items that give him more mobility, and will get items that mimic some classic NES-era power ups, like Scrooge's cane, the Bubble from Bubble Bobble, the Grappling Hook, and that kind of thing.  The Tank gets construction equipment -- excavator, bulldozer, etc -- and upgrades by manipulating its environment. Everything will evolve as I go, of course.  

 

The whole concept is to explore the idea of "Scale."  The soldier operates on a smaller scale than the Tank does, and eventually I want to get the screen size to change fluidly (right now it's just close-up on soldier or far-back on Tank) to allow the scale to change as a dramatic tool.  Like, when you find an ancient ruin or large boss, the camera can pan back to show you the size.  The plot mixes in this scale idea, too.  The backdrop is a universe where no sentient life evolved anywhere except for Earth, but where a few million years after space faring began, Earth colonists have all evolved in different directions.  And, time dilation is a real thing.  So, space-faring are not surprised to find alien life, but just assume it came from Earth at some point.  Settled people may not view it that way, as they have time to evolve, change, develop new culture, forget the past, etc during the thousands of years it takes ships to zip around space.  The spacefarers see the big picture, the settled people see it more narrowly.   Then, the game will explore how the spacefarers, crashing on an alien world, have to confront another idea of scale as they learn more about their environment.  

 

Another way I plan on adding "scale" as a tongue-in-cheek reference is in pitting the player against RPG-style tropes from the indigenous people on the planet and have them react as reasonable people with a GIANT TANK would in that situation.  Evil warlock's army attacking?  Well, I guess we just run them over with a tank and blow up the castle.  I absolutely loathed how StarCraft (and many other games) devolve into SPACE MAGIC, and I want to make a point that things get better and more powerful with progress and time, not WORSE.  Your massive ancient slumbering evil waking up to destroy the world?  Uh, technology has moved on since you were hot, Ancient Evil.  Nowadays anyone with a functioning trigger finger can shoot plasma.  No big deal.

 

Of course, step one is get all the fundamentals in place.  So for a few months more, at least, I'll be taking the advice of people smarter than me on organizing my code as I build it out to cover all the core functionality of the game.  Once I get that working, building the actual world is really not much harder than doing it using ZScript in Zelda Classic.  When I added a new projectile type for the Soldier, for example, it was like a half hour job between drawing it, adding a new object, and connecting it up.  There will be light at the end of the tunnel!

 

Are you doing this with a game engine like XNA or from scratch?

 

My ingredients started with:

Aseprite (for graphics creation)

Mappy (for map editing)

Visual Studio 2010 (for C++ coding and debugging)

Allegro 5.10 (for I/O functions)

Some-Library-That-Lets-Allegro-See-XBox-Controllers-Whose-Name-I-Cannot-Recall (for you know what)

 

Everything else is from scratch.  It's a learning experience! 


Edited by C-Dawg, 06 July 2016 - 10:50 AM.

  • Anthus and Twilight Knight like this

#72 Anarchy_Balsac

Anarchy_Balsac

    Quest Builder

  • Members

Posted 07 July 2016 - 08:35 AM

So, if one were trying to minimize the downside of globals while maximizing the upside, you'd limit their use to things that every game object probably needs to be able to see, but be very diligent about only letting VERY SPECIFIC objects actually change them.  So, for example, the following might be good candidates for being global:

 

Map Tile Data (already global in my code due to how Mappy works)

Graphics Handler (functions and the vector of loaded .pngs)

Sound Handler (functions and the vector of loaded .wavs)

key[8] (the array that holds the keys the player is pushing; I would want to keep the actual modification of this at a high level.)

Game Object Factory (something that any other function can use to spawn GameObjects)

Game Object Vectors (currently, they live in the GameObjectManager, but if they were global anything could create them.  The GameObjectManager would have sole responsibility for updating, rendering, and destroying them)

 

Something like that? 

 

This.  Though there are some creative ideas that may still require globals outside of those.  Such as hive mind enemies that all share a long life bar.  You encounter them throughout the game, but once you kill one, you kill them all.  Globals are VERY useful in such cases.



#73 C-Dawg

C-Dawg

    Magus

  • Members

Posted 11 July 2016 - 05:30 PM

Well, I modified the subscreen to be its own object, and I fixed a persistent bug in how the game was handling warps if the player was out of the tank and moved between rooms.  In doing that, I tried making more of the man data (roomNum and zoneNum) into globals, and stuff started going HAYWIRE for no particular reason.  So... not doing that anymore.  

 

With regard to GameObjectFactory, I think perhaps the thing to do is to make that an object that lives at the WorldManager level, and then pass a reference to the factory to each GameObject.  That way, any object who wants to can tell the GameObjectFactory to spawn something.  I think the same can work with the Key array; just give all Objects access to it so they can all read input when they need to do that.   That's probably my next to-do on the code-organizing side.

 

As to your suggestion about other globals, what I do plan on having eventually is a data structure of some sort to store events.  Like, a flag for each room saying you picked up the item, triggered a secret, killed a boss, that kind of thing.  Even that doesn't have to be global, though; it just has to live at the WorldManager level so it knows what to do when it builds each room from Mappy data.



#74 C-Dawg

C-Dawg

    Magus

  • Members

Posted 06 August 2016 - 08:03 PM

Pogo stick item now functional (pick up, select on subscreen, use to bounce on enemies and ground.) Need to implement damage to enemies and spike immunity for this item next.

EDIT: Destructible blocks implemented. Well, sort of. They go away when struck, but they need to have sound effects and little crumbly graphics. I think I need to make the soundHandler before going any further. Should be a simple afternoon project, based on the graphicsHandler code I already wrote.

EDIT2: Sound Manager done.

 

EDIT3:

Destructible blocks improved; sound effect plays, little boulders fall away.  Needed a new kind of effect, "Falling_Object" for that.

My son asked "how is that tank jumping?" so I added a graphic effect with the impact blast blowing away dust below the tank when it jumps.  Now he gets it.  Also added jumping sound effects.

 

Next up: more enemies!  I think.


Edited by C-Dawg, 08 August 2016 - 11:33 PM.

  • Anthus likes this

#75 C-Dawg

C-Dawg

    Magus

  • Members

Posted 10 August 2016 - 12:01 AM

Added two new enemies; a gnat-like thing that darts around, and a slow projectile spitting thing. 

 

I'm now totally convinced about the wisdom of having a GameObjectFactory and giving every GameObject a reference to it.  Having to bend over backwards to allow the GameObjectManager to spawn everything is a huge pain.  So!  Tomorrow: we start the GameObjectFactory and then spend a few days on the tedious extrication of all spawning activity from GameObjectManager.

 

EDIT: GameObjectFactory up and running!  However, it's a member owned by GameObjectManager.  Thats fine for enemies and such, but at the moment, the Tank and Soldier objects are owned by World Manager, not GameObject manager.  This is poopy and I intended to fix it anyway.  So, next steps:

 

1. Move Tank and Soldier objects into the Game Object Manager with the rest of the game objects;

2. Give all game objects references to the Game Object Factory when they're born; and

3. Make all new game object creation happen in the Factory, not the Manager.


Edited by C-Dawg, 10 August 2016 - 11:56 PM.




Also tagged with one or more of these keywords: C++

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users