Return coordinates of a tank - coordinate

I have written some code to move a tank to specific point. First I've made a wall stick and programmed it to find out when the tank moves to the bottom-left. The tank's coordinate is (18,18), but when I use getWidth() and getHeight() function it returns the tank's width and height - which is (40, 40).
I think when the tank moves to the bottom-left, the coordinate should be (getWidth()/2, getHeight()/2). What am I doing wrong here?

Related

Why is the screen space coordinate system for my sfml rendered app inverted?

I am learning C++ and I thought I'd make the original asteroids game with a fresh coat of paint using the SFML graphics library. However, for my player sprite, while the origin is at the top left corner of the screen, to the right of it is the negative x axis and downwards is negative y axis (opposite of what it's supposed to be in both cases). Also, no matter what object or rotation, invoking the setRotation function always rotates any object about the top left corner of the screen even if, for that object, I have set the origin to the object's center.
#include<SFML\Graphics.hpp>
using namespace sf;
const int W{ 1200 }, H{ 800 };
const float degToRad = 0.017453f;
int main() {
float x{ -600 }, y{ -400 };
float dx{}, dy{}, angle{};
bool thrust;
RenderWindow app(VideoMode(W, H), "Asteroids!");
app.setFramerateLimit(60);
Texture t1, t2;
t1.loadFromFile("images/spaceship.png");
t2.loadFromFile("images/background.jpg");
Sprite sPlayer(t1), sBackground(t2);
sPlayer.setTextureRect(IntRect(40, 0, 40, 40));
sPlayer.setOrigin(-600, -400);
while (app.isOpen())
{
app.clear();
app.draw(sPlayer);
app.display();
}
return 0;
}
The above code draws the player (spaceship.png) to the center of my rendered window (app) but notice how I have had to put in negative coordinates. Also, if I further put in the code for taking keyboard inputs and call the setRotation function, instead of rotating my sPlayer sprite about its center (i.e. (-600,-400)), it rotates the sprite about the top left corner of the screen which is (0,0). I can't find any explanation for this in the SFML online documentation. What should I do?
As I mentioned I have tried reading the documentation. I've watched online tutorials but to no avail.
Origin is the point on sprite where you "hold" it.
Position is the point on screen where you put Origin of the sprite.
In short, you take your sprite by Origin and put it so Origin is on Position.
By default, both Origin and Position are (0, 0), so top left of your sprite is put at top left of the screen. What you did was to say "take this point on sprite, which is way to the upper-left that actual visible part of the sprite is and put it to the top left of the screen". This had an effect of moving your sprite to the bottom right.
You probably want something like:
// This is will make sure that Origin, i.e. point which defines rotation and other transformations center is at center of the ship
sPlayer.setOrigin(sprite_width / 2, sprite_height / 2);
// This will put Origin (center of the ship) at center of the screen
sPlayer.setPosition(screen_width / 2, screen_height / 2);

How to rotate a QGraphicsPixmap around a point according to mouseMoveEvent?

I want rotate a QGraphicsPixmapItem around a point according to mouse position.
So i tried this:
void Game::mouseMoveEvent(QMouseEvent* e){
setMouseTracking(true);
QPoint midPos((sceneRect().width() / 2), 0), currPos;
currPos = QPoint(mapToScene(e->pos()).x(), mapToScene(e->pos()).y());
QPoint itemPos((midPos.x() - cannon->scenePos().x()), (midPos.y() - cannon->scenePos().y()));
double angle = atan2(currPos.y(), midPos.x()) - atan2(midPos.y(), currPos.x());
cannon->setTransformOriginPoint(itemPos);
cannon->setRotation(angle); }
But the pixmap moves a few of pixels.
I want a result like this:
Besides the mixup of degrees and radians that #rafix07 pointed out there is a bug in the angle calculation. You basically need the angle of the line from midPos to currPos which you calculate by
double angle = atan2(currPos.y() - midPos.y(), currPos.x() - midPos.x());
Additionally the calculation of the transformation origin assumes the wrong coordinate system. The origin must be given in the coordinate system of the item in question (see QGraphicsItem::setTransformOriginPoint), not in scene coordinates. Since you want to rotate around the center of that item it would just be:
QPointF itemPos(cannon->boundingRect().center());
Then there is the question whether midPos is actually the point highlighted in your image in the middle of the canon. The y-coordinate is set to 0 which would normally be the edge of the screen, but your coordinate system may be different.
I would assume the itemPos calculated above is just the right point, you only need to map it to scene coordinates (cannon->mapToScene(itemPos)).
Lastly I would strongly advise against rounding scene coordinates (which are doubles) to ints as it is done in the code by forcing it to QPoints instead of QPointFs. Just use QPointF whenever you are dealing with scene coordinates.

Rocket Curvature in C++ SDL game

I am making cabal on C++ using SDL library. Cabal is a game in which a player sits on the bottom of the screen and can only move in x direction. While enemies appear in front and shoot missiles at you. The game is a bit like this.
I want the rocket to take the trajectory shown in the green. A curved trajectory. However it takes the trajectory which is shown in the red. Keep in mind the player is also moving so trajectory is not fixed.
The code I have implemented so far is this:
void Missiles::Move(int playerX)
{
angle =atan(playerX - X);
X=X + sin(angle)*2;
}
Where PlayerX is the player's X co-ordinates and X is the rocket's X co-ordinates. I have made the Y-coordinates to change at a constant speed, so I have not shown them in the code.
To get aiming angle, it is necessary to take Y-coordinate difference into account
angle = atan2(PlayerY - RocketY, PlayerX - RocketX);
Another issue - in reality and in physics rocket velocity is limited. It consists of vertical and horizontal components
Vx = V * Cos(angle)
Vy = V * Sin(angle)

C++ 2D How to "stick" an exhaust sprite on a spaceship and allowing it to rotate accordingly?

What exactly is the formula to needed to do this?
So if I have two separate sprites named player (a spaceship) and exhaust (an exhaust animation for the bottom of the spaceship)
What math is needed so that when player rotates, the exhaust moves and positions itself at the bottom of the ship which could be to the left at this point, if player has rotated 90 degrees right.
I know how to spin / rotate the sprites to face the right direction. What I need to know is how to move the exhaust so that it's positioned correctly at the bottom of the ship when the ship turns.
And please don't link any "Move a sprite around a point" threads and such since that's not what I'm looking for.
Assuming the ship is similar to the one in the game "Asteroids", the position of the tail of the ship (relative to the ship's center) will be described by a circle whose radius is the distance between the center of the ship and the ship's tail.
Given that, you can calculate the position of the tail of the ship like this:
#include <math.h>
[...]
double radius = ship_height/2.0;
double ship_heading = /* current angle of rotation of the ship, in radians, e.g. 0 if the ship is facing right, pi if it is facing left, etc */
double tail_heading = ship_heading + 3.14159; /* ship's tail faces the opposite direction from the nose! */
double x_offset = cos(tail_heading)*radius;
double y_offset = sin(tail_heading)*radius;
double exhaust_center_x = ship_center_x + x_offset;
double exhaust_center_y = ship_center_y + y_offset;
(and if you want the exhaust-graphic to appear a little farther away from the tail of the ship, just increase the radius value slightly)

2D Collision Detection for Pong

I'm trying to make a game of Pong. I have drawn everything to screen, bounce the ball of the walls, and have made sure the paddle can only be in the map. The one problem I am having is with collision detection. The algorithm I am using works great if the ball (which is actually a square) hits the paddle in the middle without having any part of the ball hanging off the edge of the paddle. If the ball hits the corner of the paddle or some of the ball hangs off the paddle then the ball glitches into the paddle and does not bounce back. This is my algorithm...
bool CheckCollision(float Ax,float Ay,float Aw,float Ah,float Bx,float By,
float Bw,float Bh) {
if(Ax>Bx+Bw) {
return(false);
}else if(Ax+Aw<Bx) {
return(false);
}else if(Ay>By+Bh) {
return(false);
}else if(Ay+Ah<By) {
return(false);
}
return(true);
}
the A and the B represent to different objects and the x, y, w, and h stands for x pos, y pos, width, and height of that specific object. On the receiving end I have...
if(CheckCollision(ball->x,ball->y,ball->width,ball->height,paddle->x,paddle->y,
paddle->width,paddle->height)) {
ball->vellx = -ball->vellx;
}
This works as I said if the ball hits the paddle in the middle.
If you understood this (as I know that I am not the best with words) is there any way that I can have it so that the ball does not glitch into the paddle? If not, is there another algorithm I can use? Keep in mind this is only 2D.
This is a screenshot of what is happening
http://gyazo.com/920d529217864cca6480a91b217c9b61
As you can see the ball has no collision on the very sides of it, just the points.
I hope this helps
ball->vellx = -ball->vellx;
That's incorrect.
When collision is detected, you need to invert (x) velocity only if ball moves towards paddle. If ball already moves away from paddle, do nothing, and do not modify velocity.
If you'll blindly invert velocity during every collision, ball will get stuck in paddle.
P.S. There are some other things you could tweak (like making ball properly bounce against the corners, adjusting ball speed based on paddle velocity, etc), but that's another story...