libgdx - render() with a little "breaks" - libgdx

I've started to programming with Libgdx just today, and i want to move my camera infinitely down, dynamically rendering my background, so camera always have something to see.
The thing is, I made a code that does that, but I'm noticing some "breaks" in the passage of background. It is not smooth enough, and i can't figure it out why.. To see better these "breaks" just raise the property "speed".
I've hosted my project and the link is below. If someone can analyse the code, I'll be glad!
Thanks a lot!
Project: http://www.4shared.com/rar/SEjnsbLsce/drop_1.html
EDIT:
The "breaks" is like a 0.1 pause on the camera movement. Is not smooth enough, sometimes im having this little pauses.
I already tried to do manually, to see if the "breaks" continues, and it is continue.
render():
batch.draw(backgroundImage, backgroundSprite.getX(), 0);
batch.draw(backgroundImage, backgroundSprite.getX(), -800 );
batch.draw(backgroundImage, backgroundSprite.getX(), -1600 );
.
.
.
batch.draw(backgroundImage, backgroundSprite.getX(), -9600 );
I made my dynamic code really fast, i know i can do a lot better then this, but i'm programming to make it works, then, refactor:
render():
camera.position.set(camera.position.x, camera.position.y - (speed * Gdx.graphics.getDeltaTime()), camera.position.z);
batch.begin();
if( yWalked < backgroundSprite.getHeight() * backgroundCounter ){
batch.draw(backgroundImage, backgroundSprite.getX(), ( ( backgroundSprite.getHeight() * backgroundCounter ) - backgroundSprite.getHeight()) * -1);
}
if( ( yWalked + backgroundSprite.getHeight() ) > ( backgroundSprite.getHeight() * backgroundCounter ) ){
batch.draw(backgroundImage, backgroundSprite.getX(), (backgroundSprite.getHeight() * backgroundCounter) * -1 );
}
if( yWalked > backgroundSprite.getHeight() * backgroundCounter ){
backgroundCounter++;
}
yWalked = yWalked + ( speed * Gdx.graphics.getDeltaTime() );
batch.end();

Related

Wierd behaviour with cc.PhysicsSprite in cocos2dx and chipmunk

I have a game where balls bounce around the screen - simple. I have walls that prevent balls from escaping the screen space. I use the following code to add balls to the screen, which happens with some delay between each addition:
var ball = {};
ball.markedForDelete = false;
ball.dir = spawnPoint.dir;
var ballMass = 1;
var ballBody = new cp.Body( ballMass, cp.momentForCircle( ballMass, 0, this._ballRadius, cp.v(0,0) ) );
ballBody.setPos( spawnPoint.position );
var magnitude = 200;
var ang = spawnPoint.dir * Math.PI / 180;
var vel = cp.v( magnitude * Math.cos(ang), magnitude * Math.sin(ang) );
var shape = new cp.CircleShape( ballBody, this._ballRadius, cp.v( 0,0 ) );
shape.ballShapeId = this.model.getNextBallShapeId ();
shape.setElasticity( 1 );
shape.setFriction( 0 );
shape.setCollisionType( collision_type );
this._space.addShape( shape );
ball.shape = shape;
shape.ball = ball;
var sprite = cc.PhysicsSprite.create( file );
sprite.nodeName = "Ball:" + shape.ballShapeId;
sprite.setColor( cc.c3b( 255, 255, 255 ) );
sprite.setScale ( 0.5 * this.ballScale );
sprite.setBody( ballBody );
this._gameStage.addChild( sprite, 5 );
ball.sprite = sprite;
sprite.ball = ball;
this._space.addBody( ballBody );
ballBody.setVel( vel ) ;
return ball;
This code works as expected when running on a device (iOS or Android), but when I use exact same code on the web things get weird. First, it spawns about 4 balls from random spawn points without a hitch, but all following balls get spawned on top of an existing ball and seems like the two (or three or four depending on how long you play) share physics. If I enable debug physics node:
cc.PhysicsDebugNode.create( this._space );
I can see that these balls are right over each other and they stack velocities. What is going on? Is there a limit on how many I can have? Any pointers? I am so lost and confused.
Thanks!
So, i figured it out. I created an array of 4 spawn points (notice it matches how many balls i was seeing). Each spawn point was something like this spawnPoint: { position: cc.p ( x, y ) }. So, when I assign position for the body using ballBody.setPos( spawnPoint.position ) it was not creating a new cc.p object to store position, but actually using the one i provided. So, every ball i created shared one of these 4 positions. On mobile devices this works properly and cc.p is actually created, instead of just pointing to the one I provided. Hope it helps someone.

NetStream.seek error Seeking videos

i try to do seek function in NetStream class using Action Script language , The seek is not work correctly . I read about KeyFrames in NetStream , what is the relationship between KeyFrames and seek ? is there other problem of using seek function by NetStream ?
onClick() Function to Seek;
private function onClick(event:MouseEvent):void
{
if (event.currentTarget is Group)
{
var myGroup:Group = event.currentTarget as Group;
if ( myGroup.mouseX >= 100)
{
mouseClickedXPos = myGroup.mouseX;
ns.inBufferSeek = true;
var seekTime:Number = (mouseClickedXPos-100) * (totalTime/(controlBarControls.width-100));
ns.seek(seekTime);
}
}
}
there is event for netStatus for net stream
ns.addEventListener(NetStatusEvent.NET_STATUS, onNetStatus);
private function onNetStatus(event:NetStatusEvent):void
{
if ( event.info == "NetStream.Play.StreamNotFound" )
legend.text = "Video file passed, not available!";
else if(event.info.code == "NetStream.Play.FileStructureInvalid")
legend.text = "Video file passed, FileStructureInvalid";
}
event.info.code is be NetStream.Seek.InvalidTime , the video will stop playing , sometime will seek for end of video , but i trace it , the ns.time() doesn't update to new value (seekTime)
I'm not entirely sure, but I think you got this line wrong:
var seekTime:Number = (mouseClickedXPos-100) * (totalTime/(controlBarControls.width-100));
Try this instead:
var seekTime:Number = ( ( mouseClickedXPos - 100 ) / ( controlBarControls.width - 100 ) ) * totalTime;
Basically, you were comparing two completely different quantities to form a ratio and multiply that by the mouse click position. Instead, divide that mouseX by the total width (giving the position of the click as a percentage of the total width) and multiply that by the time (giving you a percentage of the total time).
I'm not overly familiar with the way NetStream works (I've used it, just not extensively enough to know this off the top of my head), but if you pass a time greater than the totalTime, there has to be an error or it has to handle it by either not completing the command or by setting the value to 0 (which I personally think is what would happen. It's how I would do it, at any rate)

How to code an audio envelope (attack time, fade in) for a Sound object?

I made a simple sine wave tone generator. The problem is that when the tone is played a strong click can be heard, and I need to implement a fast fade in (attack time) to avoid this.
I tried using tweening (like tweenmax) but it induces distortion to the audio (maybe the steps in the tweening?). I found some vague tutorials on the subject but nothing regarding attack time specifically.
How can I do this?
For the fade to sound smooth, it has to be incremented on a per-sample basis, inside your synthesis loop. A tween engine may update many times a second, but your ear can still hear the changes as a click.
In your sampleData event handler, you will have to multiply the individual samples by a volume modifier, with the range of 0 to 1, incrementing for every sample.
To quickly fade in the sound, start by setting the volume to 0, and adding a small value to it for each sample, until it reaches 1.0. You can later expand this into a more complex envelope controller.
This is a rough example of what you might start with:
for( i = 0; i < length; i++ ) {
_count++;
factor = _frequency * Math.PI * 2 / 4400;
volume += 1.0 / 4400;
if( volume > 1.0 ) volume = 1.0; //don't actually do it like this, ok?
n = Math.sin( (_count) * factor ) * volume;
_buffer.writeFloat(n);
_buffer.writeFloat(n);
}
NOTE: I haven't tested this snippet, nor would I recommend using it for production. It's just to show you roughly what I mean.
Another technique that may work for you is to put an ease / delay on the volume. Use a volumeEase variable that always 'chases' the target volume at a certain speed. This will prevent clicks when changing volumes and can be used to make longer envelopes:
var volume:Number = 0; // the target volume
var volumeEase:Number = 1.0; // the value to use in the signal math
var volumeEaseSpeed:Number = 0.001; // tweak this to control responsiveness of ease
for( i = 0; i < length; i++ ) {
_count++;
// bring the volumeEase closer to the target:
volumeEase += ( volume - volumeEase ) * volumeEaseSpeed;
factor = _frequency * Math.PI * 2 / 4400;
//use volumeEase in the maths, rather than 'volume':
n = Math.sin( (_count) * factor ) * volumeEase;
_buffer.writeFloat(n);
_buffer.writeFloat(n);
}
If you wanted to, you could just use a linear interpolation, and just go 'toward' the target at a constant speed.
Once again, the snippet is not tested, so you may have to tweak volumeEaseSpeed.

Zoom to and from point

I'm trying to zoom a DisplayObject into a certain point. I figured it would be easy, but I've spent a day now trying to figure it out.
Basically, I think this should work. Emphasis on should.
//newPoint is the point being centered. There is no initial scaling, so I do not need to compensate for that (yet)
//scale is the zoom level
//container is the parent of the obj
//obj is the object being scaled/panned
var p:Point = new Point(
( this.container.width - this.obj.width * scale + newPoint.x * scale ) / 2,
( this.container.height - this.obj.height * scale + newPoint.y * scale ) / 2
);
this.obj.scaleX = this.obj.scaleY = scale;
this.obj.x = p.x;
this.obj.y = p.y;
It centers the point if scale is 1, but it gets further and further away from center as you increase the scale. I've tried dozens of different methods. This method, which I have seen on several sites, produced the same exact results. Anyone have any idea how to get this to work?
EDIT 10-1-12:
As a followup, I took the code snippet that LondonDrugs_MediaServices provided as a basis for my original issue. I needed to be able to zoom to a specific point at a specific scale relative to the unscaled image (think how Google Maps zooms to a specific location). To do this, I had to center my image on the point before running the translation code. I've posted the additional code below. For other uses (pinch to zoom, scrolling, and double click), I used the code provided by Vesper, which worked quite well.
//obj is the object being translated
//container is its parent
//x and y are the coordinates to be zoomed to, in untranslated scaling
//obj.scaleX and obj.scaleY are always identical in my class, so there is no need to account for that
//calculates current center point, with scaling
var center:Point = new Point( ( this.container.width - this.obj.width * this.obj.scaleX ) / 2, ( this.container.height - this.obj.height * this.obj.scaleX ) / 2 );
//calulcates the distance from center the point is, with scaling
var distanceFromCenter:Point = new Point( this.obj.width * this.obj.scaleX / 2 - x * this.obj.scaleX, this.obj.height * this.obj.scaleX / 2 - y * this.obj.scaleX );
//center the object on that specific point
this.obj.x = center.x + distanceFromCenter.x;
this.obj.y = center.y + distanceFromCenter.y;
var mat:Matrix=new Matrix();
mat.translate(-p.x,-p.y);
mat.scale(desiredScale,desiredScale);
mat.translate(p.x,p.y);
yourObject.transform.matrix=mat;
The core point is that scaling is done around (0,0), but you can do it with matrix that describes affine transformations. You first make an empty matrix (that is, a matrix that doesn't transform), then apply a set of transformations to it. First, place a desired point at (0,0) by translating by -1*coordinates, then scale, then translate back.
hie guys....
thank's your comments...
i found the answer...
code :
gambar.addEventListener(TransformGestureEvent.GESTURE_ZOOM , onZoom);
function onZoom(event:TransformGestureEvent):void {
var locX:Number=event.localX;
var locY:Number=event.localY;
var stX:Number=event.stageX;
var stY:Number=event.stageY;
var prevScaleX:Number=gambar.scaleX;
var prevScaleY:Number=gambar.scaleY;
var mat:Matrix;
var externalPoint=new Point(stX,stY);
var internalPoint=new Point(locX,locY);
gambar.scaleX *= event.scaleX;
gambar.scaleY *= event.scaleY;
if(event.scaleX>1 && gambar.scaleX>6){
gambar.scaleX=prevScaleX;
gambar.scaleY=prevScaleY;
}
if(event.scaleY>1 && gambar.scaleY>6){
gambar.scaleX=prevScaleX;
gambar.scaleY=prevScaleY;
}
if(event.scaleX<1 && gambar.scaleX<0.8){
gambar.scaleX=prevScaleX;
gambar.scaleY=prevScaleY;
}
if(event.scaleY<1 && gambar.scaleY<0.8){
gambar.scaleX=prevScaleX;
gambar.scaleY=prevScaleY;
}
mat=gambar.transform.matrix.clone();
MatrixTransformer.matchInternalPointWithExternal(mat,internalPoint,externalPoint);
gambar.transform.matrix=mat;
}
The matrix answer is absolutely correct, but if you happen to be a Club GreenSock member you can get some nice functionality with very simple code with the TransformAroundPointPlugin
http://www.greensock.com/as/docs/tween/com/greensock/plugins/TransformAroundPointPlugin.html
You can see an example in the plugin explorer here:
http://www.greensock.com/tweenlite/#plugins
I use this to tween all my zooms and have much better performance than when I tried to do this manually. IMO the whole library is worth it's weight in gold (and no I have no connection other than liking the library). If you need any of the other features I'd look into it. It also has the ThrowProps plugin ( http://www.greensock.com/throwprops/ )which is very important if you are going to have a bounding box on mobile that you want to have a smooth return into the boundaries.
Set obj.x to -p.x and obj.y to -p.y, set the container scaleX and scaleY to the desired value and add p.x to the container x and p.y to the container y. Done!

Check If animation is running in cocos2d-x

I am currently learning cocos2D-x and am doing some sprite animation.
My Objective is that when a button is clicked the object moves to left with some animation.
Now if you click multiple times rapidly the animation takes place immediately and it looks like the bear is hoping instead of walking.
The solution to it looks simple that I should check if animation is already running and if running the new animation should not take place.
The following is a part of my code.
CCSpriteFrameCache::sharedSpriteFrameCache()->addSpriteFramesWithFile("AnimBear.plist");
CCSpriteBatchNode* spriteBatchNode = CCSpriteBatchNode::create("AnimBear.png", 8);
this->addChild(spriteBatchNode,10);
CCArray *tempArray = new CCArray();
char buffer[15];
for (int i = 1; i <= 8 ; i++)
{
sprintf(buffer,"bear%i.png", i);
tempArray->addObject(CCSpriteFrameCache::sharedSpriteFrameCache()->spriteFrameByName(buffer));
}
CCAnimation *bearWalkingAnimation = CCAnimation::create(tempArray,0.1f);
startAnimation = CCSprite::createWithSpriteFrameName("bear1.png");
startAnimation->setPosition(ccp (350 , CCDirector::sharedDirector()->getWinSize().height/2 -100));
startAnimation->setScale(0.5f);
startAnimation->setTag(5);
//Animation for bear walking
bearAnimate = CCAnimate::create(bearWalkingAnimation);
Here bearAnimate is a global variable and i wish to know if its currently playing the animation.
How do I do it.?Thank you.
Assume the Sprite that runs the action is
CCSprite* bear;
I think you can use something like
bear->numberOfRunningActions()
numberOfRunningActions( ) returns an unsigned integer, so to check if there are no actions, you would have to check if it returns 0
if ( bear -> numberOfRunningActions( ) == 0 ) {
CCLOG( "No actions running." );
} else {
CCLOG( "Actions running." );
}
The bearAnimate (CCAnimate) has a method to check that.
if (bearAnimate.isDone())
doWhatYouWant();
The method is inherited from CCAction. Good luck.