How to manage two objects with different speed in surface views - surfaceview

How to handle speed of two different objects drawn in surface Views.
Do I have to make two different threads for it and use sleep ? Or is there any other option to do this?

I don't think it's a good idea to make something like that, if you want two objects to be updated at different speeds you can fake it, like have a counter and every time the object is updated (or drawn depending what you want) to change every x frames. For example you want objectA to update every 2 frames, do this:
//Every frame
counter++;
if (counter >= 2)
{
counter = 0;
//Update or Draw
}
Do the same for objectB if needed.
You were not very specific what you meant by "different speeds" so that was the best I could think of, if your case is different let me know :)

Related

Anylogic - line of sight

Is there a way to check if there is a line of sight between two agents assuming some buildings and presentation markup?
(Meaning a function that would check if two agents can see each other assuming buildings and walls)
This is how I did it once in the past. The only problem is that it might be slow if you need to do that calculation thousands of times per second. And it's only in 2D. If you need 3D, the idea is not so different.
1) add all your building nodes and everything that might be an obstacle between the two agents to a collection. You may want to put a rectangular node around your buildings to keep everything in one collection (assuming you are using space markup with nodes)
2) generate a delta distance delta (equal to 1 for example) and find the angle of the line that passes through both agents.
3) Make a loop from the position of agent1 till the position of agent2. It will be something like this:
L=delta;
while(L<LThatReachesSecondAgent){
x1 = agent1.getX() + L*cos(angle);
y1 = agent1.getY() + L*sin(angle);
for(Node n : yourCollectionOfNodes){
If(n.contains(x1,y1))
return false
}
/*This can also work maybe faster
//int numNodesInTheWay=count(yourCollectionOfNodes,n->n.contains(x1,y1));
//if(numNodesInTheWay>0) return false
*/
L+=delta;
}
return true
welcome to SOF.
No, there is no build-in function, afaik. You would have to code something manually, which is possible but not straight forward. If you want help with that, you need to provide more details on the specifics.

unity3d draw same objects

I want to draw many spheres.They are all the same but the position.When the number of spheres increase to 10,000, it become very slow. I would if there is any method to draw same things quickly?
I did some experiments to find the problem.
At first I instantiate a simple object with 224 verts 10,000 times with dynamic batching. the result is like this:
Then I add two faces to the object and instantiate it 10,000 again. There is no batching but become quicker:
Third time I increase the verts 100 times and instantiate it 100 times. It become much quicker:
I wonder where is the different between them. Maybe I should use static batching to increase the speed?
What you are looking for is called instances. Here is a starting ressource for you:
http://docs.unity3d.com/ScriptReference/Object.Instantiate.html
Depending on what it is that you want to instantiate a thousand times, you can also checkout the concept of a billboard. It is basically a planar object with a fixed texture that will always face the camera no matter from what perspective you look at it. It is mainly used for things that are far away or should not use too much performance (e.g. grass).
Another thing that you need to watch out for is how many times you make draw calls. Try to use draw call batching, when possible.

cocos2d starting particles from a specific time in the future

I am developing a cocos2d based app with a space background in which I am exploiting a CCQuadParticleSystem to make blinking stars. I have generated this particle system with ParticleDesigner. As soon as I load the particle system white dots representing stars start appearing in the background and after a while they fade out so that, after few seconds in which the particle system reaches the regime state, a night sky full of stars comes out.
My problem is that I would like to know if there is a way to make the particle system starting from a specific time in the future (for instance t0 = 3sec) so that I do not have to wait to have all the starts blinking.
I hope I have clearly explained the problem
thank you in advance
Andrea
I did this and it worked exactly the way I wanted it to.
for (int i = 0 ; i < 300 ; i++)
[emitter update:.1];
Have you tried a
id actions = [CCSequence actions:[CCDelayTime actionWithDuration:3.0f],
[CCCallFunc actionWithTarget:self selector:#selector(onStallComplete)],
nil];
[self runAction:actions];
ok, granted it is probably abusing the original intent of the API's , but is useful
watch for re-entrancy in onStallComplete if you have multiple such delayed reactions.
note: newbie at SO, hope the code snippet comes out looking right
I assume you are using some kind of updateWithDelta: method in your game loop in order to update the particles. If you want the particles to start after a certain interval, make your own timer.
Edit: Based on your comment below, my method is still good, it just needs some tweaking. You need only remove the condition in the updateWithDelta: method on the particle system. That way, it will still update for those 3 seconds, but will not render, and therefore look the way you are describing.
In the .h file:
BOOL particleShouldUpdate;
float particleTimer;
In your init method:
particleShouldRender = NO;
particleTimer = 3.0f;
In your updateWithDelta: method:
if(!particleShouldRender){
particleTimer -= delta;
if(particleTimer < 0){
particleShouldRender = YES;
}
}
// update your particle.
Finally, in your render method:
if(particleShouldRender){
// render your particle.
}
Note that from this point, if you want to stop it rendering, you need only reset the 2 variables like as in the init method, and the same effect will occur.
EDIT2: Upon further clarification, we only need to adapt the init method of your particle. I will make 2 assumptions here, and you need only change them slightly to fit your needs. Suppose that your update cycle is 60 frames per second, the minimum particle lifespan is 1.01, and that you want 3 seconds of updates before you start the game. Then in the init method, try:
for(float delta = 0.0f; delta < 3.0f; delta += (1/60)){
[particle updateWithDelta:(float)(1/60)];
}
This will update your particle like it normally would, but without rendering at each interval, and before anything else gets updated. Alternatively, if you are worried about speed when updating your particle, you can try:
for(int i = 0; i < 3; i++){
[particle updateWithDelta:1];
[particle updateWithDelta:0.02];
}
This will be faster, but may have a few issues depending on your particles parameters.
EDIT3: So looking into this further, cocos2D does not let you do this for some reason. I found a similar question online to this, and they suggested you play with the posVar and speed to make them large enough while you are transitioning into the scene, and once you have fully transitioned into the scene, reset the values to normal. You may want to give that a try!
Hope that Helps!
I do not think there is a way to fast forward your particle system 3 seconds into the future. Alternatively I can imagine two different solutions depending on your circumstances:
Load the scene with the particle behind another scene (e.g. an empty black scene). After 3 seconds switch to the scene with the now nice looking particle effect. This could work f it is ok for you that the user needs to wait for 3 seconds and you only do not want them to see the particle system while everything is clunked together or if you have another scene before the scene with the particle system anyway.
Record the particle system, store it in a file then replay it in your scene. With recording I mean store the position and color of each of your particles. The drawback is, that it will look the same everytime and if you want to run it longer than what you recorded you need to make sure replaying it in a loop still looks good.
I can't think of a way to implement this directly, but could you try something like this as a workaround? I'm afraid I haven't been able to test this yet due to other errors, but working on it.
{
...
//This attempts to make 3 seconds pass 100 times quicker
[[CCScheduler sharedScheduler] setTimeScale:100];
[self schedule:#selector(cancelIncreasedTimeScale) interval:3];
...
}
int numberOfTimesCancelled = 0;
-(void) cancelIncreasedTimeScale
{
numberOfTimesCancelled ++;
//Two because the scheduler is also called straight away? Remove if it's only called after waiting an initial (3/100) seconds
if (numberOfTimesCancelled == 2) {
[self unschedule:#selector(cancelIncreasedTimeScale)];
[[CCScheduler sharedScheduler] setTimeScale:1];
}
}
The issue I do worry about is the other items on your scene would also run 100 times faster. Is that an issue?

Setting up a power meter in cocos2d

I am a straight noob. Everyone else says it, but I'm dead serious.
My question is, what is the best way to make a power meter to move a object? Meaning, how to set it up so that the longer the player holds the more power they get. Also how, would I incorporate physics?
What I'd like to accomplish is to have a player holding onto something so that when he taps on the screen and hold he powers up, and when he lets go he throws the object a certain distance.
just checking if the there is any thouch sequence or not is rather an easy thing, you just have to overload two functions for your scene class, one to inform you whenever a touch sequence begins and one to tell you touch is ended. the source code example is describe in this link. after than i think you need a gauge to show how much power is gathered so far, the easiest way is to use a texture with full power shown in it and the set it as texture and then show it little by little as the power goes up just as the code below:
// to create the gauge with zero power
CCSprite *s=[CCSprite spriteWithTexture:[CCTextureCache addImage:#"gauge.png"] rect:CGRectMake(0,0,0,10)];
// and then whenever the power changes you call this method
[s setTextureRect:CGRectmake(0,0,power,10)]
note that in my code i am using a 100x10 texture (power is somthing between 0..100 and texture height is 10 as the last parameter in both CGRectMake functions)

App with expanding animated line in iOS ... howto

The basic idea
is very easy. Simplified you could say... a snake like line realized by a let's say 3px line is expanding across the screen collecting and interacting with different stuff, can be steered through user input. Like a continous line you would draw with a pen.
I've already started reading apple's documentation on Quartz/CG.
As I understand now, I need to put my rendering code into a UIView's drawRect.
Then I would need to set a timer (found some answers/posts here and there, nothing concrete though) that fires x times per second and calls setNeedsDisplay on the UIView.
Question:
How to realize the following:
Have whole snake on UIView 1 / (Layer ?), draw new part on UIView 2, merge them, so that the new part gets appended to UIView 1 (or CALayer instead of views ?). I ask explicitly about this cause I read, that one shouldn't redraw the same content over and over again, but just the new/moving part.
I hope you can provide me some sample code or some details which classes I should use and the strategy on how to use them / which calls to make.
Edit
OK, I see that my idea or what I've read before to realize this with Quartz and different views is not so wise... ( Daniel Bleisteiner )
So I switched to OpenGL now, well I'm looking into it, reading examples, Jeff LaMarche's OpenGL blog entries, etc..
I guess I would be able to draw my line. I think I would create classes for curves, straight lines / direction changes, etc. and then on user input I would create the related objects (depending on the steer input) store them in an array and then recreate and redraw the whole line by reading the object properties from the objects stored in the array on each frame. A simple line I would draw like this (code from Beginning iPhone Development)
glDisable(GL_TEXTURE_2D);
GLfloat vertices[4];
// Convert coordinates
vertices[0] = start.x;
vertices[1] = start.y;
vertices[2] = end.x;
vertices[3] = end.y;
glLineWidth(3.0);
glVertexPointer (2, GL_FLOAT , 0, vertices);
glDrawArrays (GL_LINES, 0, 2);
Maybe I will even find a way to antialias it but
now I'm more curious if my idea is good enough or if there are some better established strategies for this
and maybe someone could tell me how to seperate code for hud's, the line drawing itself and some menus that I will have to display f.e. at the beginning ... so that it's easy to transition from one "view" to another (like with a fade)? Some hints ?
Maybe you have also read a book, that will explain how to solve this kind of problems?
Or you can point me to another good answer / example code as I have huge problems in finding "animated drawing" examples.
this got me a little further, but it is still a little vague for me.
I don't know how to realize "update path that you draw (only with needed points + one last point that moves)"
Don't try to merge different views... setNeedsDisplay has a rect parameter that tells the core graphics part that only a certain part of the screen needs to be rendered again. Respect this parameter in your drawRect method and it should be enough for standard 2D games and tools.
If you intent to use intense graphics there is no other option than to use OpenGL. The performance is multiple times better and you won't have to care about optimizations... OpenGL does much in the background.
Use OpenGL ES. Then what you will want to do is create a run loop function or method which gets called by a CADisplayLink 30 to 60 times per second. 60 is the maximum.
So how does this work?
1) Create an assign-property for CADisplayLink. Do NOT retain your CADisplayLink, because display links and timers retain their target. Otherwise you would create a retain-cycle which may cause abandoned memory issues (which is even worse than a leak and much harder to discover).
#property (nonatomic, assign) CADisplayLink *displayLink;
2) Create and schedule the CADisplayLink:
- (void)startRunloop {
if (!animating) {
CADisplayLink *dl = [[UIScreen mainScreen] displayLinkWithTarget:self selector:#selector(drawFrame)];
[dl setFrameInterval:1];
[dl addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
self.displayLink = dl;
animating = YES;
}
}
Some things to note here: -setFrameInterval:1 tells the CADisplayLink to not skip any frame. This means: You get the maximum fps. BUT: This can be bad if your code needs longer than 1/60 seconds. In that case, it's better to set this to 2, for example. Makes your animation more fluid.
3) In your -drawFrame method do your OpenGL ES drawing as usual. The only difference is that this code gets called multiple times per second. Just keep track of time and determine in your code what you want to draw, and how you want it to be drawn. If you were to animate a rectangle moving from bottom left to top right with an animation duration of 1 second, you would simply interpolate the animation frames between start and end by applying a function which takes time t as argument. There are thousands of ways to do it. This is one of them.
4) When you're done or want to halt OpenGL ES drawing, just invalidate or pause your CADisplayLink. Something like this:
- (void)stopRunloop {
if (animating) {
[self.displayLink invalidate];
self.displayLink = nil;
animating = NO;
}
}