• Advertisement


  • Content count

  • Joined

  • Last visited

Community Reputation

278 Neutral

About DonaldHays

  • Rank
  1. How to avoid Singletons/global variables

    Well from a quick glance it looks like there's a minor error in the second example: it still says `TextureManager.GenTexture(a_name)`, same as the first example, but TextureManager has been deleted, so it should now say `Texture.GenTexture(a_name)`.   In regards to singletons, the advice against them derives from a more general observation: mutable data exposed widely can easily lead to problems, and segments of code that have a lot of diverse mutable data in scope can also lead to problems, because both of those situations lead to the easy creation of complexity and unexpected dependencies between seemingly unrelated components. This observation leads to the cautions: "singletons can easily produce problems" and "God classes can easily produce problems".   That last paragraph might have been a bit overly academic, so let's look at those two examples you gave in particular. Your TextureManager class exposes a public static `m_textures` variable. Because it's public, any code in your app can access that variable. Any code can read from or write to it at any time for any reason. Some code may read from it to learn about its state, call some other code based on that state, and then do some more work itself based on that same state, but unknowingly that other code (or, worse, code in another thread) mutates that state, and so the later work's expectation about the state is violated. The more widely a mutable variable spreads, the more likely that situation is to occur, and singletons are global, so any mutable variables they expose are spread very widely indeed.   Your second example hides the static variable privately within the class. That means you still have only one instance of that variable (so it could actually still reasonably be considered a singleton variable), but now only your Texture class has access to it, dramatically reducing the opportunity for bugs (instead of your entire code base being able to screw up its handling of the variable, now only your Texture class can screw up its handling of the variable :D).   Now, you could avoid singletons entirely here by changing your architecture to not have a single authoritative store of textures, but instead allowing multiple stores (multiple instances of TextureManager) to be created, each with their own private instance map of loaded textures. When you ask those instances to GenTexture, they check their own cache to see if they've loaded the texture already, and have no knowledge about the caches of other instances of TextureManager that may or may not exist. Now, could that design lead to scenarios where you end up loading the same texture more than once, each in a different instance of TextureManager? Yup. There's tradeoffs to everything.   Now, I haven't even touched on some related topics (like the difficulty of unit testing singletons, or the horrifying realization that classes themselves can be thought of as singleton objects that create instances of themselves (food for thought if you design classes where the mere act of instantiating a class has side effects outside the instance itself)), but I'm a bit pressed for time at the moment, but hopefully what I've written helps you.
  2. I remember Hungarian Notation being discouraged back when I was first learning to program nearly twenty years ago :D   For some time now my general habit has been no prefixes on anything, but lately I've been experimenting with an underscore in front of non-public declarations.   Expanding a bit beyond talking about just declaration prefixes, and more about creating declarations in general: these days I'm programming mostly in Apple's Swift programming language. They recently developed (with community contributions) API design guidelines for public APIs written in the language, and it's one of the more thoughtful set of guidelines I've seen. Many of the guidelines are only applicable to Swift (its function syntax is C-style, but with named parameters, so many rules are built around that), but a few of the more general little gems I've liked: Methods with side effects are named as imperative verbs, methods without are named as either nouns (like properties) or verbs in "-ing"/"-ed" form. So in a Vector type, "normalized" returns a new Vector, but "normalize" mutates the original instance. Declarations that indicate whether they have side effects really help you reason about your code. The guidelines call for UpperCamelCase and lowerCamelCase, but what about acronyms like URL? Many guidelines I see seem to omit what to do with acronyms, but Swift's (very sensibly, IMO) says to uniformly uppercase or lowercase the acronym according to where it appears in the declaration, so "class URL { }", and "var urlForResource = makeURL()" The guidelines say to document every declaration, but allow for the documentation to only include the summary if that suffices to fully describe the declaration. For example, "func add(a, b)" can be fully documented as simply "returns the sum of a and b" and has no need for what in this case would be redundant "@param" or "@returns" sections like "@param a the first parameter in the sum". Also, document the complexity of any computed property (i.e., a "getter" method in some languages) that's not O(1), since users usually assume properties are O(1), and may run into trouble if they naïvely call an O(n^2) property in a major loop. Finally, on documentation, excellent words to live by: "if you are having trouble describing your API's functionality in simple terms, you may have designed the wrong API."
  3. Vitrual touchscreen joystick

    Square roots are relatively expensive, yes, and so one might want to be reluctant to use them deep in a tight loop that'll be iterated tens of thousands of time per frame (hundreds of thousands? Millions? I dunno the order of magnitude, computers are really fast these days, even phones are quite fast). A square root here and there in UI-level code (like clamping virtual joysticks) has, in my experience, an effectively-zero cost.   If you really want to avoid the square root, though, I think the math would still work out if you squared the joystick radius, and then didn't do the square root stage of computing the vector magnitude (so you did magnitude = v.x * v.x + v.y * v.y). I think that would work, but I haven't tested to see. Honestly I just do the square roots without worrying about it in similar code of mine.
  4. Vitrual touchscreen joystick

    You can get the behavior you want using basic vector math. I'll be using pseudocode in this reply because I'm not familiar with what vector types Cocos2d-x has built-in.   The idea is that your joystick can be represented as a circle, and the touch as a point that's offset from the center of that circle. If the touch is further away from the center of the circle than the radius of the circle, then clamp the touch to the edge of the circle.   // First, you have the vector that represents the center of the joystick vec2 centerJoystick = { centerXCoordinate, centerYCoordinate };   // Then, you have the radius of the joystick float radiusJoystick = 100;   // Then you have the current touch location vec2 touchLocation = { touchLocationX, touchLocationY };   // Then you compute the offset of the touch location from the center of the joystick vec2 touchRelativeToJoystickCenter = Vector2Subtract(touchLocation, centerJoystick);   // Then you take the magnitude of the relative touch offset vector. That represents the distance of the touch from the center of the joystick float magnitudeOfTouchRelativeToJoystickCenter = Vector2Magnitude(touchRelativeToJoystickCenter);   // If that magnitude is greater than the radius of the joystick, then the touch is outside the joystick, so we need to clamp it if(magnitudeOfTouchRelativeToJoystickCenter > radiusJoystick) {     // We clamp by multiplying the relative touch offset vector by a scalar. The vector will be clamped when its magnitude is equal to the radius of the joystick. So we want to multiply the vector by a scalar that reduced its magnitude to that of the joystick float scalar = radiusJoystick / magnitudeOfTouchRelativeToJoystickCenter; touchRelativeToJoystickCenter = Vector2Scale(touchRelativeToJoystickCenter, scalar); }   And that's about all there is to it. After this code is done, the magnitude of touchRelativeToJoystickCenter will not be greater than the radius of the circle.
  5. Hiya, The first part of any method call in objective-c is a pointer to the object on which you wish to call the method. In the case of calling a method on the same instance, the pointer would be "self". So your line should be: [self setDimensions:imageSlideWidth :imageWidth :minimalImageSpacing]; It's not valid syntax in objective-c to just begin the method signature without saying the object to call. Additionally, I suppose the way you're declaring your method signatures is valid (I don't actually know, I've not done it that way), but it's highly non-standard. You should generally describe the parameters prior to each colon, as in: - (void)setDimensionsWithSlideWidth:(double)imageSlideWidth width:(double)imageWidth minimalSpacing:(double)minimalImageSpacing And then the call to that would be [self setDimensionsWithSlideWidth:imageSlideWidth width:imageWidth minimalSpacing:minimalImageSpacing]; While in this example it makes it look like you're just duplicating information with each parameter name, in many cases it helps you know later what the parameters you're providing to a method will do. For example, what does the boolean in this method call do? [self setColor:[UIColor redColor] :YES]; It's just an arbitrary YES floating there. Who knows what it does? But this, on the other hand, is quite a bit clearer: [self setColor:[UIColor redColor] animated:YES];
  6. Try having the move action entirely predetermined from the start, rather than continuously moving as long as a key is held down and handling some special logic if the key gets lifted before movement is complete. In other words, have logic somewhere in your game loop along the lines of, "IF sprite is not 'moving' AND keyboard is pressing in a certain direction, THEN begin 'moving' one square in that direction. IF sprite is 'moving', THEN move it a bit closer to its destination. IF sprite is 'moving' AND sprite is at its destination, THEN stop 'moving'." Under such logic, it doesn't matter what the user presses in the time between when the sprite begins moving and when it's finished moving its one square. For all it matters the user could roll their fingers around the arrow keys, and the only direction that will register is what the user is actively pressing when the sprite has arrived at its destination square.
  7. iPhone Timer

    [NSDate timeIntervalSince1970] returns a double (typedef-ed as NSTimeInterval) with the number of seconds since January 1 1970, with subsecond precision. The number of milliseconds would be [NSDate timeIntervalSince1970] * 1000. I'm not sure the precision of the method, but it's been plenty sufficient for me for timing purposes.
  8. In thinking about how I would go about implementing a component-based entity system in plain-old-c (which has been, shall we say, an interesting exercise), I've been finding that there would likely be little difference for me between a system with a dedicated Entity type and a pure-aggregation system. While in my current javascript code all components hold references to their associated entity, in a pure-aggregation approach they would simply have an entity id. For a component to get another component on the same entity, the interface in plain-old-c would be nearly the same for either system. It would involve calling a getComponentForEntity function, passing either the pointer to the entity in the entity-type system, or the entity id in the pure-aggregation system. The most significant difference would be in performance. Holding a reference to the entity directly grants o(1) access to the entity's collection of components. Needing to lookup the entity given its id involves a likely hashtable search. Both approaches would obviously then need a search of the component collection. Now, would that performance difference actually be problematic? Probably not in the kinds of games I wish to make, no. I think, at this point, the biggest thing tripping me up is just the weird vibe I get from the pure-aggregation approach. To not have any actual objects that exist that I can point to and say, "that right thar is the entity!" is weird. It's not like the vibe I got when I learned how absolutely everything is an object in Smalltalk (even the classes!), which was like an eye-opening enlightening experience. My plan has been to try writing the asteroids game several times. I think there's a decent chance that only one rewrite will suffice for my learning purposes. The rewrite was planned from the beginning to try to mimic a pure-c approach (structs and functions, not objects), but now I think I'll also try the pure-aggregation approach, just to see how it goes. Also, just to comment on one other thing, the entities in my asteroids code do not have position or orientation data, for precisely the reason pointed to by Sphet: not all entities have position or orientation. In particular, my GameRules entity is just such an entity. My entities have a collection of components, a uid used by the system for bookkeeping purposes, a user-settable string id that can be used to get the entity from a global context (getEntityById("gameRules"), getEntityById("player")), and a user-settable type string ("asteroid", "playerShot", "playerShip", etc). That seems a reasonable set of information for an entity to have to me.
  9. Quote:Original post by elFarto Firstly, that's a nicely structured game with very clean code. Thank you kindly! Quote:Original post by elFarto In reply to your question "Sudden disappearing entity/component problem", what you have there is a synchronization issue (edit, actually it isn't, since it happens in a single thread, but the following still applies). A thought that went through my head when I was addressing the issue: "this would suck even more in a multithreaded world." Quote:Original post by elFarto 1. Make a copy of the physicsComponents array in physicsTick function. That way it won't change while you're using it, only on the next iteration. 2. Instead of remove entities directly from it, add all the entities to be removed to a separate list, and process that list after you've iterated through them all. Quote:Original post by Ariste There's a bunch of ways to handle this. The simplest is to create a list of iterators referencing to-be-destroyed objects, and then erase each one in turn after the update. Another way is to send out an EntityDestroyed message to every subsystem (including the one responsible for sending the message), and only remove components in response to this message. This way, the actual removal of the Entity from the list occurs whenever you do your message processing, not during the physics update. This will only work, of course, if your message processing doesn't occur instantaneously. I tried a deferred deletion approach at first and ran into a somewhat different issue. If a bullet intersects multiple asteroids when it runs a physics step, it would destroy all intersecting asteroids before going away. While the player might be tickled happy with that, it's not what I wanted. To solve that issue the bullet would need to mark itself as spent in some way, and subsequent physics tests would need to check against that. I like the deferred messaging, though. It reminds me a little of Cocoa's Event Loop architecture. I could queue up events, execute them in turn, and take any events out of the queue if their associated entities are destroyed. Seems a promising direction. Quote:Original post by elFarto One odd thing I noticed was your worldWrapper component. Shouldn't this function be handled in the physics component? So rather than doing: *** Source Snippet Removed *** do this instead: *** Source Snippet Removed *** For whatever reason, I felt compelled to have the player's bullets not wrap around the world. To accomplish the same behavior in the physics component would require exposing a worldWrap flag in the physics component, which would not be unreasonable, but I wanted to try components in many many places :D. I seem to recall hearing of physics engines that get fussy if you let something other than the physics engine itself move an object around, so that probably gives more weight to allowing world wrapping only inside the physics component. Quote:Original post by elFarto Another suggestion would be to split out the level logic into it's own entity/component, and have the gameRules component listen for a levelCompleted or playerDied events from it. That's reasonable, particularly on the levelCompleted event. As-is the game rules determine when a level is complete based off the number of remaining asteroids, which is a piece of logic that could also appropriately be determined by a level entity. Quote:Original post by Ariste I haven't found it. I also have an explicit Entity class. It stores positional data, a list of components, and some metadata. I don't see any reason to move this data into components, since almost every other component needs it. It doesn't make sense to eliminate Entity just for the sake of a "pure" approach. That's what it seems like to me, it just appears to be a popular thing to do, and I'm wondering if there's a particular advantage to it versus just being trendy.
  10. I love using javascript for prototyping. Its dynamic nature and relative simplicity helps me solve problems without worrying about memory management and such. I've been reading about component-based entities, and decided to try implementing a component-based entity system in a small game before attempting to develop one in a larger project. When trying to find hidden walls in a space that you don't understand well, it's often effective to just blindly run into them head first! Naturally, it's better to do this in a small, safe environment than a large one with much at stake. I chose to make a simple Asteroids clone. Please feel free to play it, download it, poke its code with a stick, etc. Edit: Oh, and BTW, the game depends on the canvas and audio tags. It'll run best in recent versions of Safari, Firefox, and Opera. There's a small audio issue in Chrome, and I don't think it'll work at all in IE. http://donaldhays.com/projects/spaceRockShooter/ I have a few thoughts and things I would like feedback on. The details of my approach. There is a core "class" called Entity. It is little more than a set of components, as well as some metadata like ids and types. I have some logic for dynamic retrieval of entities based on type and id. A component is an object encapsulating some data and logic. It has a reference to its associated entity. There aren't really any surprises here. The game has an event system. Anything can register to listen to events. Registration involves passing an entity to listen to, the name of the event, and the function to invoke when the event occurs. Anything can trigger an event. Triggering involves passing an entity to trigger the event on, the name of the event, and any miscellaneous data associated with the event. What is the virtue of a pure-aggregation approach? A commonly-cited article recommends a pure-aggregation model, where there is no explicit Entity type, and entities only exist in the sense that a set of different components share the same entity id. The article seemed light on reasons for doing this over the approach I took (my approach including an explicit Entity type). I'm not intuitively arriving at any real advantages to a pure-aggregation approach, so I'm just wondering if anybody could enlighten me. Sudden disappearing entity/component problem. When a bullet hits an asteroid, the asteroid reacts to the collision event by destroying itself and the bullet. This happens in the middle of a loop in the physics engine that iterates over all physics components. This results in a scenario where a list (the list of physics components) changes while it is being iterated over (the asteroid deletes itself and a bullet). This is an opportunity for error, and I indeed had some issues until I added some extra case-specific code. I didn't like the solution, though, and I'm wondering if anybody has a generic approach to these kinds of scenarios that doesn't involve sprinkling sanity checks everywhere. I think component-based entities were, on net, a pretty big win for me. This project only has about 1,000 lines of code, so it isn't very big, but it had a real vibe of coming together much more nicely than other projects of similar scope have. Methods are small and straightforward, modules aren't coupled all that tightly, things don't really feel like they're doing more jobs than they should, etc. I felt like I was able to just keep moving forward with feature adds or mutations to existing features without breaking things. It was nice.
  11. I would also be very interested to hear anything anyone has to say on the matter. These days, doing visibility mostly or entirely in realtime, without precomputed visibility data, seems to be the popular thing to do. I've tried to find in-depth technical information about Unreal Engine 3's visibility tech, but that search has been largely fruitless. Epic created a page that shows ways to be a good visibility citizen when constructing UE3 levels, and it describes the main tech very briefly. It "conservatively" culls primitives that "are classified as entirely invisible by convex zone frustum tests." I didn't find that description terribly helpful, but there you go. The page goes into more depth describing the things level designers can do manually to improve visibility logic. They can make primitives cease rendering after a certain distance, and also use a level of detail system to collapse multiple primitives into one. http://udn.epicgames.com/Three/VisibilityCulling.html http://udn.epicgames.com/Three/MassiveLOD.html
  12. iPhone animation system

    I hoped someone else would reply to this because it's something I'm dealing with myself, and I'm no expert on the topic. As I understand things, the tradeoff is that vertex-based animations are cheaper on the processor, but skeleton-based animations consume less memory (though the processing cost of skeletal animations can be mitigated by doing the work in a shader instead of on the CPU (but then shaders are only usable on the most recent generations of iPhones and iPod touches)). Based on that, then, the best approach for you is based on what resource you have more of: processing time or memory. Again, that's how I understand it, and I could well be wrong on any point. I'm slowly experimenting with different animation techniques, though I don't have any benchmarks yet. I'm currently trying a vertex-based format, with space costs reduced by using a fairly low animation framerate (8 fps) and storing the vertices as bytes instead of floats. I'm also minimizing the processor costs by not even lerping the animations, so to render a frame of animation I just have to point glVertexPointer at data that's just sitting in memory. This is essentially equivalent to how animations were handled in Quake 1. My plan is to move forward with more advanced techniques if I find that the iPhone is able to handle this technique easily while still pulling off a good framerate with the content I want displayed: lerping animations if I have the processor budget available, storing vertices in floats if I have the memory budget available, etc. I still hope to see others reply, because I'm very much learning about all this myself.
  13. Virtual Console?

    Awhile ago I decided that I wanted to make a virtual console, but I took a bit of a different route than actually emulating unique hardware. Rather, it was an application that was interacted with like an emulator by the user, but was actually running javascript instead of interpreting byte code. The games were a bundle file format including javascript code files and plain-text data files (including things usually represented in binary formats, like images). The way it pulled off a console feel was through artificial limitations: a 160x128 "screen" supporting four shades of gray (black, dark gray, light gray, white), a sound engine supporting three square-wave tracks and a noise track, and limited input options (a direction pad, a start button, and two action buttons). Basically, it was most comparable from the user's perspective to the original Game Boy. It was a very fun project. I was able to make games like Snake and Breakout in a matter of hours, which was very enjoyable. I didn't end up releasing it for several reasons, including the fact that the javascript API for interacting with the 'console' wasn't the best I've ever designed and the javascript engine I used was rather messy to work with. I'm now slowly spinning up work on a second version of the project that uses Lua instead of javascript, and allows for color (think Game Boy Color graphics). Maybe it'll end up being released. Essentially, I was more concerned about the end result (old-school games) than the process to get to them (electing to use a modern scripting language running off the full power of a desktop machine rather than actually emulating certain hardware, real or not). Just thought I would toss this out there for your consideration.
  14. What Language do u prefer?

    This may be odd, but most of my game development lately has been Objective-C for engine code, and javascript for game code. I'm rather fond of both. Using Cocoa and Objective-C is a very trippy but very fun experience, and javascript is just something that I'm immensely familiar and comfortable with.
  15. 2d uneven terrain

    I've been visiting GameDev for years, and just now registered for the first time. Does this look like what you want? http://www.donaldhays.com/physics/ You can view that page in Firefox, Opera, or Safari. IE doesn't work, unfortunately. The page has a simple physics engine that handles point and box collisions against an arbitrary 2D mesh. You can check the "Show Box" checkmark to display a blue box, and then use the arrow keys of your keyboard to move the blue box around. Feel free to view the source code to see how I did it (it's all javascript). I put in lots of semi-helpful comments. Essentially, what I've found over the past few years of trying to pull this off is that trying to handle box-line collisions is pretty easy until you want to handle multiple lines at once, at which point there are a massive number of edge cases that make things really difficult. The trick was to actually simulate point against line collisions, even for boxes. You can check the "Show Collision Hull" checkbox and then move the box around to see how it's simulating a point instead of a box. I'm thinking I should write a tutorial on this, because, like you, I haven't found any tutorials on this technique online. The closest I came was a tutorial on colliding with a Quake BSP file, and it didn't seem to handle a few edge cases. -Donald Hays
  • Advertisement