Jump to content

  • Log In with Google      Sign In   
  • Create Account


FLeBlanc

Member Since 10 Sep 2011
Offline Last Active Mar 21 2014 04:56 PM
-----

#5071807 Isometric Viewports

Posted by FLeBlanc on 21 June 2013 - 10:20 AM

Well, it's not like you need a full blown tutorial for something as simple as an orthographic projection matrix. It's pretty straightforward. You look at something like this article which shows you what values need to go into what elements, you plug in your left/right/top/bottom/near/far values and boom. You're done.

16e17d5ef9e6865ee357852fa7ba1a6a.png

See?

Think of an orthographic projection as a box. Anything within the box is "flattened" onto one end of the box. This end aligns with the screen. The ends of the box are defined by near and far. The sides of the box are determined by top, bottom, left and right. Together, the 6 values determine the box. It's quite a bit simpler than a perspective transform; there is just no tricky math to it at all. Hence my snarkiness.


#5071801 Isometric Viewports

Posted by FLeBlanc on 21 June 2013 - 09:57 AM

Here are some.


#5070888 How can I read a game source code? (I don't know what this files are)

Posted by FLeBlanc on 18 June 2013 - 12:00 PM

If you don't know much about programming, reading code from complex projects isn't likely to help you out all that much. Some code bases can be difficult to puzzle out even for veterans. 




#5070520 Back to the grindstone

Posted by FLeBlanc on 17 June 2013 - 12:55 PM

Said that I was experience a coding horror of my own. I must have missed the sticky that specified "must contain code",


To be fair, there really isn't any such rule. It's just more fun for us onlookers if you do post code so we can sit back and say, "whoops, yeah, that's a heckuva WTF there, bro" all while busily hiding our own WTFs from public view and pretending like we know what we're talking about and that our own code is pristine and perfect, rather than the WTF-riddled mess of hacks that it really is.


#5070423 Back to the grindstone

Posted by FLeBlanc on 17 June 2013 - 08:19 AM

I see Coding Horrors as more of a TheDailyWTF forum, rather than a place to just vent frustration in a vague, abstract manner. @OP: Post some ugly code for us to mock, dangnabbit!




#5068961 How would I create an 'enemies' database? (Text-based game)

Posted by FLeBlanc on 11 June 2013 - 03:24 PM

If you move away from a simple comma-separated list, then you would be well-advised to look at more complicated solutions such as JSON or YAML. (Or XML, though I personally detest XML and favor less wordy solutions).
 
This is a problem of data description. In this case, your enemies and player would possess both a map of key/value pairs (ie, "Health"=40) as well as an array of other complex data (the list of skills). Depending on how complicated your nested data (in this case, your skills list) gets, you might need to deepen your data description. This is where third-party software can be of immense benefit.
 
Storing your game data in sets of data files is vastly preferred over compiling it directly into the executable as you earlier suggested, in that making a small change or balance tweak won't now force a recompilation of the exe and can, in fact, be done without re-starting the exe as long as you build it to allow run-time reloading of assets and data as needed. In order to do so, you need to layout your data in a sane and sensible format. A comma-separated list is great if you have simple key/value pairs, but once your data layout gets more complicated than that you need more complicated parsing of the file.
 
Parsing is the method for extracting the data from a text file. The file is opened, various tokens are read, and the whole is interpreted according to its structure to populate a chunk of data.
 
So, for example, you could have a data file laid out like this:
 
name="Jim Darkmagic"
type="Player"
class="Wizard"
health=40
magic=100
luck=3
skills=
[
  {
    name="Magic Flame",
    casttype="TargetedArea",
    deliverytype="ExplodeOnHit",
    damagetype="Fire",
    damageradius=3,
    effects=
    [
      {
        name="Burn",
        duration=3,
        damagetype="Fire",
        damage=12,
        description="It burns. I'm burning."
      }
    ]
  },
  {
    name="Mystic Ice",
    casttype="TargetedProjectile",
    deliverytype="SingleAffectOnHit",
    damagetype="Ice",
    damageradius=0,
    effects=
    [
      {
        name="Soothe",
        duration=0,
        damagetype="Ice",
        damage=24,
        description="SHHHHHHHHHINK!"
      }
    ]
  }
]
In this example, the data description involves maps of key/value pairs as well as nested arrays. The skills array holds skill descriptors, and each skill descriptor entry holds key/values and an optional effects array. The effects array holds effect structures (key/value) and could, optionally, nest even further as your design requires.

Now, parsing this sort of structured data is a pretty involved task. You can write your own parser, but that is going to be a pretty involved project. If data parsers are not your "thing" then you can use a third-party library to do it. There are third-party libraries that are open-source and widely available for XML, JSON, YAML, or whatever your desire. My personal favorite is yaml-cpp. It's relatively easy to use, parses YAML in all its forms, and allows you to write code such as this:
YAML::Node data=YAML::LoadFile("JimDarkmagic.dat");

std::cout << "My name is " << data["name"].as<std::string>() << std::endl;
std::cout << "I am a " << data["class"].as<std::string>() << std::endl;
std::cout << "I have << data["health"].as<unsigned int>() << " health." << std::endl;
It effortlessly parses the structure no matter how deep, and gives you access through the Node class to the nested data:
std::cout << "I have the following skills: " << std::endl;
const YAML::Node &skills=data["skills"];

for(int c=0; c<skills.size(); ++c)
{
  const YAML::Node &skill=skills[c];
  std::cout << skill["name"].as<std::string>() << std::endl;
}
Once you have loaded your YAML, you can populate your player or enemy structures from the data contained therein. yaml-cpp takes care of the hard part of doing the actual parsing, letting you spend your time working on gameplay instead.


#5068738 Friend gets application error 0xc000007b

Posted by FLeBlanc on 10 June 2013 - 01:42 PM

Try something like Dependency Walker to validate the dependencies on his machine. This kind of thing happens, for example, if a 32-bit application tries to load a 64-bit DLL or vice versa. Checking the dependencies should give you an idea what to look for.




#5068736 Is this 3d or 2d?

Posted by FLeBlanc on 10 June 2013 - 01:35 PM

By, uh, mixing 3D terrain and 2D sprites. That sample seems to use extremely low-res texturing on basic cube or deformed cube geometry for the ground. For the sprites, just use vertical-axis-aligned billboards, and perform a calculation to determine what sprite set to display based on a comparison of the unit's facing direction and the direction from the unit to the camera.




#5067395 Writer looking for writing advice.

Posted by FLeBlanc on 04 June 2013 - 11:24 AM

To FLeBlanc:
What's the point of a story, if you can pull nothing out of it?

Entertainment. Believe it or not, most people don't read to be lectured to or learn deep moral lessons. They read because they want to find out what happens next, and if the guy is going to get the girl. There are parallels between traditional narrative structure and actual human experience going deep into our evolutionary history, so narratives that can make use of those parallels tug at our heart strings and trigger an instinctive response. We like to hear about Jim defeating the Big Bad Dragon because it reminds us of our own triumphs.

I'm not a moral crusader, in fact the very idea of moral crusading inspires a deep, seething hate within me. I'm a philosopher, and the purpose of any discussion of morals, politics and culture serves that end.

Whatever particular drum it is that you want to bang, if banging that drum is the sole purpose of your story people are going to sense it. They'll put your book down and say "It's okay, but it's just not grabbing me." Because it's the story that is the hook, the story that is going to reach out and grab people and make them want to stick around. If all you are doing is plastering a vaguely story-like veneer on top of a discussion of politics, you are going to drive people away.

In particular, the morality of law comes up a lot in my stories, but despite my best efforts I can't seem to have the discussion come up through the story itself and I don't really want to have a big debate scene to serve that purpose.

Well, if it doesn't come up in the story itself, then it probably doesn't fit that story. The worst thing you can do, in my opinion, is to try to force and wrench your story around to fit your philosophical point. That, to me, represents a form of intellectual dishonesty, and as Stephen King (one of my favorites) is always emphasizing, you have to be honest about what you are saying. People just know when you're bullshitting them. You can tell a lie (that's what fiction is, after all) but you need to be honest in the way you say it.


#5067367 Writer looking for writing advice.

Posted by FLeBlanc on 04 June 2013 - 09:16 AM

Story needs to come first. That is pretty much the first rule of storytelling that any spinner of yarns is going to tell you. Moral message, theme, etc... all of that is just gravy, and should follow on from story, using the story to express itself. Whenever you write, you shouldn't be thinking "how can I lecture the reader about such and such moral crusade I am on?" but instead you should be thinking "how can I craft an entertaining story that will engage people?". People are hard-wired, evolutionarily and biologically speaking, to enjoy a good narrative. What they are not hard-wired for is being lectured to. You can often sneak that stuff in there, but if the story is not strong enough to stand on its own and merely serves as a delivery mechanism for moral arguments, then it's going to fall flat on its face. 




#5066671 Compiler says class has no constructor while it actually has one

Posted by FLeBlanc on 01 June 2013 - 08:20 AM

If the line activity = new Idle(this, NULL); occurs inside Objects.h, as seems to be indicated by the info in the error message, then it's probably because where that line occurs there has only been a forward declaration of Idle. Go read what JTippetts posted again. If you want to use anything that is part of the class Idle (including constructors) then before you do so you have to include the full declaration of Idle. If the compiler encounters new Idle, and it still doesn't know what the fuck Idle looks like because all it has to work from is a forward declaration, then you're going to get that error. Whenever you have cyclical-dependency fuckery, you would probably be better off not putting any executable code at all inside your headers and keep it all to .cpp files.


#5066150 Simple, game structuring problem

Posted by FLeBlanc on 30 May 2013 - 09:11 AM

Have Logic() return a pointer to the game state that should execute next, rather than calling ChangeState directly. I usually structure my code something like this:
 
class GameState
{
public:
	virtual void event()=0;
	virtual GameState *logic()=0;
	virtual void render()=0;
};


void MainLoop::run(GameState *startstate)
{
	currentstate_=startstate;
	
	while(isRunning())
	{
		currentstate_->event();
		GameState *nextstate=currentstate_->logic();
		currentstate_->render();
		
		if(nextstate)
		{
			delete currentstate_;
			currentstate_=nextstate;
		}
	}
}
Note that you should always follow the format of not actually changing the current operating state until you are outside of your input/logic/render functions. If you were to call your Cgame::ChangeState method from inside CGameState::Logic(), then this would delete the object owning the Logic() method you are currently inside, potentially causing all sorts of problems. Instead, you should indicate that a state change is to be made as soon as it is safe to do so, and returning a pointer to the state to execute next is one way of doing so.


#5065825 How long will this take and how much will it cost?

Posted by FLeBlanc on 29 May 2013 - 09:07 AM

Given the absolute wealth of information you have provided, I estimate that it will take exactly 17 months and cost $450,000.




#5065558 Is the game loop suppose to run when the user is in the main menu?

Posted by FLeBlanc on 28 May 2013 - 12:34 PM

A pattern that is commonly used for game state management is for each game state's Update method to return a pointer to the game state that should be made current. If null is returned instead, continue with the current state. So, for example, when the game is started the main menu state is created and set as current. When the Play Game option is selected, then a new Game state is created and returned during Update, so the state manager knows to discard the current state and set the new state as current. During gameplay, if Esc is pressed, a new state (one which keeps a reference to the game play state internally so that it can continue to render the view even though that state's updating is paused) is created for the in-game options menu. If Return to Game is selected, the stored Game state is returned by Update, causing the in-game menu to be discarded.

 

Each state implements its own set of Render and Update functions to perform tasks relevant to that state. The outside loop of your game runs the same, regardless of the currently active state; however, when currentstate->Update() is called, different things happen depending on the current state. You shouldn't be updating your game while in Main Menu, for example (since it shouldn't exist yet). You may need to draw the Game state while in Options menu, but if it's single-player you shouldn't be Updating the game state. And so forth.




#5065538 Storing/Loading Randomly Generated Terrain.

Posted by FLeBlanc on 28 May 2013 - 11:06 AM

If the terrain isn't modifiable, you can simply store the random seed used to generate the chunk. If it is modifiable, you can store the seed plus a list of changes. Either way, when a chunk is to be loaded, you check to see if there is a seed stored and if not, create a new seed. If there is a seed, use it to regenerate the chunk then iterate the list of changes and apply them. If a changes list exceeds some arbitrary threshold, it might be more cost-effective to switch over to storing the whole chunk instead.






PARTNERS