Ответ в теме: Проблема взаимодействия персонажа с картой.

SFML и C++ Уроки \ Разработка игр Форумы SFML Graphics Проблема взаимодействия персонажа с картой. Ответ в теме: Проблема взаимодействия персонажа с картой.

#3777

Nodira
Участник
Сообщений:2

Зарегистрирован:
13.05.2016

Репутация:0

Доброго времени суток. У меня проблема при взаимодействии с картой. точнее когда я, в метод update добавляю метод interactionWithMap(), то у меня при запуске появляется окно и все норм, но как только я нажимаю какую либо из клавиш, появляется какая то непонятная штука :( Посмотрите пожалуйста, а то я не могу найти причину:

 

#include <SFML/Graphics.hpp>
#include “map.h”
#include”view.h”
using namespace sf;
//класс игрока//
class Player { // класс Игрока
private: float x, y = 0;
public:
bool onGround, life;
float w, h, dx, dy, speed; //координаты игрока х и у, высота ширина, ускорение (по х и по у), сама скорость
int dir; //направление (direction) движения игрока
String File; //файл с расширением
Image image;//сфмл изображение
Texture texture;//сфмл текстура
Sprite sprite;//сфмл спрайт
Player(String F, float X, float Y, float W, float H) { //Конструктор с параметрами(формальными) для класса Player. При создании объекта класса мы будем задавать имя файла, координату Х и У, ширину и высоту
dx = 0; dy = 0; speed = 0; dir = 0;
File = F;//имя файла+расширение
w = W; h = H;//высота и ширина
image.loadFromFile(“images/” + File);//запихиваем в image наше изображение вместо File мы передадим то, что пропишем при создании объекта. В нашем случае “hero.png” и получится запись идентичная image.loadFromFile(“images/hero/png”);
image.createMaskFromColor(Color(41, 33, 59));//убираем ненужный темно-синий цвет, эта тень мне показалась не красивой.
texture.loadFromImage(image);//закидываем наше изображение в текстуру
sprite.setTexture(texture);//заливаем спрайт текстурой
x = X; y = Y;//координата появления спрайта
sprite.setTextureRect(IntRect(0, 0, w, h));
sprite.setTextureRect(IntRect(0, 0, w, h)); //Задаем спрайту один прямоугольник для вывода одного льва, а не кучи львов сразу. IntRect – приведение типов
}
void update(float time) //функция “оживления” объекта класса. update – обновление. принимает в себя время SFML , вследствие чего работает бесконечно, давая персонажу движение.
{
switch (dir)//реализуем поведение в зависимости от направления. (каждая цифра соответствует направлению)
{
case 0: dx = speed; dy = 0; break;//по иксу задаем положительную скорость, по игреку зануляем. получаем, что персонаж идет только вправо
case 1: dx = -speed; dy = 0; break;//по иксу задаем отрицательную скорость, по игреку зануляем. получается, что персонаж идет только влево
case 2: dx = 0; dy = -speed; break;//по иксу задаем нулевое значение, по игреку отрицательное. получается, что персонаж идет только вверх
}

x += dx*time;// наше ускорение на время получаем смещение координат и как следствие движение
y += dy*time;//аналогично по игреку

speed = 0;//зануляем скорость, чтобы персонаж остановился.

sprite.setPosition(x, y); //выводим спрайт в позицию x y , посередине. бесконечно выводим в этой функции, иначе бы наш спрайт стоял на месте.
interactionWithMap();//вызываем функцию, отвечающую за взаимодействие с картой
}

float getplayercoordinateX() { //этим методом будем забирать координату Х
return x;
}
float getplayercoordinateY() { //этим методом будем забирать координату Y
return y;
}
void interactionWithMap()//ф-ция взаимодействия с картой
{

for (int k = y / 32; k < (y + h)/32; k++)//проходимся по тайликам, контактирующим с игроком, то есть по всем квадратикам размера 32*32, которые мы окрашивали в 9 уроке. про условия читайте ниже.
for (int l = x / 32; l < (x + w)/32; l++)//икс делим на 32, тем самым получаем левый квадратик, с которым персонаж соприкасается. (он ведь больше размера 32*32, поэтому может одновременно стоять на нескольких квадратах). А j<(x + w) / 32 – условие ограничения координат по иксу. то есть координата самого правого квадрата, который соприкасается с персонажем. таким образом идем в цикле слева направо по иксу, проходя по от левого квадрата (соприкасающегося с героем), до правого квадрата (соприкасающегося с героем)
{
if (TileMap[k][l] == ‘0’)//если наш квадратик соответствует символу 0 (стена), то проверяем “направление скорости” персонажа:
{
if (dy>0)//если мы шли вниз,
{
y = k * 32 – h;//то стопорим координату игрек персонажа. сначала получаем координату нашего квадратика на карте(стены) и затем вычитаем из высоты спрайта персонажа.
}
if (dy<0)
{
y = k * 32 + 32;//аналогично с ходьбой вверх. dy<0, значит мы идем вверх (вспоминаем координаты паинта)
}
if (dx>0)
{
x = l * 32 – w;//если идем вправо, то координата Х равна стена (символ 0) минус ширина персонажа
}
if (dx < 0)
{
x = l * 32 + 32;//аналогично идем влево
}
}

}
}
};
int main() {

RenderWindow window(VideoMode(640, 480), “SFML Application”);
view.reset(sf::FloatRect(0, 0, 640, 480));//размер “вида” камеры при создании объекта вида камеры. (потом можем менять как хотим) Что то типа инициализации.
Image map_image;//объект изображения для карты
map_image.loadFromFile(“images/map.png”);//загружаем файл для карты
Texture map;//текстура карты
map.loadFromImage(map_image);//заряжаем текстуру картинкой
Sprite s_map;//создаём спрайт для карты
s_map.setTexture(map);//заливаем текстуру спрайтом
Player p(“hero.png”, 30, 388, 64.0, 64.0);//создаем объект p класса player,задаем “hero.png” как имя файла+расширение, далее координата Х,У, ширина, высота
float CurrentFrame = 0;//хранит текущий кадр
Clock clock;

while (window.isOpen()) {
float time = clock.getElapsedTime().asMicroseconds();
clock.restart();
time = time / 800;
Event event;
while (window.pollEvent(event)) {
if (event.type == Event::Closed)
window.close();
}
if (Keyboard::isKeyPressed(Keyboard::Left)) {
p.dir = 1; p.speed = 0.2;//dir =1 – направление вверх, speed =0.2 – скорость движения. Заметьте – время мы уже здесь ни на что не умножаем и нигде не используем каждый раз
CurrentFrame += 0.008*time;
if (CurrentFrame > 8) CurrentFrame -= 8;
p.sprite.setTextureRect(IntRect(64 * int(CurrentFrame), 128, 64, 64)); //через объект p класса player меняем спрайт, делая анимацию (используя оператор точку)
}
if ((Keyboard::isKeyPressed(Keyboard::Right) || (Keyboard::isKeyPressed(Keyboard::D)))) {
p.dir = 0; p.speed = 0.2;//направление вправо, см выше
CurrentFrame += 0.008*time;
if (CurrentFrame > 8) CurrentFrame -= 8;
p.sprite.setTextureRect(IntRect(64 * int(CurrentFrame), 0, 64, 64)); //через объект p класса player меняем спрайт, делая анимацию (используя оператор точку)
}
getPlayerCoorinateForView(p.getplayercoordinateX(), p.getplayercoordinateY());//передаем координаты игрока в функцию управления камерой
p.update(time);//оживляем объект p класса Player с помощью времени sfml, передавая время в качестве параметра функции update. благодаря этому персонаж может двигаться
//viewmap(time);//функция скроллинга карты, передаем ей время sfml
window.setView(view);//”оживляем” камеру в окне sfml
window.clear();
/////////////////////////////Рисуем карту/////////////////////
for (int i = 0; i < H_MAP; i++)
for (int j = 0; j < W_MAP; j++)
{
if (TileMap[i][j] == ‘ ‘) s_map.setTextureRect(IntRect(32, 0, 32, 32)); //если встретили символ пробел, то рисуем 1й квадратик
if (TileMap[i][j] == ‘s’) s_map.setTextureRect(IntRect(0, 0, 32, 32));//если встретили символ s, то рисуем 2й квадратик
if ((TileMap[i][j] == ‘0’)) s_map.setTextureRect(IntRect(64, 0, 32, 32));//если встретили символ 0, то рисуем 3й квадратик
s_map.setPosition(j * 32, i * 32);//по сути раскидывает квадратики, превращая в карту. то есть задает каждому из них позицию. если убрать, то вся карта нарисуется в одном квадрате 32*32 и мы увидим один квадрат

window.draw(s_map);//рисуем квадратики на экран
}
window.draw(p.sprite);//рисуем спрайт объекта p класса player
window.display();
}

}

Вложения:
You must be logged in to view attached files.