Jumping effect in games - xna

I'm currently trying to make a basic platformer with XNA and I'm wondering how to create a "jumping effect." I currently have basic keyboard input which allows for sideways movement, but I would like my sprite to slowly progress into a jump rather than instantly teleporting there (right now I have something like Rectangle.Y += 40 every time I jump, making the sprite instantly appear there). Does anyone have any insight?

I'm not totally across how to implement this in XNA/C#, but in Flash games I've made I just added a vertical velocity property. I'll try write everything as C# as I can..
Example; create the velocity property:
float verticalVelocity = 0;
Vertical velocity should be constantly reduced (by gravity). Set up a gravity property somewhere accessible from your player:
float Gravity = 2.5;
And in your update() method for the player, increment the verticalVelocity by Gravity. Also increment the Y position of your player by the verticalVelocity. This will simulate falling:
verticalVelocity += Gravity;
Position.Y += verticalVelocity; // this may be -= in XNA, not sure where the y axis beings
When you hit a surface, the velocity should be reset to 0.
And finally, to jump, simply subtract a given value from verticalVelocity:
public void Jump(float height)
{
// Only jump if standing on a surface.
if(verticalVelocity == 0)
verticalVelocity -= height;
}

You'll eventually want to add gravity and possibly other forces to your game, so I highly recommend you save yourself a lot of pain and implement some kind of basic force system. This can be done using Vector2s, as you can just add them to the speed of your character. Then just apply an instantaneous force to your character to push it up.
If you really don't want to use a physics engine, you can make a Vector2 with the high point of the jump for the Y and the characters X, and then use the Vector2.Lerp method to interpolate between the characters position and the end point of the jump.
This is generally a very bad system to use, and I highly recommend you either use an existing physics engine, or make your own simple one.

use a sinusoidcode should look something like this:
float ground = 0.0f;
float angle = 330.0f;
jump(){
if(ground == 0.0f)ground = Rectangle.Y;
if(Rectangle.Y <= ground)
{
Rectangle.Y+=Math.Sin(angle/(Math.Pi*180));
angle++;
}
}

You can accurately create a gravity effect if you modify the ySpeed dynamically, as opposed to just adding 40.
You want to declare a ySpeed
ySpeed = 0;
Then you want to use an acceleration variable
acceleration = 0.25;
Okay, now that we've done that, let's add gravity, provided that our player isn't touching the floor.
if(playerLocationY + playerHeight > floorLocationY)
{
gravity = false;
}
else
{
gravity = true;
}
if(gravity)
{
ySpeed += acceleration;
}
Now that we've got that down, we want to include something that allows us to jump.
if(KeyPressed == UP)
{
ySpeed -= acceleration;
}
This will move our player in the upward direction
We now want to make sure we actually move, so let's add one last line and we're done.
playerLocationY += ySpeed;
Congratulations, you made it.

Related

Scrolling Game Scene with SpriteKit

In short: How do I make a scrolling gameScene which is NOT infinite?
I'll try to explain what I want to achieve with an example: Hill Climb Race
In this game you drive a car (or any sort of crazy vehicle, actually ;)) up a hill.
Now there is one particular thing about the game that I can't get my head around:
It's pretty obvious that the tracks of each individual stage are NOT laid out randomly. i.e. the course of the track is always the same each time you play it.
What I want to learn is:
How do you create a scrolling game scene like that? Is it a huge background node which gets scrolled or is there some sort of fancy tiling involved?
My game needs to scroll both axis (x,y). The players node starts in the center of the game area and can be moved around. There are some obstacles spread around in the area, some of which are not visible initially, because they lie at the edges of the 'game world'.
I suppose the easiest solution would be to use a big background node, but how will that affect the memory consumption of the game?Thanks for your help!
We built something like this into our SKATiledMap. The trick is to add the object you want to follow to the background you want to scroll. This will also keep the background on screen.
-(void)update
{
if (self.autoFollowNode)
{
self.position = CGPointMake(-self.autoFollowNode.position.x+self.scene.size.width/2, -self.autoFollowNode.position.y+self.scene.size.height/2);
//keep map from going off screen
CGPoint position = self.position;
if (position.x > 0)
position.x = 0;
if (position.y > 0)
position.y = 0;
//self.mapHeight*self.tileWidth gives you the size of the map in points
if (position.y < -self.mapHeight*self.tileWidth+self.scene.size.height)
position.y = -self.mapHeight*self.tileWidth+self.scene.size.height;
if (position.x < -self.mapWidth*self.tileWidth+self.scene.size.width)
position.x = -self.mapWidth*self.tileWidth+self.scene.size.width;
self.position = CGPointMake((int)(position.x), (int)(position.y));
}
}
self in this case is the background and autoFollowNode is the players. You could just use self.size.width instead of self.mapHeight*self.tileWidth Hopefully that makes sense and his helpful.

Speed up/Slow down an object once it collides with an object

I'm currently working on a 2D platformer and I'm wondering if I can get any tips on how to increase the speed that an object moves at for a few seconds after it collides with another object.
First you need a variable called velocity
Vector2 velocity = new Vector2(0.0f, 0.0f);
Every update, you change the Rectangle of the sprite by the velocity.
rectangle.X += (int)velocity.X;
rectangle.Y += (int)velocity.Y;
Then, you can change the velocity however you like and it will change the speed.
//slow down
velocity.X -= 10;
velocity.Y -= 10;
//speed up
velocity.X += 10;
velocity.Y += 10;
You can also change the X and Y values for velocity individually, like this:
velocity.Y += 10;
That will make the sprite move down when typed in.
Hope this helped! Tell me if you need any clarification!
First you want to have it react to the collision, so in the method you're using to detect the collision, add a call to a new method in your object. Let's call it SpeedUp(). It should look something like this:
public void SpeedUp()
{
_speedUpTimer = 0;
IsSpedUp = true;
_maxVelocity.X = SpedUpVelocity.X;
}
where _speedUpTimer is a variable in your object's class (or whatever component handles movement), _maxVelocity is whatever variable maintains your object's top speed, and SpedUpVelocity is the constant or variable holding the faster velocity. IsSpedUp should be initialized as false. You're also going to want a constant or variable to hold the amount of time you want the object to be faster, such as SpeedUpTime.
Then, in your object's Update(), add the lines
_speedUpTimer += gameTime.ElapsedGameTime.Milliseconds;
if (IsSpedUp && _speedUpTimer > SpeedUpTime)
{
_maxVelocity.X = UsualMaxVelocity.X;
IsSpedUp = false;
}
UsualMaxVelocity will hold your object's previous, non-sped-up maximum velocity, which your object will return to using after the timer is up.
Of course, you can always make your Y velocity increase, but I assumed you just wanted horizontal speed.

Smooth snake movement

This is language-agnostic question, more about model of my game.
I have a snake game with elements, but I move the elements smoothly, they don't just move 1 block each time, but instead they move some amount of pixels every frame.
I have an update loop that calculates the positions of the element, but I am stuck on correct calculations.
I have heading for each element:
typedef NS_ENUM(int, kElementHeading)
{
kElementHeadingNorth = 1,
kElementHeadingSouth,
kElementHeadingEast,
kElementHeadingWest
};
I also have velocity (x, y) that determines in what direction snake is going. I have problem with snake movement, because my elements are in wrong positions. I managed to localize the thing for 2 elements, but my solution fails on more elements.
First solution I tried is to save point of rotation where the head changes direction. This worked, but due to different circumstances element can move different amount of pixels each turn. Often the element would skip the point. I tried increasing the zone where it should rotate, but it adds up error. I tried fixing this error, but element would still separate from snake (quite often).
On the second try I decided to keep the snake head in center of the screen and move the world around it. It worked good for 2 elements, as I just smoothly move the next element to desired position relatively to head. But this fails badly on more elements. If you make fast turns they start dancing and not following the path.
Third thing that I tried is leaving a path for other elements to follow. But that didn't work because I intend to keep my snake on center of the screen and technically it never moves to create a path.
I'm looking to replicate the movement pattern like in Nimble Quest (or any snake).
How should I implement snake elements moving to have no errors?
Here is my code for the first method, problem with it is that often the elements would fall off. The code is pretty self-explanatory. Rotation points are the places where to change direction.
CFTimeInterval delta = self.lastTime - currentTime;
CGPoint currentPosition = self.playerSnake.head.sprite.position;
CGPoint velocity = self.playerSnake.velocity;
self.playerSnake.head.sprite.position = CGPointMake(currentPosition.x + velocity.x * delta * CONSTANTSPEEDFACTOR , currentPosition.y + velocity.y * delta * CONSTANTSPEEDFACTOR);
for (SnakeElement *element in self.playerSnake.elements) {
CGPoint currentPositionE = element.sprite.position;
CGPoint velocityE = element.velocity;
element.sprite.position = CGPointMake(currentPositionE.x + velocityE.x * delta * CONSTANTSPEEDFACTOR , currentPositionE.y + velocityE.y * delta * CONSTANTSPEEDFACTOR);
}
BOOL markToDelete = NO;
NSDictionary *deleteDictionary;
for (NSDictionary *dict in self.playerSnake.rotationPoints) {
CGPoint positionCoordinate = CGPointFromString(dict[#"position"]);
CGPoint velocityNew = CGPointFromString(dict[#"velocity"]);
double newAngle = [dict[#"angle"] doubleValue];
for (SnakeElement *element in self.playerSnake.elements) {
int xDifference = element.sprite.position.x - positionCoordinate.x;
int yDifference = element.sprite.position.y - positionCoordinate.y;
if ((xDifference > -2 && xDifference < 2) && (yDifference > -2 && yDifference < 2) ) {
element.velocity = velocityNew;
element.sprite.position = CGPointMake(element.sprite.position.x + xDifference, element.sprite.position.y + yDifference);
SKAction *action = [SKAction rotateToAngle:newAngle duration:0.2 shortestUnitArc:YES];
[element.sprite runAction:action];
if ([element isEqual:[self.playerSnake.elements lastObject]]) {
markToDelete = YES;
deleteDictionary = dict;
}
}
}
}
[self.playerSnake.rotationPoints removeObject:deleteDictionary];
If I try increase the catch zone for the turning point, the elements tend to fall off more often then when it is 1 or 2 pixels wide. I'm not sure why this happens.
This is what I was suggesting you do in the comments in terms of handling your turning on points :
1.. calculate the distance that the element should move that frame based on speed and your elapsed time since last frame. (delta)
2.. calculate distance from element's current position to the turn point. This is the beforeDistance I spoke of in the comments
3.. calculate the distance the element should move towards the NEW target turning point AFTER the turn
afterDistance = distanceToMoveThisFrame - beforeDistance
4.. Calculate the new position for your element, starting at the current turning point towards the next target turning point of the element using afterDistance
If you follow this logic, you will NEVER overshoot or undershoot the turning point.

Cocos2D - Simulating infinite scrolling

I have a BIG problem!! I want to make something like old space shooter games like “Asteroids”, where the ship, when going out of the screen, is reappearing at the other side. For example, when the ship go out at the top of the screen, it come back at the bottom. But in my game, there’s a camera following the player, showing only a quarter of the world, and I want to simulate an infinite world this way! Here’s a picture showing what I mean :
What I thought doing was simulate the scroll by only moving game objects, stored in an array, but not the player, and calculating at every frame if the objects are out of the world boundary and re-adding them at the other end of the world (i.e going out at the left would add it back at the right).
But I don’t really like that way of doing… I’d like something more… intuitive..?
Do you guys have any idea of how doing it? Like, any tutorial on the web or just the right words to explain what I mean so I could do a bright research on google (I’m french, so I had a really hard time writing that question)!
Thank you in advance!
Knowing the players position, x,y check to see if the player is within the bounds of the area. If the player has left those bounds, set the player's position to the opposite bounds, possibly adding width/height. I'll do it here for the Y coordinate only:
const float minWarpAreaY( 0 );
const float maxWarpAreaY( 400 );
//if (player.y < minWarpAreaY) { player.y = maxWarpAreaY - player.height; }
//if (player.y > maxWarpAreaY) { player.y = minWarpAreaY + player.height; }
if (player.y < minWarpAreaY) { WarpPlayer(0.0f, (maxWarpAreaY - minWarpAreaY)); }
if (player.y > maxWarpAreaY) { WarpPlayer(0.0f, -(maxWarpAreaY - minWarpAreaY)); }
void WarpPlayer(float amountX, float amountY)
{
player.x += amountX;
player.y += amountY;
for (eachObject in World)
{
eachObject.x += amountX;
eachObject.y += amountY;
}
}
Something along those lines should help.

Cocos2D Gravity?

I am really looking to try to have gravity in my game. I know everyone says use Box2D, but in my case I can't. I need to use Cocos2D for the gravity.
I know Cocos2D does not have any gravity API built in so I need to do something manually. The thing is there is like no tutorials or examples anywhere on the web that show this.
Can anyone show me what they have done or can some explain step by step on how to apply a non-constant gravity (One that gets slightly stronger while falling).
I think this will help a lot of people that are facing the same issue that I am having!
Thanks!
Gravity is nothing but a constant velocity applied to the body for every physics step. Have a look at this exemplary update method:
-(void) update:(ccTime)delta
{
// use a gravity velocity that "feels good" for your app
const CGPoint gravity = CGPointMake(0, -0.2);
// update sprite position after applying downward gravity velocity
CGPoint pos = sprite.position;
pos.y += gravity.y;
sprite.position = pos;
}
Every frame the sprite y position will be decreased. That's the simple approach. For a more realistic effect you will want to have a velocity vector for each moving object, and apply gravity to the velocity (which is also a CGPoint).
-(void) update:(ccTime)delta
{
// use a gravity velocity that "feels good" for your app
const CGPoint gravity = CGPointMake(0, -0.2);
// update velocity with gravitational influence
velocity.y += gravity.y;
// update sprite position with velocity
CGPoint pos = sprite.position;
pos.y += velocity.y;
sprite.position = pos;
}
This has the effect that velocity, over time, increases in the downward y direction. This will have the object accelerate faster and faster downwards, the longer it is "falling".
Yet by modifying velocity you can still change the general direction of the object. For instance to make the character jump you could set velocity.y = 2.0 and it would move upwards and come back down again due to the effect of gravity applied over time.
This is still a simplified approach but very common in games that don't use a "real" physics engine.

Resources