Objects pass through each other - libgdx

I've two objects, one is static and another one is dynamic. Fixtures of both of them created from ChainShape. The problem is that they pass through each other.
Screenshot :

Two ChainShapes dont collide with each other make one of them a PolygonShape.
This works for me:
BodyDef triangleDef = new BodyDef();
triangleDef.type = BodyDef.BodyType.DynamicBody;
triangleDef.position.set( 0, 0 );
Body triangleBody = this.world.createBody( triangleDef );
PolygonShape triangleShape = new PolygonShape();
triangleShape.set( new float[]{ 0, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f } );
triangleBody.createFixture( triangleShape, 1 );
triangleShape.dispose();
BodyDef groundDef = new BodyDef();
triangleDef.position.set( 0, 0 );
Body groundBody = this.world.createBody( groundDef );
ChainShape groundShape = new ChainShape();
groundShape.createLoop( new float[]{ -10, 10, -10, -10, 10, -10, 10, 10 } );
groundBody.createFixture( groundShape, 1 );
groundShape.dispose();

Related

Applying double color transform in AS3

Simply put, I would like to set several movieclips to different specific colors and then apply a tint over them.
var color1 = new ColorTransform(); color1.color = 0x0000FF;
var color2 = new ColorTransform(); color2.color = 0x00FF00;
var color3 = new ColorTransform(); color3.color = 0xFFFF00;
thing1.transform.colorTransform = color1;
thing2.transform.colorTransform = color2;
thing3.transform.colorTransform = color3;
thing1.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0);
thing2.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0);
thing3.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0);
unfortunately the colortransform resets the value. Any way to keep the value of the first color transform?
You should be able to do that with the ColorTransform.concat() function.
var color1 = new ColorTransform(); color1.color = 0x0000FF;
var color2 = new ColorTransform(); color2.color = 0x00FF00;
var color3 = new ColorTransform(); color3.color = 0xFFFF00;
color1.concat( new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0) );
color2.concat( new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0) );
color3.concat( new ColorTransform(1, 1, 1, 1, 0, 200, 150, 0) );
thing1.transform.colorTransform = color1;
thing2.transform.colorTransform = color2;
thing3.transform.colorTransform = color3;
Which essentially is the same as (clamping offset values to 255 using Math.min):
thing1.transform.colorTransform = new ColorTransform(1*1, 1*1, 1*1, 1*1, Math.min(0x00+0, 0xFF), Math.min(0x00+200, 0xFF), Math.min(0xFF+150, 0xFF), Math.min(0x00+0, 0xFF));
thing2.transform.colorTransform = new ColorTransform(1*1, 1*1, 1*1, 1*1, Math.min(0x00+0, 0xFF), Math.min(0xFF+200, 0xFF), Math.min(0x00+150, 0xFF), Math.min(0x00+0, 0xFF));
thing3.transform.colorTransform = new ColorTransform(1*1, 1*1, 1*1, 1*1, Math.min(0xFF+0, 0xFF), Math.min(0xFF+200, 0xFF), Math.min(0x00+150, 0xFF), Math.min(0x00+0, 0xFF));
Or:
thing1.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0x00, 0xC8, 0xFF, 0x00);
thing2.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0x00, 0xFF, 0x96, 0x00);
thing3.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 0xFF, 0xFF, 0x96, 0x00);
I've found a solution to this problem.
If I set an object to a color
var color1 = new ColorTransform(); color1.color = 0x0000FF;
thing1.transform.colorTransform = color1;
I can then edit the blue and green values as so to get my desired tint
color1.blueOffset+=200;
color1.greenOffset+=150;
And then use colortransform on the object to set the new color
thing1.transform.colorTransform = color1;

Bullet trajectory using LIBGDX

Im having problems with the bullet trajectory,the bullet is not accurately fire at the mouse cursor on screen when i do clicks.
Here my code:
#Override
public boolean mouseMoved(int screenX, int screenY) {
touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
gamecam.unproject(touchPos);
return false;
}
public void shoot() {
bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(x,y);
body = world.createBody(bodyDef);
polygonShape = new PolygonShape();
polygonShape.setAsBox(0.2f / 2.0f, 0.01f /2.0f);
fixtureDef2 = new FixtureDef();
fixtureDef2.shape = polygonShape;
float calc= (float) (Math.atan2(touchPos.y-(body.getPosition().y),touchPos.x-body.getPosition().x));
body.setTransform(body.getWorldCenter(),calc);
body.applyLinearImpulse((touchPos.x-body.getPosition().x)*3, (touchPos.y-body.getPosition().y)*3, 0, 0, true);
}
You're removing the bodies position from the impulse vector which is causing your body to be misaligned with your target.
body2.applyLinearImpulse(touchPos.x, touchPos.y, 0, 0, true);

Rotation without distortion using Matrix3D

How to assign a value to Matrix3D rotation about the axis Z. (li "rotation")?
The position and size are calculated correctly, but after the addition of rotation, the image is stretched.
I tried two method to rotation:
_positionMatrix.identity();
var v3:Vector.<Vector3D> = new Vector.<Vector3D>(3);
v3 = _positionMatrix.decompose();
v3[0].incrementBy(new Vector3D( x, y, 0 ));// x, y, z
v3[1].incrementBy(new Vector3D(0,0,-rotation*Math.PI/180)); // rotationX, rotationY, rotationZ
v3[2].incrementBy(new Vector3D(width,height,0)); // scaleX, scaleY, scaleZ
_positionMatrix.recompose(v3);
And:
_positionMatrix.identity();
_positionMatrix.appendScale(width,height,1);
_positionMatrix.appendTranslation(x,y,0);
_positionMatrix.appendRotation(-rotation,Vector3D.Z_AXIS );
But the effect is identical:
I find that "PerspectiveProjection" class can help, but cant to understand how to use it with rotation about the axis Z.
For start, if you have such a problem - try to eliminate matrix transforms one by one until you find which matrix is a "bad" one. For example, what will happen if you store only one transformation - scale or translation or rotation?
In your example I can't see any criminal, so the problem is further in code. I can assume that your projection matrix is wrong. Can you provide it? How do you apply final matrix to an object?
Thanks, its true, my perspective Projection matrix was "bad".
This code works perfectly:
private var _vertexData:Vector.<Number> = new <Number>[
0,0,0, 0, 0, 0, 1,// x, y, z, r, g, b,a
1, 0, 0, 0, 0, 0, 1,
1, 1, 0, 0, 0, 0, 1,
0, 1, 0,0, 0, 0,1
];
var perspectiveProjectionMatrix:Matrix3D = new Matrix3D();
var scaleX:Number = 2.0 / _stage.stageWidth; // 2.0 / 500
var scaleY:Number = -2.0 / _stage.stageHeight; // -2.0 / 375
perspectiveProjectionMatrix.copyRawDataFrom(
new <Number>[
scaleX, 0.0, 0.0, 0.0,
0.0, scaleY, 0.0, 0.0,
0.0, 0.0, -1.0, 0.0,
-1.0, 1.0, 0.0, 1.0
]
);
var modelViewMatrix:Matrix3D = trs(stage.stageWidth/2,stage.stageHeight/2, _rotation*Math.PI/180, _width*_globalScaleX, _height*_globalScaleY );
var resultMatrix:Matrix3D = new Matrix3D();
resultMatrix.prepend(perspectiveProjectionMatrix);
resultMatrix.prepend(modelViewMatrix);
_context.setProgramConstantsFromMatrix(Context3DProgramType.VERTEX, 0,resultMatrix , true);
Where "trs" is:
public function trs( tx:Number, ty:Number, rotation:Number, xScale:Number, yScale:Number ):Matrix3D {
var data:Vector.<Number> = new <Number>[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
var sin:Number = Math.sin( rotation );
var cos:Number = Math.cos( rotation );
data[0] = cos * xScale;
data[1] = sin * xScale;
data[4] = -sin * yScale;
data[5] = cos * yScale;
data[12] = tx;
data[13] = ty;
var matrix:Matrix3D = new Matrix3D();
matrix.copyRawDataFrom(data);
return matrix;
}

ActionScript 3: Tween stops mid animation...Probably the garbage collector

I have been relentlessly trying to get my tweens in ActionScript 3 to work correctly, however with reaserch I have founf that the cause for the freezing mid animation is because of the garbage collector... I have tried both these methods, and have tried putting it in my document class, and yet it still happens to freeze randomly. It looks like I may have to go for something like tween lite, however something so simple shouldn't be so hard...
Attempt 1:
function createScrollingMC(mc:MovieClip, stageLeft:int, stageRight:int, durationSecs:int) {
var scrollingTween01:Tween;
var multiplyer:int = 100;
scrollingTween01 = new Tween(mc, "x", None.easeNone, stageLeft - mc.width, stageRight + mc.width, durationSecs * multiplyer, true);
scrollingTween01.looping = true;
}
createScrollingMC(Cloud_01, 0, 1024, 1);
createScrollingMC(Cloud_02, 0, 1024, 2);
createScrollingMC(Cloud_03, 0, 1024, 3);
createScrollingMC(Cloud_04, 0, 1024, 4);
Attempt 2:
var scrollingTween01:Tween;
function createScrollingMC(mc:MovieClip, stageLeft:int, stageRight:int, durationSecs:int) {
var multiplyer:int = 100;
scrollingTween01 = new Tween(mc, "x", None.easeNone, stageLeft - mc.width, stageRight + mc.width, durationSecs * multiplyer, true);
scrollingTween01.looping = true;
}
createScrollingMC(Cloud_01, 0, 1024, 1);
createScrollingMC(Cloud_02, 0, 1024, 2);
createScrollingMC(Cloud_03, 0, 1024, 3);
createScrollingMC(Cloud_04, 0, 1024, 4);
You are re-using the Tween instance scrollingTween01. It's a good thing, but you start using it before the last one finished tweening. After you re-assign it, it will stop animation of the previous one and this has nothing to do with GC.
Create new instances for the Tween class and that should solve your problem.
function createScrollingMC(mc:MovieClip, stageLeft:int, stageRight:int, durationSecs:int)
{
var multiplyer:int = 100;
var tween = new Tween(mc, "x", None.easeNone, stageLeft - mc.width, stageRight + mc.width, durationSecs * multiplyer, true);
tween.looping = true;
}

What are width and height supposed to represent for a sprite?

I'm working with a Sprite in AS3. Initially, width,height are 0,0 as expected.
After this:
var tf : TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 48;
tf.bold = true;
text = new TextField();
text.text = "A";
text.x = 30;
text.y = 16;
text.selectable = false;
text.setTextFormat(tf);
addChild(text);
they are 100,100 (even if I shrink the text size).
After this
graphics.beginFill(0xffffff, 1);
graphics.drawRect(0, 0, 99, 99);
graphics.endFill();
graphics.beginFill(color, 1);
graphics.drawRoundRect(6, 6, 84, 84, 8, 8);
graphics.endFill();
They are 130,116. I would expect them to end up at 99,99, what am I missing?
Modification: here's the code from the first answer, but modified to use a single sprite:
var s = new Sprite();
trace("1:", s.width, ", ", s.height) // <-- 0 , 0
var tf : TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 48;
tf.bold = true;
var text = new TextField();
text.text = "A";
text.x = 30;
text.y = 16;
text.selectable = false;
text.setTextFormat(tf);
s.addChild(text);
trace("2:", s.width, ", ", s.height) //<-- 100, 100
s.graphics.beginFill(0xffffff, 1);
s.graphics.drawRect(0, 0, 99, 99);
s.graphics.endFill();
s.graphics.beginFill(0x000fff, 1);
s.graphics.drawRoundRect(6, 6, 84, 84, 8, 8);
s.graphics.endFill();
trace("3:", s.width, ", ", s.height) //<-- 130,116
Can anyone explain why these 2 behave differently?
Cheers,
Charlie.
I don't know what you're doing elsewhere, but your code is right.
import flash.display.Sprite;
var s = new Sprite();
trace(s.width, ", ", s.height) // <-- 0 , 0
var tf : TextFormat = new TextFormat();
tf.font = "Arial";
tf.size = 48;
tf.bold = true;
var text = new TextField();
text.text = "A";
text.x = 30;
text.y = 16;
text.selectable = false;
text.setTextFormat(tf);
s.addChild(text);
trace(s.width, ", ", s.height) //<-- 100, 100
var s2 = new Sprite();
with(s2) {
graphics.beginFill(0xffffff, 1);
graphics.drawRect(0, 0, 99, 99);
graphics.endFill();
graphics.beginFill(0x000fff, 1);
graphics.drawRoundRect(6, 6, 84, 84, 8, 8);
graphics.endFill();
}
trace(s2.width, ", ", s2.height) //<-- 99, 99
Are the results I get. Is something else in your code scaling objects?
the width and height attribute for a textfield returns the width and height of the textfield boarder, which by default is 100 x 100
try this to see what I'm talking about
text.border = true;
if you want the actual size of the text in the textfield you need
trace(text.textWidth);
trace(text.textHeight);