SFML и C++ Уроки \ Разработка игр › Форумы › SFML Graphics › Касание игрока с врагом, помогите
Помечено: intersect
В этой теме 5 ответов, 2 участника, последнее обновление KindRedSand 6 года/лет, 6 мес. назад.
-
АвторСообщения
-
Вообщем ничего не понимаю, я перепроверял всю программу, пробовал разные альтернативы, ничего не помогло, вообщем в 23 уроке сделал команды:
C++123456789101112131415161718192021222324252627282930313233for (it = entities.begin(); it != entities.end();){Entity *b = *it;b->update(time);if (b->life == false){it = entities.erase(it);delete b;}else it++;}for (it = entities.begin(); it != entities.end(); it++){if ((*it)->getRect().intersects(p.getRect()));{if ((*it)->name == "EasyEnemy"){if ((p.dy>0) && (p.onGround == false)){(*it)->dx = 0;p.dy -= 0.5;(*it)->health = 0;}else{/*p.dy -= 0.5;p.dx -= 0.5;*/p.health -= 25;}}}}Проблема в том, что при старте игры (игрок спавнится достаточно далеко от врага, ну я говорю про p.sprite;) у меня получается начинает все время срабатывать эти команды, игрок сразу умирает и в выведение здоровья очень быстро отнимаются жизни по 25 (p.health -= 25;), я перепроверил карту, враги расположены правильно, соответствуют своим координатам вот весь мой код:
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463#include <SFML/Graphics.hpp>#include <SFML/Audio.hpp>#include "view.h"#include <iostream>#include <sstream>#include "mission.h"#include "iostream"#include "level.h"#include <vector>#include <list>#include "tinyxml\tinyxml.h"using namespace sf;class Entity {public:std::vector<Object> obj;float dx, dy, x, y, speed, moveTimer;int w, h, health;bool life, isMove, onGround;Texture texture;Sprite sprite;String name;Entity(Image &image, float X, float Y, int W, int H, String Name) {x = X; y = Y; w = W; h = H; name = Name; moveTimer = 0;speed = 0;health = 100; dx = 0; dy = 0;life = true; onGround = false; isMove = false;texture.loadFromImage(image);sprite.setTexture(texture);sprite.setOrigin(w / 2, h / 2);}FloatRect getRect(){return FloatRect(x, y, w, h);}virtual void update(float time) = 0;};class Player :public Entity {public:enum { left, right, jump, stay } state;int playerScore;Music death;Music deathS;Music soundtrack;Music soundtrack2;Music claySong;//SoundBuffer cB; ЭТО МОЖЕТ ПОМОЧБ В ПРОБЛЕМЕ СО ЗВУКАМИ//Sound s;Player(Image &image, Level &lev, float X, float Y, int W, int H, String Name) :Entity(image, X, Y, W, H, Name){playerScore = 0; state = stay; obj = lev.GetAllObjects();//cB.loadFromFile("d");//s.setBuffer(cB);death.openFromFile("music/death.ogg");deathS.openFromFile("sounds/deathS.ogg"); deathS.setVolume(100);soundtrack.openFromFile("music/soundtrack.ogg"); soundtrack.setVolume(50);soundtrack2.openFromFile("music/soundtrack2.ogg");claySong.openFromFile("sounds/claySong.ogg");soundtrack.play(); soundtrack.setLoop(true);claySong.play(); claySong.setLoop(true);if (name == "Player1"){sprite.setTextureRect(IntRect(10, 306, w, h));}}void control() {if (life == true) {if (Keyboard::isKeyPressed(Keyboard::A)) {state = left;speed = 0.3;}if (Keyboard::isKeyPressed(Keyboard::D)) {state = right;speed = 0.3;}if ((Keyboard::isKeyPressed(Keyboard::Space) && (onGround == true))) {state = jump;dy = -0.5;//onGround = false;}}}void update(float time){control();switch (state) {case left: dx = -speed; break;case right: dx = speed; break;case jump: break;case stay: break;}x += dx*time;checkCollisionWithMap(dx, 0);y += dy*time;checkCollisionWithMap(0, dy);if (!isMove) speed = 0;sprite.setPosition(x + w / 2, y + h / 2);if (health <= 0) { life = false; }if (life == true) { getplayercoordinateforview(x, y); }dy = dy + 0.0015*time;}float getplayercoordinateX() {return x;}void checkCollisionWithMap(float Dx, float Dy) {onGround = false;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; onGround = true; }if (Dy<0) { y = obj[i].rect.top + obj[i].rect.height; dy = 0; }if (Dx>0) { x = obj[i].rect.left - w; }if (Dx<0) { x = obj[i].rect.left + obj[i].rect.width; }}if (obj[i].name == "lava"){if (Dy>0) { y = obj[i].rect.top - h; dy = 0; onGround = true; }if (Dy<0) { y = obj[i].rect.top + obj[i].rect.height; dy = 0; }if (Dx>0) { x = obj[i].rect.left - w; }if (Dx < 0) { x = obj[i].rect.left + obj[i].rect.width; }if (life = true) { life = false; }if (death.getStatus() == Sound::Playing){continue;}else {death.play();deathS.play();claySong.stop();soundtrack.stop();soundtrack2.stop();}}if (obj[i].name == "batut"){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; }if (Dx < 0) { x = obj[i].rect.left + obj[i].rect.width; }dy -= 1.5; onGround = false;}if (obj[i].name == "enemy"){soundtrack.stop();claySong.stop();if (soundtrack2.getStatus() == Sound::Playing) { continue; }else {soundtrack2.play();}sprite.setColor(Color(237, 28, 36));}/*if (obj[i].name == "poison"){}*/}}};class Enemy :public Entity{public:Enemy(Image &image, Level &lvl, float X, float Y, int W, int H, String Name) :Entity(image, X, Y, W, H, Name) {obj = lvl.GetObjects("solid");if (name == "EasyEnemy") {sprite.setTextureRect(IntRect(0, 0, w, h));dx = 0.1;}}void checkCollisionWithMap(float Dx, float Dy) {for (int i = 0; i<obj.size(); i++)if (getRect().intersects(obj[i].rect)){if (Dy>0) { y = obj[i].rect.top - h; dy = 0; onGround = true; }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) {if (name == "EasyEnemy"){//moveTime += time; if (moveTimer>3000) {dx*=-1; moveTimer = 0; }checkCollisionWithMap(dx, 0);x += dx*time;sprite.setPosition(x + w / 2, y + h / 2); // ЭТО КСТАТИ ЗАДАЕТ ПОЗИЦИЮ СПРАЙТА В КГО ЦЕНТРif (health <= 0) { life = false; }}}};int main(){sf::RenderWindow window(sf::VideoMode(1980, 1080), "Glinskii Adventures");view.reset(sf::FloatRect(0, 0, 640, 400));window.setFramerateLimit(90); // fpsLevel lvl;lvl.LoadFromFile("mainmap.tmx");Image heroImage;heroImage.loadFromFile("images/hero.jpg");heroImage.createMaskFromColor(Color(125, 99, 86));Image easyEnemyImage;easyEnemyImage.loadFromFile("images/enemy1.jpg");easyEnemyImage.createMaskFromColor(Color(255, 255, 255));/*Image map_image;map_image.loadFromFile("images/map.png");Texture map;map.loadFromImage(map_image);Sprite map_sprite;map_sprite.setTexture(map);Image house_image;house_image.loadFromFile("images/house.png");house_image.createMaskFromColor(Color(255, 255, 255));Texture house;house.loadFromImage(house_image);Sprite house_sprite;house_sprite.setTexture(house);house_sprite.setPosition(80, 539);*/Image quest_image;quest_image.loadFromFile("images/tab.jpg");Texture quest_texture;quest_texture.loadFromImage(quest_image);Sprite s_quest;s_quest.setTexture(quest_texture);s_quest.setTextureRect(IntRect(0, 0, 224, 352));/*Image map2;map2.loadFromFile("images/map2.png");Texture map2texture;map2texture.loadFromImage(map2);Sprite map2s;map2s.setTexture(map2texture);*/Object player = lvl.GetObject("player");//Object easyEnemyObject = lvl.GetObject("easyEnemy");/*SoundBuffer lowhpBuffer;lowhpBuffer.loadFromFile("sounds/lowhp.ogg");Sound lowhp(lowhpBuffer);*//*SoundBuffer walkBuffer;walkBuffer.loadFromFile("sounds/walk.ogg");Sound walk(walkBuffer);walk.setVolume(100);*/Font font;font.loadFromFile("fonts/classic.TTF");Text text("", font, 20);text.setStyle(Text::Bold);Text pickText("", font, 20);pickText.setStyle(Text::Bold);Text text2("", font, 20);text2.setStyle(Text::Bold);Text glinPlate("", font, 20);glinPlate.setStyle(Text::Bold);glinPlate.setStyle(Text::Underlined);Text nickname("", font, 20);std::list<Entity*> entities;std::list<Entity*>::iterator it;std::vector<Object> e = lvl.GetObjects ("EasyEnemy");for (int i = 0; i < e.size(); i++)entities.push_back(new Enemy(easyEnemyImage, lvl, e[i].rect.left, e[i].rect.top, 79, 59, "EasyEnemy"));Player p(heroImage, lvl, player.rect.left, player.rect.top, 70, 86, "Player1");//Enemy easyEnemy(easyEnemyImage, lvl, easyEnemyObject.rect.left, easyEnemyObject.rect.top, 79, 59, "EasyEnemy");//float CurrentFrame = 0;Clock clock;Clock gameTimeClock;int gameTime = 0;bool showMissionText = true;while (window.isOpen()){float time = clock.getElapsedTime().asMicroseconds();clock.restart();time = time / 800;if (p.life == true) gameTime = gameTimeClock.getElapsedTime().asSeconds();else {p.sprite.setColor(Color(235, 65, 7));view.zoom(0.997);view.move(0, 0.05);view.move(0.07, 0);view.rotate(0.05);}sf::Event event;while (window.pollEvent(event)){window.setKeyRepeatEnabled(false);if (event.type == sf::Event::Closed)window.close();/*if (p.life == true){if ((event.type == Event::KeyPressed) && (event.key.code == Keyboard::D)){walk.play();}}*//*if (p.life == false) {if (death.getStatus() == Sound::Playing) {continue;}else{soundtrack.stop();claySong.stop();death.play();deathS.play();}}*/if (event.type == Event::KeyPressed)if ((event.key.code == Keyboard::Tab)){switch (showMissionText){case true:{std::ostringstream task;task << getTextMission(getCurrentMission(p.getplayercoordinateX()));text2.setString("\n" + task.str());showMissionText = false;glinPlate.setString("Глиняная плита гласит:");nickname.setString("XxX_Daun_XxX");break;}case false:{text2.setString("");showMissionText = true;break;}}}}p.update(time);for (it = entities.begin(); it != entities.end();){Entity *b = *it;b->update(time);if (b->life == false){it = entities.erase(it);delete b;}else it++;}for (it = entities.begin(); it != entities.end(); it++){if ((*it)->getRect().intersects(p.getRect()));{if ((*it)->name == "EasyEnemy"){if ((p.dy>0) && (p.onGround == false)){(*it)->dx = 0;p.dy -= 0.5;(*it)->health = 0;}else{/*p.dy -= 0.5;p.dx -= 0.5;*/p.health -= 25;}}}}/*for (it = entities.begin(); it != entities.end(); it++) {(*it)->update(time);}*/changeview();window.setView(view);window.clear();lvl.Draw(window);std::ostringstream playerHealthString, gameTimeString;playerHealthString << p.health; gameTimeString << gameTime;text.setString("Здоровье: " + playerHealthString.str() + "\nВремя игры: " + gameTimeString.str());text.setPosition(view.getCenter().x - 315, view.getCenter().y - 200);window.draw(text);std::ostringstream playerScoreString;playerScoreString << p.playerScore;pickText.setString("Собрано обьектов: " + playerScoreString.str());pickText.setPosition(view.getCenter().x + 140, view.getCenter().y - 200);window.draw(pickText);if (!showMissionText){text2.setPosition(view.getCenter().x - 315, view.getCenter().y - 100);s_quest.setPosition(view.getCenter().x - 320, view.getCenter().y - 100);glinPlate.setPosition(view.getCenter().x - 315, view.getCenter().y - 100);nickname.setPosition(view.getCenter().x - 20, view.getCenter().y);window.draw(s_quest); window.draw(text2); window.draw(glinPlate); window.draw(nickname);}for (it = entities.begin(); it != entities.end(); it++) {window.draw((*it)->sprite);}window.draw(p.sprite);window.display();}return 0;}На всякий случай уточню, игрок не пересекается с врагом, все начинается сразу при запуске, и враги исчезают с карты, если же я уберу команду пересечения (for it entities… if *it->getRect.intersects) то все будет работать нормально, в чем проблема?
Вобще – учитесь с самого начала пользоватся дебагом, гораздо упрощает жизнь в отлове ошибок. Понаставляйте отметок останова в циклах и через шаг с обходом смотрите на каком моменте игрок теряет хп даже не пересекаясь.
И не проще вместо
sprite.setPosition(x+w/2,y+h/2);
использовать единожды в конструкторе
sprite.setOrigin(w/2,h/2);
и дальше спокойно использовать sprite.setPosition(x,y);Расскажите, как пользоваться дебагом, потому что в интернете есть только вопроссы про компиляцию в проекте в режиме релиз и дебаг, что за отметки мне стоит выставлять? Я пока не очень понимаю
Точки дебаг останова активируются нажатием ЛКМ в столбце напротив строки где нужно вызвать ‘паузу’ приложения.
Студия в момент дебаг остнова. Думаю не нужно обьяснять что делает кнопка продолжить. Убрать точку останова можно так же как и поставили – ЛКМ по ней.Господи, это такой треш, короче я с того момента так ничего и не придумал, спрашивал на английских форумах, там все предлагали перепроверить либы, один вообще говорил, что у меня итератор удаляется слишком рано, вообщем я отчаялся, но вдруг пересматривая уже в последний раз код я заметил это, у меня было написано if (p.getRect().intersects((*iter1)->getRect()));
что-то подозрительная точка с запятой, ОНА МЕШАЛА ПРОВЕРКИ ПЕРЕСЕЧЕНИЯ и в итоге все команды снизу начинали выполняться обходя, жесть полная, столько было теорий, даже какие-то совсем непонятные вещи мне говорили
Человеческий фактор никогда не отменялся. Странно что IntelliSense не маячит об этом…
-
АвторСообщения
Для ответа в этой теме необходимо авторизоваться.