Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411516 Posts in 69380 Topics- by 58436 Members - Latest Member: GlitchyPSI

May 01, 2024, 10:15:57 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsDeveloperTechnical (Moderator: ThemsAllTook)The "Why didn't I think of that before?" thread
Pages: [1]
Print
Author Topic: The "Why didn't I think of that before?" thread  (Read 1703 times)
baconman
Level 10
*****


Design Guru


View Profile WWW
« on: July 10, 2010, 09:17:21 AM »

Shooting through some problems with parent-childing between "playershot" and "enemyshot" objects, after attempting to idiotically parent one from the other, in a vain attempt at avoiding the "two of every object" thing... just a bit ago it hit me to make a central "shot" object, and simply parent them both off of that, setting each "side" to only respond to the other's shot types.

 Facepalm

I love/hate this feeling. I mean, I hate it because it makes me feel stupid, like I should've KNOWN to do that all along. But I love it, because when I get that feeling, it usually means I've found the right solution, and it's no longer a problem anymore.

Anybody else here have some moments/experiences (and maybe lessons along with them) like that to share?
Logged

Vino
Level 3
***


View Profile
« Reply #1 on: July 10, 2010, 11:50:58 AM »

You can also make a "shot" object without the playershot and enemyshot subclasses that changes behavior based on whatever parameters you pass into it. For example,

if (type == playershot)
  damage = 50;
else
  damage = 20;

If there's not a lot of difference between the player's shots and the enemy's shots then it might work for you.
Logged
oahda
Level 10
*****



View Profile
« Reply #2 on: July 16, 2010, 03:41:54 AM »

Ahem.

Code:
damage = (type == playershot) ? 50 : 20;

Thank you.
Logged

Vino
Level 3
***


View Profile
« Reply #3 on: July 16, 2010, 05:04:33 AM »

Alright mister smarty pants, you know full well those two are the same thing.
Logged
bateleur
Level 10
*****



View Profile
« Reply #4 on: July 16, 2010, 08:39:49 AM »

And the former is arguably better style.

And in practice I'd prefer a switch statement to either. Wizard
Logged

Linus
Level 0
***


View Profile
« Reply #5 on: July 16, 2010, 09:23:07 AM »

Ooh, I know this feeling.

I had a setup with a factory that produced objects of base type A, the problem was that A was not generic enough for the purposes I wanted to use it for, so I set up another type, B, which could be used under those circumstances.
The problem was that when I produced A, I had a set of parameters that I had to configure on it, and I needed the same parameters configured on B, this meant I needed to reimplement a base class C for A in B. I say re-implement because there was another class specifying a certain behaviour for A, which also needed to exist on its own, but wasn't always necessary in B, and sometimes prohibitive:
A now inherits B and D.
B and D both inherit C.
This meant that I had now arrived at a famous problem, the diamond problem.

Seeing as I worked in C++, I put some effort into figuring out how this problem worked, and what it meant.
What happens is that, since you have two of the same class in two different classes, you get two(!) instances of the classes connected by the diamond. Some more exploration revealed that inheriting virtual classes solved the problem and created some new ones in C++. I read onwards a bit, digressed onto other topics, then I realised my folly.
In the end, the solution was this:
B did not have to inherit C. Instead, this:

class C {/*...*/};
class D : public C{/*...*/};
class B {
public:
   virtual C* getC() = 0;
};
class A : public D{
   C* getC(){return this;}
};

Oh, the Facepalm.
Logged
oahda
Level 10
*****



View Profile
« Reply #6 on: July 18, 2010, 04:42:41 AM »

Alright mister smarty pants, you know full well those two are the same thing.

I'm at least very happy that you didn't use brackets.
Logged

Vino
Level 3
***


View Profile
« Reply #7 on: July 18, 2010, 02:08:18 PM »

Question mark colon notation ain't so bad, I use it sometimes, just not for simple if statements like that. Here's a real-world example of me using it:

Code:
	Vector vecAttackDirection = ((bDirectHit?pAttacker:pInflictor)->GetOrigin() - GetOrigin()).Normalized();

I only use it for things where I won't need excessive parenthesis to make sure that the order of operations will run properly.

Re: Diamond problem, I'm pretty sure C++ will only make a single instance of the parent class, class C in your case. I don't think I have this problem in my game (I avoid it) but I think I've run into it before and some careful specifications of what should call what can make sure it's not a big deal.
Logged
Linus
Level 0
***


View Profile
« Reply #8 on: July 18, 2010, 09:45:34 PM »

C++ specs say that if you have two parents inheriting the same class, there'll be two objects unless you use virtual inheritance, all cases.

As for brackets, before I often had a tendency to squish
Code:
if (type == playershot) damage = 50; else damage = 20;
things together when there's one-line commands, giving me a visual cue that it's a bracket-free if-statement. Lately though, I'm prone to split the lines anyhow and still skip the brackets, allowing auto-indentation to do the visual work for me. ?: is also very nice when applicable.
Logged
Pages: [1]
Print
Jump to:  

Theme orange-lt created by panic