How do I make the ball move in a certain direction? - c++

I want to make my player, make the ball move in a certain direction, roughly 120 degrees up. At the moment the ball goes in al direction, but the ball goes up not down. The ball also goes at 4 different speeds.
if(CGRectIntersectsRect(BallA.frame, PlayerA1.frame)){
Y = arc4random() %5;
Y = 0-Y;
}
}
Ball movement
timer = [NSTimer scheduledTimerWithTimeInterval:0.006 target:self selector:#selector(BallMovement4) userInfo:nil repeats:YES];
-(void)BallMovement4{
[self Computer4Movement];
[self Collision4];
Ball4.center = CGPointMake(Ball4.center.x + X, Ball4.center.y + Y);
if (Ball4.center.x < 15) {
X = 0 - X;
}
if (Ball4.center.x > 305) {
X = 0 - X;
}
Please Help,
Thank You
Milan

It's a little unclear what you're trying to do and how your classes work, but in general, if you want to move things around, one good way to do that is to use vectors. For example, if you want the ball to move 3 pixels per frame in a given direction, the ball would have a position and a velocity vector, like this:
typedef struct Ball { // could be a class if that makes sense for your use
CGPoint position;
CGPoint velocity;
} Ball;
You'd set them to some initial value, like this:
Ball ball = { { 0.0, 0.0 }, // Ball starts at the origin
{ 1.0, 2.0 } }; // Ball starts out moving 1 pixel to the right and 2 pixels up
Then on each frame of gameplay, you'd add the velocity to the position, like this:
ball.position.x += ball.velocity.x;
ball.position.y += ball.velocity.y;
You can change the velocity, for example, when the ball hits a wall. If you're trying to simulate something real, you'd need to find the angle at which the ball hit the wall and reverse that.

Related

Applying gravity to objects

I'm having trouble with implementing gravity on objects.
I have a bunch of circle objects that I'm drawing using OpenGL. I'm using delta-x and delta-y to move the circles (balls). I'm trying to add a gravitational constant to the y coordinate each frame so it simulates being pulled downward, but I'm not sure exactly how to do that.
Here's the relevant code:
class Ball
{
public:
double x;
double y;
double radius;
double deltaX;
double deltaY;
};
std::vector<Ball> gAllBalls; // a vector of balls with random positions and delta-values
double gGravity = ?; // gravitational constant - I know it's 92 m/s^s, but I don't know how to apply that to deltaX and deltaY
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
for (auto &thisBall : gAllBalls)
{
// draw
glColor3d(thisBall.red, thisBall.green, thisBall.blue);
DrawCircle(thisBall.x, thisBall.y, thisBall.radius);
// gravity - not working
if (thisBall.y + thisBall.radius < gScreenHeight - gGravity)
{
thisBall.y += gGravity;
}
// wall bouncing
if (thisBall.y + thisBall.radius + thisBall.deltaY >= gScreenHeight) // up
{
thisBall.deltaY = -thisBall.deltaY;
}
if (thisBall.y + thisBall.deltaY - thisBall.radius < 0) // down
{
thisBall.deltaY = -thisBall.deltaY;
}
if (thisBall.x + thisBall.deltaX - thisBall.radius < 0) // left
{
thisBall.deltaX = -thisBall.deltaX;
}
if (thisBall.x + thisBall.radius + thisBall.deltaX >= gScreenWidth) // right
{
thisBall.deltaX = -thisBall.deltaX;
}
// move
thisBall.x += thisBall.deltaX;
thisBall.y += thisBall.deltaY;
}
glutSwapBuffers();
glutPostRedisplay();
}
A big problem I'm having is that I don't know how to calculate the gravity, since I'm using deltaX and deltaY instead of having separate speed and distance variables to calculate 92 m/s^2. However, no matter what I set the gravity to, the balls don't behave like they should - regardless of gravity strength, so there has to be something else wrong, but I don't know what.
I think the problem here is the physics, rather than the programming technique.
In your case, I would change the 'delta' members of your Ball class to 'speed', since they are a unit of distance that change the position of your object per cycle (time), however this is just a suggestion to make it easier to visualize...
class Ball
{
public:
double x;
double y;
double radius;
double speedX;
double speedY;
};
In second place, I in your code, you are changing the 'y' member, rather than the speed, and since gravity changes speed, hence the problem.
Try doing that, and for debugging purposes, I would try with punctual objects (no radius, just plain (x,y) coordinates).
So, to conclude, I would simply change your gravity code to the following:
// gravity - 'fixed'
if (thisBall.y + thisBall.radius < gScreenHeight - gGravity)
{
thisBall.speedY -= gGravity; //notice the '-'
}
The value of gravity should be absolute and positive, so as to keep things as simple as posible. If you try this, you should have an ideal simple physics simulator, with a ball of constant speedX (only changing its direction, not magnitude).
Please try this, and let me know how it went, good luck, keep it up =)

How to rotate an object so it faces another?

I am making a game in opengl, and i can't figure out how to make my enemy characters turn to face my player. I only need the enemy to rotate on the y axis towards the player. Then I want them to move towards him.I have tried a bunch of different methods but haven't been able to get anything to work.
There are a few things you need to decide on yourself at the beginning of the project to be used throughout the project, like the representation of positions and the orientation (as well as the setup of the screen/clip planes etc.) However, you haven't mentioned any of this. So you may have to adapt the code below to suit your game, but it should be easily adaptable and applicable.
For the following example, I'll assume that -y axis is the top of your screen.
#include <math.h> // atan2
// you need to way to represent position and directions
struct vector2{
float x;
float y;
} playerPosition, enemyPosition;
float playerRotation;
// setup the instances and values
void setup() {
// Set some default values for the positions
playerPosition.x = 100;
playerPosition.y = 100;
enemyPosition.x = 200;
enemyPosition.y = 300;
}
// called every frame
void update(float delta){
// get the direction vector between the player and the enemy. We can then use this to both calculate the rotation angle between the two as well as move the player towards the enemy.
vector2 dirToEnemy;
dirToEnemy.x = playerPosition.x - enemyPosition.x;
dirToEnemy.y = playerPosition.y - enemyPosition.y;
// move the player towards the enemy
playerPosition.x += dirToEnemy.x * delta * MOVEMENT_SPEED;
playerPosition.y += dirToEnemy.y * delta * MOVEMENT_SPEED;
// get the player angle on the y axis
playerRotation = atan2(-dirToEnemy.y, dirToEnemy.x);
}
void draw(){
// use the playerPosition and playerAngle to render the player
}
Using the above code, you should be able to move your player object around and set the angle of rotation (you need to watch out for radians/degrees of the returned and expected angle values).

Can I make CCFollow follow more naturally?

I want to build a platform game with cocos2d/Box2D. I use CCFollow to follow the player sprite but CCFollow constantly puts it in the center of the screen. I want CCFollow to follow more naturally, like a human turning a camcorder with an acceptable lag, a small overshoot ...etc.
Here is a method of mine that didn't work: I attached (via a distance joint) a small physics body to the player that doesn't collide with anything, represented by a transparent sprite. I CCFollow'ed the transparent sprite. I was hoping this ghost body would act like a balloon attached to the player, hence a smooth shift in view. The problem is distance joint breaks with too heavy - too light objects. The balloon moves around randomly, and of course, it pulls the player back a little no matter how light it is.
What is a better way of following a moving sprite smoothly?
Try add this to CCActions in cocos2d libs.
-(void) step:(ccTime) dt
{
#define CLAMP(x,y,z) MIN(MAX(x,y),z)
CGPoint pos;
if(boundarySet)
{
// whole map fits inside a single screen, no need to modify the position - unless map boundaries are increased
if(boundaryFullyCovered) return;
CGPoint tempPos = ccpSub(halfScreenSize, followedNode_.position);
pos = ccp(CLAMP(tempPos.x,leftBoundary,rightBoundary), CLAMP(tempPos.y,bottomBoundary,topBoundary));
}
else {
// pos = ccpSub( halfScreenSize, followedNode_.position );
CCNode *n = (CCNode*)target_;
float s = n.scale;
pos = ccpSub( halfScreenSize, followedNode_.position );
pos.x *= s;
pos.y *= s;
}
CGPoint moveVect;
CGPoint oldPos = [target_ position];
double dist = ccpDistance(pos, oldPos);
if (dist > 1){
moveVect = ccpMult(ccpSub(pos,oldPos),0.05); //0.05 is the smooth constant.
oldPos = ccpAdd(oldPos, moveVect);
[target_ setPosition:oldPos];
}
#undef CLAMP
}
i get this from cocos2d forums.
Perhaps this http://www.cocos2d-iphone.org/wiki/doku.php/prog_guide:actions_ease can help you get an "acceleration" effect with CCFollow.

Shooting bullets with a joystick cocos2d

I have a working joystick in my cocos2d app but I cannot figure out how to make the 'player' shoot bullets out of it in the direction the joystick is pointing. I have the player moving and rotating. Also the bullets need to disappear when they hit the edges of the screen. Any help would be great. Thanks in advance.
You should get the angle from joystick.
For instance, SneakyInput has a degrees property which enables you to rotate your bullets like this :
_bullet.rotation = -joystick.degrees;
And your update method can be like this :
void update:(ccTime) delta
{
float moveAngle = _bullet.rotation;
CGPoint deltaPos = CGPointMake(cos(moveAngle) * velocity, sin(moveAngle) * velocity);
_bullet.position = ccpAdd(self.position, deltaPos);
}

How do I make projectiles?

I am totally stumped on this one. I'm using C++ and SFML 1.6 for a game I'm developing, and I have no bloody idea. How do I make projectiles (like bullets)? I just don't understand it. It could be my lack of sleep but I don't know.
So my question is how do I create a Sprite that moves in a definite direction based on where the mouse is? (Think of a top down shooter with mouse aiming)
Easiest solution:
If the mouse is at Mx,My and the ship is at Sx,Sy then calculate the direction from the ship to the mouse:
Dx=Sx-Mx
Dy=Sy-My
Now normalise D (this means scale it so that it's length is one):
DLen=sqrt(Dx*Dx + Dy*Dy)
Dx/=DLen;
Dy/=DLen;
Now Dx is the distance you want to move the bullet on the x axis in order to get bullet speed of 1.
Thus each frame you move the bullet like so (position of bullet: Bx,By Speed of bullet: Bs [in pixels per millisec] Frame time Ft[in millisec])
Bx=Bx+Dx*Bs*Ft
By=By+Dy*Bs*Ft
This give you a bullet that moves towards the mouse position at a speed independent of the direction of the mouse or framerate of the game.
EDIT: As #MSalters says you need to check for the DLen==0 case when the mouse is directly above the ship to avoid division by zero errors on the normalise
One way to do it is to make the bullet face the mouse and then move it across the x and y axis by using trigonometry to find the hypotinuse from the angle. I don't think i explained this very well, so here the code to make a sprite move from its rotation:
void sMove(sf::Sprite& input,float toMove, int rotation){
bool negY = false;
bool negX = false;
int newRot = rotation;
if (rotation <= 90){
negY = true;
}
else if (rotation <= 180){
//newRot -= 90;
negY = true;
}
else if (rotation <= 360){
newRot -= 270;
negY = true;
negX = true;
}
float y = toMove*cos(newRot*PI/180);
float x = toMove*sin(newRot*PI/180);
if (negY){
y = y*-1;
}
if (negX){
x = x*-1
}
input.move(x, y);
}