SFML и C++ Уроки \ Разработка игр › Форумы › SFML System, Window и другие вопросы › Проблемы с обработкой столкновений с объектами при использовании tinyXML(урок22)
Помечено: TinyXML, столкновения
В этой теме 5 ответов, 2 участника, последнее обновление stunage 7 года/лет, 8 мес. назад.
-
АвторСообщения
-
Такая проблема… вроде во всём следую урокам, и всё до недавних пор вполне себе получалось. Не без косяков, но получалось. А тут такая неудача. Не обрабатываются, так сказать, столкновения. Карта загрузилась, персонаж и враг двигаются, но обработка solid стенок не происходит чуть менее, чем никак.
Вот сама функция обработки столкновений, так же прикрепляю саму картуC++1234567891011121314void checkCollisionWithMap(float Dx, float Dy){for (int i = 0; i < obj.size();i++)if (getRect().intersects(obj[i].rect)){if (obj[i].name == "solid"){if (Dy>0) { y = obj[i].rect.top - h; dy = 0; }if (Dy<0) { y = obj[i].rect.top + obj[i].rect.height; dy = 0; }if (Dx>0) { x = obj[i].rect.left - w; dx = 0; }if (Dx<0) { x = obj[i].rect.left + obj[i].rect.width; dx = 0; }}}}когда пошагово прогонял, у меня как-то игнорировалась вот эта строка.
Даже если её закомментировать, ничего не меняется. Я не понимаю, что я делаю не так
C++1if (getRect().intersects(obj[i].rect))C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240#include <vector>#include <map>#include <SFML/Graphics.hpp>#include <sstream>#include "map.h"#include "view.h"#include "iostream"#include "level.h"#include <list>#include <vector>using namespace sf;using namespace std;RectangleShape Rectangle(Vector2f(32, 32));class Entity{public:vector<Object>obj;float dx, dy, x, y, speed, moveTimer;float CurrentFrame = 0;int w, h, health;bool life, isMove;Texture texture;Sprite sprite;String name;Entity(Image &image, String Name, float X, float Y, int W, int H){x = X; y = Y; w = W; h = H; name = Name; moveTimer = 0;speed = 0; health = 15; dx = 0; dy = 0;life = true; isMove = false;texture.loadFromImage(image);sprite.setTexture(texture);sprite.setOrigin(w / 2, h / 2);}FloatRect getRect(){return FloatRect(x, y, w, h);}};class Player: public Entity{public:enum{ left, right, up, down, stay } state;Player(Image &image, String Name, Level&lev, float X, float Y, int W, int H) :Entity(image, Name, X, Y, W, H){state = stay;sprite.setTextureRect(IntRect(0, 0, w, h));obj = lev.GetAllObjects();}void update(float time){if(life)control(time);switch (state){case right:dx = speed; dy = 0; break;case left:dx = -speed; dy = 0; break;case up:dx = 0; dy = -speed; break;case down:dx = 0; dy = speed; break;case stay: break;}x += dx*time;checkCollisionWithMap(dx, 0);y += dy*time;checkCollisionWithMap(0, dy);if (!isMove)speed = 0;sprite.setPosition(x , y );if (health <= 0){ life = false; }if (life){ getplayercoordinateforview(x, y); }}void control(float time){if (Keyboard::isKeyPressed(Keyboard::Left)){state = left; speed = 0.1;sprite.setTextureRect(IntRect(32 * int(CurrentFrame), 32, 32, 32));CurrentFrame += 0.005*time;if (CurrentFrame > 3)CurrentFrame -= 3;exit;} elseif (Keyboard::isKeyPressed(Keyboard::Right)){state = right; speed = 0.1;sprite.setTextureRect(IntRect(32 * int(CurrentFrame), 64, 32, 32));CurrentFrame += 0.005*time;if (CurrentFrame > 3)CurrentFrame -= 3;exit;} elseif (Keyboard::isKeyPressed(Keyboard::Up)){state = up; speed = 0.1;sprite.setTextureRect(IntRect(32 * int(CurrentFrame), 96, 32, 32));CurrentFrame += 0.005*time;if (CurrentFrame > 3)CurrentFrame -= 3;exit;} elseif (Keyboard::isKeyPressed(Keyboard::Down)){state = down; speed = 0.1;sprite.setTextureRect(IntRect(32 * int(CurrentFrame), 0, 32, 32));CurrentFrame += 0.005*time;if (CurrentFrame > 3)CurrentFrame -= 3;exit;}}void checkCollisionWithMap(float Dx, float Dy){for (int i = 0; i < obj.size();i++)if (getRect().intersects(obj[i].rect)){if (obj[i].name == "solid"){cout << h<<" "<<w<<"/n";if (Dy>0) { y = obj[i].rect.top - h; dy = 0; }if (Dy<0) { y = obj[i].rect.top + obj[i].rect.height; dy = 0; }if (Dx>0) { x = obj[i].rect.left - w; dx = 0; }if (Dx<0) { x = obj[i].rect.left + obj[i].rect.width; dx = 0; }}}}float getplayercoordinateX(){ return x; }float getplayercoordinateY(){ return y; }};class Enemy : public Entity{public:Enemy(Image &image, String Name, Level &lvl, float X, float Y, int W, int H) :Entity(image, Name, X, Y, W, H){obj = lvl.GetObjects("solid");sprite.setTextureRect(IntRect(0, 0, w, h));dx = 0.05;//даем скорость.этот объект всегда двигается}void checkCollisionWithMap(float Dx, float Dy, float time){for (int i = 0; i<obj.size(); i++)//проходимся по объектамif (getRect().intersects(obj[i].rect))//проверяем пересечение игрока с объектом{if (obj[i].name == "solid")//если встретили препятствие{if (Dy>0) { y = obj[i].rect.top - h; dy = 0; }if (Dy<0) { y = obj[i].rect.top + obj[i].rect.height; dy = 0; }if (Dx>0) { x = obj[i].rect.left - w; dx = -0.1; sprite.scale(-1, 1); }if (Dx<0) { x = obj[i].rect.left + obj[i].rect.width; dx = 0.1; sprite.scale(-1, 1); }}}}void update(float time){moveTimer += time; if (moveTimer>3000){sprite.scale(-1, 1); dx *= -1; moveTimer = 0;}sprite.setTextureRect(IntRect(32 * int(CurrentFrame), 64, 32, 32));CurrentFrame += 0.005*time;if (CurrentFrame > 3)CurrentFrame -= 3;checkCollisionWithMap(dx, 0, time);if(life)x += dx*time;sprite.setPosition(x , y);if (health <= 0){ life = false; }}};int main(){char num = '0';Font font;font.loadFromFile("ALGER.ttf");Text text("", font, 20);text.setColor(Color::Red);RenderWindow window(sf::VideoMode(800, 600), "Dungeon test");view.reset(FloatRect(0, 0, 800, 600));Level lvl;lvl.LoadFromFile("map.tmx");Image map_image;map_image.loadFromFile("images/maps.png");Texture map;map.loadFromImage(map_image);Sprite s_map;s_map.setTexture(map);Image Bobimage;Bobimage.loadFromFile("Images/testhero.png");Image Lol;Lol.loadFromFile("Images/testhero.png");Object player = lvl.GetObject("player");Object LalkaObject = lvl.GetObject("Lalka");Player Bob(Bobimage, "Player", lvl, player.rect.left, player.rect.top, 11, 6);Enemy Lalka(Lol, "Lalka", lvl, LalkaObject.rect.left, LalkaObject.rect.top, 6, 6);text.setPosition(view.getCenter().x - 165, view.getCenter().y - 200);//задаем позицию текста, отступая от центра камерыfloat CurrentFrame = 0;Clock clock;while (window.isOpen()){ostringstream PlayerHealthString;PlayerHealthString << Bob.health;text.setString("Health:" + PlayerHealthString.str());//задаем строку тексту и вызываем сформированную выше строку методом .str()window.draw(text);//рисую этот текстfloat time = clock.getElapsedTime().asMicroseconds();clock.restart();time = time / 700;Event event;while (window.pollEvent(event)){if (event.type == Event::Closed)window.close();}////////////////////////Controlings with animations//////////////////////////Bob.update(time);Lalka.update(time);window.setView(view);window.clear();lvl.Draw(window);///////////Map drawing//////////text.setPosition(view.getCenter().x + 230, view.getCenter().y + -300);window.draw(Bob.sprite);window.draw(Lalka.sprite);window.draw(text);window.display();}return 0;}Ладно, вопрос решил) протупил в одном моменте
Только осталась одна проблема – если сверху подходить к объекту, он наполовину на него заезжает, а с других сторон – нет.(игра с видом сверху)
Прикрепляю весь main.cpp
Буду премного признателен, если мне укажут на мою ошибкуВложения:
You must be logged in to view attached files.возможно где то стоит setOrigin (пополам) , а где то не стоит setPosition (х+ширина/2, у+высота/2). что то в эту сторону смотреть надо
Да, setPosition не был поделён пополам, так сказать(просто были х,у), однако после правки проблем прибавилось, в общем слева и сверху всё равно проходит на полтайла в стены, справа и снизу всё в порядке.
ох, да уж, ну и глупенький я. Зря только тему развивал) Оказалось, я просто неверно указал размер тайла персонажа
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.