Box2d How to create a Slider Platform - cocos2d-iphone

How to create Slider Platform in Box2d? Platform that i can move from side to side just like volume controller.

b2PrismaticJointDef jointDef;
jointDef.Initialize(fixture->GetBody(), groundBody, fixture->GetBody()->GetWorldCenter(), b2Vec2(0.5f,0.0f));
jointDef.maxMotorForce = 500.0;
jointDef.enableMotor = true;
jointDef.lowerTranslation = -2.5f;
jointDef.upperTranslation = 2.5f;
jointDef.enableLimit = true;

Related

Cocos2d-x Game screen not fit in iPhone 4 with iOS 7

I am new for Cocos2d-x, I found strange issue in my game we are testing in all simulator that working fine. also we are testing our game in iPhone 5 and iPad all thing working perfect but got an issue in only iPhone 4 device. there is game screen display small and there are show top and right side black area like following screenshot:
I check its all Default images size and resolution is correct as par apple guide line.
Can you please suggest me how to fix this issue. i can't figure it out is there any code related issue or something need to change in xcode.
Following is iPhone 5 screen shot:
Here is my appdelegate code:
bool AppDelegate::applicationDidFinishLaunching()
{
wrapper->authenticateLocalPlayer();
// initialize director
CCDirector *pDirector = CCDirector::sharedDirector();
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
pDirector->setOpenGLView(CCEGLView::sharedOpenGLView());
// turn on display FPS
pDirector->setDisplayStats(false);
// set FPS. the default value is 1.0/60 if you don't call this
pDirector->setAnimationInterval(1.0 / 60);
CCSize Size = CCDirector::sharedDirector()->getWinSize();
IPADX = Size.width/1024;
IPADY = Size.height/768;
if (Size.width==1024 || Size.width==2048){
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(1024, 768, kResolutionExactFit);
SCALEX = 1.0f;
SCALEY = 1.0f;
}
else
{
if (Size.width<568)
{
SCALEX = 960.0f/1024;
SCALEY = 640.0f/768;
}
else
{
SCALEX = 1136.0f/1024;
SCALEY = 640.0f/768;
}
}
// create a scene. it's an autorelease object
CCScene *pScene = HelloWorld::scene();
// run
pDirector->runWithScene(pScene);
return true;
}
Try this:
//set design resolution
Size designSize = Size(960, 640);
if (Size.width==1024 || Size.width==2048){
designSize = Size(1024, 768);
SCALEX = 1.0f;
SCALEY = 1.0f;
}
else
{
if (Size.width<568)
{
SCALEX = 960.0f/1024;
SCALEY = 640.0f/768;
}
else
{
SCALEX = 1136.0f/1024;
SCALEY = 640.0f/768;
designSize = Size(1136, 640);
}
}
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width, designSize.height, kResolutionExactFit);
CCEGLView::sharedOpenGLView()->setContentScaleFactor(MAX(768/designSize.height,1024/designSize.width) );

DirectX C++ Xbox Controller Input Issue

So I've started using DirectX C++ and have a base game with is a bunch of asteroids which you can shoot using the mouse. It also has a drawn crosshair sprite which follows the mouses location.
I have decided that I would like to change input to support Xbox 360 controllers. I have managed to program the shoot button to the A button on the gamepad however I am having some issues changing to movement of the crosshair from mouse to the analog sticks on the controller.
The following is the code which is used for determining the mouses location and getting its position for use:
virtual void Update()
{
POINT mousePosition;
D3DXVECTOR3 position, currentPosition;
DirectInput::Get().ProcessMouse();
mousePosition = DirectInput::Get().GetCurrentMousePosition();
position.x = (float) mousePosition.x;
position.y = (float) mousePosition.y;
position.z = 0.0f;
currentPosition = m_pCrossHairs->GetSpritePosition();
position.x -= currentPosition.x;
position.y -= currentPosition.y;
position.x = position.x/2.0f;
position.y = position.y/2.0f;
m_pCrossHairs->SetTranslationMatrix(position);
m_pCrossHairs->CheckBoundary();
m_pCrossHairs->Update();
}
And here is what I've changed it to for use with an Xbox Controller Instead:
virtual void Update()
{
POINT crosshairPosition;
D3DXVECTOR3 position, currentPosition;
crosshairPosition.x = XBox360Controller::Get().RightJoyStickX();
crosshairPosition.y =- XBox360Controller::Get().RightJoyStickY();
position.x = crosshairPosition.x;
position.y = crosshairPosition.y;
position.z = 0.0f;
currentPosition = m_pCrossHairs->GetSpritePosition();
position.x -= currentPosition.x;
position.y -= currentPosition.y;
position.x = position.x/2.0f;
position.y = position.y/2.0f;
m_pCrossHairs->SetTranslationMatrix(position);
m_pCrossHairs->CheckBoundary();
m_pCrossHairs->Update();
}
On a positive note what I have done kind of works. The Crosshair does move when I move the analog stick, however it is stuck in the top right hand corner and can only move within a range of about 1 square inch on the screen. I'm a bit stuck as to why this is and therefore would appreciate any kind of input. Sorry if I'm lacking any important info that I may have missed, a bit of a late post however would really love to get it working!
On a side note - I'm getting an error on the following giving me a warning about conversion from long to float or something (should I be worried about this)?
crosshairPosition.x = XBox360Controller::Get().RightJoyStickX();
crosshairPosition.y =- XBox360Controller::Get().RightJoyStickY();
Once again thank you in advance.
Billy
Edit:
Code for XBox360Controller::Get().
XBox360Controller& XBox360Controller::Get()
{
if (s_pXBox360Controller == NULL)
s_pXBox360Controller = new XBox360Controller();
return *s_pXBox360Controller;
}
Code for Right analog stick X-Axis
float XBox360Controller::RightJoyStickX()
{
float joyStickX = GetState().Gamepad.sThumbRX;
// Make sure there has been movement, as joystick does return different values even if no movement.
if ( joyStickX< XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE &&
joyStickX > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
return 0;
else
return joyStickX/DynamicRange;
}
Code for Right analog stick Y-Axis
float XBox360Controller::RightJoyStickY()
{
float joyStickY = GetState().Gamepad.sThumbRY;
// Make sure there has been movement, as joystick does return different values even if no movement.
if ( joyStickY< XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE &&
joyStickY > -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)
return 0;
else
return joyStickY/DynamicRange;
}
EDIT SOLVED:
Added a new translation matrix and it's fixed the issue, thanks for the help.

Moving a box2d object along the x axis while gravity pulls on the y axis

I have a box2d object that is being moved down the screen via gravity
int32 velocityIterations = 6;
int32 positionIterations = 2;
self.world->Step(dt, velocityIterations, positionIterations);
self.world->ClearForces();
for(b2Body *b = self.world->GetBodyList(); b; b=b->GetNext()) {
if (b->GetUserData() != NULL) {
id object = (id)b->GetUserData();
if([object isKindOfClass:[FallingObject class]])
{
CCSprite *sprite = (CCSprite *)b->GetUserData();
sprite.position = CGPointMake(b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO);
sprite.rotation = -1 * CC_RADIANS_TO_DEGREES(b->GetAngle());
}
}
}
When the user moves their finger across the screen either left or right i want to move the box2d object left or right while the object is still moving down the screen.
Can anyone suggest the best way to do this. I have tried applying linear velocity but it just seems to shoot of screen.
Any suggestions
Thanks
There some ways to do this, and you need to try the best for your case.
You can apply forces, impulse, or change the body velocity manually just for X parameter:
// x axis force
b2Vec2 xAxisForce = b2Vec2(10, 0);
// Try one of these
b->ApplyForce(xAxisForce, b->GetWorldCenter());
b->ApplyForceToCenter(xAxisForce);
b->ApplyLinearImpulse(xAxisForce, b->GetWorldCenter());
// Or change the body velocity manually
b->SetLinearVelocity(b2Vec2(10, b->GetLinearVelocity().y));

How to create a tank with cocos2dx

Me and a friend of mine are trying to make a tank with cocos2dx.
we are so far that the tank is on the screen and the barrel is attached to the tank
but now we want to try to the rotate the barrel but nothing is happening, the joint is at the center where the barrel start en de dome ends. both the tank and the barrel are dynamic bodies and we are using a friction joint (see code)
// Create sprite and add it to the layer
CCSprite *tank = CCSprite::create();
//tank->initWithFile("../Resources/tanks/001/tank.png");
tank->setPosition(pos);
tank->setTag(1);
this->addChild(tank);
// Create ball body
b2BodyDef tankBodyDef;
tankBodyDef.type = b2_dynamicBody;
tankBodyDef.position = toMeters(&pos);
tankBodyDef.userData = tank;
tankBody = _world->CreateBody(&tankBodyDef);
// Create shape definition and add body
shapeCache->addFixturesToBody(tankBody, "001/tank");
pos = CCPointMake(580, 450);
// Create sprite and add it to the layer
CCSprite *barrel = CCSprite::create();
//barrel->initWithFile("Tanks/001/barrel.png");
barrel->setPosition(pos);
barrel->setTag(2);
this->addChild(barrel);
// Create ball body
b2BodyDef barrelBodyDef;
barrelBodyDef.type = b2_dynamicBody;
barrelBodyDef.position = toMeters(&pos);
barrelBodyDef.userData = barrel;
barrelBody = _world->CreateBody(&barrelBodyDef);
tankBarrelAnchor = CreateRevoluteJoint(tankBody, barrelBody, -85.f, 180.f, 2000000.f, 0.f, true, false);
tankBarrelAnchor->localAnchorA = b2Vec2(0, 0);
tankBarrelAnchor->localAnchorB = b2Vec2(0, 0);
tankBarrelAnchor->referenceAngle = 0;
joint = (b2RevoluteJoint*)_world->CreateJoint(tankBarrelAnchor);
b2RevoluteJointDef* Level::CreateRevoluteJoint(b2Body* A, b2Body* B, float lowerAngle, float upperAngle, float maxMotorTorque, float motorSpeed, boolean enableMotor, boolean collideConnect){
b2RevoluteJointDef *revoluteJointDef = new b2RevoluteJointDef();
revoluteJointDef->bodyA = A;
revoluteJointDef->bodyB = B;
revoluteJointDef->collideConnected = collideConnect;
revoluteJointDef->lowerAngle = CC_DEGREES_TO_RADIANS(lowerAngle);
revoluteJointDef->upperAngle = CC_DEGREES_TO_RADIANS(upperAngle);
revoluteJointDef->enableLimit = true;
revoluteJointDef->enableMotor = enableMotor;
revoluteJointDef->maxMotorTorque = maxMotorTorque;
revoluteJointDef->motorSpeed = CC_DEGREES_TO_RADIANS(motorSpeed); //1 turn per second counter-clockwise
return revoluteJointDef;
}
I think the problem is that your anchor positions are not correct. This setting:
tankBarrelAnchor->localAnchorA = b2Vec2(0, 0);
tankBarrelAnchor->localAnchorB = b2Vec2(0, 0);
... would put the anchors at those two red and green axes you can see in your screenshot, and it will try to pull those two points together. Try turning on the joints display in the debug draw and this should be more obvious.
You need to give the anchors as local coordinates from the point of view of each body. For example from the point of view of the tank body, the swivel point looks like (1,2) and from the point of view of the barrel body, it looks like (-1,0). Of course the dimensions you are using are probably different, but the directions should be somewhat similar.
See the "Local anchors" section here: http://www.iforce2d.net/b2dtut/joints-revolute

Change PrismaticJoint engine direction

Is it possible to modify the direction of the engine after the joint is created?
This is the definition of a joint:
//Define a prismatic joint
b2PrismaticJointDef jointDef;
b2Vec2 axis = b2Vec2(1.0f, 0.0f);
axis.Normalize(); //Important
jointDef.Initialize(staticBody, body, b2Vec2(0.0f, 0.0f),axis);
jointDef.localAnchorA = b2Vec2(0.0f,0.0f);
jointDef.localAnchorB = body->GetLocalCenter();
jointDef.motorSpeed = 3.0f;
jointDef.maxMotorForce = +200*body->GetMass();
jointDef.enableMotor = true;
jointDef.lowerTranslation = -2.0f;
jointDef.upperTranslation = 3.0f;
jointDef.enableLimit = true;
_horPrismaticJoint = (b2PrismaticJoint*) world->CreateJoint(&jointDef);
Inside CCTouchesBegan I tried to change the force value but it's not working:
_horPrismaticJoint->SetMaxMotorForce(-200.0f);
The cocos distribution is cocos2d-iphone-1.0.1
Yes, you just need to change the speed (not the max force):
joint->SetMotorSpeed( -3.0f );
The max force describes how strong the joint motor is, so it should not be negative.