Jump to content

  • Log In with Google      Sign In   
  • Create Account

Josh Petrie

Member Since 11 Jun 2003
Offline Last Active Private

#4999350 The Singleton Pattern: To be or not to be [used]?

Posted by Josh Petrie on 09 November 2012 - 11:14 AM

In Game I might have a World class which also have Update() and Draw() methods. And in World there is a Player, but the Player class should be able to call a function in Graphics when a key is pressed. I can't do that in either Update() or Draw() since they only are passed one of Input and Graphics. In this case I find it really useful for one of them to global since I don't have to bother about this issue. I can see two options to solve this without the use of globals.

  • Change Game::Update() and World::Update() to take a Graphics* parameter.
  • Add a Graphics* mGraphics member variable to each class that needs it, and set it with SetGraphics(Graphics* pGraphics) on initialization (what if I forget to set it?)
Maybe there are more options, what do you recommend doing?

Ah, but like I noted before, I would argue here that the problem is with the design whereby "the Player class should be able to call a function in Graphics when a key is pressed." That's giving the player object responsibility over two very distinct systems (graphics and input), especially when the player appearance to be nothing more in this design than an entity within the logical world. You are now conflating, and thus coupling, your logical objects with your input and your rendering. With a bunch of singletons/globals this is less obvious, but when you remove them as you have suggested here, you discover those dependencies.

Ideally all three of those (logic, rendering, input processing) should be independent of each other. Communication between them should occur via the higher level container for each subsystem (in this case, the game itself, so perhaps in your "game" class).

The input system collects a bunch of keyboard events, or whatnot. Your game translates those (maybe via some kind of action mapper). Then it asks the world for the currently-controlled entity and uses the public interface of that entity to apply the actions. Once all that's done and the rest of the world goes through it's simulation step, the game collects all the visible/renderable entities and constructs (or updates) rendering descriptions for them, and feeds those rendering descriptions to the renderer object itself.

In this system:
  • The "Player" class makes the most sense as the action mapper; all it has are a pointer to the currently-controlled world entity, and a bunch of methods to translate unmapped key codes into actions based on the entity state (for example, making the "V" key either draw or stow the entity's weapons, depending on the entity's current "are weapons drawn" state). The responsibility of the player is to change entity state.
  • World logic, input logic and rendering are all independant, tied together at the topmost level by the game itself, which uses a Player object to translate between input and world systems.
  • Similarly, the topmost game object also feeds input to the graphics by iterating all the active and renderable game entities and creating render descriptions (sprites, for example) using that data. The game determines whether to use animation sequence 0 (weapons stowed) or 1 (weapons drawn) for an entity based on that entity's state, but the graphics system only knows about and only has to see a bunch of sprites.
You arrive at the quandary you posed about the player object by incorrectly taking the OO mentality too far -- OO design is about modelling objects in real-world terms, but only to extent. Your initial description of a Player does model a human player very literally -- it is the human player who, however indirectly, causes graphics to change when they press keys. But the in-code version of that object shouldn't be developed that literally, because it leads to exactly the kind of spaghetti of dependencies you encountered.

#4998925 The Singleton Pattern: To be or not to be [used]?

Posted by Josh Petrie on 08 November 2012 - 10:51 AM

I don't understand how you can completely avoid globals? I completely understand to avoid it as much as absolutely possible, but for instance a logger object. Should you really pass your logger instance to all objects in your game that might need logging? And also say for example you use a framework like GLFW for input, how would you pass on the callback without storing some info globally?

Remember that not everything has to be an object. Turning everything into an object can be very poor object-oriented design, in fact. Logging facilities are something that can be implemented perfectly well without resorting to some kind of "logger object" should you so choose.

But if you choose to build that API as an object or set of objects, then passing those objects to interfaces that require them is a perfectly valid solution and generally more desirable than making those objects global if for no other reason than it makes the dependency on the logging system explicit.

A typical argument for why singletons/globals are good or necessary is along the lines of your initial query: "without global access, I will need to pass this object to every function." The flaw in that argument is that it exists because of a deeper implementation issue: every function is coupled to that object.

#4998511 --- Finished Breakout ---

Posted by Josh Petrie on 07 November 2012 - 12:21 PM

You have one of the more unusual indentation styles I've ever seen (or was that the forum's useless "helpful" reformatting?). In any case, I will look over this when I get a chance and give you some specifics, but from a quick glance I can suggest two avenues you might want to look at:
  • Consider looking at a system by which you wouldn't need to hard-code collision detection mechanisms between "the ball" and "the wall" -- how could you generalize your collision representation and handling so you could add new things without modifying the ball code?
  • Your sprite manager is rather coupled to your game logic in a few key ways -- for example, "StartGame." How could you factor that dependency out so you can reuse this sprite management code in your next project?

#4998498 --- Finished Breakout ---

Posted by Josh Petrie on 07 November 2012 - 12:00 PM

I have no intention of playing it (and the OP did not specifically ask for that), I want to look at the code and critique that.

I'm also not in the habit of downloading and running random executable from forums anyhow, especially this one. It only takes one such instance for us to have a repeat of fongerchat.

#4998489 --- Finished Breakout ---

Posted by Josh Petrie on 07 November 2012 - 11:40 AM

Why don't you just paste the code here? It's far more likely that somebody will take a look at it.

#4991148 What to choose?

Posted by Josh Petrie on 17 October 2012 - 10:13 AM

And between SlimDX and normal DirectX with C# what would you recommend?

DirectX is a set of native COM-like libraries, but most of them are not well-behaved COM and so cannot be used via COM interop in C#. Direct3D in particular, which is what you're really asking about.

In other words, there is no "normal DirectX" for C#, you only have options that are wrappers (XNA is a very high level wrapper around D3D, as was Microsoft's MDX which is now deprecated and their CodePack which is now effectively abandoned). Your only sane choices are SlimDX or SharpDX, both of which will work fine.

#4990802 What makes Debug different from Release?

Posted by Josh Petrie on 16 October 2012 - 11:12 AM

The difference between Debug and Release is whatever you define it to be.

"Debug" and "Release" are idioms of Visual Studio (and many other IDEs) -- they are the names of default build configurations generated for a solution/project/whatever-your-IDE-calls-it. Generally, the "debug" configuration does no optimization and enables a bunch of extra sanity checking and safety mechanisms that are not present in the "release" configuration (which also enables optimizations). Almost all of the options in the configuration correspond directly to parameters that can be given to the compiler and linker and any other tools used to actually build your project.

Every major IDE that supports these kinds of configurations also allows you to modify them as you need to, and usually to define additional ones as well.

#4968530 Best way to follow up a tutorial?

Posted by Josh Petrie on 11 August 2012 - 04:40 PM

No. Read the tutorial and try to internalize the concepts it's conveying. Implement them yourself -- don't just copy the code, even if you think you "understand" it, that's a sure way to disaster. If you do understand the concepts and the code you'll have no trouble reimplementing the thing on your own.

Be aware that many tutorials are downright terrible and shouldn't be trusted on their own.

#4968426 To DirectInput or Not to DirectInput

Posted by Josh Petrie on 11 August 2012 - 09:37 AM

Through C++/CX for the .NET side of things. I'm entirely sure it's all possible yet, but I'm working on that side of it ATM and it seems to be going fairly smoothly... Is that not going to work?


C++/CX is C++ with some extensions to support accessing the new Windows Runtime (WinRT); it is primarily syntactic sugar for COM support. C++/CX produces native code as WinRT is a native code framework. You cannot mix managed and native code in a C++/CX project, so you cannot even combine it with C++/CLI. Using C++/CX -- like using C++ -- gives you a 100% native binary.

C++/CLI looks the same as C++/CX because Microsoft basically lifted the syntax. C++/CLI would let you produce managed code, but it isn't C++ -- it's a managed language, so at that point you may as well just be using C#. There is no point to ever using C++/CLI unless you are writing an interop library to expose a native API to managed code or the other way around.

I might not be using the proper term here and may actually be referring to WInRT. But it all looks very similar to .NET to me... I wouldn't want to use a wrapper here either, I would want to interface directly with the library where at all possible for the clearest picture of what's going on.

Yeah, you're not. WinRT isn't .NET, it's not related to the CLR or managed code at all. Furthermore, you can't even use DirectInput for Metro apps in WinRT.

It sounds like all of your plans are based around an assumption of compatibility, when in fact the technologies you're all talking about are quite incompatible at varying levels. You should probably revisit your plan by determining what platform you want to target or what language you want to use and then doing some research into what is possible with that platform -- MSDN is an excellent resource, you should start there.

#4968220 Best language to make 2d games

Posted by Josh Petrie on 10 August 2012 - 04:22 PM

Well this got off-topic fast, didn't it?

I have stripped the topic of the irrelevant and off-course discussion concerning cx_freeze and Python, etc etc. Take it to some other forum, please.

#4967879 To DirectInput or Not to DirectInput

Posted by Josh Petrie on 09 August 2012 - 01:24 PM

So creating a game I hope to be able to compile and run as both Win32 and .Net 4.5,

To use Win32, you need C or C++ (or other native language). To use .NET 4.5 you need C#. How exactly do you expect to do this?

I'm considering using DirectInput to handle all user input as it'll basically be unchanged across both.

The code will have to change rather drastically in fact as the C or C++ interface to DirectInput (via COM) is superficially very different from the available managed wrappers that support DirectInput (SlimDX and SharpDX). The code won't directly compile at all.

I have a feeling you don't quite understand the distinction between Win32 and .NET. Win32 is a native C API, .NET is an implementation of the CLR. They are not equivalent technologies.

Could anyone elucidate why this might be the recommendation?

DirectInput is deprecated and just sits on top of Win32 messages or RawInput, depending. So it's generally better just to use Win32 messages or RawInput. The only thing you'd really need DirectInput for is joystick support.

#4967037 is C# an alternative to C++?

Posted by Josh Petrie on 07 August 2012 - 09:16 AM

This does not appear to be constructive at all.

#4956007 HELP!

Posted by Josh Petrie on 05 July 2012 - 09:31 AM

Please don't go so overboard tagging your post (for example, there is no need to tag your post with variations of your own username or variations of the word "programming" that are spelled incorrectly or different capitalizations of various APIs).

I have removed most of the tags.

#4950998 Looking to start programming, where to start?

Posted by Josh Petrie on 20 June 2012 - 09:35 AM

I would recommend you start with C# or Python. Learn the basics of the language with simple, text-based programs. You can graduate to simple text-based games (tic-tac-toe or hangman or the like) relatively quickly and keep working on those until you feel accomplished and comfortable enough with the environment to move on to something larger. Practice is key.

Isnt C# a subsidiary of C/C++?

No. C# is an entirely distinct language, although it has some syntactical similarities to other C-like languages.

I wanted to start out using Visual Basic, but read its outdated, would C# or Python be good starting languages?

C# or Python are both probably better choices. However, a newer version of Visual Basic (VB .Net) would be suitable as well, it's just sort of an ugly language with (in general) poor toolchain support for games. A lot of libraries and APIs that work in Visual Basic do so primarily because VB .Net is a managed CLR language like C#, so things "work" but they don't quite end up feeling right.

If I can learn to program one language, are most of them basically the same? (I know theyre all different, but theyre all programming languages so they have similarities right)?

Learning any language of one paradigm (imperative, functional, et cetera) would make learning other languages of that paradigm easier, and to some extent even make learning new programming paradigms easier, yes.

#4947146 Creating graphics for a full screen game? What dimensions?

Posted by Josh Petrie on 07 June 2012 - 01:27 PM

You don't own this thread and have no authority to attempt to dictate it's course. This is a discussion forum. The only people who have that authority are the moderators, and I am the moderator of this forum. Do not attempt to play rules-lawyer with me.

Now then.

I think that was pretty harsh, and quite frankly unnecessary. A game design doc can be one of the most helpful things when making a game if it's done right, and I don't know why you would accuse someone of making mistakes outright like that.

Yes, it was harsh. But I did not say that a game design document is a bad thing, I said that trying to do all the design work up front is bullshit, and quoted the term GDD to express some skepticism at the idea of specific pixel sizes being relevant to the design of the game. It's an implementation detail, and potentially one that belongs more in a technical specification if anything. As for mistakes? Anybody who believes they've never made any is a fool, or as Ravyne suggests, has never developed anything particular complex. All software has bugs in it, all designs have errors or omissions or exploits or loopholes. We make mistakes, probably more often than we made things correctly, and that's good because we learn from them. That's why we iterate.

The pre-development phase is free since I'm the one doing it.

The more important details I can include in the GDD that I give out to the team later the smoother and faster development will be = cost less money.

So It's just much smarter if I already know what sizes the images should be and even have them ready = saves lots of time because the programmer can just puzzle the pieces together instead of discussing and planning with me = cost more money.

Opportunity cost is relevant and needs to be considered. Especially if you going to hand off your design to a third party to actually get it implemented, you cannot expect to actually get anything produced without any kind of back and forth dialog and iteration. It is just impractical, it doesn't work that way. You will invariably have forgotten something that your developer will need to ask you about. You're only human.

Worrying about specific image resolutions isn't something you need in the GDD. What you want to call out is, as Ravyne suggested, that you want scalable resolution support. Your developer will be able to translate that into the technical details he needs to produce the implementation you desire.