Jump to content

  • Log In with Google      Sign In   
  • Create Account

DekuTree64

Member Since 29 Aug 2000
Offline Last Active Oct 03 2015 06:46 PM

#5243020 Breaking out of a nested loop

Posted by DekuTree64 on 27 July 2015 - 12:20 PM

If you've got two for loops you're looking at O(n*n) execution times.I'd be tempted to refactor the code and eliminate the for loops if possible but that's just me...

In all seriousness, I'd be interested to see that.

for(int i = 0; i < 100; ++i)
{
    if(((i / 10) - 1) == ((i % 10) + 1))
        break;
}
at least 1 is gone and we only need a normal break tongue.png

And suddenly the code is more complicated and about 10-100x slower, because the divisions are taking many more cycles than the other simple operations.

for(int i=0,n=0; n<10; n += ((i+1)==10), i+=((i+1)==10)*-9+((i+1)!=10)){
}
look ma, no division or additional branching tongue.png


Anyone else who is going to stop using nested loops at all?


Help! How do I break out of nested quotes??

break;

If you want to see a real masterpiece, look at page 3 or 4 of the comments here https://derpibooru.org/883523


#5241072 How do you write this down?

Posted by DekuTree64 on 17 July 2015 - 10:29 AM

Two more versions smile.png These are not precisely equivalent to the original, because of the x != 0 condition instead of < or >. But if x is guaranteed to start off in the direction that it will reach 0 without having to wrap around the long way, then they should work.
int inc = 1;
bool (*f1)() = doA;
bool (*f2)() = doB;

if (v <= 0)
    inc = -1, f1 = doB, f2 = doA;

while(x != 0)
{
    x += inc;
    y += x - inc;
    z += y + inc;
    if (f1())
        f2();
}
int inc = v > 0 ? 1 : -1;

while(x != 0)
{
    x += inc;
    y += x - inc;
    z += y + inc;
    if(v > 0) { if(doA()) doB(); }
    else      { if(doB()) doA(); }
}



#5240618 Has anyone got a feeling of this when you were starting as game developer?

Posted by DekuTree64 on 15 July 2015 - 05:10 PM

I feel like I'm cheating by not refining my own silicon to grow into crystals to cut wafers and make microchips to program my games on.




#5240487 Has anyone got a feeling of this when you were starting as game developer?

Posted by DekuTree64 on 15 July 2015 - 08:04 AM

Excellent post, n3Xus smile.png
 

5) You realize that for almost every new gameplay feature you want to add you need to write a entirely new part of the engine.

Exactly. This is what "make games, not engines" means. Trying to anticipate everything you'll need just ends up making a bunch of wasted functionality.
Do the bare minimum to get stuff moving on the screen, and then write only what you actually need for this specific game.
 

6) Eventually you create a simple prototype for your game and you realize that you hardly even wrote any gameplay code, you mostly just added engine functionality.

Yep, this is another big one. Gameplay code is hard to envision, and under-taught compared to engine code. Small games like Pong/Tetris are easy, because everything just does what it does until some condition happens and the game is over. But in an adventure or RPG type game, you need some way of defining where enemies/interactable things are on maps, some way to control what gets spawned when, and how to control the game progression. A lot of the time it can feel pretty silly how simple it is... just place an object in front of a door, and when some variable is set, remove the object. But I would recommend starting early on this aspect of the game, to be sure that all the gameplay code you write can interact properly with the level data and game progression.
 

12) You stop working on your game because you lose motivation.

The nearly inevitable end to all amateur games tongue.png Anticipate it, and prepare yourself emotionally to muscle through it. IME, games tend to go in this progression:
1) Yay! Everything is clean and new, the possibilities are endless!
2) It's starting to get cluttered and it doesn't really do anything yet.
3) Miserable, endless code. More and more and more, for months on end, and it just looks like a random collection of features, not a functioning game.
4) All the main features are more or less done. Running out of time. Bugs everywhere. Fix bugs. More bugs. Why does it still not look like a game?
5) Wait a second, it looks like a game now? It's done? Yay!
6) If you have any time left, go beyond simply making it function. Add little finishing touches to make it really special.

 

...and that's if you have other people making all the artwork/level design for you.




#5240294 Has anyone got a feeling of this when you were starting as game developer?

Posted by DekuTree64 on 14 July 2015 - 12:17 PM

Yep. But eventually I realized that eschewing the use of all libraries is another form of cheating. To be a software developer requires constant learning and adaptation. One way or the other won't cut it unless you're a hobbyist working alone. Learn how to create games from scratch, and learn how to use engines to save yourself the time. And by then the industry will be different, and you'll have to learn a bunch more stuff tongue.png




#5240176 Outside simulator help for giant ping pong game!

Posted by DekuTree64 on 13 July 2015 - 08:29 PM

Sounds like a fun project :) My first thought is to have each player wear a belt with infrared LEDs on it, and put two IR cameras in the center of the field to watch them, and calculate their positions by finding the bright spots in the video data. Either that or put the LEDs on their heads and a single camera above the field, if there's a convenient place to hang it.

 

Either way, it would be a lot like the wii remote and its sensor bar... except in that case it's the camera that's moving.




#5240171 Efficient 2D collision detection with many dynamic OBB

Posted by DekuTree64 on 13 July 2015 - 08:01 PM

Yeah, use circles for the bullets. To do a circle->OBB check, subtract the box center from the circle center, and then rotate the circle center by -boxAngle. Then it's just a regular circle->AABB check.

 

And since it looks like your boxes will tend to be in clumps that share the same angle, you could probably optimize it further by making a "box group" collision object, which has a center point, and list of child boxes relative to that point. Then inverse rotate the circle center around the box group center, and you can check against all the child boxes without having to do the rotation operation every time. But it might not be worth the effort since every time the enemy is split into two chunks, you'd have to split the box group as well, and recalculate the box positions relative to the new center points.




#5237200 how to program A LOT of skills/spells?

Posted by DekuTree64 on 27 June 2015 - 11:13 PM

A function pointer table and array of unlock flags would be better.

 

As for how to code them, the more you know upfront, the better. If you've already designed all of them, then go through the list and write down groups of skills that have common elements to them. Then write functions to do the common things. Use data tables when possible, where you index in with the skill ID to get whatever values the common function needs. Doing huge if/else chains or switch statements is ok sometimes too, but tables are usually nicer to work in. Keep the individual functions for each skill short when possible, mostly making calls to common functions. Easier to navigate and work in than a scattering of long and short functions.




#5177600 For-loop-insanity

Posted by DekuTree64 on 02 September 2014 - 12:51 AM

Classic mistake. There is a generic way to make it work, if you really want to, though:

uint8_t j = 0;

do
{
  printf("%i\n", j);
}
while (j++);

Which is pretty readable, since the while loop is clearly going to terminate as soon as j overflows. And like Ravyne said, it doesn't really make anything faster in general, that said I personally don't see this as an optimization tactic, but more as a type correctness thing, in other words, the loop variable is going to be used as an 8-bit unsigned integer, so let's not lie to ourselves, make it an 8-bit unsigned integer. But with this comes the responsibility of watching out for overflow and other low-level things which generally don't come up when simply using a sufficiently large signed integer like int, people will have their own opinions on that matter smile.png

Don't you mean ++j?

 

I just tried it on ARM7, which has only 32-bit registers, and it compiled to a compare with 256, branch if not equal. So it doesn't actually force the wrapping, but did get the logic correct, and no different than using an int and comparing with 256.




#5173199 Can't solve problems without googling?

Posted by DekuTree64 on 12 August 2014 - 04:31 PM

Lots of good answers here. I especially like Glass_Knife and phantom's.

 

Another thing you can do is read just the overview of the solution, and try to work out the details yourself, but with a chicken exit if you need it.

 

Also, don't be afraid to solve the same problem more than once :) Sometimes when you have a large and complex challenge, you just have to dive head first into it and make a big mess of code. Then refactor and it looks a little better. But with your deeper understanding of the problem, you might be able to approach it from a different angle and come up with a more elegant system overall.

 

A good example for me is side scroller collision detection with slopes. It seems so simple, and often it is, depending on how many cases you want to handle. But it can get really complicated if you want to support slopes steeper than 45 degrees, sloped ceilings, not having off-by-one problems between left and right slopes, colliding the center of your rectangle with the slope but corner when standing at the edge of a solid tile, etc. I finally managed a system that does everything I want, but it's not quite the level of elegance I want to reach before writing an article series on it (because all the articles I've read don't solve it completely). So one more iteration, one of these days :)




#5147238 How to stop users from manipulating Game Save Data

Posted by DekuTree64 on 15 April 2014 - 06:48 PM

First thing, don't make it so readable tongue.png Use meaningless labels, and no newlines so it's a pain to find the number you're after.

 

Second, do some sort of encryption on the numbers (could be as simple as differential encoding, so changing one number modifies everything after it).

 

For a single player game, there's no need to prevent save hacking... just deter it so the player doesn't feel like they're wasting time by playing the game when it would be so easy to type in a number. If anyone cares enough to make a save editor tool, let them have their fun.




#5146917 I need help with matrices

Posted by DekuTree64 on 14 April 2014 - 09:20 AM

Not meaning to hijack the thread, but I suspect using matrices would help me too.

 

I have a camera class, it has this simple function to apply it.

//Some weird shit going on here
//Old comment but kept for lols
void Camera::ApplyICam()
{
  glRotatef(-m_rotation.m_xValue*180/PI, 1.0, 0.0, 0.0);
  glRotatef(-m_rotation.m_yValue*180/PI, 0.0, 1.0, 0.0);
  glRotatef(-m_rotation.m_zValue*180/PI, 0.0, 0.0, 1.0);

  glTranslatef(-m_position.m_xValue, 
               -m_position.m_yValue, 
               -m_position.m_zValue);
}

 

 

My object class also stores position and rotation as two 3 dimensional vectors. Using this system I can move my camera and view my objects just fine, the problem comes when I want to rotate the object.

 

Doing a simple initial rotation is easy, I simply set my m_rotate in object, my question is how to rotate my object after this initial rotation. Say we have an aircraft and I want the plane to bank left aka roll anticlockwise along it's central axis by say 15 degrees. I am unsure how to calculate this rotation given that the plane is no longer aligned along one of our axis, it has its own arbitrary axis. Simply put I cannot figure out how I need to alter my initial rotation.

 

Here is part of my code showing the order of transformations

  glLoadIdentity();
  cam->ApplyICam();
  obj->AddRotation(0.0, 0.025, 0.0);
  obj->ApplyTransformations();
  obj->GetMesh()->DrawMesh();
  cam->ApplyICam();

This code correctly draws my object in position, spinning around the y axis by 0.025 per frame. What I want to know is how to make my object bank as described above, no matter how it happens to be rotated at the time.

 

I am sorry for the poor description, I have always had a hard time visualizing these rotations 

This is where you get into "incremental rotations". Store the aircraft's orientation as a matrix (or quaternion), and when the player wants to turn, generate a pitch, yaw or roll matrix with the small angle delta (your 0.025 value) and multiply the orientation by it. So for example a yaw rotation will rotate around the plane's current up axis, modifying the X and Z axes in the process. Then next time you want to do a pitch rotation, it will be around the modified X axis..It doesn't really matter what order you do them in if the player wants to rotate around multiple axes at the same time, since the change is so small each frame.

 

It can be more tricky at first, working with the orientation as a matrix/quaternion rather than angles, but it's actually easier once you get the hang of it. For example, if you want to move the plane forward, just multiply a vector (0,0,speed) by the orientation, and add it to the position.

 

And don't forget to re-normalize/orthogonalize the orientation periodically to correct any numerical accuracy problems that accumulate.




#5128303 "Oh God, Who Wrote This?", "You Did", "Wait? I wrote Thi...

Posted by DekuTree64 on 02 February 2014 - 08:22 PM

laugh.png That is indeed horrible. Way too many parenthesis to keep track of what's inside what (and some are entirely unnecessary). Try separating the function arguments onto separate lines so you can see them, and separate out some of the repeating ugly things into variables.

for (totalMatches = 1; totalMatches <= (pIt)->first->getSize(); ++totalMatches)
{
    int eventIndex = eventLog.size()-totalMatches;
    const Event *event = eventLog[eventIndex];
    if (!(pIt)->first->compare(
         (pIt)->first->getSize()-totalMatches,
         event->getType(),
         translator->translate(event->getKeyCode()),
         getTimeDiff(eventIndex)))
         break;
}

Or better yet, put the whole thing in a function that returns true at the end, and have the if statement return false instead of breaking.




#5108384 Appropriate number of bugs

Posted by DekuTree64 on 10 November 2013 - 07:39 PM

If those are the kind of bugs you have, then go fix 'em. Most of those sound less like mistakes and more like incomplete features. Minor visual things like shadows and model intersections won't impede anyone's work, so they can be put off until later, but failing to load or unload objects should be fixed right away.

 

The helper guys not helping is just an incomplete feature, so if someone was scheduled to do it and didn't finish it, then add it to their schedule for next iteration. If they did everything that could be done for the initial implementation given the state of the rest of the game at the time, then add it to their schedule whenever all the other prerequisites are up to speed. When you have a lot of things that interact with eachother, it can take several rounds and a lot of meetings to finish them.

 

As you gain experience, you'll get better at the analysis phase and foresee more details before writing any code. But you should also test code as you write it. For example, the thing of facing the wrong direction when loading the game... that should be pretty obvious if you test the loading code in a few different levels to make sure it's working before checking it in to source control. And you shouldn't check "implement save/load" off the list if you know it's not done yet.

 

And certainly not all bugs are created equal. Personally, when I track down a really tough crash bug, it's satisfying enough just to finally understand it and add it to my knowledge base of what to look out for in the future. But if alcohol motivates you, and it takes you all night to fix a bug, then take off early the next day and party :)




#5102310 "Pixel-Perfect" Collisions...

Posted by DekuTree64 on 17 October 2013 - 11:03 PM

What kind of game? I don't know of any tutorials, but for collision detection, it should be pretty straightforward. I'd do it with bitmasks, where each bit corresponds to one pixel of the sprite (1 for solid, 0 for non-solid). Then bitshift according to the sprites' relative X positions, AND together, and if the result is zero, no collision. Nonzero means one or more pixels overlapping. If you limit your sprites to 32 pixels wide, the collision mask can just be an array of 32-bit unsigned longs, one for each row of pixels in the sprite.

 

But I'd only use it for detection of collisions with bullets or other attacks, not for anything motion related. Motion is hard enough with geometric shapes, and pixel perfect might not behave well even if you did get it working (snagging pixels of the character on ledges and such)






PARTNERS