RPG Game loop and class structure (cocos2D for iPhone) - iphone

I'm looking to make an RPG with Cocos2D on the iPhone. I've done a fair bit of research, and I really like the model Cocos2D uses for scenes. I can instantiate a scene, set up my characters etc. and it all works really nicely... what I have problems with is structuring a game loop and separating the code from the scenes.
For example, where do I put my code that will maintain the state of the game across multiple scenes? and do I put the code for events that get fired in a scene in that scene's class? or do I have some other class that separates the init code from the logic?
Also, I've read a lot of tutorials that mention changing scenes, but I've read none that talk about updating a scene - taking input from the user and updating the display based on that. Does that happen in the scene object, or in a separate display engine type class.
Thanks in advance!

It sounds like you might do well to read up on the Model-View-Controller pattern. You don't have to adhere slavishly to it (for example, in some contexts it makes sense to allow some overlap between Model and View), but having a good understanding of it will help you to build any program that has lots of graphical objects and logic controlling them, and the need to broadcast state or persist it to disc (game save), etc.
You also have to realize that cocos2d provides a good system for structuring the graphical scene graph and rendering it efficiently, but it doesn't provide a complete infrastructure for programming games. In that sense it's more of a graphics engine than a game engine. If you try to fit your game's architecture into the structure of cocos2d, you might not end up with the most maintainable result. Instead, you should treat cocos2d as what it is: a great tool to take care of your display and animation needs.
You should definitely have an object other than the scenes that maintain the game state, because otherwise where will all the state go when you switch between scenes? And within scenes/levels, you should simply try to use good Object Oriented design to have state distributed over objects of various classes. Each character object remembers its own state etc. Here you can see where MVC becomes useful: when you save the game to disc, you want to remember each character's health level, but probably not which exact frame index the sprite animation was showing. So you need to distinguish between the sprite and the character (model) itself. That said, as I mentioned before, for game objects that don't have a lot of logic attached to them, or which don't need to be saved, it might be ok to just fuse the Model and View together into one class (basically by subclassing CCSprite).
To pull off MVC the way it's supposed to be, you should also learn the basics of Key-Value Observing. (And you'd do well to use this replacement for Apple's interface.) In more intensely real-time games, techniques like this might be too slow, but since you're making a RPG (good choice for starting out) you could probably sacrifice performance for a more maintainable architecture.
The game scene (which is just another cocos2d sprite) plays the role of Controller, in terms of the MVC pattern. It doesn't draw anything itself, but tells everything else to draw itself based on inputs and state. It's tempting to put all kinds of logic and functionality into the game scene, but when you notice that it swells, you should ask yourself how you could separate that functionality into other classes. Analyze which type of functionality you're implementing. Is it to do with data and state (Model)? Or is it about animation and rendering (View)? Or is it about connecting logic with rendering (in which case you should try to make the View observe the Model directly)?
The game scene/Controller is basically a dispatch center, which takes input events (from the user or from sprites reporting that they've hit something, for example) and decides what to do with them: it might tell one or several of the Model objects to update themselves in some way, or it might just trigger an animation in some other sprites, for example.
In a real-time game, you'd have a "tick" or "step" method in the scene which tells all objects to update themselves. This method (the game loop) is the heart of the program and is run every time a new frame is drawn. (In modern game engines there's a lot of multi-threading but let's not think about that.) But in your case, you might want to create a module that can "play the game" completely separate from the game scene. Imagine creating a program that can play chess through the terminal, using only text input. If you create the whole game system in that manner, and then connect it to the graphics engine through a small and clean interface, you'll have a really maintainable app with lots of reusable code for future projects!
Some good rules of thumb: the model (data) shouldn't know anything about sprites or display states; the view (sprites) shouldn't contain any of the game's actual logic (the game rules) but only know how to do simple things like moving and bouncing and reporting to the scene if something complicated happens. Whenever possible, the view should react to changes in the model directly, without the controller having to interfere.

Related

How should I handle a multiple scenes project?

I'm trying to make this game using the approach of multiple scenes to make things more modular.
In my actual case I have an "Initialization" scene which holds some global state objects and the one to control the state machine of all the scenes in the game.
As for the other scenes, for now I divided them just in two: the base scenes (which for now contains everything besides UI) and its UI scenes (which basically have a Canvas and all the UI elements and UI-related scripts).
The confusion in my mind is simple though: as I tried to make the UI scenes as modular and independent as possible, there are a lot of points of interactions between the base scene and its UI scene.
For the sake of illustrating this question please take this problem I'm facing right now: I have camera animations that should be played as a response to user inputs to the UI (like the click of a button should trigger a specific camera animation). Thing is: that camera is not in the UI scene. The way I'm resolving this problem right now is creating a ScriptableObject which holds events for important actions triggered in the UI scene that are fired in the UI scene and subscribed in any other place. The same can occur in the opposite direction: the UI scene need to react to many actions that happens in other scenes.
Considering that the "camera animation" problem I explained above can happen with many other objects, if there is not a better way to handle that wouldn't splitting a game into multiple scenes be just too much of work just for the benefit of modularity? And by that I also asks: am I handling this problem the right way?
If you want to keep things consistent between scenes, there are a few ways to do it.
PlayerPrefs lets you keep variables consistent, I don't need to do a whole tutorial here, look it up.
DontDestroyOnLoad lets you take an object and make it consistent throughout the whole game. If you want, you can use DontDestroyOnLoad on one of your cameras and just delete the others in the other scenes if you want to keep a consistent camera.

Automatically add platform area tile as player approaches the edge of current tile

Firstly, I'm new to Unity and I'm currently learning c#, please be gentle!
As a project, I'd like to create a simple 3d platform game. The idea being the player starts on a square tile, which is the game platform playing area. They explore different elements on this tile by moving around.
The perspective is 3rd person, so the player is looking down on the action. As they approach the edge of the tile Unity recognises this and adds another tile to the existing one, basically doubling the playing area.
As the player moves around further to the tiles edge, other tiles are added, increasing the discovered areas each time.
My thinking to achieve this would be to have 5 tile game objects, that have different elements like trees already built on them. The question is what is the best way to achieve this.
Would it be to build the complete level with all tiles and then using code restrict how far ahead the player can see, basically to the width and length of the tiles.
Or would it be better to trigger a new tile to appear as the player approaches the edge of the current tile.
Thought, links to example code that I could recycle would be very handy.
Thank you.
The question is primarily opinion based, but here is some advise:
There is no right way to make a game in unity. The correctness is mainly focused on performance; memory and processing.
There are two approaches here:
condition: Your world is endless (or very large) and player moves very slowly over time (say each tile takes more than a second to traverse).
solution: Do not instantiate everything at start, instead when player reaches the edge of a tile look for the next tile in your level structure to retrieve its data and then instantiate its objects.
condition: Your world is not very large (say it has less than overall 10K objects) OR player can move fast (as in Age of Empires game).
solution: Instantiate everything in loading phase and deactivate the game objects as they are being instantiated so that nothing is getting processed at the start of the game. In this case the level structure is a collection of game objects where you activate or deactivate them.
Hints:
Pooling is a good practice when it comes to repetitive objects. Pool is basically an empty game object with a script, and many many deactivated children.
e.g. If you have 1K trees of the same kind you better have a tree pool. Create a game object named tree pool, add a pool script to it and make that script generate 1K deactivated tree game objects in the loading phase. Then whenever your level generator needs a new tree just fetch a tree from tree pool and activate and reposition it. Make sure you clean up the pool after the game ends to prevent memory leak.
you can implement the pool as you like to provide object variations for a specific pool.
Instantiation in run-time is costly especially in mobile devices. Whenever you need to instantiate several game objects at once consider using a coroutine to prevent lag or freeze (this applies to loading phase too).
e.g.
IEnumerable CreateObjects(Data[] data)
{
foreach(var e in data)
{
Instantiate(e);//instantiate here and then wait
yield return null;//this line prevents lag
}
}
//...
StartCoroutine(CreateObjects(data));
//...
Having many active game objects is also costly especially in mobile devices. If many active game object have heavy scripts, the update methods will ruin performance. If many active game objects have rigidbodies or colliders the physics engine processing gets heavy.
Activating game objects is costly but less than instantiation, since it only runs Start method on its script if any, and also causes the physics engine to re-evaluate its structure if it has static collider or rigidbody.
Rendering is costly if only the rendered visuals are (fully or partially) visible to the cameras.
Create an editor project where you can design your levels. in this project you will make use of unity's editor classes to generate some kind of data (JsonObject) which represents your whole world. (collection of levels, tiles in each level and objects in each tile). Moreover you can have other data such as objectives and stuff each stored in a different JsonObject. Then use this data in your game by reading it and storing its structure in memory.
The reason I recommend JsonObject to store data is its size, portability, flexibility, accessibility and simplicity to work with. JsonObject is a dictionary stored as a plain text. and since it's a text you can encrypt it as you like

Use one or multiple SKScenes for Level based Game

I'm making a level based game using SpriteKit. I would like to know the best practice for making level changes. I was originally using one Scene as my gameplay scene and when a level is completed, it removes all nodes in the scene and then adds the ones for the next level. I am using a background node that is persistent throughout the entire course of the game. I'm worried about memory because I don't think ARC will deallocate the nodes removed because the scene is persistent. Is this method ok or should I instantiate a new scene for when a level is changing?
The best practice is to separate game data and assets from game code. This way, you can make changes to stuff without having to recompile (and is handy if you are working with another person who doesn't code).
Here is what apple has to say about it at WWDC 2014:
When you transition between scenes, ARC will deallocate the prior scene, assuming you made no strong references to it. Since you're starting out it's unlikely you need to worry about this right now... it's mostly done with globals and closures, and you should be able to fix it if it becomes a problem (but likely won't).
You can use things like unowned self and weak var etc to ensure this doesn't happen when needed. Again this is a more advanced topic but it's good to be aware of them.
Really, making level changes is entirely up to you... if you want to make a state manager that swaps out stuff to one scene, you can certainly do that... or, you could make a bunch of scenes and transition to that. Again, the best practice here is separating game content from game code, not necessarily how you switch scenes.
Personally, I would used separate SKScenes-- because it's already built in with transitions, memory management--and you have the option of using the editor, and you get to give each scene it's own file if desired.
There is also GameplayKit which has a statemanager, in which case you could use one scene and have different states be the level.
here are some resources, buried in there are some nuggets pertaining to what you want.
https://developer.apple.com/library/content/documentation/GraphicsAnimation/Conceptual/SpriteKit_PG/DesigningGameswithSpriteKit/DesigningGameswithSpriteKit.html
https://developer.apple.com/videos/play/wwdc2014/608/
https://developer.apple.com/library/content/samplecode/DemoBots/Listings/DemoBots_SceneManager_swift.html

Which design pattern to use for a 2D iPhone game?

To give a little background about the game: falling items float from the top, and the objective is to flick/slide another object to hit them. If an item hits the ground, you lose a life, and gain points for hitting falling items.
Here is where I'm a little confused. In O'Reilly's iPhone game development. They state have the AppDelegate inherit a game state machine object, and have the main game loop in the App Delegate. Nothing about MVC.
I was going to use MVC. I have all the objects identified for the models, and was going to use one controller to update each model and their corresponding view. Then have a navigation controller in the App Delegate, and push certain controllers (Play, instructions, stats) from the home screen. Then have the game loop run in my gameViewController. I am using Chipmunk as a physics engine by the way.
This is my first game so I'm little confused. I would greatly appreciate any advice on how to proceed. I would like to get the object orientated design right from the start before jumping into code.
I don't think MVC is really what you want here. MVC could apply to your overall application state - ie a view for the menu, a view for the gameboard etc. It doesn't fit well WITHIN the game play - at least just thinking off the top of my head.
Take a look at this post on gameDev. Lots of useful patterns from people smarter about this than I.
https://gamedev.stackexchange.com/questions/4157/what-are-some-programming-design-patterns-that-are-useful-in-game-development
My MVC goes something as follows. Each Game Object that is create is just a single Model. Empty data with no logic attached. When the object is created it also gets a Brain or controller attached to it. Each created Brain is added to the Brain list. The Brain List updates each brain and the brains change the Model.
To show something on screen the Brain adds the Model to the Scene. The scene keeps a list of all the models it is rendering. The Scene is also Updated from the Game Loop. Each update the Scene looks at each Model, any model without a View, is given a view (a new view is created based on data in the model). The Scene then tracks the view until the Model's data says it no longer needs it.
When I have been working on the iPhone I like to break the game loop out onto its own thread. Those folks over at O'Reilly are pretty smart though so take what I've got to say with a grain of salt.
[NSThread detachNewThreadSelector:#selector(GameLoop:) toTarget:self withObject:nil];
Then the game loop itself is updating first the Brains (or "Controller List"), then the Scene (or "view list").
The final piece that ties it all together is the input. For iPhone I use a full screen View. In the touchesBegan and touchesEnd of the view I generate Events which I pass off to the InputManager. The InputManager will send events to different models as needed.
Do you not consider that game state machine to be a kind of data model? I don't have the O'Reilly book you mention, but the description you give sounds to me very much like MVC.
The main point of MVC is to separate an application's content from the way that content is represented on the screen. The "model" in MVC doesn't have to consist of dumb data objects that you read from a file or a web server... it could just as easily be a simulation, a connection to another device, etc. The way I think of it is that the model is the part that you'd keep if you were going to throw out app's GUI and replace it with a script, a command line interface, or maybe a web service. A game state machine could certainly fit that description.
It's not uncommon in an iOS app to have the application delegate instantiate the model. You then have view controllers that know how to talk to the model and translate the data that it provides into something that can be displayed in the view(s). If some of the data that the model provides are graphic elements like textures or meshes, that's okay... those are the data that the game operates on, after all.

Iphone Game Develoment - Need design guidance

I have started programming a game for the iphone and as all beginners I feel like I am shooting in the dark. I just want to run my design and how my "graphics engine" works by you to see if it is anything close to standard design or good practise. Let me explain how it works:
For simplification reasons lets just say I have the following 3 classes:
LevelView: inherits from UIViewController and is a view with 10 buttons for each level of the game. Clicking a button creates a new GameViewController object (using initWithLevel) and instantiates it with an integer ( 1-10) according to the level the player chose.
GameViewController: inherits from UIViewController and has the initWithLevel(int) method and a big switch statement which performs the level setup according to the int that was passed. So it instantiates two types of objects (robots and planets) in various numbers according to each level. Each object it creates is inserted into an array belonging to a singleton. Then at the end it will start the gameloop which is another method in this class.
GameView: inherits from UIView and is where everything is drawn ( has a drawRect method) and where the touches Began,Moved and Ended methods are. What will happen for every gameLoop is that this will pull all objects from the global array (the array in the singleton) and according to what object it is it will draw the correct image at the correct location. ( location of robots and planets is stored within their respective objects as variables)
In the touches Began,Moved,Ended methods according to what the user does the relevant objects are pulled back from the Singleton array and their position/ability is updated. Therefore the next time the loop runs and they are drawn again the draw method wil update their location or behaviour.
Does this sound about right at this point? Should I be instantiating a GameViewController object to start the level? Should the gameLoop be in the GameViewController or should it be in the GameView. I have added the GameView onto the GameViewController in InterfaceBuilder It will draw the initial objects but I am not sure how to update them going forward. How do I call the drawRect method to update everything?
Anyways, sorry for the extremely long post. I am not looking for a specific answer just a review from someone more experienced in this to tell me:
1) yes you are going in the right direction design wise
2) no you need to rethink a few things
Thanks for your help
Stav
I would really really really recommend using a good game framework like Cocos2d, rather than rolling it all your own.
It's very fast and easy to get rolling with it, and a lot of top games were made with it.
It even has handling for "levels" like you are trying to do.
I downloaded it, and had my first test app up and running in 24 minutes!
Check it out at:
http://www.cocos2d-iphone.org/
I agree on the Cocos2d. On the other hand if you are interested in how the graphics work, start learning OpenGL ES, it's tough to learn but once you know it you aren't as limited as before by using frameworks that do all the work.
On your other question, the design. Apps are built on the MVC model. Depending on the scale of the app, you could put the game loop(logic) in the controller class or for a larger project (and a better design) you should separate the 2 in my opinion.