Game Over condition simple Snake c++ game - c++

I have basic knowledge of c++ and am trying to create a simple Snake game that runs in a while loop, as long as a "Game Over" condition evaluates to false.
If it turns to "true" (when the snakes head goes out of bounds), "Game Over!" is printed on a lcd screen.
For some reason, the code skips directly to the game over screen without running the game itself.
My code involves a few classes, and in one of those I have a collision detection function that looks like this:
bool SnakeEngine::collision_detection()
{
// check the snake coordinates so that the head doesn't go off screen
if (_head_y < 1) {
return 1;
}
if (_head_y > HEIGHT - 4) {
return 1;
}
if (_head_x < 1) {
return 1;
}
if (_head_x > WIDTH - 4) {
return 1;
} else {
return 0;
}
}
And in the main loop I have:
int main()
{
snake.draw(lcd); // draw the initial game frame and the sprites
lcd.refresh();
while(!snake.collision_detection()) {
snake.read_input(pad); // reads the user input
snake.update(pad); // updates the sprites positions and calls the collision_detection() function
render(); // clears the lcd, draws the sprites in the updated positions, refreshes the lcd
wait(1.0f/fps);
}
lcd.printString("Game Over!",6,4);
lcd.refresh();
}
How come is this not working?
Thank you

The collision detection is a suspect. If all specific conditions which you check do not return true (1) the final result should be false (0).
This condition is too restrictive:
if (_head_x > WIDTH - 4) {
return 1;
} else {
return 0;
}
It should be limited to:
if (_head_x > WIDTH - 4) {
return 1;
}
return 0;
The modified code with the use of bool types true and false looks like:
bool SnakeEngine::collision_detection()
{
// check the snake coordinates so that the head doesn't go off screen
if (_head_y < 1) {
return true;
}
if (_head_y > HEIGHT - 4) {
return true;
}
if (_head_x < 1) {
return true;
}
if (_head_x > WIDTH - 4) {
return true;
}
return false;
}

Try this, just guessing.I think when all the four conditions are false, than you should conclude that there is no collision. I think you did a blunder in the last else statement in your collision_detection() .
bool SnakeEngine::collision_detection()
{
// check the snake coordinates so that the head doesn't go off screen
if ( _head_y < 1 || _head_y > (HEIGHT - 4) || _head_x < 1 || _head_x > (WIDTH - 4) )
return true;
return false;
}

Related

Tetris function for checking if piece fits doesn't work right

Im practicing C++, and been working on tetris clone. I have tried to figure out my own solutions with help of few tutorials to learn to code with this language. Im having almost everything else working, but this function is giving me some problems:
bool Board::isBoxFree(int pX, int pY, int pPiece[][4], int pBoard[][20])
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if (pPiece[i][j] != 0)
{
if (pBoard[(pX / 15) + i][(pY / 15) + j] != 0)
{
return false;
break;
}
if (pY / 15 + j > 18)
{
return false;
break;
}
else
return true;
break;
}
}
}
This works with some of the pieces, but gives wrong values systematically with different tetris pieces. For example when checking if straight line can go right the last block overlaps borders. With n-shape or t-shape there is no problem. Sometimes when going down tetrominos overlap one block before function working and tetromino saving to board with the overlapping position. Some tetrominos don't seem to hit anything but are still collided and saved to the board one block away when they should have been collided.
Is this function written wrong or is there something wrong with my use of two dimensional arrays?
This is how I check if tetromino can go down inside game tick:
if (this->playBoard(xLoc, yLoc, this->arr, rotate, this->boardArr).isBoxFree(xLoc, yLoc + boxSize, this->arr, this->boardArr))
And here is how I check if tetromino can go left or right:
if (this->ev.key.code == Keyboard::Left)
{
if (this->playBoard().isBoxFree(xLoc - boxSize, yLoc , this->arr, this->boardArr)&& move ==false )//(move == false && xLoc>boxSize)
{
xLoc = xLoc - boxSize;
move = true;
}
}
else if (this->ev.key.code == Keyboard::Right)
{
if(this->playBoard().isBoxFree(xLoc+boxSize*3, yLoc , this->arr, this->boardArr)&& move == false) //(move == false && xLoc<boxSize*7)
{
xLoc = xLoc + boxSize;
move = true;
}
}
As you can see I have multiplied boxSize with 3 when checking if going right is possible for it to work right with at least some tetrominos. That alone tells that there is something wrong with my code that I haven't figured out.
Help is much appreciated since this is one of the last problems I have with my tetris. Even the line clearing function works.
Re: Is this function written wrong
You have an error in your Board::isBoxFree() functin, in the inner for loop (I've removed redundant breaks, as Paul commented):
if (pPiece[i][j] != 0)
{
if (pBoard[(pX / 15) + i][(pY / 15) + j] != 0)
return false;
if (pY / 15 + j > 18)
return false;
else
return true;
}
You can remove else too, as if a condition was true - you would return already. So:
if (pPiece[i][j] != 0)
{
if (pBoard[(pX / 15) + i][(pY / 15) + j] != 0)
return false;
if (pY / 15 + j > 18)
return false;
return true;
}
So for the first pPiece[i][j] that is NOT 0, if the board at that location is empty - you would return true, without checking other elements.
This is a common pattern. You check all elements of your pPiece and return false as soon as you find the collision. Then, when you are out of the loop (no collisions were found) - you return true
Re: is there something wrong with my use of two dimensional arrays?
Possibly. My eyes hurt a little looking at all those / 15, > 18... :)

Water in a falling sand simulation

I am currently working on a very simple 'Falling Sand' simulation game in C++ and SDL2, and am having problems with getting water to flow in a more realistic manner. I basically have a grid of cells that I iterate through bottom-to-top, left-to-right and if I find a water cell, I just check below, down to left, down to the right, left then right for empty cells and it moves into the first one its finds (it makes a random choice if both diagonal cells or both horizontal cells are free). I then mark the cell it moved into as processed so that it is not checked again for the rest of that loop.
My problem is a sort of 'left-bias' in how the particles move; if I spawn a square of water cells above a barrier, they will basically all shift to left without moving once the particles begin to reach the barrier, while the cells on the right will run down in the proper way. So instead of forming a nice triangular shape flowing out evenly to both sides, the whole shape will just move to the left. This effect is reversed whenever I iterate left-to-right, so I know it's something to do with that but so far I've been stumped trying to fix it. I initially thought it was a problem with how I marked the cells as processed but I've found no obvious bugs with that system in many hours of testing. Has anyone faced any similar challeneges in developing a simulation like this, or knows something that I'm missing? Any help would be very much appreciated.
EDIT:
Ok so I've made a little progress, however I've ran into another bug that seems to be unrelated to iteration, since now I save a copy of the old cells and read from that to decide an update, then update the original cells and display that. This already made the sand work better, however water, which checks horizontally for free cells, now 'disappears' when it does move horizontally. I've been testing it all morning and have yet to find a solution, I thought it might've been someting to do with how I was copying the arrays over, but it seems to work as far as I can tell.
New snippets:
Simulation.cpp
void Simulation::update()
{
copyStates(m_cells, m_oldCells); // so now oldcells is the last new state
for(int y = m_height - 1; y>= 0; y--)
for(int x = 0; x < m_width; x++)
{
Cell* c = getOldCell(x, y); // check in the old state for possible updates
switch(c->m_type)
{
case EMPTY:
break;
case SAND:
if(c->m_visited == false) update_sand(x, y);
break;
case WATER:
if(c->m_visited == false) update_water(x, y);
break;
default:
break;
}
}
}
void Simulation::update_water(int x, int y)
{
bool down = (getOldCell(x, y+1)->m_type == EMPTY) && checkBounds(x, y+1) && !getOldCell(x, y+1)->m_visited;
bool d_left = (getOldCell(x-1, y+1)->m_type == EMPTY) && checkBounds(x-1, y+1) && !getOldCell(x-1, y+1)->m_visited;
bool d_right = (getOldCell(x+1, y+1)->m_type == EMPTY) && checkBounds(x+1, y+1) && !getOldCell(x+1, y+1)->m_visited ;
bool left = (getOldCell(x-1, y)->m_type == EMPTY) && checkBounds(x-1, y) && !getOldCell(x-1, y)->m_visited ;
bool right = (getOldCell(x+1, y)->m_type == EMPTY) && checkBounds(x+1, y) && !getOldCell(x+1, y)->m_visited ;
// choose random dir if both are possible
if(d_left && d_right)
{
int r = rand() % 2;
if(r) d_right = false;
else d_left = false;
}
if(left && right)
{
int r = rand() % 2;
if(r) right = false;
else left = false;
}
if(down)
{
getCell(x, y+1)->m_type = WATER; // we now update the new state
getOldCell(x, y+1)->m_visited = true; // mark as visited so it will not be checked again in update()
} else if(d_left)
{
getCell(x-1, y+1)->m_type = WATER;
getOldCell(x-1, y+1)->m_visited = true;
} else if(d_right)
{
getCell(x+1, y+1)->m_type = WATER;
getOldCell(x+1, y+1)->m_visited = true;
} else if(left)
{
getCell(x-1, y)->m_type = WATER;
getOldCell(x-1, y)->m_visited = true;
} else if(right)
{
getCell(x+1, y)->m_type = WATER;
getOldCell(x+1, y)->m_visited = true;
}
if(down || d_right || d_left || left || right) // the original cell is now empty; update the new state
{
getCell(x, y)->m_type = EMPTY;
}
}
void Simulation::copyStates(Cell* from, Cell* to)
{
for(int x = 0; x < m_width; x++)
for(int y = 0; y < m_height; y++)
{
to[x + y * m_width].m_type = from[x + y * m_width].m_type;
to[x + y * m_width].m_visited = from[x + y * m_width].m_visited;
}
}
Main.cpp
sim.update();
Uint32 c_sand = 0xedec9a00;
for(int y = 0; y < sim.m_height; y++)
for(int x = 0; x < sim.m_width; x++)
{
sim.getCell(x, y)->m_visited = false;
if(sim.getCell(x, y)->m_type == 0) screen.setPixel(x, y, 0);
if(sim.getCell(x, y)->m_type == 1) screen.setPixel(x, y, c_sand);
if(sim.getCell(x, y)->m_type == 2) screen.setPixel(x, y, 0x0000cc00);
}
screen.render();
I've attached a gif showing the problem, hopefully this might help make it a little clearer. You can see the sand being placed normally, then the water and the strange patterns it makes after being placed (notice how it moves off to the left when it's spawned, unlike the sand)
You also have to mark the destination postion as visited to stop multiple cells moving in to the same place.

advanced Collision detection?

Hi i'm currently making an RPG similar to Legend of Zelda. I have a feature in my game where when Player attacks enemy with his sword, the enemy is knocked back n units. i have a collision detection that sometimes works as intended, and other times the enemy goes through the wall and gets stuck on the other side, and then other times the enemy can simply walk right through the wall. If possible, making the enemy move toward player upon collision with wall would be one possible solution to this problem I believe, but I do not know how to implement this. Here is my current collision code:
// Enemy Collides with Wall
counter1 = 0;
for (iter4 = enemyArray.begin(); iter4 != enemyArray.end(); iter4++)
{
counter2 = 0;
for (iter15 = wallArray.begin(); iter15 != wallArray.end(); iter15++)
{
if (enemyArray[counter1].rect.getGlobalBounds().intersects(wallArray[counter2].rect.getGlobalBounds()))
{
enemyArray[counter1].isCollided = true;
//Hit Wall
if ((enemyArray[counter1].direction == 1 || enemyArray[counter1].rect.getPosition().y >= wallArray[counter2].rect.getPosition().y)) //up
{
enemyArray[counter1].canMoveUp = false;
enemyArray[counter1].canMoveLeft = false;
enemyArray[counter1].canMoveRight = false;
enemyArray[counter1].rect.move(0, 7);
}
else if ((enemyArray[counter1].direction == 2 || enemyArray[counter1].rect.getPosition().y <= wallArray[counter2].rect.getPosition().y)) //Down
{
enemyArray[counter1].canMoveDown = false;
enemyArray[counter1].canMoveRight = false;
enemyArray[counter1].canMoveLeft = false;
enemyArray[counter1].rect.move(0, -7);
}
else if ((enemyArray[counter1].direction == 3 || enemyArray[counter1].rect.getPosition().x >= wallArray[counter2].rect.getPosition().x)) //Left
{
enemyArray[counter1].canMoveLeft = false;
enemyArray[counter1].canMoveUp = false;
enemyArray[counter1].canMoveDown = false;
enemyArray[counter1].rect.move(7, 0);
}
else if ((enemyArray[counter1].direction == 4 || enemyArray[counter1].rect.getPosition().x <= wallArray[counter2].rect.getPosition().x)) //Right
{
enemyArray[counter1].canMoveRight = false;
enemyArray[counter1].canMoveUp = false;
enemyArray[counter1].canMoveDown = false;
enemyArray[counter1].rect.move(-7, 0);
}
}
counter2++;
}
counter1++;
}
//Knock Back enemy away from sword && sword2
counterKnockBack++;
counter2 = 0;
for (iter4 = enemyArray.begin(); iter4 != enemyArray.end(); iter4++)
{
if (enemyArray[counter2].knockback == true)
{
if (enemyArray[counter2].isCollided == false)
{
if ((Player1.rect.getPosition().y > enemyArray[counter2].rect.getPosition().y))
{
enemyArray[counter2].rect.move(0, -3); //up
}
else if ((Player1.rect.getPosition().y < enemyArray[counter2].rect.getPosition().y))
{
enemyArray[counter2].rect.move(0, 3); //down
}
if ((Player1.rect.getPosition().x > enemyArray[counter2].rect.getPosition().x))
{
enemyArray[counter2].rect.move(-3, 0); //left
}
else if ((Player1.rect.getPosition().x < enemyArray[counter2].rect.getPosition().x))
{
enemyArray[counter2].rect.move(3, 0); //right
}
if (counterKnockBack >= 20)
{
enemyArray[counter2].knockback = false;
}
}
}
counter2++;
}
//turn off collided counter
counterCollided++;
counter2 = 0;
for (iter4 = enemyArray.begin(); iter4 != enemyArray.end(); iter4++)
{
if (enemyArray[counter2].isCollided == true)
{
if (counterCollided >= 30)
enemyArray[counter2].isCollided = false;
}
counter2++;
}
I have no idea why the enemy is able to sometimes simply walk right through the wall without being knocked back. So how can I fix this, any ideas?
Without reading the code completely I can already tell you that your collision detection code is wrong. Mostly because you are moving your objects directly, probably without checking for collisions within your rect::move function.
It is possible that the rect::move function will move objects through the walls without triggering any collision reaction code. Consider the following scenario:
First frame:
enemyArray[counterX].rect.move(3, 0);
Second frame:
The enemy object is moved behind the wall and will not trigger the collision detection code.
My advise is (despite the obvious one: read some books): for each enemy store its previous location and check for collision not between the enemy and the wall's rectangle but between wall and a rectangle between two enemy positions. Something like that:
This is of course only one of the possible scenarios when your collision detection code would be error-prone.

c++ card game, hand being dealt more than once when a new round deck is created / new round is started

I'm writing a video poker game and I'm having a problem with a hand being drawn and then replaced when a new round is started.
The idea is you start with five cards, you select which cards to keep and then the others are switched out when you click "deal", you will then be shown your new cards and told what you've won, after that you will be asked to start a new round, when you click "new round" the deck that was used previously should be discarded, a new hand taken from that deck and then drawn onto the screen.
The first two things work, the problem is that when I click "new round" it very quickly draws the hand to the screen and then replaces it with another hand, this doesn't effect the players bet, the money they have, absolutely nothing, it took me a while to notice that it was actually happening.
I can't post a working example, that would require the entire game to be uploaded (my code isn't very elegant) but I will try to show the relevant text.
Main:
int main(int argc, char *argv[])
{
srand(time(NULL));
//load static cards
SDL_Surface* deal_card = load_surface("resources/images/cards/misc/deal.png");
SDL_Surface* round_card = load_surface("resources/images/cards/misc/new_round.png");
SDL_Surface* held = load_surface("resources/images/cards/effect/held.png");
//initiate standard sdl modules
if(!init())
{
printf("fail init");
}
//initiate SDL_ttf
else if(TTF_Init() == -1)
{
printf("TTF INit fail");
}
else
{
//should exit
bool quit = false;
//events
SDL_Event e;
//font and font colour to be used for rendering text1
TTF_Font* font = TTF_OpenFont("resources/fonts/OpenSans-Regular.ttf", 18);
SDL_Color text_colour = {236, 251, 100};
//create a new deck, draw out a hand, sort it numerically, setup images and positions for cards
vector<card>my_deck = new_shuffled_deck();
vector<card>my_hand = hand(my_deck);
sort_hand(my_hand);
setup_hand(my_hand);
//should switch cards that are not held and remove those used
//must be TRUE on start otherwise the first deal will duplicate cards
bool switch_hand = true;
int round_number = 1;
//get or set bet information
read_bet(player_pot, cash_borrowed);
while(!quit)
{
//starting mouse position
int mouse_x_pos = 0;
int mouse_y_pos = 0;
//push current mouse position to starting mouse positions
SDL_GetMouseState(&mouse_x_pos, &mouse_y_pos);
//set up to blit hold icon
update_hold_position(my_hand);
//check for winning hand
winning_hand hand_details = my_scores.card_check(my_hand, bet_amount);
//setup render and blit text
render_and_blit_text(font, hand_details, player_pot, cash_borrowed, text_colour);
scoring_text(font, hand_details, text_colour);
//switch out cards that are not held
if(switch_hand == true)
{
swap_cards(my_hand, my_deck);
}
switch_hand = false;
while(SDL_PollEvent(&e) != 0)
{
if(e.type == SDL_QUIT)
{
quit = true;
}
if(e.type == SDL_MOUSEBUTTONDOWN)
{
//set mouse position to carry over without resetting
int n_mouse_pos_x = mouse_x_pos;
int n_mouse_pos_y = mouse_y_pos;
//check if card is clicked, if is selected de-select, if not selected then select
for(size_t cpc = 0; cpc < my_hand.size(); cpc++)
{
// if mouse position is in range of left side of card and right side of card
if(n_mouse_pos_x > my_hand[cpc].position.x and n_mouse_pos_x < my_hand[cpc].position.x + my_hand[cpc].image->w &&
n_mouse_pos_y > my_hand[cpc].position.y and n_mouse_pos_y < my_hand[cpc].position.y + my_hand[cpc].image->h)
{
//if clicked un-click, if un-clickde click
if(my_hand[cpc].selected == 0)
{
my_hand[cpc].selected = 1;
}
else if(my_hand[cpc].selected == 1)
{
my_hand[cpc].selected = 0;
}
}
}
//if deal is clicked
if(n_mouse_pos_x > deal_rect.x and n_mouse_pos_x < deal_rect.x + deal_card->w &&
n_mouse_pos_y > deal_rect.y and n_mouse_pos_y < deal_rect.y + deal_card->h)
{
//switch held cards, if last round switch entire hand, update cash
deal_clicked(switch_hand, round_number, my_hand, my_deck, cash_borrowed, player_pot, amount_won,
bet_amount, hand_details);
}
}
}
//blit section
//blit cards to screen
blit_cards(my_hand, round_number, held, screen_surface, deal_rect, round_card, deal_card);
SDL_Surface* fill_screen;
fill_screen = SDL_CreateRGBSurface(0, screen_width, screen_height, 32, 0, 0, 0, 0);
SDL_UpdateWindowSurface(window);
SDL_FillRect(screen_surface, 0, SDL_MapRGB(fill_screen->format, 18, 17, 233));
SDL_FreeSurface(fill_screen);
SDL_Delay(30);
}
}
close();
return 0;
}
Swap cards:
void swap_cards(vector<card>&my_hand, vector<card>&my_deck)
{
for(size_t b = 0; b < my_hand.size(); b++)
{
if(my_hand[b].selected == false)
{
SDL_FreeSurface(my_hand[b].image);
//replace card with card of the same index from the deck
my_hand[b] = my_deck[b];
// remove card from deck so it cannot be chosen again
my_deck.erase(my_deck.begin() + b);
}
else
{
// this prevents memory leak on held cards, no idea why.
SDL_FreeSurface(my_hand[b].image);
}
}
//set up images and position for cards again
setup_hand(my_hand);
}
Deal clicked:
void deal_clicked(bool &switch_hand, int &round_number, vector<card>&my_hand, vector<card>&my_deck,
int &cash_borrowed, int &player_pot, int &amount_won, int& bet_amount, winning_hand &hand_details)
{
switch_hand = true;
round_number++;
// aka if(round_number % 2 == 0 and round_number != 0)
if(round_number == 3)
{
//free card surface images
for(size_t d = 0; d < my_hand.size(); d++)
{
SDL_FreeSurface(my_hand[d].image);
}
vector<card>().swap(my_deck);
//replace deck with new deck
my_deck = new_shuffled_deck();
//draw new hand
vector<card>().swap(my_hand);
my_hand = hand(my_deck);
//sort hand by card number
sort_hand(my_hand);
//load images and position cards
setup_hand(my_hand);
//set round number back to beginning
round_number = 1;
//distribute winnings and take next bet amount
amount_won = hand_details.hand_score;
if(cash_borrowed > 0)
{
cash_borrowed -= amount_won;
}
else if(cash_borrowed < 0)
{
player_pot += abs(cash_borrowed);
cash_borrowed = 0;
}
else
{
player_pot += amount_won;
}
if(player_pot <= 0)
{
cash_borrowed +=5;
}
else
{
player_pot -= bet_amount;
}
write_bet(player_pot, cash_borrowed);
}
}
Hopefully that should be enough for someone to have an idea about where my problem is coming from.
If anyone wants more code I can post it, it jut gets even more messy, these are the only areas I think could be causing the problem, then again I can't figure out what it is.
EDIT:
Solved, duplicate call to the setup_hand function.
Duplicate call to setup_hand function.

SFML Sprite moving violently down on 2nd tick

I am working on an SFML game and for some reason after spawning the player, the player gets teleported down. On the first tick he is correctly positioned, but after wards, he is moved down. Any idea on how to diagnose this problem? I set up breakpoints in the move mechanism, the only place where the player's co-ordinates change, and it seems to happen right after the function ends. This is the main function:
int main(){
App.ShowMouseCursor(false);
mainch.mainchinventory.read();
while (App.IsOpened())
{
sf::Event Event;
while (App.GetEvent(Event))
{
if (Event.Type == sf::Event::Closed)
App.Close();
}
float time = App.GetFrameTime();
mainch.move(time);
App.Clear();
drawall();
App.Display();
}
return EXIT_SUCCESS;
}
Mainch.move(t):
void cmainchar::move(float t){
if (App.GetInput().IsKeyDown(sf::Key::S)) mainchinventory.save();
if (App.GetInput().IsKeyDown(sf::Key::R)) mainchinventory.read();
if (App.GetInput().IsKeyDown(sf::Key::A)) A = true;
else A = false;
if (App.GetInput().IsKeyDown(sf::Key::D)) D = true;
else D = false;
if(grounded)
if (App.GetInput().IsKeyDown(sf::Key::W)) first = true;
if ((App.GetInput().IsKeyDown(sf::Key::I)) && (keyreleased)){
if (mainchinventory.drawmain){
mainchinventory.drawmain = false;
mainchinventory.press(mainchinventory.selectionx, 3);
}
else{
mainchinventory.drawmain = true;
}
keyreleased = false;
}
else if (!App.GetInput().IsKeyDown(sf::Key::I))
keyreleased = true;
if(!mainchinventory.drawmain){
if(App.GetInput().IsKeyDown(sf::Key::Num1)) mainchinventory.press(0, 3);
else if(App.GetInput().IsKeyDown(sf::Key::Num2)) mainchinventory.press(1, 3);
else if(App.GetInput().IsKeyDown(sf::Key::Num3)) mainchinventory.press(2, 3);
else if(App.GetInput().IsKeyDown(sf::Key::Num4)) mainchinventory.press(3, 3);
else if(App.GetInput().IsKeyDown(sf::Key::Num5)) mainchinventory.press(4, 3);
else if(App.GetInput().IsKeyDown(sf::Key::Num6)) mainchinventory.press(5, 3);
else if(App.GetInput().IsKeyDown(sf::Key::Num7)) mainchinventory.press(6, 3);
else if(App.GetInput().IsKeyDown(sf::Key::Num8)) mainchinventory.press(7, 3);
else if(App.GetInput().IsKeyDown(sf::Key::Num9)) mainchinventory.press(8, 3);
else if(App.GetInput().IsKeyDown(sf::Key::Num0)) mainchinventory.press(9, 3);
if(App.GetInput().IsMouseButtonDown(sf::Mouse::Button::Left)){
mainchinventory.dockitems[mainchinventory.selectionx].use();
spells.push_back(cspell());
}
}
else if ((App.GetInput().IsMouseButtonDown(sf::Mouse::Button::Left)) && (mainchinventory.drawmain) && (buttonreleased)){
mainchinventory.checkmouse();
buttonreleased = false;
}
else if (!App.GetInput().IsMouseButtonDown(sf::Mouse::Button::Left))
buttonreleased = true;
int xmap = (View.GetCenter().x - 320) / 40;
int ymap = (View.GetCenter().y - 240) / 40;
if ((xmap != xmapold) || (ymap != ymapold))
maps.read();
xmapold = xmap;
ymapold = ymap;
collisions();
for(std::list<cspell>::iterator i = mainch.spells.begin(); i != mainch.spells.end(); i++)
if (i->move(t))
spells.erase(i);
if (A && left){
animate(2, t);
you.Move(-160 * t, 0);
}
if (D && right){
animate(1, t);
you.Move(160 * t, 0);
}
if (!D && !A)
animate(0, t);
if (up){
if(grounded && first){
jump = 1.25;
first = false;
}
if (jump > 0){
you.Move (0,-250 * t * jump);
jump = jump - 1 * t;
}
if (jump <= 0){
jump = 0.f;
}
}
else{
first = false;
jump = 0.f;
}
if (down){
fall = fall + 10 * t;
you.Move(0, 25 * fall * t);
grounded = false;
}
else{
fall = 0.f;
grounded = true;
}
if(teleport){
mainchinventory.spawn = true;
fall = 0.f;
jump = 0.f;
maps.changemap(maps.nxtmap);
teleport = false;
}
moveview();
}
You don't show the code where you're manipulating the sf::Sprite object, so I (or anyone else, really) can't say for certain, but...that said, I have a strong guess as to what's happening.
I've been familiarizing myself with SFML recently, too, and I encountered this issue myself. What I think is happening is you're calling sf::Sprite::Move(x,y) to move the sprite to position (x,y). This is incorrect; what you should be calling is sf::Sprite::SetPosition(x,y). (Both these functions take will take a 2d vector as an argument instead, btw).
I'm operating under the assumption you're using SFML 1.6, yes? Looks that way...version 2.0 changes the API somewhat, so in case you're using that Sprite::Move() becomes Sprite::move() and Sprite::SetPosition() becomes Sprite::setPosition().
Anyways, to wrap this up: the difference between Move(x,y) and SetPosition(x,y) is that Move adjusts the sprite's position relative to its current position, whereas SetPosition moves the sprite to a new position regardless of where it was before.
Again, this is a blind guess since the relevant code was not included...so was my shot in the dark correct?
Unfortunately, you haven't provided enough code for a straightforward diagnosis. With what you provided however, my best guess is that your fall variable hasn't been initialized. If it hasn't been initialized, its values can be completely random, likely being much larger than expected. This would explain your 'teleporting' behavior.