Endless Scroller Enemy Spawning cocos2d-iphone - cocos2d-iphone

I'm developing an Endless Scroller type of game and I need help with ways to spawn enemies. I have two background images that repeat over and over. I spawn the enemy just above the screen then schedule an update to move the position down.
The current way I'm spawning the enemies at the start is just scheduling a selector every 8 seconds, then based on the score, I unschedule the selector and reschedule it again for 6 seconds etc. My character doesnt shoot you just have to navigate around the enemies so the quickest I can have the selector scheduled is 3 seconds otherwise there isnt enough of a gap to get around them.
I'm only new to programming and cocos2d so I'm not to sure how expensive the unschedule and schedule will be.
So basically my question is, Is there a better way of spawning the enemies? keeping in mind that there always has to be a path to survive?

Your options are to either use the ccScheduler, or implement your own via a timer in update(). Something along the lines of if nextWaveTime > timeBetweenWaves. I would recommend using the scheduler in Cocos2D because I'm sure it has some optimizations built in by some very smart people. Also, scheduling is 'a drop in the bucket' compared to the cost of draw calls. Be sure to reuse the enemies if at all possible. When active enemies go off the screen, don't remove them but instead place them back at the desired 'enter screen' point.

Related

Exact delay in screen draw and keyboard keypress event in Qt

I am working on a Qt project in which exact time at which certain events occur is of prime importance. To be specific: I have a very simple animation that must be drawn to the screen at certain time say t1. Once I issue the QWidget update to start the animation, it will take a small time dt (depending on screen refresh rates etc.) to actually show the update on screen. I need to measure this extra time dt. I am unsure as to how to do it.
I thought of using QTime and QElapsedTimer object in the paint event of the QWidget but I'm not sure if that would achieve my goal.
Similarly, when the user presses a key it will be registered after a small delay based on the polling rate of the keyboard. I need to account for this delay as well. If I could get the polling rate I know on average how much will the delay be.
What you're asking for is--by definition--not possible from within the computer.
How would you expect to be able to tell when a pixel "actually showed up" on the screen, without a sensor stuck to the monitor and synchronized to an atomic clock the computer has access to also? :-)
The odds are stacked even further against Qt because it's generally used as an abstraction layer on top of Win/OSX/Linux. Those weren't Real-Time Operating Systems of any kind in the first place.
All you can know is when you asked for something to happen. Then you can time how long it takes for you to get back control to make another request. You can set some expectations on your basic "frame rate" throughput by doing this, but there are countless factors that could lead to wide variations in performance at any moment in time.
If you can dig through to the kernel/driver level you can find out a closer-to-the-metal measure of when the actual effect went to the hardware. But that's not Qt's domain, and still doesn't tell you the "actual" answer of when the effect manifested in the outside world.
About the best you're going to get out of Qt is a periodic QTimer. It can make a callback at (roughly) millisecond resolution. If that's not good enough... you're going to need a smaller boat. :-)
You might get a little boost from stuff related to the search term "high resolution timer":
Qt high-resolution timer
http://qt-project.org/forums/viewthread/31941
I thought of using QTime and QElapsedTimer object in the paint event of the QWidget but I'm not sure if that would achieve my goal.
This is, in fact, the only way to do it, and is all you can actually do. There is nothing further that can be done without resorting to a real-time operating system, custom drivers, or external hardware.
You may not need both - the QElapsedTimer measuring the time passed since the last update is sufficient.
Do note that when the event loop is empty, the delay between invocation of widget.update() and the paintEvent executing is under a microsecond, assuming that your process wasn't preempted.
it is a reaction time experiment for some studies. A visual input is presented to which the user responds via keyboard or mouse. To be able to find the reaction time precisely I need to know when was the stimulus presented on the screen and when was the key pressed.
There is essentially only one way of doing it right without resorting to a realtime operating system or a custom driver, and a whole lot of ways of doing it wrong. So, what's the right way?
A small area of the screen needs to change color or brightness coincidentally with the presentation of the visual stimulus. You attach a fiber optic to the screen, and feed it into a receiver attached to an external event timer. The contact closure in the keyboard is also fed to the same event timer. This lets you precisely time the latency of the response with no regard for operating system latencies, thread preemption, etc. The event timer can be something as cheap as an Arduino, if you are willing to do a bit more development work.
If you are showing the stimulus repetitively and need a certain timing between stimulus presentations, you simply repeat the presentation often and collect both response latency and stimulus-to-stimulus timing in your data. You can then discard the presentations that were outside of desired tolerances.
This approach is screen-agnostic and you can use it even on a mobile device, as long as it can somehow interface with your timer hardware. The timer hardware can of course be networked, making interfacing easy.

How to add a short pause (think time) in a cocos2d game

I'm working on a two player iOS game that is similar to checkers. I'm using cocos2d to create this game.
I want a think time of .5 seconds between when the player's move renders and when the computer's move renders to simulate think time.
The flow of the game is controlled using NSNotification events and looks like this...
Player (computer or human) submits a move -> The board adds the new sprite -> The game controller updates the current player and asks them to submit a move.
I've tried adding usleep(500000) at the end of the board update or the beginning of the game update. What ends up happening is the sprites added in the board update, for the human player, don't show up until after the computer player has submitted his move. So the game waits 500 milliseconds and then updates with both moves.
Is there a way to force the CCLayer to update its child sprites before the usleep, or is there just a better way of adding this think time?
Thanks
if you schedule for receiving an update in your controller, you could slip time in the update:(ccTime)dt function.
in your .h
float _slipTime;
in your .m
// with other declaratives
static float THINK_TIME=.5f;
// last line before the stall
_slipTime=0.f;
[self schedule:#selector(pauseForThink:)];
-(void) pauseForThink:(ccTime) dt {
_slipTime+=dt;
if(_slipTime>THINK_TIME) {
[self unschedule:#selector(pauseForThink:)];
// trigger here whatever you wanted to accomplish after
// the think pause.
}
}
ok, this is simple, but will prevent the main loop from being blocked (this is what happens with your sleep). When running at 60 FPS, the pauseForThink method will be called about 30 times, and cocos will have 30 draw cycles during the pause.

Are offscreen animations ignored by rendering and CPU?

Just wondering how Cocos manages the CPU cycle and graphics engine for CCSprites that are offscreen, including those in the middle of an animation. If you have many animated sprites going on and off the screen, I could check and stop each animation when it's off the screen then restart it when it is about to come back on, but I'm wondering if this is necessary?
Suppose you had a layer with a bunch of them and you make the layer invisible, but don't stop the sprite animations. Will they still use CPU time?
I just did a quick test (good question :) ), in a game where i can slide the screen over a large map that contains images of soldiers performing an 'idle' animation. They continue running when off-screen (I tacked a CCCallFunc in a sequence in a repeat forever, to a simple selector that logs).
I suspect they would also run when the object is not visible. It kind of makes sense, especially for animations. If you look at my use case, if the animation were stopped, it could cause a cognitive disconnect if the user slided the soldier in and out of view, especially when the soldier is doing a walk on the map - he could actually walk-in the view without the user having done any interaction with the screen.

How to change touch priority on overlapping sprites

Is there any way to change the touch priority for cocos2d iOS sprites? What I have are multiple cards on the screen and they are arrayed in an arc, just like it would when you hold them in your hands. So in this setup, they overlap, and I need to recognize on which card the touch was made. I could measure the coordinates of each vertex of cards and determine the visible area of a card and then check if the touch was made inside that area (couldn't I?) but I thought there would be an easier way to deal with this, say changing the touch priority? Which means that the card closest to the screen would have the highest priority and it'll keep decreasing along the way into the background, so that even if the touch was made on 2 sprites at once (the above and below one), it would be registered only on the sprite with higher priority.
Reading on the internet only revealed ways to change the priority for a sprite and layer so that it defines whether the touch was made on the layer or the sprite, but that's not what I want.
As far as I know, by default you get exactly that behavior, the sprites closer (on the z ax) to you have priority. However, I think they pass down the event to the ones behind them as well. So, what i think you need to do is to eat the event when it gets to any of your sprites. To do that, just return NO when overwriting the "touchBegin" method. Hope it helps.

Manually controlling framerate of Cocos2d-iPhone game strategy

Most game developers should have encountered the "low framerate" issue at least once when developing games. But I, on the other hand, am making a sudoku-like puzzle game where low framerate is not a problem since it does not have constantly moving sprites/elements, and in fact I plan to decrease the framerate so that the game will take less CPU time and hence reduce the power consumption of the iDevices; all this just as a courtesy to the players :)
I already know that I can control the framerate in Cocos2d-iphone by modifying animationInterval:
[[CCDirector sharedDirector] setAnimationInterval:1.0/60];
But I'm having troubles on the strategy on when to lower the framerate and when to revert to the normal framerate (60Hz). At this point I only managed to define the strategy for touch event, that is:
Start with lower framerate. On ccTouchBegan, revert to normal framerate. On ccTouchEnded, switch to lower framerate. Make sure multitouch is handled accordingly.
I'm left with two more conditions:
Handling CCActions on CCNodes: as long as some CCNodes have running actions, revert to normal framerate.
Particle system: as long as there exist some particle systems that are emitting particles, revert to normal framerate.
Basically I need to be able to detect if there are actions that are still running on any sprites/layers/scene, also if some particle systems are still emitting particles. I prefer to not having the checking done on individual objects, and I'd rather have a simple [SomeClass isActionRunning]. I imagine that I might be able to do this by checking the list of "scheduled" object but I'm not sure how. I'd appreciate if you could also suggest some other conditions where I need to revert to normal framerate.
Hmm.. I would recommend that you set it to 30fps.. Yes.. Its the rate that screen refreshes.. But the most important is how you code the game.. It must be efficient.. Rather than running extra processes checking if something is running or not.. It may eat up slightly more processing power..
though i know it's not a very clean way but you can hack CCScheduler class and check if there are any object in scheduledMethods. and i guess you have to check if the objects there are yours since cocos2d itself schedule some classes.
This might be what you are looking for, at least regarding actions.
When you run an action you can call a block at the end of your action, in which you reset the frame rate.
[[CCDirector sharedDirector] setAnimationInterval:1.0/60];//set your fast frame rate
[self runAction:[CCSequence actions:
[CCMoveBy actionWithDuration:0.5f position:ccp(100,100)], //Do whatever action it is you want to do
[CCCallBlock actionWithBlock:^
{
[[CCDirector sharedDirector] setAnimationInterval:1.0/30]; //Revert to slow frame rate... could also check within the block for other actions
}],
nil]];