SFML и C++ Уроки \ Разработка игр › Форумы › SFML System, Window и другие вопросы › Урок 20 SFML Притяжение персонажа к земле
В этой теме 2 ответа, 3 участника, последнее обновление MicroSDA 8 года/лет, 2 мес. назад.
Просмотр 3 сообщений - с 1 по 3 (из 3 всего)
-
АвторСообщения
-
Буду очень признателен за помощь. Всё было хорошо и решаемо до этого урока. Прилагаю свой код вместе с ошибкой которая выбивается при компиляции. MVS 2010.
C++123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198#include <SFML/Graphics.hpp>#include "map.h"#include "view.h"#include <iostream>#include <sstream>#include "level.h"#include <vector>#include <list>using namespace sf;class Player { // класс Игрокаprivate:float x, y;public:float w, h, dx, dy, speed; //координаты игрока х и у, высота ширина, ускорение (по х и по у), сама скоростьint dir; //направление (direction) движения игрокаint playerScore, health;bool life, isMove,isSelect,onGround;enum { left,right,up,down,jump,stay } state;//добавляем тип перечисления - состояние объектаString File; //файл с расширениемImage image;//сфмл изображениеTexture texture;//сфмл текстураSprite sprite;//сфмл спрайтPlayer(String F, float X, float Y, float W, float H){life = true; isMove = false; isSelect = false; onGround = false;speed = 0;dir = 0;playerScore = 0;health = 100;File = F;w = W;h = H;image.loadFromFile("images/" + File);texture.loadFromImage(image);sprite.setTexture(texture);x = X;y = Y;sprite.setTextureRect(IntRect(0, 0, w, h));sprite.setOrigin(w/2, h/2);}void update(float time){control();//функция управления персонажемswitch (state)//тут делаются различные действия в зависимости от состояния{case right: dx = speed;break;//состояние идти вправоcase left: dx = -speed;break;//состояние идти влевоcase up: break;//будет состояние поднятия наверх (например по лестнице)case down: break;//будет состояние во время спуска персонажа (например по лестнице)case jump: break;//здесь может быть вызов анимацииcase stay: break;//и здесь тоже}x += dx*time;checkCollisionWithMap(dx, 0);//обрабатываем столкновение по Хy += dy*time;checkCollisionWithMap(0, dy);//обрабатываем столкновение по Yif (!isMove) speed = 0;sprite.setPosition(x+w/2, y+h/2); //задаем позицию спрайта в место его центраif (health <= 0){life = false;}dy = dy + 0.0015*time;//делаем притяжение к земле}void checkCollisionWithMap(float Dx, float Dy)//ф ция проверки столкновений с картой{for (int i = y / 32; i < (y + h) / 32; i++)//проходимся по элементам картыfor (int j = x / 32; j<(x + w) / 32; j++){if (TileMap[i][j] == '0')//если элемент наш тайлик земли? то{if (Dy>0){y = i * 32 - h; dy = 0; onGround = true; }//по Y вниз=>идем в пол(стоим на месте) или падаем. В этот момент надо вытолкнуть персонажа и поставить его на землю, при этом говорим что мы на земле тем самым снова можем прыгатьif (Dy<0){y = i * 32 + 32; dy = 0;}//столкновение с верхними краями карты(может и не пригодиться)if (Dx>0){x = j * 32 - w;}//с правым краем картыif (Dx<0){x = j * 32 + 32;}// с левым краем карты} else {onGround=false;}if (TileMap[i][j] == 'f') {health-=40;//если взяли ядовитейший в мире цветок,то переменная health=health-40;TileMap[i][j] = ' ';//убрали цветок}if (TileMap[i][j] == 'h') {health += 20;//если взяли сердечко,то переменная health=health+20;TileMap[i][j] = ' ';//убрали сердечко}}}void control(){if (Keyboard::isKeyPressed(Keyboard::Left)){state = left; speed = 0.1;//CurrentFrame += 0.005*time;//if (CurrentFrame > 8) CurrentFrame -= 8;//p.sprite.setTextureRect(IntRect(35*int(CurrentFrame)+35, 49, -35, 48));}if (Keyboard::isKeyPressed(Keyboard::Right)){state = right; speed = 0.1;//CurrentFrame += 0.005*time;//if (CurrentFrame > 8) CurrentFrame -= 8;//p.sprite.setTextureRect(IntRect(35*int(CurrentFrame), 49, 35, 48));}if (Keyboard::isKeyPressed(Keyboard::Up) && (onGround)){state = jump; dy = -0.5; onGround = false;//CurrentFrame += 0.005*time;//if (CurrentFrame > 1) CurrentFrame -= 1;//p.sprite.setTextureRect(IntRect(32*int(CurrentFrame), 0, 32, 48));}if (Keyboard::isKeyPressed(Keyboard::Down)){state = down; speed = 0.1;//CurrentFrame += 0.005*time;//if (CurrentFrame > 1) CurrentFrame -= 1;//p.sprite.setTextureRect(IntRect(32*int(CurrentFrame), 0, 32, 48));}}float getplayercoordinateX(){ //этим методом будем забирать координату Хreturn x;}float getplayercoordinateY(){ //этим методом будем забирать координату Yreturn y;}};int main(){RenderWindow window(VideoMode(800, 400), "Game");view.reset(sf::FloatRect(0, 0, 800, 400));//размер "вида" камеры при создании объекта вида камеры. (потом можем менять как хотим) Что то типа инициализации.Font font;//шрифтfont.loadFromFile("CyrilicOld.ttf");//передаем нашему шрифту файл шрифтаText text("", font, 20);//создаем объект текст. закидываем в объект текст строку, шрифт, размер шрифта(в пикселях);//сам объект текст (не строка)text.setColor(Color::Black);//покрасили текст в красный. если убрать эту строку, то по умолчанию он белыйtext.setStyle(Text::Bold | Text::Underlined);//жирный и подчеркнутый текст. по умолчанию он "худой":)) и не подчеркнутыйImage map_image;//объект изображения для картыmap_image.loadFromFile("images/map.png");//загружаем файл для картыTexture map;//текстура картыmap.loadFromImage(map_image);//заряжаем текстуру картинкойSprite s_map;//создаём спрайт для картыs_map.setTexture(map);//заливаем текстуру спрайтомPlayer p("Knuckles the Echidna.png", 32, 32, 32.0, 48.0);float CurrentFrame = 0;Clock clock;Clock gameTimeClock;//переменная игрового времени, будем здесь хранить время игрыint gameTime = 0;//объявили игровое время, инициализировали.while (window.isOpen()){float time = clock.getElapsedTime().asMicroseconds();if (p.life) gameTime=gameTimeClock.getElapsedTime().asSeconds();//игровое время в секундах идёт вперед, пока жив игрок, перезагружать как time его не надо. оно не обновляет логику игрыclock.restart();time = time / 800;Event event;while (window.pollEvent(event)){if (event.type == Event::Closed)window.close();}float coordinatePlayerX, coordinatePlayerY = 0;coordinatePlayerX = p.getplayercoordinateX();coordinatePlayerY = p.getplayercoordinateY();if (p.dir = 4){CurrentFrame += 0.004*time;if (CurrentFrame > 21) CurrentFrame -= 21;p.sprite.setTextureRect(IntRect(32*int(CurrentFrame), 0, 32, 48));}getplayercoordinateforview(coordinatePlayerX, coordinatePlayerY);p.update(time);window.setView(view);window.clear();/////////////////////////////Рисуем карту/////////////////////for (int i = 0; i < HEIGHT_MAP; i++)for (int j = 0; j < WIDTH_MAP; j++){if (TileMap[i][j] == ' ') s_map.setTextureRect(IntRect(0, 0, 32, 32)); //если встретили символ пробел, то рисуем 1й квадратикif (TileMap[i][j] == 's') s_map.setTextureRect(IntRect(32, 0, 32, 32));//если встретили символ s, то рисуем 2й квадратикif (TileMap[i][j] == '0') s_map.setTextureRect(IntRect(64, 0, 32, 32));//если встретили символ 0, то рисуем 3й квадратикif ((TileMap[i][j] == 'f')) s_map.setTextureRect(IntRect(96, 0, 32, 32));//добавили цветокif ((TileMap[i][j] == 'h')) s_map.setTextureRect(IntRect(128, 0, 32, 32));//и сердечкоs_map.setPosition(j * 32, i * 32);//по сути раскидывает квадратики, превращая в карту. то есть задает каждому из них позицию. если убрать, то вся карта нарисуется в одном квадрате 32*32 и мы увидим один квадратwindow.draw(s_map);//рисуем квадратики на экран}std::ostringstream playerHealthString, gameTimeString; // объявили переменнуюplayerHealthString << p.health; gameTimeString << gameTime; //занесли в нее число здоровья, то есть формируем строкуtext.setString("Здоровье: " + playerHealthString.str() + " :|: Время в игре: " + gameTimeString.str());//задаем строку тексту и вызываем сформированную выше строку методом .str()text.setPosition(view.getCenter().x-370, view.getCenter().y-200);//задаем позицию текста, отступая от центра камерыwindow.draw(text);//рисую этот текстwindow.draw(p.sprite);window.display();}return 0;}Вложения:
You must be logged in to view attached files.где-то выход за пределы массива/карты.
или игра проседает по фпс , персонаж проваливается и в итоге ошибка. попробуйте убрать столкновение персонажа с картой, будет ли работать?Если гравитация обрабатывается после колижжина то такое в полне возможно но с учетом того что код большой.
-
АвторСообщения
Просмотр 3 сообщений - с 1 по 3 (из 3 всего)
Для ответа в этой теме необходимо авторизоваться.