Программирование игр, создание игрового движка, OpenGL, DirectX, физика, форум
GameDev.ru / Программирование / Форум / SDL логика A*

SDL логика A*

Поделиться
Frodo4500Пользовательwww27 мая 201717:04#0
Доброго времени суток форумчане. Ниже код для игры точки, но столкнулся с проблемой определения, окружена ли точка противником или нет.
Не могу получить данные о ячейке, зная часть ее параметров.
Возможно я что-то в корне неверно а коде сделал, потому прошу вашего совета - критики !
#include <SDL.h>
#include <SDL_image.h>
#include <SDL_mixer.h>
#include <string>
#include <iostream>
#include <array>
#include <map>
#include <vector>
#include <utility>

SDL_Window* window = NULL;
SDL_Surface *windowSurface = NULL;
SDL_Surface *imageSurface = NULL;
SDL_Renderer* renderer = NULL;

const int SCREEN_WIDTH = 640;
const int SCREEN_HEIGHT = 480;

using namespace std;

void chip(string wayimage, SDL_Rect MySrcR, SDL_Rect MySrcR2);
void close();

class Cell                                    // класс являющийся ячейкой
{
public:
  int MyX;                              // начало отрисовки. координаты по X
  int MyY;                              // начало отрисовки. координаты по Y
  int MyWidth;                       // ширина клетки
  int MyHeight;                      // высота клетки
  bool MyClick;                       // факт создания клетки
  bool MyFriend;                    // является ли клетка вражеской или нет

  Cell()
  {
    MyX = 0; MyY = 0; MyWidth = 0; MyHeight = 0; MyClick = false; MyFriend = false;
  }
  Cell(int x, int y, int nWidth, int nHeight, bool nClick, bool nFriend) : MyX(x), MyY(y), MyWidth(nWidth), MyHeight(nHeight), MyClick(nClick), MyFriend(nFriend)
  {
  };
  void show()                                                                                         // рисую клетку
  {
    SDL_Rect outlineRect = { MyX, MyY, 20 , 20 };                                  // по полученным координатам X и Y создается прямоугольник
    SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);           // заливка прямоугольника цветом
    SDL_RenderDrawRect(renderer, &outlineRect);                                   // сама отрисовка на рендере
  }
};

void chip(string wayimage, SDL_Rect MySrcR, SDL_Rect MySrcR2)         //для рисования точки
{
  SDL_Surface *myimage = SDL_LoadBMP(wayimage.c_str());               // загружаем картинку по полученному пути
  if (myimage == NULL)
  {
    cout << "Error of loading of the image" << endl;                               // выдаем ошибку если картинка не загрузилась
  }
  SDL_Texture *mytexture = SDL_CreateTextureFromSurface(renderer, myimage);  // создаем текстуру
  SDL_FreeSurface(myimage);                                                                                 
  SDL_RenderCopy(renderer, mytexture, NULL, &MySrcR);                                       
  SDL_RenderPresent(renderer);                                                           // рисуем нашу точку
  SDL_BlitSurface(imageSurface, &MySrcR2, windowSurface, &MySrcR);
}

void close()                                                                                          // очищаем память от всего с чем работали
{
  SDL_FreeSurface(imageSurface);
  imageSurface = NULL;
  window = NULL;
  windowSurface = NULL;
  renderer = NULL;
  SDL_DestroyWindow(window);
  SDL_Quit();
}

int main(int argc, char* args[])
{
  SDL_Init(SDL_INIT_VIDEO);
  window = SDL_CreateWindow("sdl game", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);           // создаем окно
  if (window == NULL)
  {
    cout << "Error of creation of a window" << endl;                     // в случае ошибки, выдаем сообщение и выходим из программы
    return 0;
  }
  renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);        // создаем рендер

  SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF);                                    // заливаем рендер цветом
  SDL_RenderClear(renderer);

  int step = 20;

  map<tuple<int, int, bool, bool>, Cell *> nMap;                                                      // создаем массив экземпляров класса Cell

  int MouseX;
  int MouseY;

  bool isRunning = true;
  SDL_Event e;

  while (isRunning)
  {
    while (SDL_PollEvent(&e) != 0)
    {
      if (e.type == SDL_QUIT)
        isRunning = false;

      switch (e.type)
      {
      case SDL_MOUSEMOTION:             // считываем и записываем координаты мыши
        MouseX = e.motion.x;
        MouseY = e.motion.y;

        if (e.button.button == 1 || e.button.button == 4)            // если  нажата левая или правая клавиша мыши, то
        {
          int i = 20;
          int j = 20;
          for (i; i < (MouseX - 20);)                                              // в этом цикле, и том что ниже приводим координаты к нормальному виду, чтобы клетка рисовалась по 
//              x и y от начала координат с кратностью 20 (ширина и высота клетки) - в результате клетки не будут пересекаться друг с другом при отрисовке
          {
            i += 20;
          //  cout << i << " " << endl;
          }
          for (j; j < (MouseY - 20);)
          {
            j += 20;
          //  cout << j << " " << endl;
          }

          auto it = make_tuple(i, j, false, false);                      // кортеж или динамический массив - кому как удобней
          nMap[it] = new Cell(i, j, 20, 20, false, false);            // создаю экземпляр класса по данным из кортежа
    //      cout << i << "  " << j << endl;                           // отладочная инфа, дабы быть уверенным, что овсе просчитано норм
          cout << "" << endl;
        
        for (auto it : nMap)
        {
          Cell * nCell = it.second;
          SDL_Rect SrcR;                                  // создаю прямоугольник в котором будет рисоваться текстура
          SrcR.x = nCell->MyX;
          SrcR.y = nCell->MyY;
          SrcR.w = 20;
          SrcR.h = 20;

          SDL_Rect SrcR2;                              // указания, тому прямоугольнику, что выше, откуда он будет рисоваться
          SrcR2.x = MouseX;
          SrcR2.y = MouseY;

          if (nCell->MyClick == false)           // проверка, если клетка уже существует, то в этом месте мы рисовать не можем
          { 
            bool b1 = (nCell->MyX < MouseX) && (MouseX < nCell->MyX + nCell->MyWidth);
            bool b2 = (nCell->MyY < MouseY) && (MouseY < nCell->MyY + nCell->MyHeight);
            if (b1 && b2)
            {
              windowSurface = SDL_GetWindowSurface(window);
              if (e.button.button == 1)             // если нажата ЛКМ, то рисуем синию фишку
              {
                nCell->MyClick = true;
                chip("data/image/btn_blue.bmp", SrcR, SrcR2);
              }
              else
              {                                                  // иначе рисуем красную
                nCell->MyClick = true;
                nCell->MyFriend = true;
                chip("data/image/btn_red.bmp", SrcR, SrcR2);
              }
              
              if (nCell->MyClick == true)
              {
                int MyX1 = SrcR.x;
                int MyY1 = SrcR.y;

                for (int k = (MyX1 - 20); k <= (MyX1 + 20); k += 20)
                {
                  for (int j = (MyY1 - 20); j <= (MyY1 + 20); j += 20)
                  {
                                                                                              // здесь я могу получать координаты вокруг только что поставленной мной точки, для
//       дальнейшей проверки , но не могу понять как получить экземпляр класса, зная лишь x и y, для того чтобы проверить, вражеская это клетка или нет.
                    cout << k << "  " << j << endl;
                    
                  }
                }
              }
              
            }
            nCell->show();
          }
        }
        }
      }
    }
    SDL_RenderPresent(renderer);
  }
  close();

  return 0;
}

Правка: 27 мая 2017 17:57

ChebПостоялецwww27 мая 201717:29#1
Вопрос задан неправильно:

1. Вывалить простыню кода "а вы уж в ней сами разбирайтесь" - моветон. Ты неверно предполагаешь, что знатоки сразу бросятся разбираться в чужом коде, что есть заметный труд. Оно им надо? Код должен быть иллюстрацией к описанию проблемы человеческим языком.

2. Ты продемонстрировал леность и нежелание потрудиться объяснить свои методы и алгоритмы подробнее.

Вывод? Ты выставил себя нахлебником и выказал неуважение к тем, кому адресован вопрос.
Отвечать будут одни тролли да неадекваты.

Правка: 27 мая 2017 17:30

Frodo4500Пользовательwww27 мая 201717:54#2
Благодарю за замечание, вроде правильно вас понял
kiparПостоялецwww27 мая 201720:18#3
auto aCell = nMap[make_tuple(k/20, j/20, false, false)];
а хотя там и за границами поля тоже перебирается, так что или в цикле условие исправить или в индексах проверку.
но в целом конечно похоже на безумие, вместо двухмерного массива с которым самого вопроса бы не возникло тут map кортежей координат в пикселях и каких-то флагов.

Правка: 27 мая 2017 20:18

Frodo4500Пользовательwww27 мая 201722:37#4
Я бы с радостью отказался от map-а , но флаги нужны для того, чтобы можно было я мог различать своя клетка или чужая, и флаг ее наличия, для запрета постановления своей точки на вражескую. Может конечно я что-то не понимаю (опыта не так много как хотелось бы), но мои попытки представлены ниже.
kiparПостоялецwww27 мая 201723:10#5
Точка на карте может быть в одном из трех состояний - своя, вражеская, пусто. Это можно сделать например енумом, или просто числом, хотя можно и классом Cell. Это и будет объект "клетка".
А дальше просто сделай двумерный массив из этих объектов, рисуй их по координатам (i*20, j*20), проверяй соседей с помощью nMap[i-1, j], nMap[i+1, j].

/ Форум / Программирование игр / Игровая логика и ИИ

2001—2017 © GameDev.ru — Разработка игр