SFML weird movement - c++

For some reason when I run the code below... The character only moves diagonally down. Lets say line I"m drawing is character:
\
\
\
\
\
That's the only direction it moves if I press up, right, down or left key!
Please help, I want to go right if right, up if up, down if down, and left if left.
My Code is:
#include<iostream>
#include<string>
#include<SFML\Graphics.hpp>
using std::cout;
using std::endl;
enum Direction
{
DOWN,
LEFT,
RIGHT,
UP
};
int main()
{
sf::RenderWindow _Win(sf::VideoMode(600, 600), "Hello World");
sf::Texture _texture;
if (!(_texture.loadFromFile("Resources/SPRITE.png")))
{
cout << "Could not load iamge" << endl;
}
//Source, tell us our starting position.
//Vector2i = Vector of 2 in SFML
sf::Vector2i source(1, DOWN/*or 0*/);
sf::Sprite _sprite(_texture);
float x = _sprite.getPosition().x;
float y = _sprite.getPosition().y;
while (true)
{
sf::Event _event;
while (_Win.pollEvent(_event))
{
switch (_event.type)
{
case sf::Event::Closed:
_Win.close();
exit(1);
break;
case sf::Event::KeyPressed:
switch (_event.key.code)
{
case sf::Keyboard::Up:
source.y = UP;
_sprite.move(sf::Vector2f(x,y--));
y = 3, x=3;
break;
case sf::Keyboard::Down:
source.y = DOWN;
_sprite.move(sf::Vector2f(x, y++));
y = 3, x = 3;
break;
case sf::Keyboard::Right:
source.y = RIGHT;
_sprite.move(sf::Vector2f(x++, y));
y = 3, x = 3;
break;
case sf::Keyboard::Left:
source.y = LEFT;
_sprite.move(sf::Vector2f(x--, y));
y = 3, x = 3;
break;
}
break;
}
}
//Cropping Out Image
//Please Look at sprite in resources/Sprite.png
//When we run this :
//_sprite.setTextureRect(sf::IntRect( source.x*32 , source.y*32 , 32 , 32 ));
//Its going to give us the top left corner sprite image. Thats so because
//we are cropping source.x*32 , which of 32 is the width of the sprite.. So it
//starts from 1 * 32. 32 is the width of one sprite so it goes to the end of it.
//Same Applies to the y. source.y * 32. It just goes to the end of the down sprite.
//As you go down the y increases, 1 * 32 = 32. And 32 is the width of one sprite
//so it shows body of one full sprite.
_sprite.setTextureRect(sf::IntRect( source.x*32 , source.y*32 , 32 , 32 ));
//Clears Window(Flickering..)
_Win.clear();
//Draw Sprite
_Win.draw(_sprite);
//And Finally Display the Window.
_Win.display();
}
}

In every case of your switch statement, you move the sprite by (x,y), and then either increment or decrement x or y, depending upon the direction. However, this is fruitless, since on the very next line, you reset them both to 3. So in effect, whatever direction key is pressed, you are doing this:
_sprite.move(sf::Vector2f(3, 3));
That is, 3 units to the right and 3 units down, which seems to fit your description of the movement you are seeing. I'm not sure what kind of movement you're going for, but here's an example that could work:
switch (_event.key.code) {
case sf::Keyboard::Up:
_sprite.move(sf::Vector2f(0, -3));
break;
case sf::Keyboard::Down:
_sprite.move(sf::Vector2f(0, 3));
break;
case sf::Keyboard::Right:
_sprite.move(sf::Vector2f(3, 0));
break;
case sf::Keyboard::Left:
_sprite.move(sf::Vector2f(-3, 0));
break;
}
This would move the sprite 3 units each time a direction key was pressed, in that direction.

Related

OpenGL:How to make "Feet" go up and down?

I'm writing code that draws a polygon and gives it two feet, walks from the right until it gets to the middle, does a flip, and then lands and walks to the left. I'm having a lot of trouble figuring out how to animate his feet. All I want to do is make one go up, then come down, then the other go up, and then come down. I know all I have to do is change the Y values of his feet, but I can't figure out how.
My professor talks about key frames a lot, but wouldn't every step that my "Polyman" would take be a key frame leading to infinite amount of cases? Here is my timer function...
void TimerFunction(int value) //float plx = 7.0, ply=-3.0, linet=0.00;
{
switch(frame)
{
case 1:
dx-=0.15;
plx-=0.15; //dx=polygon, plx = one foot, pl2x = other foot
pl2x-=0.15;
if(dx<=0.0)
{
plx=0.0; //this case makes polyman walk to the middle
dx=0.0;
pl2x=0.0;
frame=2;
}
break;
case 2:
dxt+=0.05;
if (dxt<=-0.00) //this is a triangle I translate over polyman appearing as if he's opening his mouth
{
dxt=0.00;
frame=3;
}
break;
case 3:
dy+=0.2;
theta+=10.0;
thetat+=10.0;
dyt+=0.2; //this is the flip with polyman's mouth open
ply+=0.2;
pl2y+=0.2;
linet2+=10.0;
linet+=10.0;
if(dy>5.0 || theta>360.00)
{
dy=5.0;
dyt=5.0;
ply=5.0;
pl2y=5.0;
linet2=0.0;
theta=0.0;
thetat=0.0;
linet=0.0;
frame=4;
}
break;
case 4:
dy-=0.2;
dyt-=0.2;
ply-=0.2;
pl2y-=0.2;
if(dy<=-3.0) //this is polyman coming back down to earth
{
dy=-3.0;
dyt=-3.0;
ply=-3.0;
pl2y=-3.0;
frame=5;
}
break;
case 5:
dxt-=0.2;
if (dxt<-3)
{ //this is the triangle slowly translating left appearing as if he's closing his mouth
dxt-=3.0;
}
if (dxt<=-8)
{
dxt = -8;
frame = 6;
}
break;
case 6:
dx-= 0.15;
plx-= 0.15;
pl2x-=0.15; //this is polyman walking off the stage to the left
if(dx<=-8.0)
{
dx=-8.0;
plx=-8.0;
pl2x=-8.0;
}
break;
}
glutPostRedisplay();
glutTimerFunc(30, TimerFunction, 1);
}
All variables that are used in my timerfunction are global. Thanks for your time! If you need any more of my code just ask and i'll append.

Calculating ball deflection angle when colliding with paddle in brick slayer game

Here is my code:
void Draw()
{
int x = 59;
int y = 500;
int temp = x;
int colour;
for (int i = 0; i < 9; ++i)
{
for (int j = 0; j < 10; ++j)
{
if (i % 2 == 0)
colour = 2;
else
colour = 3;
DrawRectangle(x, y, 65, 25, colors[colour]);
x += 67;
}
x = temp;
y -= 39;
}
DrawRectangle(tempx, 0, 85, 12, colors[5]);
DrawCircle(templx, temply, 10, colors[7]);
}
// This function will be called automatically by this frequency: 1000.0 / FPS
void Animate()
{
templx +=5;
temply +=5;
/*if(templx>350)
templx-=300;
if(temply>350)
temply-=300;*/
glutPostRedisplay(); // Once again call the Draw member function
}
// This function is called whenever the arrow keys on the keyboard are pressed...
//
I am using OpenGL for this project. The function Draw() is used to print the bricks, slider, and the ball. The Animate() function is called automatically by the frequency given in the code. As it can be seen, I have incremented the values of templx and temply, but the ball goes out of screen as it crosses its limit. I have to deflect the ball if it collides with the paddle or the wall. What can I do to achieve this? All the conditions that I have used by now do not work properly.
So basically you would like to have a ball that is bouncing from the edges of your window. (For this answer I will ignore the slider, finding collision with the slider is very similar to finding collision with the walls).
templx and temply pair is position of your ball. I don't know what is the 3rd argument of DrawCircle function so I will assume that it is the radius. Let wwidth and wheight be width and height of a game window. Note that this magic constant 5 is, in fact, a velocity of the ball. Now ball is moving from upper left corner to lower right corner of your window. If you change 5 to -5 it will move from lower right corner to upper left corner.
Let's introduce two more variables vx and vy - velocity on x axis and velocity on y axis. The initial values will be 5 and 5. Now notice that when ball hits the right edge of the window it doesn't change its vertical velocity, it is still moving up/down but it changes its horizontal velocity from left->right to right->left. So if the vx was 5, after hitting the right edge of the window we should change it to -5.
The next problem is how to find out if we hit the edge of the window or not.
Note that the right-most point on the ball has the position templx + radius and the left-most point on the ball has the position templx - radius etc. Now to find out if we hit the wall or not we should just compare this values with window dimensions.
// check if we hit right or left edge
if (templx + radius >= wwidth || templx - radius <= 0) {
vx = -vx;
}
// check if we hit top or bottom edge
if (temply + radius >= wheight || temply - radius <= 0) {
vy = -vy;
}
// update position according to velocity
templx += vx;
temply += vy;

trying to use switch statement to move an image in relation to mouse position c++ SFML

as I'm new to coding in general I'm sure that my thinking is just heading in the wrong direction with this however..
I'm trying to get a sprite to chase the mouse on left click. I had tried to use else if statements but only the first 2 statements would run even on multiple clicks.
I want to be able to say if mouseposition.x > playerposition.x then move playerimage right, and so one for the other directions.
as I'm using sfml, I've used the below to get the positions of both.
sf::Vector2i mousePosition = sf::Mouse::getPosition(window);
sf::Vector2f playerPosition = playerImage.getPosition();
I was hoping to use the switch statement as below but I'm at a loss as to how to create the argument and compare the cases to that argument.
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
switch()
{
case 1:
playerImage.move(0.02, 0);
case 2:
playerImage.move(-0.02, 0);
case 3:
playerImage.move(0, -0.02);
case 4:
playerImage.move(0, 0.02);
}
Maybe something like this?
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
sf::Vector2f offset;
if (mousePosition.x > playerPosition.x) {
offset.x = 0.02f;
} else if (mousePosition.x < playerPosition.x) {
offset.x = -0.02f;
}
if (mousePosition.y > playerPosition.y) {
offset.y = 0.02f;
} else if (mousePosition.y < playerPosition.y) {
offset.y = -0.02f;
}
playerImage.move(offset);
}

movement not working ncurses game

I am making an ncurses game which has a spaceship fire bullets at other enemies.
I've got the ship firing bullets how ever when I fire more than one bullet, only the latest bullet will move and the rest will stay still.
int i=0 , j=-1;
switch(key){
case KEY_UP: playership.row=changeRow(playership.row,-1,playership.col); /* move up */
break;
case KEY_DOWN: playership.row=changeRow(playership.row,+1,playership.col); /* move down */
break;
case KEY_LEFT:playership.col=changeColumn(playership.col,-1,playership.row); /* move left */
break;
case KEY_RIGHT:playership.col=changeColumn(playership.col,+1,playership.row); /* move right */
break;
case ' ': {j++; bullets[0].col=playership.col+5; bullets[j].row=playership.row-2 ;break;}
default: break; /* do nothing if other keys */
}
if (j!=-1){
attrset(COLOR_PAIR(2));
mvprintw(bullets[j].row,bullets[0].col,"%c",bullet);
mvprintw(bullets[j].row+1,bullets[0].col," ");
bullets[j].row=bullets[j].row-1;
refresh();
}
I tried to implement the suggestion from the comments in this answer to my earlier question, but I don't think I've done it right:
If you can have 5 bullets at once, you need to store their positions.
If you have int bullet_pos[5] that would be fine. You could use -1 in
each position to say that no bullets are active. Then when you want to
fire one you search the array to find the first position that is -1
and change it to 0. When you draw the bullets, you go through the
array and draw a bullet for any position that is not -1, and update
its position.
If you don't already, try adding a flag to your bullet structure. Something like alive.
When you want to fire, you check through your array and find an unused bullet position (if any):
for( int i = 0; i < MAX_BULLETS; i++ ) {
if( !bullets[i].alive ) {
bullets[i].alive = true;
bullets[i].row = playership.row;
bullets[i].col = playership.col+5;
break;
}
}
Then when you update or draw:
for( int i = 0; i < MAX_BULLETS; i++ ) {
if( bullets[i].alive ) {
attrset(COLOR_PAIR(2));
mvprintw(bullets[i].row, bullets[i].col, "%c", bullet);
mvprintw(bullets[i].row+1, bullets[i].col, " " );
bullets[i].col++;
// TODO check for bullet death. If bullet is done, set `alive` to false.
}
}
refresh();

SDL collision handling

I have an instance where a SDL_Rect is inside of a big SDL_Rect and i need it to make it so it cannot leave that rect but can still move. The movement of the little rect needs to be like board game movement where you click the button once and it moves a certain cords here is my code:
if( event.type == SDL_KEYDOWN) {
switch( event.key.keysym.sym ) {
case SDLK_UP:
yVel -= 10;
if (!check_collision(box,Cont))
{
std::cout<<"in the water"<<std::endl;
box.y -= yVel - 10;
}
break;
case SDLK_DOWN:
if (!check_collision(box,Cont))
{
std::cout<<"in the water"<<std::endl;
box.y -= yVel + 20;
}
else
{
yVel += 10;
}
break;
case SDLK_LEFT:
xVel -= 10;
if (!check_collision(box,Cont))
{
std::cout<<"in the water"<<std::endl;
}
break;
case SDLK_RIGHT:
xVel += 10;
if (!check_collision(box,Cont))
{
std::cout<<"in the water"<<std::endl;
}
break;
case SDLK_1:
return 2;
break;
}
}
You have inconsistencies in your SDLK_DOWN and the rest of your inputs - no velocity change happens if there are no collisions.
Your input code is changing coordinates, it shouldn't be like that. Make your input code manage the "intent", and have a game loop apply velocity to the object and to the collision detection.
Also, your collision checks should check if I'm at position and I move of delta, will I collide? If I do collide, what's the collision reaction? Do you want the entity to "slide" on collisions or simply stop as soon as a collision is detected?
Considering you are doing a board game, you shouldn't even have to do collision detection. Represent your board as a graph of possible positions your unit can be, translate mouse clicks into board coordinates and calculate the shortest path (use the A* algorithm) between your current position and your destination; invalid clicks (out of bounds) shouldn't translate into movement commands.