So my idea is have a special bullet that freezes the enemies, and after a period of time the enemies unfreeze itself and continue with their actions/animations. Here's a simple version of what I did:
-(void)update:(ccTime)dt
{
CCSprite *enemySprite;
CCARRAY_FOREACH(enemies, enemySprite)
{
if (CGRectIntersectsRect(_bullet.boundingBox, enemySprite.boundingBox))
{
_bullet.visible = NO;
[enemySprite pauseSchedulerAndActions];
enemySprite.pausingDuration = CACurrentMediaTime() +5;
}
if (CACurrentMediaTime() > enemySprite.pausingDuration)
[enemySprite resumeSchedulerAndActions];
}
}
Now, the problem I think I am encounter is that enemySprite has stop updating its scheduler here, so next time the update method is called the enemySprite that has been paused won't get update! I wish I knew a better way of explaining this, but I think any expert programmer would see what's wrong with this code immediately.
Please help me out with suggestions to improve the code or even just an idea would be appreciated, thank you for your time.
You called? :)
Yes, pauseSchedulerAndActions as well as Director's pause methods are both crappy ways of implementing pause because you have no control over what gets paused and what can continue to run (such as a pause menu layer perhaps).
In your case you can at least be more specific and for example only pause actions, but not scheduled updates:
[enemySprite.actionManager pauseTarget:enemySprite];
For more fine grained control it is recommended not to rely too heavily on scheduled methods in each object, instead have a central object (scene or layer) send all updates to its children - that way you can later decide more easily which children should continue to receive updates during pause.
Related
So I'm pretty new with programming from scratch, have mainly used unity for a few years up untill now so my general programming knowledge is pretty good. Started studying game development at a university after summer though where we began programming from scratch and as a task we have to make a simple game in a 2D engine we made together in class.
So the game I decided to make was a copy of bomberman and I've gotten as far as where I'm now making the bombs functional.
The problem I'm having is that I don't know how to propperly add in a timer that counts down the time to where the bomb exlpode so the player can avoid it.
I've tried SDL_Delay and _sleep which both just pause the entire program so that doesn't work and I've searched around for more options but not really understood how things work. If I could get some expamples and links to pages that explains how to properly make something like this work (something easy and small hopfully :P) then that would be highly appreciated!
Note that we are using SDL in the engine.
Thanks!
Typically, a game uses a loop, in which you read user input (you are probably using SDL_PollEvent for that), advance the game state for a short time period and draw the screen. This loop is typically called the game loop, render loop or main loop.
A simple, accurate and typical way to delay an event (such as a timed explosion), is to store the future time into a queue. Then, each time the game state advances, check the first and therefore the oldest timestamp in the queue and if the current time is higher than the stored one, then we know that the the thing should now happen and you can call the function that executes the event without delay. Then remove the timestamp from the queue and check the next one until only future events remain or the queue is empty.
If the event delay can vary, then you'll need to use a priority queue to always get the event that should fire next.
skypjack points out in the comments that this is a problematic approach if you need to implement pausing the game. That can be solved by not measuring wall clock, but instead use a separate simulation time that drifts from the wall clock when the game is paused. They also propose a simpler solution:
store a timeToEvent (to be elapsed) and decrement it, so that you detach the game time from the real one. Once it's <= 0, it's its time.
That approach is simpler, but has more overhead for checking the expiration of deadlines.
Recently I'm trying to create a Game by myself, and now I run into one question...
I want to render my Game at 60 times per second, and that's good, but then I use Directinput8 to get my keyboard and mouse set up, And I Debug my Game...
I found my keyboard also get update 60 times per sec. for example I press 'UP' and my menu goes crazy! I know I can use a few variable to fix this, but I also heard that Timer and Threads are helpful, may I ask some guy who once made a Game or know what I should do to give me some advise? Anything will be helpful! thanks! :)
By the way I know there are some cool library(like Allegro?) that are done, maybe someone can tell me how did they conquer this "update and render" issue?
Often there is a single rendering thread per game. It periodically, say each second, updates the whole screen taking all the input you have at this moment. The input, such as keyboard and mouse, you collect outside of that thread and that thread gets it for each update.
In my project i'm running a train which stops moving when it reaches a particular point this moving is carried out by glutTimerFunc .I once again want the train to start from the location where i click my mouse to a particular location
BUT THE PROBLEM HERE IS,
My timer still running even after reaching that location,so even when i initialise the starting point its not working(it continues from the left location).
Now i need to stop the timer and start the train timer for the new location.
The API documentation has the following to say:
There is no support for canceling a registered callback. Instead, ignore a callback based on its value parameter when it is triggered.
So, add a boolean to your software and ignore the event whenever it is triggered. It would be better to use a clock-based timer rather than an event-driven timer and do your timed updates manually everytime the main loop runs (you detect the amount of time since the last update, and you determine whether to perform an update tick(s)), in the long run however. This is how physics and various other time-based simulations are handled in most professional software, using the event-driven model sets you up to miss or frequently wind up handling a timed event excessively late.
Welcome to the world of game engines and actors.
My recommendation is that you don't try to do this by turning glutTimerFunc on or off directly. The timer function should be the top level "heartbeat" for the entire program, and it's job is just to tell every object that has behaviour - an "actor" - that it should update itself. The train should have its own internal state that knows where it is and whether it should be moving or not.
I have a GUI app that I am creating with wxWidgets. As part of the functionality, I have to run "tasks" simultaneously with manipulation of the GUI window. For example, I may run the code:
long currentTime = wxGetLocalTime();
long stopTime = wxGetLocalTime() + 3;
while (wxGetLocalTime() != stopTime) {}
wxMessageBox("DONE IN APP");
For the duration of those 3 seconds, my application would essentially be frozen until the wxMessageBox is shown. Is there a way to have this run in the background without the use of multiple threads? It creates problems for the application that I've developing.
I was wondering if there are some types of event handling that could be used. Any sort of help is greatly appreciated.
There are 3 ways to run time-consuming tasks in GUI wx applications:
By far the most preferred is to use a different thread. The explanation of the application being "very GUI intensive" really doesn't make any sense to me, I think you should seriously reconsider your program design if its GUI intensity (whatever it is) prevents you from using background worker threads. If you do use this approach, it's pretty simple but pay special attention to the thread/program termination issues. In particular, you will need to either wait for the thread to finish (acceptable if it doesn't take a long time to run) or cancel it explicitly before exiting the program.
Use EVT_IDLE event to perform your task whenever there are no other events to process. This is not too bad for small tasks which can be broken in small enough pieces as you need to be able to resume processing in your handler. Don't forget to call event.RequestMore() to continue getting idle events even when nothing is happening otherwise.
The worst and most dangerous was is to call wxYield() as suggested by another answer. This can seem simple initially but you will regret doing it later because this can create extremely difficult to debug reentrancy problems in your code. If you do use it, you need to guard against reentrancy everywhere yourself and you should really understand what exactly this function does.
Try this:
long currentTime = wxGetLocalTime();
long stopTime = wxGetLocalTime() + 3;
while (wxGetLocalTime() != stopTime) {
wxYield();
}
wxMessageBox("DONE IN APP");
I know this is late to the game, but...
I've successfully used the EVT_IDLE method for YEARS (back in the 90's with Motif originally). The main idea is to break your task up into small pieces, where each piece calls the next piece (think linked-list). The mechanism to do this is using the CallAfter() method (using C++, of course). You just "CallAfter()" as the last step in the piece and that will allow the GUI main loop to run another iteration and possibly update GUI elements and such before calling your next piece. Just remember to keep the pieces small.
Using a background thread is really nice, but can be trickier than you imagine... eventually. As long as you know the data you're working on in the background won't be touched/viewed by anything else, you're OK. If you know this is the case, then that is the way to go. This method allows the GUI to remain fully responsive during background calculations (resizing/moving the window, etc.)
In either case, just don't forget to desensitize appropriate GUI elements as the first step so you won't accidentally launch the same background task multiple times (for example, accidentally clicking a push button multiple times in succession that launches the background thread).
Got really stuck, need some advise or real examples.
1) I have boost::thread vector producer thread (data arrives fast ~ 100 samples per second)
2) I want QMathGL to paint data as it arrives
3) I don't want my Qt gui freeze
I tried to move QMathGL::update() to separate thread - Qt argues that QPixmap not allowed in separate thread.
What should i try, Without modifying QMathGL?
Only thing comes in mind to repaint on timer (fps?), but i don't like this solution, please tell me if i am wrong.
I would strongly advise to go with a timer. Repaint operations are costly and I would assume that no user could realistically process more then 10 printed vectors a second. So I can't see a real benefit for the end user, apart from maybe that the display is updated more "smoothly" and entry for entry. But you could achieve these effects far easier with animations ;)
When repainting with every data change, you get the annoying behaviour you describe. Working around that is (imho) not worth the trouble.
I´ve also come along a similar problem sometimes.
The usual resolution i used is to buffer the data and repainting on a timer. This goes along the line of this (Pseudo Code) :
void Widget::OnNewData(void *dataSample)
{
this->threadSafebuffer->appendData(dataSample);
}
void Widget::OnTimeout()
{
DataBuffer renderBatch = this->threadSafebuffer->interlockedExchange();
/* Do UI updates according to renderBatch */
}
This assumes that OnNewData is called on a background thread. The OnTimeout is called from a QTimer on the UI-EventLoop. To prevent contention it justs does an interlocked exchange of the current buffer pointer with a second buffer. So no heavy synchronization (e.g. Mutext/Semaphore) is needed.
This will only work if the amount of work to do for rendering a renderBatch is less than the timeout.