Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Tilemap - check collision from sides  (Read 1158 times)

0 Members and 1 Guest are viewing this topic.

Szedou

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • Email
Tilemap - check collision from sides
« on: January 09, 2017, 05:51:37 pm »
Hi,
I got problem. I got Tilemap.
Tilemap.h
#pragma once

#include <SFML/Graphics.hpp>
#include <iostream>

#include "Player.h"

#include "Enemy.h"

using namespace std;
using namespace sf;

class newTiled{
    public:
        newTiled(void);
        ~newTiled(void);

        void draw(RenderWindow &);
        void Update(Player &player, Time &dt);

    private:

        vector <RectangleShape>::const_iterator wallit;
        vector <RectangleShape> wallGroup;

        int map_width = 42;
        int map_height = 12;


        Texture tileset_texture;
        Sprite tileset_sprite;

        Texture bg_txt;
        Sprite bg_sprite;

        RectangleShape t;

        int counter;

    int level[42 * 12] ={
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
    };


};

 

Tilemap.cpp
#include "newTiled.h"
#include <cmath>

using namespace sf;
using namespace std;

newTiled::newTiled(){
    if(!tileset_texture.loadFromFile("assets/images/tajlmap.png"))
       return;

    if(!bg_txt.loadFromFile("assets/images/bg2.png"))
       return;


    tileset_sprite.setTexture(tileset_texture);
    bg_sprite.setTexture(bg_txt);


}

newTiled::~newTiled(){

}

void newTiled::draw(RenderWindow &window){
      window.draw(bg_sprite);

    t = RectangleShape(Vector2f(64, 64));
    t.setFillColor(sf::Color::Transparent);

    for(int y = 0; y < map_height; ++y){
        for(int x = 0; x < map_width; ++x){
            int tilecount = x + y * map_width;

            tileset_sprite.setPosition(x * 64, y * 64);
            tileset_sprite.setTextureRect(IntRect(level[tilecount] * 64, 0, 64, 64));

            if(level[tilecount] == 2){
                t.setPosition(x*64, y*64);
                wallGroup.push_back(t);
            }

            window.draw(tileset_sprite);


        }
    }

            counter = 0;
            for(wallit = wallGroup.begin(); wallit != wallGroup.end(); wallit++){
                window.draw(wallGroup[counter]);

                counter++;
            }
}

void newTiled::Update(Player &player, Time &dt){
            float bottom, top, left, right;


            int posX = floor((int)(player.getPosition().x / 64));
            int posY = floor((int)(player.getPosition().y / 64));

            int tilecount = posX + posY * map_width;

            if(level[tilecount] == 1)
                player.m_onGround = true;
            else
                player.m_onGround = false;


            counter = 0;
            for(wallit = wallGroup.begin(); wallit != wallGroup.end(); wallit++){
                bottom = wallGroup[counter].getPosition().y + 64;
                top = wallGroup[counter].getPosition().y;
                right = wallGroup[counter].getPosition().x + 66;
                left = wallGroup[counter].getPosition().x;
              if(player.getBounds().intersects(wallGroup[counter].getGlobalBounds())){
                    if(player.right > left && player.right > right){
                        player.setPosition(player.getPosition().x - 1, player.getPosition().y);
                    }
                    else if (player.left < right && player.left < left){
                           player.setPosition(right + player.left, player.getPosition().y);
                    }

                    //top tile collision
                    else if(player.bottom > top && player.bottom > bottom){

                    }  else if (player.top < bottom && player.top < top){

                        }





              }else {
                //  player.m_onTile = false;
                   // player.setColor(sf::Color::Red);
              }

                counter++;
            }

}
 

And my Player is sf::RectangleShape. I check his sides with :
    bottom = m_rect.getPosition().y + m_rect.getSize().y;
    left = m_rect.getPosition().x;
    right = m_rect.getPosition().x + m_rect.getSize().x;
    top = m_rect.getPosition().y;

And I got problem with wall collision from left/right/top/bottom just to stop player from moving etc.

JayhawkZombie

  • Jr. Member
  • **
  • Posts: 76
    • View Profile
Re: Tilemap - check collision from sides
« Reply #1 on: January 09, 2017, 11:54:24 pm »
You can use the intersects method, but a different version of it: http://www.sfml-dev.org/documentation/2.4.1/classsf_1_1Rect.php#a5f1874792b04c7e221bb786b31f5836e

You can pass a reference to another rect and it will store in that rect by how much the two are overlapping.
You can use the player's movement to create a vector in the direction of movement. If they hit a wall, you can correct the movement based on how much they overlap and place them directly on the edge of the wall.
It's by no means perfect collision detection, but it might suffice.

Szedou

  • Newbie
  • *
  • Posts: 11
    • View Profile
    • Email
Re: Tilemap - check collision from sides
« Reply #2 on: January 10, 2017, 10:38:59 pm »
Thanks for reply!
I made something like this. It works with left/right collision and bottom. Top works as well but , now when my player is on the block the yVelocity is 0(m_Tile = true) and that is ok but the player will stay in the same Y position even when i move out of blocks. How can I get it simple to work?

counter = 0;
            for(wallit = wallGroup.begin(); wallit != wallGroup.end(); wallit++){
                bottom = wallGroup[counter].getPosition().y + 64;
                top = wallGroup[counter].getPosition().y;
                right = wallGroup[counter].getPosition().x + 64;
                left = wallGroup[counter].getPosition().x;
              if(player.getBounds().intersects(wallGroup[counter].getGlobalBounds())){
                   if(!player.m_onTile){
                        if(player.m_velocity.x > 0 && player.getPosition().x < right){
                            player.setPosition(player.getPosition().x - 1, player.getPosition().y);

                        } else if(player.m_velocity.x < 0 && player.getPosition().x > right){
                            player.setPosition(player.getPosition().x + 1, player.getPosition().y);
                        }

                        //top collision
                         else if(player.m_velocity.y > 0 && player.getPosition().y < bottom){
                                player.m_onTile = true;
                               
                        }

                        else if(player.m_velocity.y < 0 && player.getPosition().y > bottom){
                                player.setPosition(player.getPosition().x,player.getPosition().y + 2);

                        }

                   } else {
                       

                  }

              }else {
                   
              }

                counter++;
            }