Hey i have another issue regarding jump sprite body. In my code i am using moveLeft and moveRight Button and when i am press moveRight Button using following code
if (moveRight.active==YES)
{
b2Vec2 force=b2Vec2(4,0);
ballBody->SetLinearVelocity(force);
}
Its move perfectly and When i release this Button than sprite body stop using following code
else
{
b2Vec2 force=b2Vec2(0,0);
ballBody->SetLinearVelocity(force);
}
But when i put this else part then jump can not done. My jump code is following
if (jumpSprite.active==YES)
{
NSLog(#"Jump Sprite");
b2Vec2 locationWorld;
locationWorld=b2Vec2(0.0f,4.0f);
double force=ballBody->GetMass();
ballBody->ApplyLinearImpulse(force*locationWorld, ballBody->GetWorldCenter());
}
If i remove else part then jump will perform complete but sprite body can not stop after release button.
So what to do??
Thanks in advance
I got the answer.
I we create body and first check it is circle or polygon because circle body can not have rolling resistance so and in this case we don't need to stop manually using linearVelocity to 0.
Using friction all body stop automatically excepting circle body.
Related
In my scene class I've overridden the update function and I call scheduleUpdate() in the onEnter() method as suggested here. So in the update function I call the update of my layer class which should update my sprites:
void View::update(float dt)
{
world->Step(dt, 10, 10);
for(b2Body *b = world->GetBodyList(); b; b=b->GetNext())
{
if(b->GetUserData() != NULL && b->GetType() != b2_kinematicBody))
{
cocos2d::CCSprite *data = (cocos2d::CCSprite*)b->GetUserData();
data->setPosition(ccp(b->GetPosition().x * PTM_RATIO, b->GetPosition().y * PTM_RATIO));
data->setRotation(-1 * CC_RADIANS_TO_DEGREES(b->GetAngle()));
}
}
}
At the moment, the only movement is falling down because of gravity. However, the character moves so fast. It almost instantaneously hits the floor. Is there a way to slow this down?
When I used this tutorial for objective c, the ball was falling down much slower.
Did you correctly set the mass of your character? Try to reduce it. Also I recommend you to use a small wrapper which makes life with box2d and cocos2d-x much easier.
Found the problem. I set the position of my sprite to the center of my screen, but I set the position of the body to the bottom. So in the first frame the sprite immediately appeared on the bottom side.
So if anyone has the same problem: check the position of your body. Not just the sprite's position.
What I'm trying to do is:
I have a sprite. And this sprite has 3 textures. First texture, let's call it "not-visited", is the initial one. Now, when I click on the sprite it should change it texture to "clicked" meaning that the sprite was clicked. And this texture should remain until I click somewhere else on the screen. When I do this, the texture should change to the third one, "visited". And if I click on the sprite again it should change its texture to "clicked"...
So, I should have here a bool function called "ClickDetected" and its code should do this:
if (event.type == Event::MouseButtonReleased && event.mouseButton.button == Left)
if (mouse_over_sprite)
return true;
Right? OK, then, I have a class Node. This class has a method "Clicked":
bool Clicked {
if (ClickDetected) { return true; }
}
I know it may be unnecessary, but let it stay for now. Next, in Update() method of this class:
if (Clicked) { change_texture_to_"clicked"; if (!visited) visited=true; }
else {
if (!visited) change_texture_to_"not-visited";
if (visited) change_texture_to_"visited";
}
But this doesn't work how it should. When I click on sprite texture changes to "clicked". When I release the mouse button the "clicked" texture stays... But when I move the mouse texture changes to "visited". And it should remain "clicked", until I click somewhere else. I tried to use a while loop here, but it didn't work. What can I do?
I've put this code to Graph class (method Update()) to manage many Nodes. I've change it a little bit and now it works fine.
Over the last few days I have been trying to implement simple collision detection of objects drawn using OpenGL.
With the aid of the Pearson, Computer Graphics with OpenGL I have managed to write the following function:
void move(){
if(check_collision(sprite,platform1) || check_collision(sprite,platform2)){ //if colliding...
if (downKeyPressed ){ y_Vel += speed; downKeyPressed = false;} //going down
else if(upKeyPressed ){ y_Vel -= speed; upKeyPressed = false;} //going up
else if(rightKeyPressed){ x_Vel -= speed; rightKeyPressed = false;} //going right
else if(leftKeyPressed ){ x_Vel += speed; leftKeyPressed = false;} //going left
} // always glitches on whatever is last else if above?!?!
else{ glTranslatef(sprite.x+x_Vel, sprite.y+y_Vel, 0.0); }
}
My sprite moves in accordance to keyboard inputs (the arrow keys). If it collides with a stationary object it stops moving and stays in its position.
So far, it works when colliding with the top, left side and bottom of the stationary object. Unfortunately (even though I use the same logic) the right hand side doesn't work and upon a collision the sprite is redrawn at its original x/y coordinates. I'm baffled.
As it turns out, which-ever is the last check in the move() function (the last else-if) is the one that doesn't work... I have swapped the left with the right and sure enough when left is then the last one and the one that plays up :(
Any advice or ideas on how I can improve this and stop it glitching?
Please excuse my naivety and amateur coding. I'm merely a self-taught beginning. Thanks.
You should not use an else if. There is a possibility that it is hitting a side and the top or the bottom in the same frame. Trying changing those to all ifs because you want to check each one. or at the least change it to this.
if( /* check top */)
{
}
else if( /* check bot */)
{
}
if( /* check right */ )
{
}
else if( /* check left */)
{
}
Also, you should avoid declaring global variables like Y_VEL and X_VEL as this creates confusion. You may just be doing this to get your feet wet but I would avoid it. Create a class for each object and then have the velocities as members of that class.
Well, it seems to me that you have an issue when it comes to translating the actual object.
Your move code states
if(there is a collision)
{
//do stuff
}
else
{
glTranslateF( );
}
SO, whenever there is a collision, the translate function never gets called.
My opinion is that you should pull the glTranslateF() call out of the else {...}, just have it get called every time. However, it seems you're using the exact same 'draw' function for every rectangle, not just the player sprite. You'll probably have to ind a way to distinguish between regular rectangles (such as the platforms) and the player rectangle. Perhaps the simplest way for you to implement this, would be to have two different drawSprite functions: one for regular platforms, and the other for the player. Only call the move() function from within the player's draw function (perhaps called drawPlayer()?)
I don't quite have the time to look over all of your code to make a more educated and specific suggestion at the moment; however, I'll be free later this evening if this question is still open and needing help.
As you've already figured out, the problem is related to glTranslate(). Since you operate on both sprite's position and velocity, you should repeatedly update the positions using the velocities. That is:
sprite.x += x_vel;
sprite.y += y_vel;
and do it simply all the time (i.e. by some timer or every frame, if the scne is redrawn repeatedly). A collision then is equivalent to changing the velocity vector (x_vel, y_vel) in some way to simulate the collision effect: either zero it to stop any movement at all, or change the velocity component sign (x_vel = -x_vel) to make it rebound in an absolutely elastic manner, or do something else that fits.
What happens now with glTranslate() is that x_vel, y_vel actually hold offsets from the starting position, but not velocities of movement.
I am creating a space invaders game for my university assignment. I am breaking the parts down on paper, I thought a good place to start would be to move the sprites across the screen. The issue I have at the moment is this, when the sprite his the right hand side of the screen it would just carry on moving, so I added this code:
if (invadersSprite.getPosition().x > 650)
{
std::cout << "WIDTH_END" << std::endl;
}
I basically used this for debugging for future reference. The output popped up into the console so I knew I was onto something. So, I started moving on from the output to actually moving the sprites back to the left hand side of the screen. I am now having more issues then expected.
I declared some ints for up, left, right and down just for easability when it comes to reading the code.
int spriteWalkSpeed = 50;
int up=-spriteWalkSpeed, down=spriteWalkSpeed, left=-spriteWalkSpeed, right=spriteWalkSpeed;
I've tried using the SFML move commands and also setPosition, but none of them really work as I thought they should.
move:
The issue I have had with this one is it basically stops in the middle of the screen. It still animates the leg movement and such, but it doesn't move left or right.
if (invadersSprite.getPosition().x > 650)
{
invadersSprite.move(left, 00);
}
setPosition:
This is a little closer to what I am after, but still no cigar. The movement pauses for around a second and then pops up at the left hand side of the screen. What I need is to move back down the screen.
if (invadersSprite.getPosition().x > 650)
{
invadersSprite.setPosition(left, 00);
}
I haven't been using SFML for very long so I am a little puzzled by this.
EDIT
At the moment the sprite is moving to the right of the screen, as needed:
if(spriteTimer>delay)
{
invadersSprite.setTextureRect(area);
++count;
invadersSprite.move(right,0);
if(count==SPRITECOLS) //WE HAVE MOVED OFF THE RIGHT OF THE IMAGE
{
area.left=0; //reset texture rect at left
count=0; //reset count
}
else
{
area.left+=spaceWidth; //move texture rect right
}
spriteTimer=0; //we have made one move in the sprite tile - start timing for the next move
}
Your current logic will only move the sprite left once if the x-coord is greater than 650 - but that's not exactly what you want. What you want is for the sprite to continuously move left after reaching the edge.
To do this you'll need to keep track of a current velocity for your sprite. For example, when your sprite starts, it will be moving right:
xVelocity = right;
Then you can have 2 conditions that will switch direction (when hitting edges of screen):
if (invaderSprite.getPosition().x >= screenWidth) {
// hit the right side of screen
xVelocity = left;
} else if (invaderSprite.getPosition().x <= 0) {
// hit the left side of screen
xVelocity = right;
}
Now, on ever game tick, you simply move your sprite according to its current velocity:
invaderSprite.move(xVelocity, yVelocity);
There are some other things that will need to be fixed, like taking the width of the sprite into consideration, changing the y velocity, etc., but this is the main idea.
I have issue in jumping sprite body. Following is the update method for jumping sprite body
-(void) update: (ccTime) dt
{
world->Step(dt, 10, 10);
// BOOL worldAsleep=true;
for(b2Body *b=world->GetBodyList();b;b=b->GetNext())
{
if(b->GetUserData() !=NULL)
{
CCSprite *myActor=(CCSprite *)b->GetUserData();
myActor.position=ccp(b->GetPosition().x *PTM_RATIO, b->GetPosition().y *PTM_RATIO);
b->SetTransform(b2Vec2(b->GetPosition().x,b->GetPosition().y), b->GetAngle());
if (fire.active==YES)
{
id jump=[CCJumpBy actionWithDuration:1 position:ccp(b->GetPosition().x, b->GetPosition().y) height:100 jumps:1];
[myActor runAction:jump];
b2Vec2 force = b2Vec2(0,350);
}
}
}
}
Here fire.active is a button for jumping sprite and ccjumpto method is used for jump sprite but what to do to jump body.
For jump sprite body i was used ApplyLinearImpuls but it can not jump like sprite type.
I want to jump both sprite and body same like only sprite jump
Thanks for replay
hey you jump body according to button clicked you put below code when button clicked:
b2Vec2 locationWorld;
locationWorld = b2Vec2(0.0f,8.0f);
double Force= _body->GetMass();
_body->ApplyLinearImpulse(Force*locationWorld, _body->GetWorldCenter());