Jump to content

  • Log In with Google      Sign In   
  • Create Account


Member Since 17 Dec 2009
Offline Last Active Today, 03:37 AM

#5145344 Leveraging multiple monitors

Posted by Strewya on 08 April 2014 - 08:23 AM

Having recently bought myself two wide screen monitors purely for development purposes, i began thinking about potential design choices for games which could leverage the users' extra monitors.


I am not aware of any games that use multiple monitors in an interesting gameplay-wise way, similar to what the new consoles are offering with their "LCD screen on your controller" scheme, and having a minimap always shown on the other display (i remember seeing that somewhere).


Note that this shouldn't apply to multiplayer games because you want to have maximum fairness in those, where neither player has an obvious advantage just because they have more money to throw at peripherals, but rather single player games.


The choice also has to be optional because not everyone has more than one monitor, and the game still needs to be playable on a single monitor computer.


If you had the money/freedom/need to design an optional feature for multiscreen setups, what would it/they be? Minimap on the second screen? List of party members? Inventory always shown?


I'm interested to see what different people would do if they had the option. :)

#5145242 Question regarding Box2D

Posted by Strewya on 08 April 2014 - 12:44 AM

I used box2d to make Pong. That's overkill. But it was a fun experience, and helped me learn box2d and it's applications.


Saying box2d is overkill for a platformer means nothing if you don't have the full list of features of the game, and none of those features include anything remotely complex and related to movement, collision and collision response.


I'd say, try getting as far as you can without adding new movement/collision/response code. If you can implement your whole game without adding code for these things, you're golden. If you find yourself adding new code for these things because you need them, consider box2d.

#5144282 Mapping Multiplayer Controls for Play on a Single PC

Posted by Strewya on 04 April 2014 - 01:35 AM

You should also be wary of hardware limitations. Some keyboards can't have more than 2-4 keys pressed with them registering as individual keypresses. This has to do with the interface type of the keyboard (PS/2 or USB), the type of keyboard (mechanical vs membrane) and the build process (how the internal hardware registeres key presses).

Look into ghosting and key rollover for more info.


What you plan here is having 2 players on one keyboard. If we assume the minimal number of simultaneous key presses required is 2 (diagonal movement), then you'll reach the maximum number of registered key presses really fast (for people who have (2|3|4)-KRO keyboards), with the result of only one player moving, or both players moving in only one direction (and not diagonal which they wanted). I suggest you provide alternative input devices for extra players on the same computer, otherwise your game might be unplayable for some people.

#5139928 Forward declared returned reference

Posted by Strewya on 18 March 2014 - 02:48 AM


It is possible to declare a pointer to a declared but undefined type. But Visual C++ does not allow a reference to an undefined type.

The following sample generates C2027.

// C2027_b.cpp
class A;
A& CreateA();

class B;
B* CreateB();

int main() {
CreateA(); // C2027
CreateB(); // OK


You're basically hitting a VC++ limitation with references to declared but undefined types.

#5138641 Spritesheet animation storage

Posted by Strewya on 13 March 2014 - 03:30 AM

I'll describe my way, which i've only started implementing, so i might miss some details.


I have several classes which are used for a specific task.

The Spritesheet class has a string name for identification, a list of images and a texture ID. The idea here is that a spritesheet is just a definition of where the individual sprites/images are on some texture.


Then i have an Animation class which also has a name for identification, has a spritesheet ID, a sequence of images (stored as indices for the spritesheets image list), and the default duration and repeat info. The idea is that an animation is just a sequence of images which are located on some spritesheet, and which has a default duration and whether it should be looped by default or not.


Then, i will have (not implemented yet) and AnimationSystem which internally has a list of current animations to update. Lets say, an AnimationController, which references an Animation instance and a Spritesheet instance, pulls data from them and executes certain animation logic. It all depends on a timer which controls the animation direction (feeding the timer a negative time delta will move the animation backwards), where each animation controller has its' own timer, and its' own internal set of control variables. The output of the whole system is the image which should be provided to the graphics system (along with the texture ID from the spritesheet) so the correct image can be drawn on the screen.


This all is just the animation part. In order to control which animation should be played, you need to have a separate system/logic which checks the animated objects' internal state, and depending on it sets which animation should be played by the animation system. For this, refer to what EricsonWillians said: if your object is running, set the animation to "running", if you press the key which translates to the WALK command, set the animation to "walking", if your object dies, play the "death" animation, which, when it finishes, does not have a next animation, but simply forever on draws the same image of the object being dead.


It would also be very useful to have some kind of notification/callback/flag that tells you when a non-looped animation has finished, so you can set the next animation to be played.

#5137124 How to make spread when shooting? and rotate bullets correctly?

Posted by Strewya on 07 March 2014 - 08:28 AM

If you want a spread pattern that is independent of the distance from the cursor, compute the angle to the cursor that you're firing the bullets towards and apply a small randomized +/- offset to that angle for each bullet fired.  The maximum allowed offset will dictate how much spread you have, and it won't matter whether the cursor is right in front of the gun or on the other side of the screen.

If you mean angles by using radians/degrees, wouldn't that require a sin/cos calculation each and every time you create a bullet, which is fairly expensive?


I believe it's easier to do what Vortez said. Calculate the direction vector from player pos to cursor and normalize it, then multiply it by a constant distance, and keep everything else exactly the same. Basically, pretend the cursor is always at a certain distance from the player, and don't change any of the existing code.

normCur = normalize(cursorPos);
xdir = some_constant_for_distance*normCur.x;
ydir = some_constant_for_distance*normCur.y;

spread.x = (rand()%spread_value)-spread_value/2+xdir;
spread.y = (rand()%spread_value)-spread_value/2+ydir;

#5136759 Copy protection system

Posted by Strewya on 06 March 2014 - 05:16 AM

I think frequent updates are the best way to make your legit users happy, and make the pirates wish they didn't have to download yet another version because a new update was released. Especially if the update includes changes to a lot of files, which would make the pirates download the entire thing. Again. Worked against me :P

But then again, some people have bandwidth caps for download, so you should make your updater efficient to only download deltas or something.

Just an idea here. :)

#5136758 Game Event System

Posted by Strewya on 06 March 2014 - 05:09 AM

I'm just going to point you to this great post by L.Spiro.

The events you get from the OS are NOT the same thing as gameplay/high level logic events. You translate OS events into gameplay events where applicable (mostly input events), and the others are fed into certain systems directly or by translating them into system specific function calls, but not by going through your high level events system.


Of course, this can be done in many different ways, but the general idea is that you should not treat OS events the same way you treat your high-level-game-specific events.


As for how event dispatching can be done, depends on the use case, in certain situations you need to propagate every event to every listener, in other situations you should filter them out. Do what suits you best, and whichever solution makes you feel good when using it.

#5136303 box2d checking for multiple collisions simultaneously

Posted by Strewya on 04 March 2014 - 08:00 AM

Don't do that inside your contact listener, instead, when the contact listener is called mark that the player is colliding with the obstacle inside your Player struct/class. Same thing with the ground sensor.


Then, after world.step() returns, check your boolean(s) to determine if you have to kill the player or not.


Example (pseudo code for the most part):

void killCheck(b2Contact* contact)
   auto fa = contact->getFixtureA();
   auto fb = contact->getFixtureB();

   auto ba = fa->getBody();
   auto bb = fb->getBody();

   if(ba->getUserData() == ENUM_PLAYER_TYPE && bb->getUserData() == ENUM_OBSTACLE_TYPE)
      //the vice versa should also be checked, if bb is player and ba is obstacle
      m_player.isPlayerColliding = true;

   if(ba->getUserData() == ENUM_GROUND_SENSOR_TYPE && bb->getUserData() == ENUM_OBSTACLE_TYPE)
      //the vice versa should also be checked, if bb is sensor and ba is obstacle
      m_player.isSensorColliding = true;

///after world.step() returns

if(m_player.isPlayerColliding == true && m_player.isSensorColliding == false)
   //kill player

#5129297 C++ SDL - Deleting dynamically allocated objects

Posted by Strewya on 06 February 2014 - 07:26 AM

MinGW 4.7 onward (if i remember the version correctly) supports most of C++11, if not all of it, and unique_ptr is part of that.


His solution avoids deleting stuff in the middle of the game loop. If you do a lot of deleting and allocating within the main loop, you're going to run into hiccups in your framerate when you kill a lot of stuff at the same time. Also, iterating over a container of objects and deleting them at the same time is a bad idea and just invites bugs and/or crashes.

#5129246 C++ SDL - Deleting dynamically allocated objects

Posted by Strewya on 06 February 2014 - 01:51 AM

I may have missed something, but is there a reason to keep the Background object as a pointer? Would it be better to keep it on the stack and rely on it being automatically cleaned up when the Game object dies?

You obviously use a load function to get the texture into memory, you could also use an unload function to remove it from memory if the need exists. And deciding if it should be drawn or not is also something that should exist if you have such requirements, it's easier to give it a bool isDrawn, and instead of deleting the object, simply set it as isDrawn = false. Seems like a nicer choice to me.

#5126930 Empty Array In Structures

Posted by Strewya on 28 January 2014 - 06:19 AM

You can have an empty array at the end of a structure like:

struct Test_Structure {
   const int32_t some_data_0;
   const uint32_t array_of_some_sort[];
I find these can be useful when using memory mapped files.  In many file formats you'll have a header to a block of data, and then a variable number of some item following the header.  These sorts of trailing empty arrays can make traversing the files very easy I found.  These sorts of things are good when the memory is allocated through some other means.  As Hodgman pointed out, if you intend to allocate the memory your self, use a std::vector or similar container.


I would take note that const makes you unable to change the data of this structure, so it would need to be initialized in a constructor initializer list, and also that uint32_t array[] is equal to typing uint32_t* array, but the latter makes it a bit more clear as to what the variable is: a pointer, as there's no such thing as an empty array in C++. Using such a construct is fine in C, but it'd personally avoid it in C++, considering there's a safe way to do it which avoids accidental memory leaks.

I failed at reading the specific use case, as is explained in later posts, which now makes sense to me. Learn something new everyday!

#5126448 &++x Lvalue but &x++ not?

Posted by Strewya on 26 January 2014 - 01:47 AM

The post-increment is equal to the following code segment:

int postincrement(int& x)
   int oldX = x;
   return oldX;

Hope this makes it more clear why x++ does not return an lvalue.

#5125283 Struct versus class?

Posted by Strewya on 21 January 2014 - 02:58 AM

Actually they are not pretty much identical they are identical, the code generated from them is exactly the same, a struct can have all the same things as a class.


The only difference is semantical regarding the default access rule for members (public vs private), which is why i said "pretty much identical", but yeah, the generated bytecode is the same.

#5125266 Struct versus class?

Posted by Strewya on 21 January 2014 - 01:40 AM

As frob mentioned, in C++ a class and a struct are pretty much identical. The choice of which to use is yours to make, seeing as the following two are very much the same:

struct Vec
   float x, y, z;

class Vec
   float x, y, z;

One issue i ran into when i used a mix of structs and classes was when forward declaring them. Sometimes i would simply forget if Vec was a class or a struct. Similar with Color, Rect, Transform, etc. So i settled on using classes only, and if something needs to have all of it's members public, i simply set them as public and not protected/private.