Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> реализация волнового алгоритма 
:(
    Опции темы
lenarano
Дата 22.10.2015, 20:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 17.4.2014

Репутация: нет
Всего: нет



Делаю игру Пакман
В Игре имеются следующие классы
Map.h
Код

#ifndef MAP_H
#define MAP_H


#include <SFML\Graphics.hpp>

const int HEIGHT_MAP=25;
const int WIDTH_MAP=28;


static sf::String TileMap[HEIGHT_MAP]={
    "0000000000000000000000000000",
    "0                          0",
    "0                          0",
    "0  0 s0   0      0   0s 0  0",
    "0  0000   0mmmmmm0   0000  0",
    "0  0  0   00000000   0  0  0",
    "0                          0",
    "0                          0",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "t         00000000         T",
    "t                          T",
    "t                          T",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "0         00000000         0",
    "0                          0",
    "0  0  0              0  0  0",
    "0  0000   00000000   0000  0",
    "0  0 s0              0s 0  0",
    "0                          0",
    "0                          0",
    "0000000000000000000000000000",
};




#endif MAP_H

Entity.h и Entity.cpp
Код

#ifndef ENTITY_H
#define ENTITY_H
 
 
#include <SFML/Graphics.hpp>
#include "map.h"
 
 
 
class Entity{
public: 
 
    float px,py;
    float dx,dy,x,y,w,h,speed;
    enum {left,right,up,down,stay} state;//состояние обьекта
    bool life;
    sf::Texture texture;
    sf::Sprite sprite;
    sf::String name;
    Entity::Entity(sf::Image &image,sf::String Name, float X,float Y, float W, float H);
 
    sf::FloatRect getRect();
 
    virtual void update(float time) = 0;
 
    void getPlayerCoord(float X,float Y);
 
    };
 
#endif ENTITY_H
 
 
#include "Entity.h"
 
 
Entity::Entity(sf::Image &image,sf::String Name, float X,float Y, float W, float H){
        name=Name; x=X; y=Y; w=W; h=H;
        speed=0;dx=0; dy=0;
        life=true;
        texture.loadFromImage(image);
        sprite.setTexture(texture);
        sprite.setOrigin(w/2,h/2);
    }
 
sf::FloatRect Entity::getRect(){//ф-ция получения прямоугольника. его коорд,размеры (шир,высот).
        return sf::FloatRect(x, y, w, h);//эта ф-ция нужна для проверки столкновений 
    }
 
void Entity::getPlayerCoord(float X,float Y)
    {
        px=X;
        py=Y;
    }


Player.h и Player.cpp
Код

#ifndef PLAYER_H
#define PLAYER_H
 
 
 
#include "Entity.h"
#include "View.h"
 
 
 
class Player:public Entity{
public:
    int health,counter,createObjectForMapTimer,counterBonus,counterGoldIngot;
    float CurrentFrame;
    bool killer,bonus;
    
    Player(std::shared_ptr<sf::View> view, sf::Image &image,sf::String Name,float X, float Y, float W, float H);
 
    void control();
    
    void update(float time);
 
    void interactionWithMap();
    void randomMapGenerate();
    float GetPlayercoordinateX(){return x;}
    float GetPlayercoordinateY(){return y;}
private:
    std::shared_ptr<sf::View> m_view;
};
#endif PLAYER_H
//Player.cpp реализация 



Собственно класс Врага по которому вопрос
Код

#ifndef ENEMY_H
#define ENEMY_H
 
#include "Entity.h"
 
 
 
 
class Enemy:public Entity{
    int zq,timer; 
public:
    Enemy (sf::Image &image,sf::String Name,float X, float Y, float W, float H): Entity(image,Name,X,Y,W,H){
        zq=1;state=left;timer=0;int maps[30][30]={0};
        if(name=="EasyEnemy"){
            sprite.setTextureRect(sf::IntRect(0,0,w,h));
 
        }
    }
 
    void checkCollisionWithMap()//ф ция проверки столкновений с картой
    {
        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;}
                    if (dy<0){y = i * 32 + 32;}
                    if (dx>0){x = j * 32 - w;}
                    if (dx < 0){x = j * 32 + 32;}
                }
            }
    }
 
 
    void update(float time)
    {
        if (name == "EasyEnemy"){//для персонажа с таким именем логика будет такой
            //timer+=time;
            //if (timer+1000>1000) {zq=rand()%3;}
            //if (timer>500) {if (zq==0)  {if (x>px) {speed=0.1,state=left; timer=0;} {if (y>py) {speed=0.1,state=up; timer=0;} }}}
            //if (timer>500) {if (zq==1)  {if (x<px) {speed=0.1,state=right; timer=0;} {if (y<py) {speed=0.1,state=down; timer=0;} }}}
 
 
            switch(state)
            {
            case right: dx=speed; dy=0;  break;
            case left: dx=-speed; dy=0;  break;
            case down: dx=0; dy=speed; break;
            case up: dx=0; dy=-speed;   break;
            case stay:break;
            }
 
            x += dx*time;
            y += dy*time;
            checkCollisionWithMap();
            void find_path(int HEIGHT_MAP,int WIDTH_MAP );
            sprite.setPosition(x + w / 2, y + h / 2); //задаем позицию спрайта в место его центра
 
        }
    }
 
    void find_path(int N,int M)
{
    struct t{
        int x, y;
    };
    t Q[10000], S, G;
    int i_st=0, i_end=1, t, i, j, a[100][100]={0};
    for(i=0; i<N; i++)
        for(j=0; j<M; j++)
        {
            if(TileMap[i][j]=='G') {G.x=i; G.y=j;}
            if(TileMap[i][j]=='S') {S.x=i; S.y=j;}
        }
    a[G.x][G.y]=1;
    Q[0].x=G.x; Q[0].y=G.y;
    while(i_st<i_end)
    {
        if(a[Q[i_st].x-1][Q[i_st].y]==0 && TileMap[Q[i_st].x-1][Q[i_st].y]!='0')
        {
            Q[i_end].x=Q[i_st].x-1; Q[i_end++].y=Q[i_st].y;
            a[Q[i_st].x-1][Q[i_st].y]=a[Q[i_st].x][Q[i_st].y]+1;
        }
        if(a[Q[i_st].x+1][Q[i_st].y]==0 && TileMap[Q[i_st].x+1][Q[i_st].y]!='0')
        {
            Q[i_end].x=Q[i_st].x+1; Q[i_end++].y=Q[i_st].y;
            a[Q[i_st].x+1][Q[i_st].y]=a[Q[i_st].x][Q[i_st].y]+1;
        }
        if(a[Q[i_st].x][Q[i_st].y-1]==0 && TileMap[Q[i_st].x][Q[i_st].y-1]!='0')
        {
            Q[i_end].x=Q[i_st].x; Q[i_end++].y=Q[i_st].y-1;
            a[Q[i_st].x][Q[i_st].y-1]=a[Q[i_st].x][Q[i_st].y]+1;
        }
        if(a[Q[i_st].x][Q[i_st].y+1]==0 && TileMap[Q[i_st].x][Q[i_st].y+1]!='0')
        {
            Q[i_end].x=Q[i_st].x; Q[i_end++].y=Q[i_st].y+1;
            a[Q[i_st].x][Q[i_st].y+1]=a[Q[i_st].x][Q[i_st].y]+1;
        }
        i_st++;
    }
    if(a[S.x][S.y]==0)
       std:: cout<<"No way"<<std::endl;
    else
    {
        t=a[S.x][S.y];
        while(t>1)
        {
            if(a[S.x-1][S.y]==t-1)
            {
                TileMap[S.x-1][S.y]='+';
                S.x--; t--;
            }
            else
            if(a[S.x+1][S.y]==t-1)
            {
                TileMap[S.x+1][S.y]='+';
                S.x++; t--;
            }
            else
            if(a[S.x][S.y-1]==t-1)
            {
                TileMap[S.x][S.y-1]='+';
                S.y--; t--;
            }
            else
            if(a[S.x][S.y+1]==t-1)
            {
                TileMap[S.x][S.y+1]='+';
                S.y++; t--;
            }
        }
    }
}
 
};



В этом классе я хочу реализовать волновой алгоритм для преследования моими привидениями пакмана. Сам алгоритм я нашла и как могла разобрала. Создала функцию void find_path(int N,int M), которая находит кратчайший путь и указывает его +. Эту функцию добавила в void update(float time) этого класса, чтобы она оживала и передала ей размер своей карты.
Теперь мне надо, что бы она как-то заработала в main. Все было бы хорошо, но в моей карте нет 'G' и 'S'. я использую классы.В main я создаю список врагов и для прохождения в списке использую итератор.
Код

std::list<Entity*> entities;//список,куда будем бросать объекты
    std::list <Entity*>::iterator it;//итератор, чтобы проходить по элементам списка
    std::list <Entity*>::iterator it2;//враг-враг
 
    entities.push_back(new Enemy(easyEnemyImage,"EasyEnemy",100,200,32.0,32.0));
    entities.push_back(new Enemy(easyEnemyImage,"EasyEnemy",200,60,32.0,32.0));
    entities.push_back(new Enemy(easyEnemyImage,"EasyEnemy",60,60,32.0,32.0));


Функцию void update(float time) вызываю для каждого в списке,т.е для каждого врага иницилизируется свой массив для поиска в void find_path(int N,int M) и это правильно, т.к. врагов много
Код

for (it = entities.begin(); it != entities.end();)//говорим что проходимся от начала до конца
        {
            Entity *b = *it;//для удобства, чтобы не писать (*it)->
            b->update(time);//вызываем ф-цию update для всех объектов (по сути для тех, кто жив)
            if (b->life == false)   { it = entities.erase(it); delete b; }// если этот объект мертв, то удаляем его
            else it++;//и идем курсором (итератором) к след объекту. так делаем со всеми объектами списка
        }



До этого момента я думаю, что у меня все правильно. Посмотрите.
Трудность у меня в запуске всего этого механизма, хотя наверное все просто до безобразия.
Я в main проверяю объекты на пересечение в цикле "пока окно открыто"и там же хочу добавить и кусок для запуска всего этого.

Я так понимаю , что мне нужно получить координаты игрока и врага тут и присвоить в этом месте в карте 'G' и 'S'. Потом как-то подчищать и добавлять заново. Вообщем тут вообще запара.
Код

for (it = entities.begin(); it != entities.end(); it++)//проходимся по эл-там списка
        {   
                if ((*it)->name=="EasyEnemy")
            {
                ///(*it)->getPlayerCoord(pacman.x,pacman.y);
                ////TileMap[(*it)->x][(*it)->y]='S';
                //////Тут что-то нужно сделать-не знаю что
            } 
 


 Ребята, помогите. Мне кажется тут очень легко, но я туплю страшно.

Добавлено через 11 минут
И еще хотела спросить. что не так с самим файлом map.h на то, что он переопределяется еще раз хотя я в него добавила 
#ifndef MAP_H
#define MAP_H
#endif MAP_H
Пришлось делать его статическим, чтобы как то продолжить работу, хотя его таким оставлять никак нельзя, т.к. тайлы не убираются когда надо. В чем может быть ошибка?
PM MAIL   Вверх
math64
Дата 23.10.2015, 08:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



По основному вопросу - ничего  не могу сказать, алгоритм слишком сложный, долго разбираться, используется незнакомая библиотека.
В заголовке же инициализируется sf::String TileMap[HEIGHT_MAP];
В "правильных" заголовках так не делают. Твой заголовок можно включить только один раз.
Добавив static, ты размножаешь TileMap столько раз, сколько раз этот заголовок используется.
Без static, TileMap инициализируется столько раз, сколько раз этот заголовок используется. Это будет обнаружено при линковке, умный компилятор может выдать предупреждение.
Выход: убрать инициализацию из заголовка и инициализировать в одном из файлов .cpp, например, в Map.cpp

Это сообщение отредактировал(а) math64 - 23.10.2015, 08:30
PM   Вверх
lenarano
Дата 23.10.2015, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 17.4.2014

Репутация: нет
Всего: нет



map.h
Код

#ifndef MAP_H
#define MAP_H


#include <SFML\Graphics.hpp>

class Map{
public: 
const int HEIGHT_MAP=25;
const int WIDTH_MAP=28;


 sf::String TileMap[HEIGHT_MAP][HEIGHT_MAP];

};


#endif MAP_H


map.cpp
Код

#include "map.h"


sf::String Map::TileMap[HEIGHT_MAP]={
    "0000000000000000000000000000",
    "0                          0",
    "0                          0",
    "0  0 s0   0      0   0s 0  0",
    "0  0000   0mmmmmm0   0000  0",
    "0  0  0   00000000   0  0  0",
    "0                          0",
    "0                          0",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "t         00000000         T",
    "t                          T",
    "t                          T",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "0         00000000         0",
    "0                          0",
    "0  0  0              0  0  0",
    "0  0000   00000000   0000  0",
    "0  0 s0              0s 0  0",
    "0                          0",
    "0                          0",
    "0000000000000000000000000000",
};


Посмотрите, вот так? 
Выдает ошибки:
В map.h

Код

Ошибка    1    error C2864: Map::HEIGHT_MAP: в пределах класса могут быть инициализированы только статические константные данные-члены целого типа    
Ошибка    3    error C2327: Map::HEIGHT_MAP: не является именем типа, статическим членом или перечислителем
Ошибка    4    error C2065: HEIGHT_MAP: необъявленный идентификатор    



В map.cpp
Код

Ошибка    6    error C2761: sf::String Map::TileMap[1][1]: повторное объявление функции не разрешается    
Ошибка    5    error C2597: недопустимая ссылка на нестатический член "Map::HEIGHT_MAP"    

PM MAIL   Вверх
math64
Дата 23.10.2015, 13:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Костанты внутри класса и вне класса - разные вещи. Внутри класса - это обычное поле, не доступное к изменению, должно инициализироваться в конструкторе. Компилятор значения этого поля не знает, поэтому не сможет создать массив TileMap[HEIGHT_MAP][HEIGHT_MAP].
В старом стандарте C++ для этого используется enum (в  С++ 11 есть альтернатива, но я не помню как она используется):
Код

#ifndef MAP_H
#define MAP_H
#include <SFML\Graphics.hpp>
class Map{
public:
 enum { HEIGHT_MAP=25. WIDTH_MAP=28 };
 static char TileMap[HEIGHT_MAP][WIDTH_MAP+1];
};
#endif


При определении статического поля размерности массива указывать не нужно, компилятор их уже знает.
Ширина массива увеличена на 1, иначе C-строка, заканцивающаяся '\0' не влезет:
Код

#include "map.h"
char Map::TileMap[][]={
    "0000000000000000000000000000",
    "0                          0",
    "0                          0",
    "0  0 s0   0      0   0s 0  0",
    "0  0000   0mmmmmm0   0000  0",
    "0  0  0   00000000   0  0  0",
    "0                          0",
    "0                          0",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "t         00000000         T",
    "t                          T",
    "t                          T",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "0         00000000         0",
    "0                          0",
    "0  0  0              0  0  0",
    "0  0000   00000000   0000  0",
    "0  0 s0              0s 0  0",
    "0                          0",
    "0                          0",
    "0000000000000000000000000000",
};

Если поле не статическое, его нужно инициализировать в конструкторе:
Код

#ifndef MAP_H
#define MAP_H
#include <SFML\Graphics.hpp>
class Map{
public: 
 enum { HEIGHT_MAP=25. WIDTH_MAP=28 };
 sf::String TileMap[HEIGHT_MAP];
 inline Map()
 {
    static const char* localMap[] = {
    "0000000000000000000000000000",
    "0                          0",
    "0                          0",
    "0  0 s0   0      0   0s 0  0",
    "0  0000   0mmmmmm0   0000  0",
    "0  0  0   00000000   0  0  0",
    "0                          0",
    "0                          0",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "t         00000000         T",
    "t                          T",
    "t                          T",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "0         00000000         0",
    "0                          0",
    "0  0  0              0  0  0",
    "0  0000   00000000   0000  0",
    "0  0 s0              0s 0  0",
    "0                          0",
    "0                          0",
    "0000000000000000000000000000",
   };
   for(int i=0; i < HEIGHT_MAP; i++)
     TileMap[i] = localMap[i];
 }
};
#endif

(inline коструктор можно разместить в заголовке, но лучше его не делать inline и разместить в cpp).
PM   Вверх
lenarano
Дата 23.10.2015, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 17.4.2014

Репутация: нет
Всего: нет



Посмотрите правильно ли я поняла код и пояснения. (указала коменты в коде)
Код

#ifndef MAP_H
#define MAP_H
#include <SFML\Graphics.hpp>
class Map{
public: 
 enum { HEIGHT_MAP=25, WIDTH_MAP=28 };//перечисление. Поняла, что так можно задавать константы в классе
 sf::String TileMap[HEIGHT_MAP];//теперь я уже не могу обращаться в других классах и в main TileMap[i][j]-это можно как то изменить?
 inline Map()
 {
    static const char* localMap[] = {//static const-я поняла const-чтобы оставалась таким значение static-чтобы передать TileMap
    "0000000000000000000000000000",
    "0                          0",
    "0                          0",
    "0  0 s0   0      0   0s 0  0",
    "0  0000   0mmmmmm0   0000  0",
    "0  0  0   00000000   0  0  0",
    "0                          0",
    "0                          0",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "t         00000000         T",
    "t                          T",
    "t                          T",
    "0  0mm0   00000000   0mm0  0",
    "0  0000              0000  0",
    "0  0mm0              0mm0  0",
    "0         00000000         0",
    "0                          0",
    "0  0  0              0  0  0",
    "0  0000   00000000   0000  0",
    "0  0 s0              0s 0  0",
    "0                          0",
    "0                          0",
    "0000000000000000000000000000",
   };
   for(int i=0; i < HEIGHT_MAP; i++)//передали и теперь у нас 25 строк
     TileMap[i] = localMap[i];
 }
};
#endif





Теперь я уже не могу обращаться к элементом карты как TileMap[i][j], но на этом завязана прорисовка карты, обращения к элементам, замена тайликов. Можно ли здесь как то исправить?
Код

/////////////////////////////Рисуем карту/////////////////////
        for (int i = 0; i < HEIGHT_MAP; i++)
        for (int j = 0; j < WIDTH_MAP; j++)
        {
            if (TileMap[i][j] == ' ')  s_map.setTextureRect(sf::IntRect(0, 0, 32, 32));
            if (TileMap[i][j] == '0')  s_map.setTextureRect(sf::IntRect(64, 64, 32, 32));
            if ((TileMap[i][j] == 's')) s_map.setTextureRect(sf::IntRect(930, 1670, 32, 32));//бонусы меч
            if ((TileMap[i][j] == 'm')) s_map.setTextureRect(sf::IntRect(737, 1860, 32, 32));//бонусы золото
            if ((TileMap[i][j] == 't')) s_map.setTextureRect(sf::IntRect(0,1373, 32, 32));//бонусы телепорт
            if ((TileMap[i][j] == 'T')) s_map.setTextureRect(sf::IntRect(28,1373, -32, 32));//бонусы телепорт
            if ((TileMap[i][j] == 'f')) s_map.setTextureRect(sf::IntRect(704,1535, 32, 32));//бонусы яблоко
            s_map.setPosition(j * 32, i * 32);
            window.draw(s_map);
            
        }
        
Ошибка    14    error C2065: TileMap: необъявленный идентификатор    
Ошибка    12    error C2065: WIDTH_MAP: необъявленный идентификатор    



PM MAIL   Вверх
Starikan
Дата 23.10.2015, 15:43 (ссылка)    | (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 87
Регистрация: 25.10.2007

Репутация: 1
Всего: -15




Модератор: Сообщение скрыто.

PM MAIL   Вверх
math64
Дата 26.10.2015, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Теперь у тебя TileMap - поле класса, а не глобальная переменная. HEIGHT_MAP и WIDTH_MAP то же находятся внутри класса.
Т. е. нужно создать где-то Map* map = new Map(); и писать map->TileMap[i][j], Map::HEIGHT_MAP и Map::WIDTH_MAP .
map может быть глобальной переменной (тогда она создается и удаляется в main() ) или полем класса (тогда она создаётся в конструкторе класса, а удаляется в деструкторе).

Добавлено через 7 минут и 36 секунд
Код

    static const char* localMap[] = { "0000000000000000000000000000", ... };

const - потому что строки "0000000000000000000000000000" имеют тип const char*
static - чтобы массив инициализировался компилятором во время компиляции. Без static массив будет создаваться и инициалзироваться при каждом вызове конструктора Map::Map().
PM   Вверх
lenarano
Дата 27.10.2015, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 17.4.2014

Репутация: нет
Всего: нет



Получилось. smile 
Создала в Main: Map* map = new Map();
Добавила в класс игрока и врага поля: Map* m_map;
И добавила в конструктор каждого класса:
Код

Player::Player(Map* map,std::shared_ptr<sf::View> view, sf::Image &image,sf::String Name,float X, float Y, float W, float H):Entity(image, Name, X,Y,W,H){
    m_view = view;    
    m_map=map;

И теперь обращаюсь как 
Код

randomElementX = 1 + rand() % (m_map->WIDTH_MAP - 1);

....
m_map->TileMap[i][j] = ' ';

Спасибо огромное. 
Еще хотела спросить, если я хочу, чтобы уровней было несколько и соответственно карт тоже, как мне лучше всего реализовать? Я хочу добавить в класс игрока переменную bool, которая станет "правдой", если мой пакман съест все точки. И если она станет правдой, то будет реализован 2ой уровень.

Добавлено через 2 минуты и 59 секунд
Я имела ввиду, что я же создаю конструкторе свою карту, но она может то быть разной в зависимости от уровня. 
PM MAIL   Вверх
math64
Дата 27.10.2015, 12:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



Цитата(lenarano @  27.10.2015,  12:37 Найти цитируемый пост)
если я хочу, чтобы уровней было несколько и соответственно карт тоже, как мне лучше всего реализовать?

Код

#ifndef MAP_H
#define MAP_H
#include <SFML\Graphics.hpp>
class Map{
public: 
 enum { HEIGHT_MAP=25, WIDTH_MAP=28 };
 sf::String TileMap[HEIGHT_MAP];
 int m_level;
 Map()
 {
    setLevel(0);
 }
 int getLevel() { return m_level; }
 void setLevel(int level)
 {
    static const char* levelsMap[][HEIGHT_MAP] = {
      { /* Инициализация 0-го уровня */ },
      { /* Инициализация 1-го уровня */ },
      { /* Инициализация 2-го уровня */ },
      ...
   };
   int levelsCount = sizeof(levelsMap) / sizeof(levelsMap[0]);
   if (level < 0 || level >= levelsCount)
     level = 0;
   m_level = level;
   for(int i=0; i < HEIGHT_MAP; i++)
     TileMap[i] = levelsMap[level][i];
 }
};
#endif

Но лучше уровни считать из файла. В этом случае char levelsMap[LEVELS_COUNT][HEIGHT_MAP][WIDTH_MAP]; будет полем класса Map и считываться в конструкторе.
PS: в предыдущем сообщении в коде вставь перенос в длинной строки, чтобы страница форума выглядела нормально.


Это сообщение отредактировал(а) math64 - 27.10.2015, 13:04
PM   Вверх
lenarano
Дата 27.10.2015, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 17.4.2014

Репутация: нет
Всего: нет



Реализовала в функции void Player::update(float time)
Код

if(counterGoldIngot<=0){m_map->setLevel(+1);counterGoldIngot=3;x=460;y=720;}

Герой собирает золото и если все собрал, то перешел на новый уровень. Можно ли как то преобразовать, чтобы подходила не для 2 уровней, а для нескольких 
вот тут m_map->setLevel(+1); 
И еще вопрос, как только сработало это условие у меня загрузилась моя новая карта, герой переместился, но не может двигаться. Т.е. анимация есть, но как  будто  там стоит стенка, которую не видно. Почему так происходит? Я вот думаю, что может вопрос в прорисовке карты, мы же здесь по факту ничего не перезапускали. Может сталкивались smile 

PM MAIL   Вверх
math64
Дата 27.10.2015, 15:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2505
Регистрация: 12.4.2007

Репутация: 12
Всего: 72



После переключения уровня нужно найти начальное положение героя и заново пересоздать врагов. Начальное положение геороя и врагов можно задать специальными значками на карте. А можно из положения задавать случайно (проверяя чтобы они не попали на клетки со стенками).
Кроме того, программа может не всегда обращаться к карте для проверки наличия стенки, помня  что раньше она там была или там было свободно (например, где-то был расчитан и запомнен путь движения). Подобные кеш-буфера должны быть сброшены.

Добавлено через 54 секунды
Ну, и да, экран надо перерисовать.
PM   Вверх
lenarano
Дата 1.11.2015, 00:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 17.4.2014

Репутация: нет
Всего: нет



Спасибо большое за предыдущие ответы. Надеюсь и здесь все разжуете))
В классе врага хочу прописать алгоритм, по которому враг будет преследовать пакмана.
добавляю в класс новые функции
1. Чтобы нарисовать мой двумерный массив. Видимо ошибка в прорисовке    printf("%.*s\n", m_map->WIDTH_MAP, m_map->TileMap[i]); т.к. отображается не мой массив, а другие символы. В алгоритме были char maze[NROWS][MCOLS].
Код


    void display_maze(void)
{
        int i;

        printf("MAZE:\n");
        for ( i = 0; i < m_map->HEIGHT_MAP; i++ )
                printf("%.*s\n", m_map->WIDTH_MAP, m_map->TileMap[i]);
         
        printf("\n");

        return;
}

int
find_path(int x, int y)
{
        // If x,y is outside maze, return false.
        if ( x < 0 || x > m_map->WIDTH_MAP - 1 || y < 0 || y > m_map->HEIGHT_MAP - 1 ) return FALSE;

        // If x,y is the goal, return true.
        if ( m_map->TileMap[y][x] == 'G' ) return TRUE;

        // If x,y is not open, return false.
        if ( m_map->TileMap[y][x] != ' ' && m_map->TileMap[y][x] != 'S' ) return FALSE;

        // Mark x,y part of solution path.
        m_map->TileMap[y][x] = '+';

        // If find_path North of x,y is true, return true.
        if ( find_path(x, y - 1) == TRUE ) return TRUE;

        // If find_path East of x,y is true, return true.
        if ( find_path(x + 1, y) == TRUE ) return TRUE;

        // If find_path South of x,y is true, return true.
        if ( find_path(x, y + 1) == TRUE ) return TRUE;

        // If find_path West of x,y is true, return true.
        if ( find_path(x - 1, y) == TRUE ) return TRUE;

        // Unmark x,y as part of solution path.
        m_map->TileMap[y][x] = 'x';

        return FALSE;
}




Далее в функции движения должен прорисовываться путь, пока его нет.
Код

 display_maze();
             if ( find_path(0, 0) == TRUE )
                printf("Success!\n");
        else
                printf("Failed\n");

        display_maze();
         int i;
        cin >> i;


2. Как все-таки переделать наш класс Map, чтобы уровней было несколько.

Реализовала в функции void Player::update(float time)
код C++
1:
if(counterGoldIngot<=0){m_map->setLevel(+1);counterGoldIngot=3;x=460;y=720;}

Герой собирает золото и если все собрал, то перешел на новый уровень. Можно ли как то преобразовать, чтобы подходила не для 2 уровней, а для нескольких 
вот тут m_map->setLevel(+1); 
PM MAIL   Вверх
lenarano
Дата 1.11.2015, 08:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 17.4.2014

Репутация: нет
Всего: нет



Я смогла вывести свой массив в класса Map, добавив пару строчек кода в  void Map:: setLevel(int level)
Код

void Map:: setLevel(int level)
 {
    static const char* levelsMap[][HEIGHT_MAP] = {
      { 
    /* Инициализация 0-го уровня */
 ...............
    "0  0000              0000  0",
    "0  0                    0  0",
    "0                          0",
    "0      0000      0000      0",
    "0  0      0s    s0      0  0",
    "0  0  0   00000000   0  0  0",
    "0  0  0   0mmmmmm0   0  0  0",
    "0                          0",
    "0                          0",
    "0000000000000000000000000000", },
      { /* Инициализация 2-го уровня */ },
        };
   int levelsCount = sizeof(levelsMap) / sizeof(levelsMap[0]);
   if (level < 0 || level >= levelsCount)
     level = 0;
   m_level = level;
   for(int i=0; i < HEIGHT_MAP; i++)
     {TileMap[i] = levelsMap[level][i];
      std::cout<<levelsMap[level][i];
       printf("\n");
     }
 }

  


 {TileMap[i] = levelsMap[level][i];
      std::cout<<levelsMap[level][i];
       printf("\n");
     }
 
Но я все же хочу отдельную функцию. Как мне реализовать ее? И какие значения передать? Что тут изменить?
void display_maze(void)
{
        int i;

        printf("MAZE:\n");
       {TileMap[i] = levelsMap[level][i];//ругается,что эти индивикаторы не определены
      std::cout<<levelsMap[level][i];
       printf("\n");
     }

        return;
}

Добавлено через 6 минут и 32 секунды
Мне нужно передать наверное значение по ссылке , но я не понимаю как

PM MAIL   Вверх
lenarano
Дата 1.11.2015, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 17.4.2014

Репутация: нет
Всего: нет



попробовала вот так, хотя не уверена-ошибку подчеркивает

Код

void display_maze( sf::String TileMap,char* levelsMap[])
{
        int i;

        printf("MAZE:\n");
       {TileMap[i] = levelsMap[level][i];//ругается,что level не определен
      std::cout<<levelsMap[level][i];
       printf("\n");
     }

        return;
}


Добавлено через 10 минут и 30 секунд
void display_maze( sf::String TileMap,char* levelsMap[][],int level)//массив не может содержать элементы этого типа

Это сообщение отредактировал(а) lenarano - 1.11.2015, 09:14
PM MAIL   Вверх
lenarano
  Дата 1.11.2015, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 62
Регистрация: 17.4.2014

Репутация: нет
Всего: нет



Код

void display_maze( sf::String TileMap,int level,char*levelsMap[][Map::HEIGHT_MAP])
{
    int i;
    printf("MAZE:\n");
    for(int i=0; i < Map::HEIGHT_MAP; i++)
    {TileMap[i] = levelsMap[level][i];//pЗначения типа char*нельзя присвоить сущности типа sf::Uint32
    std::cout<<levelsMap[level][i];
    printf("\n");
    }

    return;
}



Выдает непонятную мне ошибку , да вообще хотелось бы понять, что не так.

Добавлено через 14 минут и 14 секунд
Я в конец запуталась. Очень жду подмогу)))
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1544 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.