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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++]игровое поле 
:(
    Опции темы
mego4el
Дата 14.12.2011, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Добрый день, бьюсь головой уже долго и никак не получается нормально сделать игровую карту.

1) у меня есть массив int m[43][16], это и есть карта, мне нужно прочитать из фаила матрицу, в которой нули и единицы, затем вывести ее на экран "ровно", в заданные координаты. вот с этим и начались проблемы(, у меня меню находится ближе к центру:

Код
void Menu_Draw()
    {
        system("cls"); cout<<endl;
        //up-bottom
        int upbot=1;
        int px1=4;
        int px2=48;
        while (upbot!=46)
            {
                GotoXY(px1,3);
                SetColor(7,8);
                putchar(26);
                px1++;

                GotoXY(px2,21);
                SetColor(7,8);
                putchar(27);
                px2--;
 
                Sleep(12);
                upbot++;
            }
        //left-right
        int riglef=1;
        int qx1=3;
        int qx2=21;
        while (riglef!=20)
            {
                GotoXY(4,qx1);
                SetColor(7,8);
                putchar(37);
                qx1++;

                GotoXY(48,qx2);
                SetColor(7,8);
                putchar(37);
                qx2--;
        
                Sleep(12);
                riglef++;
            }


это каркас для меню, само меню находится по центру, печатается таким же по пиксельным способом.

мне нужно вывести в этот каркас - мой массив из нулей и единиц, который был считан с фаила:

Код
void Level::LoadMap()
{
    Console console;
    int gy=4, gx=5;
    FILE *f;
    char fname[16]="lvl1.map";
    f=fopen(fname,"rt");
    char ch;
    if(f!=NULL)
    {
        //printf("Map was opened: \n");
        while((ch=getc(f))!=EOF)
        {
            if(ch=='\n')
                console.GotoXY(5,gy++);
            else
                cout<<ch;
        }
    }
    fclose(f);


никак не получается вывести ровно под в этот каркас данный массив(, не могу разобраться в чем я допускаю ошибки..(

2)необходимо этот массив преобразовать из нулей и единиц в определенные символы, допустим нули - в пробелы, а единицы - решетки (аля стены и пути), затем вывести на экран, помогите пожалуйста!

3) как можно будет реализовать данные стены, что бы если обьект в них упирается, то он не двигался дальше (движение сделано с помощью стрелок)?
PM MAIL   Вверх
t_gran
Дата 14.12.2011, 18:29 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

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



Ну вот, по быстрому наклепал демку. Правда дохленькая, но должна помочь.

По существу, вы не верно выполнили декомпозицию задачи. Дело в том, что нельзя смешивать действие загрузки с выводом. К тому же вам нежны данные по вашей карте в дальнейшем. Поэтому, карту нужно сначала загрузить, а потом уже выводить.

Вывод в заданной стартовой точке, я думаю, вам не составит труда. Там всё просто, в моей демке по этому поводу есть комментарий.

Что касается второго вопроса, то это очень просто, преобразовать ASCII символ в цифровое его значение. 0 есть 48. Соответственно, чтобы получить число, нужно просто из номера символа вычесть 48. Но, поверьте мне, как человеку написавшему не одну игру, что если вы не будите делать редактор для ваших карт, то лучше вместо 0,1,2 и т.п. испольуйте реальные символы. Сравните два вида:
Код

1111111111111111
1000000001000001
1001011111011101
1011010001000001
1010010101001001
1011110101011101
1000000100001001
1111111111111111

и
Код

****************
*        *     *
*  * ***** *** *
* ** *   *     *
* *  * * *  *  *
* **** * * *** *
*      *    *  *
****************

Что легче воспринимается?  smile 

Ну и по последнему вопросу - это метод IsWall в моей демке.

Код

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>

class TMap
{
   public:
      enum
      {
         HEIGHT = 8, // Сделал поменьше для демонстрации
         WIDTH = 16
      };

   protected:
      int map[HEIGHT][WIDTH];
   
   public:
      bool Load(const char* theName); // И так понятно, что загрузка
      
      void Draw(); // Прорисовка. Если нужно указывать координаты, то тогда:
                   // void Draw(int theX, int theY);
      
      // Проверка, является ли данные элемент карты стеной
      // В рамках демки не используется, но это ответ 3-ий вопрос
      bool IsWall(unsigned theI, unsigned theJ) const;
};
//----------------------------------------------//
// Загрузка. Тут ничего интересного
bool TMap::Load(const char* theName)
{
   FILE* f = fopen(theName, "r");
   
   if (f)
   {
      int i = 0, j = 0;
      while (!feof(f) && (i < HEIGHT))
      {
         int ch = getc(f);
         
         if (ch == 10)
         {
            i++;
            j = 0;
         }
         else if (j < WIDTH)
         {
            map[i][j++] = ch-48;
         }
      }
      fclose(f);
   }
   
   return f;
}
//----------------------------------------------//
// Прорисока
void TMap::Draw()
{
   const char CWall = 219;
   const char CPassage = 32;
   
   for (int i = 0; i < HEIGHT; ++i)
   {
      for (int j = 0; j < WIDTH; ++j)
      {
         // Если введёте координаты, то используйте gotoxy для смещения:
         // gotoxy(x+j, y+i);
         
         // Вот так отображается стена или пространство
         printf("%c", map[i][j] ? CWall : CPassage);
      }
      printf("\n");
   }
}
//----------------------------------------------//
// Проверка, является ли данная часть карты стеной
bool TMap::IsWall(unsigned theI, unsigned theJ) const
{
   bool isWall = true;
   
   if ((theI < HEIGHT) && (theJ < WIDTH))
   {
      isWall = map[theI][theJ];
   }
   
   return isWall;
}
//----------------------------------------------//

int main()
{
   const char* CFileName = "level1.map";

   TMap map;
   
   if (map.Load(CFileName))
   {
      map.Draw();
   }
   else
   {
      printf("error: file '%s' not found ...\n", CFileName);
   }
   
   system("pause");
   
   return 0;
}


user posted image




Это сообщение отредактировал(а) t_gran - 15.12.2011, 10:18

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  archive.7z 3,40 Kb


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
mego4el
Дата 14.12.2011, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



примного вам благодарен!!!!!!!

в общем во всем разобрался, кроме 

Код

void Level::Draw()
{
    Console console;
    unsigned int sX=5, sY=4;
    const char CWall = 219;
    const char CPassage = 32;

    for (int i=0; i<HEIGHT; ++i)
    {
        for (int j=0; j<WIDTH; ++j)
        {
            console.GotoXY(sX+j, sY+i);
            // Вот так отображается стена или пространство
            printf("%c", map[i][j] ? CWall : CPassage);
        }
        printf("\n");
    }
}


компилятор не хочет преобразовывать char Cwall, cpassage в int:

warning C4305: 'initializing' : truncation from 'const int' to 'const char'
warning C4309: 'initializing' : truncation of constant value
PM MAIL   Вверх
mego4el
Дата 15.12.2011, 00:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



разобрался. char же принимает значения до 127.

попробовал сделать unsigned char.
PM MAIL   Вверх
mego4el
Дата 17.12.2011, 23:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



еще раз здравствуйте. пожалуйста помогите разобраться с методом isWall.

не получается его использовать практически(, подскажите как действовать?

сделал для передвижения следующую функцию:

Код

void Pacman::Move()
{
    Console console;
    unsigned int stX=26, stY=11;
    console.GotoXY(stX,stY);

    const unsigned char tWall=177;
    const unsigned char tPassage=32;

    while(1)
    {
        int keys;
        keys=getch();
        switch(keys)
        {
        case 75: //left 75
            if(tPassage)
            {
                putchar('\b'); putchar(0); fflush(stdin);
                console.GotoXY(stX--,stY); putchar(1);
                break;
            }
            else
            {
                console.GotoXY(stX,stY);
                putchar(1);
                break;
            }
        case 77: //right 77
            if(tPassage)
            {
                putchar('\b'); putchar(0); fflush(stdin);
                console.GotoXY(stX++,stY); putchar(1);
                break;
            }
            else
            {
                console.GotoXY(stX,stY);
                putchar(1);
                break;
            }
        case 72: //up 72
            if(tPassage)
            {
                putchar('\b'); putchar(0); fflush(stdin);
                console.GotoXY(stX,stY--); putchar(1);
                break;
            }
            else
            {
                console.GotoXY(stX,stY);
                putchar(1);
                break;
            }
        case 80: //down 80
            if(tPassage)
            {
                putchar('\b'); putchar(0); fflush(stdin);
                console.GotoXY(stX,stY++);
                putchar(1);
                break;
            }
            else
            {
                console.GotoXY(stX,stY);
                putchar(1);
                break;
            }
        }
    }
}


метод IsWall:

Код

bool Level::IsWall(unsigned int theI, unsigned int theJ)
{
   bool isWall = true;

   if ((theI<HEIGHT) && (theJ<WIDTH))
   {
      map[theI][theJ] = isWall;
   }
   return isWall;
}

PM MAIL   Вверх
t_gran
Дата 18.12.2011, 16:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

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



Код

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

class TMap
{
   public:
      const char CWall;
      const char CPassage;
   
      enum
      {
         HEIGHT = 8,
         WIDTH = 16
      };
   protected:
      int map[HEIGHT][WIDTH];
      unsigned x, y;
   
   public:
      TMap(unsigned theX = 1, unsigned theY = 1)
      : CWall(219), CPassage(32), x(theX), y(theY) { ; }
   
      bool Load(const char* theName);
      
      void Draw();
      
      void Redraw(unsigned theI, unsigned theJ);
      
      bool IsWall(unsigned theI, unsigned theJ) const;
};
//----------------------------------------------//
bool TMap::Load(const char* theName)
{
   FILE* f = fopen(theName, "r");
   
   if (f)
   {
      int i = 0, j = 0;
      while (!feof(f) && (i < HEIGHT))
      {
         int ch = getc(f);
         
         if (ch == 10)
         {
            i++;
            j = 0;
         }
         else if (j < WIDTH)
         {
            map[i][j++] = ch-48;
         }
      }
      fclose(f);
   }
   
   return f;
}
//----------------------------------------------//
void TMap::Draw()
{
   for (int i = 0; i < HEIGHT; ++i)
   {
      for (int j = 0; j < WIDTH; ++j)
      {
         Redraw(i, j);
      }
   }
}
//----------------------------------------------//
void TMap::Redraw(unsigned theI, unsigned theJ)
{
   gotoxy(x+theJ, y+theI);
   
   printf("%c", map[theI][theJ] ? CWall : CPassage);
}
//----------------------------------------------//
bool TMap::IsWall(unsigned theI, unsigned theJ) const
{
   bool isWall = true;
   
   if ((theI < HEIGHT) && (theJ < WIDTH))
   {
      isWall = map[theI][theJ];
   }
   
   return isWall;
}
//----------------------------------------------//
int main()
{
   const char CPlayer = 1;

   const unsigned COffsetX = 2;
   const unsigned COffsetY = 1;

   const char* CFileName = "level1.map";
   
   TMap map(COffsetX, COffsetY);
   
   if (!map.Load(CFileName))
   {
      printf("error: file '%s' not found ...\n", CFileName);
      system("pause");
      return 1;
   }

   map.Draw();

   int key = 0;
   unsigned i = 1, j = 1;
   
   while (key != 27)
   {
      gotoxy(COffsetX+j, COffsetY+i);
      putchar(CPlayer);

      key = getch();
     
      switch(key)
      {
         case 75:
            if (!map.IsWall(i, j-1))
            {
               map.Redraw(i, j--);
               gotoxy(COffsetX+j, COffsetY+i);
               putchar(CPlayer);
            }
            break;

         case 77:
            if (!map.IsWall(i, j+1))
            {
               map.Redraw(i, j++);
               gotoxy(COffsetX+j, COffsetY+i);
               putchar(CPlayer);
            }
            break;

         case 72:
            if (!map.IsWall(i-1, j))
            {
               map.Redraw(i--, j);
               gotoxy(COffsetX+j, COffsetY+i);
               putchar(CPlayer);
            }
            break;

         case 80:
            if (!map.IsWall(i+1, j))
            {
               map.Redraw(i++, j);
               gotoxy(COffsetX+j, COffsetY+i);
               putchar(CPlayer);
            }
            break;
      }
   }
   
   return 0;
}


Рабочая демка ниже

Это сообщение отредактировал(а) t_gran - 19.12.2011, 10:33

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  archive.7z 5,15 Kb


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
mego4el
Дата 20.12.2011, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



спасибо большое!!  smile 

не подскажите, как можно реализовать условие, при котором если нажать определенную стрелку, что бы обьект двигался по направлению стрелки, пока не упрется в стенку?
PM MAIL   Вверх
t_gran
Дата 20.12.2011, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 621
Регистрация: 13.11.2007
Где: г.Усть-Илимск

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



mego4el, фигня вопрос, забирайте!
Код

#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

class TMap
{
   //...
};
//...

int main()
{
   const char CPlayer = 1;
   const unsigned COffsetX = 1;
   const unsigned COffsetY = 1;
   const char* CFileName = "level1.map";
   
   TMap map(COffsetX, COffsetY);
   
   if (!map.Load(CFileName))
   {
      printf("error: file '%s' not found ...\n", CFileName);
      system("pause");
      return 1;
   }
   map.Draw();

   unsigned i = 1, j = 1;
   
   while (true)
   {
      gotoxy(COffsetX+j, COffsetY+i);
      putchar(CPlayer);
      
      if (GetAsyncKeyState(VK_DOWN))
      {
         if (!map.IsWall(i+1, j))
         {
            map.Redraw(i++, j);
            gotoxy(COffsetX+j, COffsetY+i);
            putchar(CPlayer);
         }
      }
      if (GetAsyncKeyState(VK_UP))
      {
         if (!map.IsWall(i-1, j))
         {
            map.Redraw(i--, j);
            gotoxy(COffsetX+j, COffsetY+i);
            putchar(CPlayer);
         }
      }
      if (GetAsyncKeyState(VK_LEFT))
      {
         if (!map.IsWall(i, j-1))
         {
            map.Redraw(i, j--);
            gotoxy(COffsetX+j, COffsetY+i);
            putchar(CPlayer);
         }
      }
      if (GetAsyncKeyState(VK_RIGHT))
      {
         if (!map.IsWall(i, j+1))
         {
            map.Redraw(i, j++);
            gotoxy(COffsetX+j, COffsetY+i);
            putchar(CPlayer);
         }
      }
      if (GetAsyncKeyState(VK_ESCAPE))
      {
         break;
      }
      Sleep(100);
   }
   
   return 0;
}


Это сообщение отредактировал(а) t_gran - 20.12.2011, 08:47

Присоединённый файл ( Кол-во скачиваний: 3 )
Присоединённый файл  archive.7z 5,28 Kb


--------------------
Я знаю, что ничего не знаю© Сократ
user posted image
PM MAIL WWW   Вверх
mego4el
  Дата 3.1.2012, 17:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



огромное спасибо!

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

подскажите пожалуйста smile 
PM MAIL   Вверх
mego4el
Дата 3.1.2012, 18:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



и еще маленький вопросик, как можно сделать таймер? допустим засекается при старте уровня 60 секунд, если за них не прошел до конца, то пишет гейм овер)?
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Центр помощи"

ВНИМАНИЕ! Прежде чем создавать темы, или писать сообщения в данный раздел, ознакомьтесь, пожалуйста, с Правилами форума и конкретно этого раздела.
Несоблюдение правил может повлечь за собой самые строгие меры от закрытия/удаления темы до бана пользователя!


  • Название темы должно отражать её суть! (Не следует добавлять туда слова "помогите", "срочно" и т.п.)
  • При создании темы, первым делом в квадратных скобках укажите область, из которой исходит вопрос (язык, дисциплина, диплом). Пример: [C++].
  • В названии темы не нужно указывать происхождение задачи (например "школьная задача", "задача из учебника" и т.п.), не нужно указывать ее сложность ("простая задача", "легкий вопрос" и т.п.). Все это можно писать в тексте самой задачи.
  • Если Вы ошиблись при вводе названия темы, отправьте письмо любому из модераторов раздела (через личные сообщения или report).
  • Для подсветки кода пользуйтесь тегами [code][/code] (выделяйте код и нажимаете на кнопку "Код"). Не забывайте выбирать при этом соответствующий язык.
  • Помните: один топик - один вопрос!
  • В данном разделе запрещено поднимать темы, т.е. при отсутствии ответов на Ваш вопрос добавлять новые ответы к теме, тем самым поднимая тему на верх списка.
  • Если вы хотите, чтобы вашу проблему решили при помощи определенного алгоритма, то не забудьте описать его!
  • Если вопрос решён, то воспользуйтесь ссылкой "Пометить как решённый", которая находится под кнопками создания темы или специальным флажком при ответе.

Более подробно с правилами данного раздела Вы можете ознакомится в этой теме.

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

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


 




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


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

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