Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[SFML][C++] Kolizja tilemap - Gracz

Ostatnio zmodyfikowano 2021-05-17 18:28
Autor Wiadomość
R0ut4
Temat założony przez niniejszego użytkownika
[SFML][C++] Kolizja tilemap - Gracz
» 2021-05-15 22:19:08
Yo, dawno nie pisałem w tym dziale :D

Mianowicie: Nie mam pojęcia jak zrobić, aby po spotkaniu się Sprite spPlayer i tile nr 1 lub 2, gracz nieszedł dalej, albo zresetował swoją pozycję.

Męczę się już przynajmniej tydzień z wymyśleniem jak  mogę zobić kolizję i nic nie wymyśliłem. Próbowałem pobrać jakoś "numer" tile'a, ale nic to nie dało. Przeszukałem internet i chyba potrzebuje jakichś specjalistycznych zajęć XD
Ktoś ma pomysł i mógłby mnie naprowadzić?

main.cpp
C/C++
#include <iostream>

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include "tilemap.hpp"
#include "playermove.hpp"
#include "player.hpp"
#include "Levels.hpp"
#include "przycisk.hpp"

int main()
{
   
int widthmap = 1280, heightmap = 720;
   
sf::RenderWindow window( sf::VideoMode( widthmap, heightmap ), "Game" );
   
window.setFramerateLimit( 60 );
   
   
int WDmap = 16;
   
int HGmap = 16;
   
TileMap map1;
   
if( !map1.load(( "tileset.png" ), sf::Vector2u( 100, 100 ), level, WDmap, HGmap ) )
   
{
       
return - 1;
   
}
   
TileMap map2;
   
if( !map2.load(( "tileset.png" ), sf::Vector2u( 100, 100 ), level1, WDmap, HGmap ) )
   
{
       
return - 1;
   
}
   
   
Gracz spPlayer;
   
spPlayer.setOrigin( 25.f, 25.f );
   
spPlayer.setPosition( 640, 360 );
   
sf::View kamera;
   
//kamera.setCenter (spPlayer.getPosition());
   
kamera.setSize( 1280.f, 720.f ); //(640.f, 360.f);
   
   
Stan start;
   
sf::Font font_menu;
   
font_menu.loadFromFile( "Marlboro.ttf" );
   
   
Guzik przycisk_start( "Start", sf::Color::White, font_menu, 100, sf::Vector2i( 550, 300 ) );
   
Guzik przycisk_exit( "Exit", sf::Color::White, font_menu, 100, sf::Vector2i( 550, 400 ) );
   
   
sf::Event e;
   
while( window.isOpen() )
   
{
       
while( window.pollEvent( e ) )
       
{
           
if( e.type == sf::Event::Closed )
           
{
               
window.close();
           
}
        }
       
//WYDARZENIA
       
switch( start )
       
{
       
case Menu:
           
{
               
if( przycisk_start.getGlobalBounds().contains( sf::Mouse::getPosition( window ).x, sf::Mouse::getPosition( window ).y ) )
               
{
                   
przycisk_start.setColor( sf::Color::Red );
                   
if( sf::Mouse::isButtonPressed( sf::Mouse::Left ) )
                   
{
                       
start = Game;
                   
}
                }
               
else
               
{
                   
przycisk_start.setColor( sf::Color::White );
               
}
               
if( przycisk_exit.getGlobalBounds().contains( sf::Mouse::getPosition( window ).x, sf::Mouse::getPosition( window ).y ) )
               
{
                   
przycisk_exit.setColor( sf::Color::Red );
                   
if( sf::Mouse::isButtonPressed( sf::Mouse::Left ) )
                   
{
                       
window.close();
                   
}
                }
               
else
               
{
                   
przycisk_exit.setColor( sf::Color::White );
               
}
               
if( sf::Keyboard::isKeyPressed( sf::Keyboard::Escape ) )
               
{
                   
window.close();
               
}
            }
//Menu wydarzenia
           
break;
       
case Game:
           
{
               
playerMove( spPlayer, kamera, heightmap, widthmap, Game, Game1, start );
               
if( spPlayer.getPosition().x ==( 16 * 100 ) )
               
{
                   
if( spPlayer.getPosition().y > 200 && spPlayer.getPosition().y < 300 )
                   
{
                       
start = Game1;
                       
spPlayer.setPosition( 25, 250 );
                   
}
                }
               
if( sf::Keyboard::isKeyPressed( sf::Keyboard::Num1 ) )
               
{
                   
start = Game1;
                   
spPlayer.setPosition( 50, 50 );
               
}
               
if( sf::Keyboard::isKeyPressed( sf::Keyboard::Escape ) )
               
{
                   
window.close();
               
}
               
if( sf::Keyboard::isKeyPressed( sf::Keyboard::Tab ) )
               
{
                   
start = Menu;
               
}
               
//kolizja(spPlayer, map1, map2);
           
} //game wydarzenia
           
break;
       
case Game1:
           
{
               
if( sf::Keyboard::isKeyPressed( sf::Keyboard::Num2 ) )
               
{
                   
start = Game;
                   
spPlayer.setPosition( 50, 50 );
               
}
               
playerMove( spPlayer, kamera, heightmap, widthmap, Game, Game1, start );
               
if( spPlayer.getPosition().x == 0 )
               
{
                   
if( spPlayer.getPosition().y > 200 && spPlayer.getPosition().y < 300 )
                   
{
                       
start = Game;
                       
spPlayer.setPosition( 1575, 250 );
                   
}
                }
            }
//game1 wydarzenia
           
break;
       
case Eq:
           
           
break;
       
} //switch wydarzenia
        //WYŒWIETLANIE
       
window.clear();
       
switch( start )
       
{
       
case Menu:
           
{
               
window.draw( przycisk_start );
               
window.draw( przycisk_exit );
           
}
           
break;
       
case Game:
           
{
               
kamera.setCenter( spPlayer.getPosition() );
               
window.draw( map1 );
               
window.draw( spPlayer );
               
window.setView( kamera );
           
} //case Game wyswietlanie
           
break;
       
case Game1:
           
{
               
kamera.setCenter( spPlayer.getPosition() );
               
window.draw( map2 );
               
window.draw( spPlayer );
               
window.setView( kamera );
           
} //case Game1 wyswietlanie
           
break;
       
case Eq:
           
           
break;
       
} //switch wyswietalnie
       
window.display();
   
}
}

tilemap.cpp
C/C++
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include "tilemap.hpp"

bool TileMap::load( const std::string & tileset, sf::Vector2u tileSize, const int * tiles, unsigned int width, unsigned int height )
{
   
//sf::Texture m_tileset;
    //Wczytywanie tekstur tileset
   
if( !m_tileset.loadFromFile( tileset ) )
   
{
       
return false;
   
}
   
//Level size
    //sf::VertexArray m_vertices;
   
m_vertices.setPrimitiveType( sf::Quads );
   
m_vertices.resize( width * height * 4 );
   
   
for( unsigned int i = 0; i < width; i++ )
   
{
       
for( unsigned int j = 0; j < height; j++ )
       
{
           
//pobieranie obecnego numeru tile
           
int tileNumber = tiles[ i + j * width ];
           
           
// find its position in the tileset texture
           
int tu = tileNumber %( m_tileset.getSize().x / tileSize.x );
           
int tv = tileNumber /( m_tileset.getSize().x / tileSize.x );
           
           
// get a pointer to the current tile's quad
           
sf::Vertex * quad = & m_vertices[( i + j * width ) * 4 ];
           
           
// define its 4 corners
           
quad[ 0 ].position = sf::Vector2f( i * tileSize.x, j * tileSize.y );
           
quad[ 1 ].position = sf::Vector2f(( i + 1 ) * tileSize.x, j * tileSize.y );
           
quad[ 2 ].position = sf::Vector2f(( i + 1 ) * tileSize.x,( j + 1 ) * tileSize.y );
           
quad[ 3 ].position = sf::Vector2f( i * tileSize.x,( j + 1 ) * tileSize.y );
           
           
// define its 4 texture coordinates
           
quad[ 0 ].texCoords = sf::Vector2f( tu * tileSize.x, tv * tileSize.y );
           
quad[ 1 ].texCoords = sf::Vector2f(( tu + 1 ) * tileSize.x, tv * tileSize.y );
           
quad[ 2 ].texCoords = sf::Vector2f(( tu + 1 ) * tileSize.x,( tv + 1 ) * tileSize.y );
           
quad[ 3 ].texCoords = sf::Vector2f( tu * tileSize.x,( tv + 1 ) * tileSize.y );
           
       
}
    }
   
return true;
}

void TileMap::draw( sf::RenderTarget & target, sf::RenderStates states ) const
{
   
// apply the transform
   
states.transform *= getTransform();
   
   
// apply the tileset texture
   
states.texture = & m_tileset;
   
   
// draw the vertex array
   
target.draw( m_vertices, states );
}
P-178615
DejaVu
» 2021-05-15 22:58:45
Frazy, które należy wpisać w wyszukiwarkę google:
P-178616
R0ut4
Temat założony przez niniejszego użytkownika
» 2021-05-16 13:20:26
Próbowałem coś wyłuskać z tych linków (zaszedłem aż na 3 stronę google XD) i nic nie dało rady. Osobne kody, łączenie kilku, zmiany w kodach, próby tworzenia nowego. Nic nie dałem rady zrobić xd
Wcześniej zapomniałem podać plik z danymi o levelu

leve.hpp
C/C++
#ifndef Levels_hpp
#define Levels_hpp

/*
0 = trawa
1 = woda
2 = drzewa
3 = most
*/
const int level[ ] =
{
   
0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   
0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 2, 0, 0, 0, 0,
   
1, 1, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
   
0, 1, 0, 0, 2, 0, 3, 3, 3, 0, 1, 1, 1, 0, 0, 0,
   
0, 1, 1, 0, 3, 3, 3, 0, 0, 0, 1, 1, 1, 2, 0, 0,
   
0, 0, 1, 0, 3, 0, 2, 2, 0, 0, 1, 1, 1, 1, 2, 0,
   
2, 0, 1, 0, 3, 0, 2, 2, 2, 0, 1, 1, 1, 1, 1, 1,
   
0, 0, 1, 0, 3, 2, 2, 2, 0, 0, 0, 0, 1, 1, 1, 1,
   
1, 1, 1, 1, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   
1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   
1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1,
   
1, 1, 1, 1, 1, 1, 3, 0, 0, 0, 0, 0, 0, 0, 2, 2,
   
1, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2,
   
1, 0, 0, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2,
   
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2,
   
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
const int level1[ ] =
{
   
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
   
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 1, 1, 0,
   
3, 3, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
   
1, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1,
   
1, 1, 3, 3, 3, 3, 3, 3, 2, 2, 0, 0, 0, 2, 2, 3,
   
0, 0, 1, 1, 1, 1, 1, 3, 3, 3, 0, 0, 0, 0, 0, 3,
   
0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3,
   
2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2,
   
2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2,
   
2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2,
   
0, 2, 1, 1, 1, 2, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2,
   
0, 2, 1, 1, 1, 2, 0, 0, 0, 0, 2, 2, 0, 0, 2, 2,
   
0, 2, 1, 1, 3, 0, 0, 0, 2, 2, 2, 0, 0, 0, 0, 2,
   
0, 2, 1, 1, 1, 2, 0, 0, 2, 2, 2, 0, 0, 0, 2, 2,
   
0, 2, 2, 2, 2, 2, 0, 0, 2, 0, 0, 0, 0, 2, 1, 1,
   
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 1, 1,
};
#endif  // Levels_hpp
P-178617
DejaVu
» 2021-05-16 18:43:30
Opcja pierwsza - przesuń obiekt i cofnij w przypadku kolizji:
C/C++
obiekt1.przesun();
if( obiekt1.czyJestKolizja( wszystkieObiekty ) )
   
 obiekt1.cofnijPrzesuniecie();

Opcja druga - sprawdź czy nowa pozycja jest pusta i jeżeli tak to wykonaj przesunięcie:
C/C++
if( wszystkieObiekty.czyPolePuste( obiekt1, nowaPozycja ) )
   
 obiekt1.ustawPozycje( nowaPozycja );

Może powinieneś zacząć od prostszego projektu, skoro ten sprawia tyle problemów. Zacznij np. od gier karcianych, sapera, tetrisa albo arkanoida. Mniejsza złożoność jest tych projektów, a i tak będziesz miał wystarczająco dużo wyzwań w projekcie.
P-178620
pekfos
» 2021-05-16 18:46:00
C/C++
sf::Vector2f pozycjaGracza, ruch;

if( !kolizjaZMapa( pozycjaGracza + ruch ) )
   
 pozycjaGracza += ruch;
Wystarczy zaimplementować sprawdzanie kolizji prostokąta (kafel mapy) z czymkolwiek jest gracz w tym programie.
P-178621
R0ut4
Temat założony przez niniejszego użytkownika
» 2021-05-16 21:27:07
Tylko nie mam pojęcia jak porównać pozycje (lub po prostu cały kafel) kafla z pozycją gracza. Tzn nie wiem jak pobrać pozycje danego kafla
P-178622
DejaVu
» 2021-05-16 21:42:28
No to są niestety proste if-y, więc jak tego nie ogarniasz to musisz wrócić do podstaw.
P-178623
pekfos
» 2021-05-16 23:25:18
Tzn nie wiem jak pobrać pozycje danego kafla
Rysujesz go na ekranie, więc jakoś pozycję określasz. Rozrysuj na papierze jak miałoby to działać, ostatecznie to matematyka. Póki nie masz planu, nie masz tu nic do programowania.
P-178624
« 1 » 2
  Strona 1 z 2 Następna strona