SDL joystick shooting angle c++ - c++

I'm having some issues with my shooting mechanics in my c++ 2D platform game using the SDL joystick. When I direct the joystick in any direction the bullet seem to go in the right direction-ish. When I do not direct the joystick in any dirction but press the shoot button I want the bullet to go in a horizontal line in the direction the player is facing( either 0 or -180), but right now the angle seems to be -108ish.
This is the code I use to get the angle of the joystick relative to the players position.
controller_y = SDL_JoystickGetAxis(j, 1); // get controller y axis
controller_x = SDL_JoystickGetAxis(j, 0); // get controller x axis
int deltax = xpos - controller_x; // diference in x pos
int deltay = ypos - controller_y; // diference in Y pos
angle = atan2(-deltay, -deltax) * 180 / PI;
and in my update function I update the bullets position like this:
box.x += speed *(cos(angle*PI / 180)) * delta;
box.y += speed *(sin(angle*PI / 180)) * delta;
When I do not move the joystick in any direction the x and y value of the Joystick is usually lower 500 and bigger than -500. So my question is how I can get the bullet to go in the angle -180 if my player is facing left and I do not move the joystick and the angle 0 if my player is facing right when I do not move the joystick if that makes sense.

Related

How to make a 3D model follow the mouse movements?

I'm writing a simple version of the game Duck Hunt in C++, using OpenGL. I managed to render the 3D model of a rifle in the center of the screen, and what I want is to rotate it on his y and z axes depending on the mouse movements, so that the rifle is always pointing to the mouse pointer. I have tried to compute the rotation angles using the arctan equation, in order to have the right proportion between the mouse movements and the distance of the pointer from the rifle, but the result is not really good as the sensibility of the rotation seems to be too low. Here there is my current implementation:
void passiveMotion(int x, int y) {
switch (gamePhase) {
case gameStarted:
if(x > 540 && x < 1000)
gunYrot = ((-(atan(abs(y-720) / (double)(x-540)))) * 180 / M_PI);
else if(x > 80 && x < 540)
gunYrot = (((atan(-abs(y - 720) / (double)(x - 540)))) * 180 / M_PI - 180);
if (y > 320 && y < 355) gunZrot = y;
break;
default: break;
}
}
The game screen is this:
Any clues about what could be the best approach to move the rifle?
Bonus question: at the moment, the bullet is shot from the point in which the rifle is rendered (so it starts from its center); how could I dinamically compute the coordinates of where the gun barrel ends to make it the starting point of the bullet?
Thank you for any help with this.

Rotation Angle of Sprite towards Mouse is only calculated but Sprite does not rotate. But, it works well in Debugger

I am a beginner in C++ and know SFML. I have read a lot of articles about Sprite rotation towards Mouse and have been able to calculate proper angle of rotation of Sprite using this code:
void Player::changeAngle(double Mx, double My) { // This is for making Player point towards Mouse
double dX = x - Mx; // x and y are global Varibales declared outside
double dY = y - My;
double magnitude = sqrt((dX*dX) + (dY*dY));
double normalizedX = dX / magnitude;
double normalizedY = dY / magnitude;
// This part is for Making Player move to Mouse
Xvelocity = normalizedX * speed; // Xvelocity, Yvelocity and speed are global variables
Yvelocity = normalizedY * speed;
// Rotate towards the Mouse
double angle = ( atan2(dY, dX) ) * 180 / M_PI;
entity.setRotation(angle); // entity is a sf::RectangleShape
}
And, this bit actually worked and the Sprite was rotating properly only before a few days. Now the Sprite is just frozen on the screen, nothing happens. I had not made any changes in that code but I had added a View from the main.cpp.
So here is how I call changeAngle() from the main.cpp :
case Event::MouseMoved : {
Vector2f worldPos = window.mapPixelToCoords(Mouse::getPosition(window), view);
double x = worldPos.x;
double y = worldPos.y;
player.changeAngle(x, y);
break;
}
I tried running the debugger and stepped through the code. I found that the angle is properly calculated and my mouse coordinates are also right. And, to my surprise, the sprite was Rotating now !
I could not understand why, but every time its in debugging mode, the Sprite will rotate. But, it won't rotate while running normally.
Can anyone tell me why and how to fix it so it rotates every time ? Tell me if there is any problem with my code.
Thanks !

Issue with angle limiting

I am creating a game using SFML 2.2 and Box2D. The game is similar to Peggle in that you have a cannon attached to the top of the screen. I have the movement of the cannon mostly working but I would like to limit the rotation so it cannot rotate and point straight up (off screen). I have implemented the code below and it works to an extent. The cannon can move fine within the bounds, but if it hits one of the two edges it becomes stuck there. If I press the opposite direction, instead of rotating back around it quickly jumps to the opposite edge, causing the cannon to be either all the way to the right or all the way to the left.
In my game, when the cannon is pointing straight down the angle is 0/360 degrees, all the way left is 90 degrees and all the way right is 270 degrees.
//******************************/
// Aiming Controls
//******************************/
if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Left))
{
float sin = sinf(-m_fRotationSpeed*elapsedTime);
float cos = cosf(-m_fRotationSpeed*elapsedTime);
sf::Vector2f newDirection;
newDirection.x = (cos*m_vAimDirection.x) - (sin * m_vAimDirection.y);
newDirection.y = (sin*m_vAimDirection.x) + (cos*m_vAimDirection.y);
//Update sprite rotation
// Find angle of rotation by acos(v1dotv2)
float rotationAngle = acosf(1 * m_vAimDirection.y);
// Check to make sure we get the right direction!
if (m_vAimDirection.x < 0)
rotationAngle = (b2_pi*2.0f) - rotationAngle;
// convert to degrees
rotationAngle *= 180.0f / b2_pi;
// HERE IS WHERE I CHECK THE BOUNDS
if (rotationAngle > 88.0f && rotationAngle < 272.0f)
rotationAngle = 88.0f;
else
m_vAimDirection = newDirection;
//apply new rotation
m_sCannon.setRotation(rotationAngle);
}
else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Key::Right))
{
float sin = sinf(m_fRotationSpeed*elapsedTime);
float cos = cosf(m_fRotationSpeed*elapsedTime);
sf::Vector2f newDirection;
newDirection.x = (cos*m_vAimDirection.x) - (sin * m_vAimDirection.y);
newDirection.y = (sin*m_vAimDirection.x) + (cos*m_vAimDirection.y);
//Update sprite rotation
// Find angle of rotation by acos(v1dotv2)
float rotationAngle = acosf(1 * m_vAimDirection.y);
// Check to make sure we get the right direction!
if (m_vAimDirection.x < 0)
rotationAngle = (b2_pi*2.0f) - rotationAngle;
// convert to degrees
rotationAngle *= 180.0f / b2_pi;
// HERE IS WHERE I CHECK THE BOUNDS
if (rotationAngle < 272.0f && rotationAngle > 88.0f)
rotationAngle = 272.0f;
else
m_vAimDirection = newDirection;
//apply new rotation
m_sCannon.setRotation(rotationAngle);
}

algorithm for drawing a sort of nozzle(line),whose is direction determined by the mouse?

i am using The old Turbo C++ and am a beginner.
This is the code of a ongoing project that i am planning.
the circle moves withe WSAD keys
But the problem is that i want the nozzle(a line from the center) of that circle to follow the movement of the mouse,but i cant figure out the mathematical part to restrict the length of that nozzle to, say 30 pixels. the line goes on touching the pointer's location.
I tried to use the Distance formula and the line equation to get with an expression which has both the slope and the length of the line. But the problem here is that there is an square root in the denominator, and i think that is causing the problem
Most of the code here is unnecessary for the following problem, so please ignore
here is the relevant code
originx=getmaxx()/2;
originy=getmaxy()/2;
while(doga==0) //main game loop
{ if(kbhit())
op=getch();
if(limiter>10) //limiter is used to restrict the motion of the circle for a limited // time
{ op=0;limiter=0;} // otherwise the cirlce moves in that direction unless another //key is pressed
//movement of the circle
if(op==72)
{ originy--; limiter++;}
if(op==80)
{originy++; limiter++;}
if(op==75)
{ originx--; limiter++ ;}
if(op==77)
{ originx++; limiter++; }
circle(originx,originy,5);
mouseposi(x,y,cl);
printf(" %d %d",x,y);
printf("\b\b\b\b\b\b\b\b");
m=sloper(originx,originy,x,y);
line(originx,originy,80/sqrt(1+m*m),m*80/sqrt(1+m*m)); //THIS LINE IS WHERE THE PROBLEM IS
delay(30);
cleardevice();
if(op==49) //for exiting
doga=2;
}
}
Let (x,y) be the point you're after, (ox, oy) be your origin, and (mx, my) be the mouse location.
The vector from the origin to the mouse is (dx, dy) = (mx - ox, my - oy).
The distance between the mouse and the origin is the same as the norm of that vector:
distance = sqrt(dx * dx + dy * dy);
Normalizing (scaling) the vector to get a new vector of length 1 ("unit length") we get
nx = dx / distance;
ny = dy / distance;
And finally we can scale those coordinates by the desired length (remembering to add back the origin)
x = ox + length * nx;
y = oy + length * ny;

Make an object follow the camera in OpenGL

I'm making a racecar game in OpenGL (just a small project) and I'm having problems trying to make my car follow the camera view.
It wasn't hard to make it follow the camera as the camera moves forward and/or backward, but as I rotate the camera (look right or left) the car remais still. I mean, it still moves forward and backward but it's not in front of the camera (it's on the side).
Here is my code (the part where I try to implement it):
void updateCam() {
gluLookAt(posX,posY + 0.025 * std::abs(sin(headPosAux*PI/180)),posZ,
posX + sin(roty*PI/180),posY + 0.025 * std::abs(sin(headPosAux*PI/180)) + cos(rotx*PI/180),posZ -cos(roty*PI/180),
0.0,1.0,0.0);
listenerPos[0] = posX;
listenerPos[1] = posY;
listenerPos[2] = posZ;
source0Pos[0] = posX;
source0Pos[1] = posY;
source0Pos[2] = posZ;
GLfloat distD;
distD = posZ - 3.3;
//makes the car "follow" the camera
modelPOR.Translate(posX,posY,distD);
}
I think the problem is that you change the center location in gluLookAt and not in the modelPOR.Translate
the 3 middle parameters of gluLookAt set the center of the view, so the car should be at the exact same position but you modify the center without modifying the car's position.
gluLookAt(posX,posY + 0.025 * std::abs(sin(headPosAux*PI/180)),posZ,
// center x
posX + sin(roty*PI/180),
// center y
posY + 0.025 * std::abs(sin(headPosAux*PI/180)) + cos(rotx*PI/180),
// center z
posZ -cos(roty*PI/180),
0.0,1.0,0.0);
you should probably translate the car by those same values. then it will be centered.
another problem that seems to be in that code is that you rotate the camera and not the car, so the car probably will not stay pointing in the same direction as the camera. (is that desired or do you do it elswhere?)
but are you really sure you want to make the car follow the camera? it would probably be better the other way around.