Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > игра сокобан


Автор: ratgunter 11.10.2009, 19:33
подскажите, как организовать игровое поле размером 10 на 10?

Автор: ИванМ 11.10.2009, 19:46
Легче всего пользоваться компонентом типа TDrawGrid: RowCount=10, ColCount=10. 
Также можно свой компонент написать, можно вручную рисовать в канве, можно воспользоваться OpenGL/DirectX, ...

Автор: ratgunter 12.10.2009, 09:21
помогите преобразовать код с паскаля в билдер
Код

function done:boolean;
var i1,j1:integer;
k:boolean;
begin
k:=true;
for i1:=1 to max_i do
for j1:=1 to max_j do if stage[i1,j1]=4 then begin
                                             k:=false;
                                             break;
                                             end;
done:=k;
end;

Автор: Usper 12.10.2009, 12:38
Примерно так:
Код

bool done ()
{
bool k;
k=true;
for(int i1=1; i1<=max_i; i1++)
   for(int j1=1; j1<=max_j; j1++)
      if(stage[i1,j1]=4 {k=false; break;}
return k;
}


Честно говоря, я подзабыл уже как организуются циклы в паскале, поэтому возможно надо вместо "<=" поставить "<" здесь i1<=max_i и здесь  j1<=max_j

Автор: ИванМ 12.10.2009, 19:28
Код

bool done()
{
for(int i1=0; i1<max_i; i1++)
   for(int j1=0; j1<max_j; j1++)
      if(stage[i1][j1]==4) return false;
return true; 
}

Автор: ratgunter 15.10.2009, 05:38
Спасибо!

Автор: ratgunter 19.10.2009, 15:27
Помогите заставить двигаться крота и ящики! вот прога: 
http://rapidshare.com/files/295030201/_____________________________.rar.html
или подскажите как всеже сделать игровое поле, а то я тупо изображениями его построил.

Автор: ratgunter 28.10.2009, 20:58
подскажите как выполнить данный код:

 for (int i=100;i<107;i++)
   {
      Imagei->Visible=false;
   }
Надо чтоб все Image с 100 по 107 стали невидимыми

Автор: xvr 29.10.2009, 14:03
Цитата(ratgunter @ 28.10.2009,  20:58)
подскажите как выполнить данный код:

 for (int i=100;i<107;i++)
   {
      Imagei->Visible=false;
   }
Надо чтоб все Image с 100 по 107 стали невидимыми

Код

for (int i=100;i<108;i++)
   {
     ((TControl*)FindComponent(String("Image")+i))->Visible=false;
   }

Автор: ratgunter 29.10.2009, 17:41
Огромное спасибо!!!!

Автор: ratgunter 31.10.2009, 14:54
Подскажите, как сделать чтобы не вручную для Image1 загружать картинку?
Должно по моему быть вот так, но почему то не работает:
Код

Image1->Picture->LoadFromFile(OpnDlg->FileName)

хотя так у меня на OpnDlg ругается.
Например у меня картинка называется 'Крот'
подскажите как написать.

Автор: xvr 31.10.2009, 16:45
Цитата(ratgunter @ 31.10.2009,  14:54)
Подскажите, как сделать чтобы не вручную для Image1 загружать картинку?
Должно по моему быть вот так, но почему то не работает:
Код

Image1->Picture->LoadFromFile(OpnDlg->FileName)


Вроде правильно
Цитата

хотя так у меня на OpnDlg ругается.
Видимо OpnDlg отсуствует

Автор: ratgunter 31.10.2009, 17:33
Еще раз скажу что надо: например у меня есть Image1. Если Image2->Top==80, то надо чтобы Image1 автоматически загрузила картинку например с такого пути C:\Users\Ratgunter\Desktoр

Автор: xvr 1.11.2009, 09:55
Цитата(ratgunter @ 31.10.2009,  17:33)
Еще раз скажу что надо: например у меня есть Image1. Если Image2->Top==80, то надо чтобы Image1 автоматически загрузила картинку например с такого пути C:\Users\Ratgunter\Desktoр

Код

if (Image2->Top==80) Image1->Picture->LoadFromFile("C:\\Users\\Ratgunter\\Desktoр");

Автор: ratgunter 1.11.2009, 12:08
Выдает такую ошибку:
http://pixs.ru/showimage/1jpg_9070974_337452.jpg
Правильно ли я все делаю?
Код

Image1->Picture->LoadFromFile("C:\\Users\\Ratgunter\\Desktop\\Крот");

Рисунок надо в формате jpeg или bmp?

Автор: xvr 1.11.2009, 18:54
Цитата(ratgunter @ 1.11.2009,  12:08)
Выдает такую ошибку:
http://pixs.ru/showimage/1jpg_9070974_337452.jpg
Правильно ли я все делаю?

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

Автор: ratgunter 1.11.2009, 19:30
Спасибо большое smile  smile  smile  Очень помогли!!!

Автор: ratgunter 1.11.2009, 21:29
Еще вопросик: как сделать такую запись
Код

(TControl*)FindComponent(String("Image")+i)->Picture->LoadFromFile("C:\\Users\\Ratgunter\\Desktop\\Крот.jpg");
 
Пишет, что Picture не является компонентом  Control, ну или типа того.

Автор: xvr 2.11.2009, 10:37
Цитата(ratgunter @ 1.11.2009,  21:29)
Еще вопросик: как сделать такую запись
Код

(TControl*)FindComponent(String("Image")+i)->Picture->LoadFromFile("C:\\Users\\Ratgunter\\Desktop\\Крот.jpg");
 
Пишет, что Picture не является компонентом  Control, ну или типа того.

Надо привести типы более точно -
Код

((TImage*)FindComponent(String("Image")+i))->Picture->LoadFromFile("C:\\Users\\Ratgunter\\Desktop\\Крот.jpg");

Автор: ratgunter 2.11.2009, 14:21
Еще раз огромнейшее спасибо за помощь!!! 

Автор: ratgunter 2.11.2009, 17:48
Простите за кучу вопросов, но как сделать:
1)
если я нажал на Image60, то поменять картинку.
Код

Image640->Picture->LoadFromFile("D:\\Крот.jpg");
       if (Image60->OnClick)
       Image640->Picture->LoadFromFile("D:\\Крот2.jpg");

После данного кода независимо от того, нажал я Image60 или нет, сразу загружается Крот2.

2)
Как сравнить, чтобы не двигалось, если стена рядом: 
Код

if(Image640->Left!=((TImage*)FindComponent(String("Image")+i))->Picture->LoadFromFile("D:\\Стена3.jpg")->Left)
{
if(Key==68) Image640->Left+=40;
}

HELP!!!
 

Автор: xvr 2.11.2009, 19:47
Цитата(ratgunter @ 2.11.2009,  17:48)
Простите за кучу вопросов, но как сделать:
1)
если я нажал на Image60, то поменять картинку.
Код

Image640->Picture->LoadFromFile("D:\\Крот.jpg");
       if (Image60->OnClick)
       Image640->Picture->LoadFromFile("D:\\Крот2.jpg");

После данного кода независимо от того, нажал я Image60 или нет, сразу загружается Крот2.

разумеется. OnClick - это event (т.е. указатель на процедуру). Если он присвоен, то if (Image60->OnClick) будет всегда выполняться.
Что бы что то сделать при нажатии, это что-то надо поместить в функцию обработки события Click
Цитата

2)
Как сравнить, чтобы не двигалось, если стена рядом: 
Код

if(Image640->Left!=((TImage*)FindComponent(String("Image")+i))->Picture->LoadFromFile("D:\\Стена3.jpg")->Left)
{
if(Key==68) Image640->Left+=40;
}

HELP!!!
Сей кусок кода не понял. Нафига там Picture->LoadFromFile("D:\\Стена3.jpg") ?

Автор: ratgunter 2.11.2009, 21:32
Насчет первого вопроса сам разобрался, намудрил много smile 
Насчет второго-просто хотел упростить алгоритм движения...

Автор: Platov 4.11.2009, 17:11
Мне кажется проще поле хранить в массиве например int где на каждый тип клетки своё число. Все операции выполнять с этим массивом. А потом по массиву отрисовывать поле в специальной функции.
 smile 

Автор: ratgunter 11.11.2009, 09:36
Подскажите, как можно сделать таблицу рекордов. Счетчики у меня есть, мне надо результаты как то записать в файл. Помогите!

Автор: xvr 11.11.2009, 16:23
Цитата(ratgunter @ 11.11.2009,  09:36)
Подскажите, как можно сделать таблицу рекордов. Счетчики у меня есть, мне надо результаты как то записать в файл. Помогите!

fprintf уже отменили?

Автор: ratgunter 12.11.2009, 16:54
Да просто никогда в билдере ничеог в файл не записывал..

Автор: xvr 12.11.2009, 18:26
Ну тогда по порядку:
  •  Открываешь файл с помощью fopen
  •  Пишешь в него построчно в цикле (или как надо) с помощью fprintf
  •  Закрываешь с помощью fclose

Автор: ratgunter 16.11.2009, 08:07
подскажите идейки, как можно сделать редактор уровней.

Автор: ratgunter 20.11.2009, 18:08
Вопрос такой:
Я делаю уровень в редакторе уровней. Сам редактор работает так: на панель закидываю много Image и им программно задаю картинки.
Но как мне сохранить панель и открыть ее с моими Image' ами? Диалог SaveDialog сохраняет только Image, а хотелось бы чтоб полностью мою панель...
Помогите!!! надо до 10 декабря доделать!

Автор: DenWPF 20.11.2009, 18:48
вообще не правльный какой то подход.

1. игра это массив int  - где каждая цифра отвечается свою ячейку и все 
2. есть функция конторая рисует этот массив.


и вот мой пример, даже не помню на чем написан. вроде C++ GDI+ VS2008

Автор: ratgunter 23.11.2009, 10:16
Ну а я может так хочу сделать) Ладно, буду думать сам...

Автор: DenWPF 23.11.2009, 12:32
ну мучайся)

Автор: ratgunter 24.11.2009, 16:14
Подскажите как сделать таблицу рекордов.
У меня есть 10 уровней, для каждого уровня есть свой Label, для каждого уровня считаю количество сделанных шагов и для каждого Label в свойство Caption присваиваю значение. Как теперь эти значения сохранить, куда сохранить? Например на форме их сохранять в StringGrid? А подмкажите как эти значения сохранить в файле, а потом эти значения загружать в StringGrid.

Автор: xvr 24.11.2009, 18:59
Цитата(ratgunter @ 24.11.2009,  16:14)
Подскажите как сделать таблицу рекордов.
У меня есть 10 уровней, для каждого уровня есть свой Label, для каждого уровня считаю количество сделанных шагов и для каждого Label в свойство Caption присваиваю значение.

Мсье не ищет легких путей  smile 
Цитата

Как теперь эти значения сохранить, куда сохранить? 
Ну например понаделать директорий из имен победителей и счета. Вполне будет в духе остальных решений  smile 

Цитата

Например на форме их сохранять в StringGrid? 
Присваивать руками поштучно

Цитата

А подмкажите как эти значения сохранить в файле, а потом эти значения загружать в StringGrid.

Код

StringGrid1->Cols[0]->SaveToFile("names.lst");
StringGrid1->Cols[1]->SaveToFile("values.lst");
для загрузки соотвественно LoadFromFile

Автор: DenWPF 24.11.2009, 19:31
так стоп, а как же ты хранишь карты????точнеее где??

скажу что самое простое..хранить их в файле текстовом с своим расширением.

очень удобно.

Автор: Platov 25.11.2009, 18:07
Уже 2 человека говорят что подход не верен изначально. Если работать с массивом то всё это делается ОЧЕНЬ просто и редактор уровней тоже! Если начать сначала то можно и до 1 декабря успеть.

Автор: ratgunter 25.11.2009, 22:46
Ну а где на форме этим массивом рисовать?

Автор: DenWPF 25.11.2009, 23:07
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

вот массив 4 на 4
проходишь по нему где 0 там рисуешь элемент соотвествующий 0.

Автор: ratgunter 26.11.2009, 15:31
Да я понял, на форме то как  этот массив сделать?

Автор: DenWPF 26.11.2009, 15:47
в плане на форме? 
ты GDI+ знаешь что такое?

Автор: ratgunter 26.11.2009, 17:20
Нет

Автор: DenWPF 26.11.2009, 18:04
а как ты рисуешь что то ?

Автор: ratgunter 26.11.2009, 21:58
Через Image

Автор: DenWPF 26.11.2009, 22:13
ну вот и рисуй, тольо в нужных кординатах.
кордината картинки  = размер * (х + y) вроде

Автор: Platov 27.11.2009, 10:13
Лови мега пример рисования image с нужной картинкой в нужном месте.
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

const int rx=50,ry=50;
int n=0;
AnsiString DIR;

//---------------------------------------------------------------------------
void __fastcall TForm1::create(int X, int Y,TObject *Sender,AnsiString pic)
{
n++;
TImage* Im=new TImage(Form1);

Im->Parent=Form1;

Im->Picture->LoadFromFile(pic);
Im->Width=rx;
Im->Height=ry;

Im->Name="Im"+String(n);
Im->Left=X;
Im->Top=Y;

}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
DIR=ParamStr(0);DIR=ExtractFileDir(DIR)+"\\";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
create(100, 100,Sender,DIR+"p1.bmp");
}
//---------------------------------------------------------------------------


Автор: ratgunter 27.11.2009, 13:28
Подскажите, как сделать так, чтобы текстовый файл file.txt был всегда привязан к папке Sokoban. И как задать путь  Sokoban\file.txt чтобы программа сама его находила, а не пришлось самому его прописывать.

Автор: DenWPF 27.11.2009, 13:35
Directory.GetCurrentDirectory - но это Сшарп =)) что то подобное и у тебя должно быть=)

Автор: xvr 27.11.2009, 14:50
Цитата(ratgunter @ 27.11.2009,  13:28)
Подскажите, как сделать так, чтобы текстовый файл file.txt был всегда привязан к папке Sokoban. И как задать путь  Sokoban\file.txt чтобы программа сама его находила, а не пришлось самому его прописывать.

Код

ExtractFilePath(Application->ExeName)+"file.txt"

Автор: Platov 27.11.2009, 17:43
Этот вариант лучше. Поверьте мне. 

Код

DIR=ParamStr(0);DIR=ExtractFileDir(DIR)+"\\";


Как бы вы не запустили прогу, а её место на венике неизменно. А вот все остальные методы не дают 100% гарантии.

хотя
Код

ExtractFilePath(Application->ExeName)+"file.txt"


скорее всего равноценен.

Автор: xvr 27.11.2009, 20:31
Цитата(Platov @ 27.11.2009,  17:43)
Этот вариант лучше. Поверьте мне. 

Код

DIR=ParamStr(0);DIR=ExtractFileDir(DIR)+"\\";


Как бы вы не запустили прогу, а её место на венике неизменно. 

Очень распространенное заблуждение.  smile Проблема в том, что argv[0] (ParamStr(0)) формируется ЗАПУСКАЮЩЕЙ программой, и она вольна положить туда что угодно  smile 
Пример:
Код

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

int main(int argc, char** argv)
{
 if (argc==1)
  {
   STARTUPINFO si = {sizeof(STARTUPINFO)};
   PROCESS_INFORMATION pi = {0};
   CreateProcess("tst.exe","QuqQua Im Not a me",NULL,NULL,FALSE,0,NULL,NULL,&si,&pi);
   return 0;
  }
 for(int i=0;i<argc;++i)
  printf("%s\n",argv[i]);
 return 0;
}
Если это запустить с параметрами, то она их печатает:
Цитата

C:\!t>tst.exe 1 2 3
C:\!t\tst.exe
1
2
3
Если же ее запустить без параметров, то она запускает себя, но вместо своего имени в 0м параметре задает QuqQua:
Цитата

C:\!t>tst.exe
QuqQua
Im
Not
a
me


Цитата

хотя
Код

ExtractFilePath(Application->ExeName)+"file.txt"

скорее всего равноценен.
Действительно равноценно:
Код

function TApplication.GetExeName: string;
begin
  Result := ParamStr(0);
end;
Тогда вместо Application->ExeName надо пользоваться этим:
Код

   char buf[MAX_PATH];
   GetModuleFileName(NULL,buf,sizeof(buf));
   ...=ExtractFilePath(buf)+"file.txt";
Это 100% гарантия

Автор: Platov 27.11.2009, 23:12
 
xvr,  smile 

Автор: ratgunter 29.11.2009, 09:29
Ой как много всего, спасибо. Но что-то я немножко не понял. Я хочу написать НЕ
Код

RecordTable->Rows[1]->SaveToFile("D:\\number.txt");

А вот так хочу написать, просто название папки, чтобы прога сама ее нашла и записала в нее:
Код

RecordTable->Rows[1]->SaveToFile("Sokoban");

Автор: xvr 29.11.2009, 09:49
Цитата(ratgunter @ 29.11.2009,  09:29)
Ой как много всего, спасибо. Но что-то я немножко не понял. Я хочу написать НЕ
Код

RecordTable->Rows[1]->SaveToFile("D:\\number.txt");

А вот так хочу написать, просто название папки, чтобы прога сама ее нашла и записала в нее:
Код

RecordTable->Rows[1]->SaveToFile("Sokoban");

Код

AnsiString file_name(AnsiString n)
{
  char buf[MAX_PATH];
  GetModuleFileName(NULL,buf,sizeof(buf));
  return ExtractFilePath(buf)+n;
}


...
RecordTable->Rows[1]->SaveToFile(file_name("sokoban.txt"));
...


Автор: ratgunter 29.11.2009, 10:15
Ругается на 
AnsiString file_name(AnsiString n)
Пишет:
[C++ Error] Unit1.cpp(1085): E2108 Improper use of typedef 'AnsiString'

Автор: xvr 29.11.2009, 18:41
Цитата(ratgunter @ 29.11.2009,  10:15)
Ругается на 
AnsiString file_name(AnsiString n)
Пишет:
[C++ Error] Unit1.cpp(1085): E2108 Improper use of typedef 'AnsiString'

Эта часть
Код

AnsiString file_name(AnsiString n)
{
  char buf[MAX_PATH];
  GetModuleFileName(NULL,buf,sizeof(buf));
  return ExtractFilePath(buf)+n;
}

является глобальной функцией и должна быть записана ВНЕ каких либо функций (на уровне файла)

Добавлено через 3 минуты и 22 секунды
PS. Советы в конференции не надо трактовать как книгу по черной магии, которую надо вызубрить назубок, и не приведи господь ошибиться хоть в звуке  smile 
Тут дают советы, и предполагается, что спрашивающий в состоянии их понять и применить, а не тупо скопировать к себе в код куда попало  smile 

Автор: DenWPF 29.11.2009, 18:50
прям блин в описание разделов "Тут дают советы, и предполагается, что спрашивающий в состоянии их понять и применить, а не тупо скопировать к себе в код куда попало   "
сори за флуд

Автор: ratgunter 30.11.2009, 14:50
Как говорится:"Не стыдно не знать - стыдно не учиться". 
Еще один вопрос:
Так работает все правильно
Код

RecordTable->Rows[1]->SaveToFile("D:\\test.txt");

А можно ли сохранить не ряд целиком, а только один фрагмент, например
Код

RecordTable->Cells[2][1]->SaveToFile("D:\\test.txt");

Автор: xvr 30.11.2009, 15:09
Цитата(ratgunter @ 30.11.2009,  14:50)
А можно ли сохранить не ряд целиком, а только один фрагмент, например
Код

RecordTable->Cells[2][1]->SaveToFile("D:\\test.txt");

Нет. RecordTable->Cells[2][1] - это AnsiString, у него нет метода SaveToFile. Открывай файл обычным методом (fopen или ofstream), и printf (или <<) туда.

Автор: ratgunter 1.12.2009, 18:05
Блин, подскажите пожалуйста без всяких насмешек:
У меня есть Label1 и у него в Caption записано число 7.
Напишите плиз подробно, как это число записать в файл, а потом как его считать и загрузить например в Label2->Caption, при этом сделав все преобразования типов. Помогите пожалуйста!!!!

Автор: xvr 1.12.2009, 20:02
Цитата(ratgunter @ 1.12.2009,  18:05)
Блин, подскажите пожалуйста без всяких насмешек:
У меня есть Label1 и у него в Caption записано число 7.
Напишите плиз подробно, как это число записать в файл, 

Код

FILE* f=fopen("file.txt","wt");
fprintf(f,"%d\n",Label1->Caption.c_str());
fclose(f);


Цитата

а потом как его считать и загрузить например в Label2->Caption, 

Код

FILE* f=fopen("file.txt","rt");
int val;
fscanf(f,"%d",&val);
Label2->Caption=val;
fclose(f);



Автор: ratgunter 1.12.2009, 20:26
Спасибо.

Автор: ratgunter 2.12.2009, 15:15
Простите за тупой вопрос:
А перед написанием этих строк, где и что надо прописать(например прога ругается на  FILE и f)
Блин ступил, надо добавить stdio.h да?

Автор: ratgunter 2.12.2009, 15:56
У меня Label1->Caption==91;
А когда я открываю свой текстовый файл, то в нем не 91, а 17070136
Что это за цифры?

Автор: xvr 2.12.2009, 16:57
Цитата(ratgunter @ 2.12.2009,  15:56)
У меня Label1->Caption==91;
А когда я открываю свой текстовый файл, то в нем не 91, а 17070136
Что это за цифры?

Это адрес строки  smile Я немного ошибся в формате printf - надо так
Код

fprintf(f,"%s\n",Label1->Caption.c_str());

Автор: ratgunter 2.12.2009, 17:10
Спасибо! Сохраняет нормально!

Добавлено через 4 минуты и 47 секунд
Но теперь загружает из фала неправильно)
как загрузить например цифру 7
и как загрузить например Имя игрока

Автор: xvr 2.12.2009, 20:25
Цитата(ratgunter @ 2.12.2009,  17:10)
Спасибо! Сохраняет нормально!

Добавлено @ 17:14
Но теперь загружает из фала неправильно)
как загрузить например цифру 7
и как загрузить например Имя игрока

Читать тоже строкой в массив
Код

char buf[1024];
fgets(buf,sizeof(buf),file);
Label1->Caption=AnsiString(buf).Trim();
Trim тут нужен что бы убрать символ '\n' в конце строки. Но при этом обрежутся все пробелы в начале и конце

Автор: ratgunter 2.12.2009, 20:52
Т.е. вот этот код
Код

char buf[1024];
fgets(buf,sizeof(buf),file);
Label1->Caption=AnsiString(buf).Trim();

надо написать вместо вот этого
Код

FILE* f=fopen("file.txt","rt");
int val;
fscanf(f,"%s",&val);
Label2->Caption=val;
fclose(f);

Или как?

Автор: Platov 2.12.2009, 22:10
может так легче будет...

Код

TStringList * text = new TStringList ; //общая часть

//запись
text->Clear;
text->Add(Label1->Caption);//число
text->Add(Label2->Caption);//имя
text->SaveToFile("file.txt");


//чтение
if (FileExists("text.txt")
 {
  text->LoadFromFile("text.txt");
  if (text->Count>1)
   {
    Label1->Caption=text->Strings[0]; //число
    Label2->Caption=text->Strings[1]; //имя
   }
 }


delete text; //общая часть


и число и имя будут жить в одном файле (это намёк на то что не следует каждый Label сохранять в отдельном файле... сохрани всё что надо в один конфигурационный файл)

Автор: xvr 2.12.2009, 22:22
Цитата(ratgunter @ 2.12.2009,  20:52)
Т.е. вот этот код
надо написать вместо вот этого

Угу

PS. Platov абсолютно прав по поводу сохранения всего в один файл (с помощью TStringList)

Автор: ratgunter 2.12.2009, 22:44
Спасибо xvr и Platov!!!!

Автор: ratgunter 5.12.2009, 12:33
Хочу сказать спасибо всем кто помогал. В игре у меня щас все работает. Осталось самое ужасное- редактор уровней.
Вообще что мне надо сделать:
1) Редактор уровней
2) Возможность сохранять созданные уровни, а потом их загружать.
3) К названию уровня добавлять имя создателя. 
 Прошу всех помочь в создании. Сперва хочу понять как, на чем и где его размещать в билдере и сам алгоритм:
1) Создать txt файл, в котором будет 10 рядов по 10 столбцов. 
 Пусть 1-ящик
           2-стена
           3-место для ящика
           4-крот.
Вопросы:
Как этот txt файл загрузить на форму, как для каждой цифры загрузить картинку(например "Крот.jpg")
Как потом это все двигать ну т.д.
Прошу помочь, надо сдавать 13 декабря.

Автор: xvr 5.12.2009, 15:54
Цитата(ratgunter @ 5.12.2009,  12:33)
Вообще что мне надо сделать:
1) Редактор уровней
2) Возможность сохранять созданные уровни, а потом их загружать.
3) К названию уровня добавлять имя создателя. 
 Прошу всех помочь в создании. Сперва хочу понять как, на чем и где его размещать в билдере и сам алгоритм:
1) Создать txt файл, в котором будет 10 рядов по 10 столбцов. 
 Пусть 1-ящик
           2-стена
           3-место для ящика
           4-крот.
Вопросы:
Как этот txt файл загрузить на форму, 

Собственно сам уровень внутри редактора (и игры) лучше хранить в виде массива (2х мерного)
Код

char level[10][11];
11й char для завершающего 0. Сами данные хранить в виде символов (1/2/3/4 или лучше каких нибудь более осмысленных, например '*# K')
Запись в файл (параметр - имя создателя уровня):
Код

void SaveLevelToFile(AnsiString creator, AnsiString file_name)
{
 TStringList* sl=new TStringList;
 for(int i=0;i<10;++i) sl->Add(level[i]);
 sl->Add(creator);
 sl->SaveToFile(file_name);
 delete sl;
}
Чтение, возвращает имя создателя уровня:
Код

AnsiString LoadLevelFromFile(AnsiString file_name)
{
 TStringList* sl=new TStringList;
 sl->LoadFromFile(file_name);
 for(int i=0;i<10;++i) strncpy(level,sl->Strings[i].c_str(),10);
 AnsiString rv=sl->Strings[10];
 delete sl;
 return rv;
}
Инициализация массива уровней (для нового уровня)
Код

void init()
{
 for(int i=0;i<10;++i)
  {
   memset(level[i],' ',10);
   level[i][10]=0;
  }
}

Цитата

как для каждой цифры загрузить картинку(например "Крот.jpg")
Куда ее надо грузить?
Цитата

Как потом это все двигать ну т.д.
А не надо это двигать. Простейший редактор можно сделать просто задавая содержимое для каждой конкретной ячейки. Т.е. рисуем на экране курсор вокруг текущей ячейки (например рамкой), по нажатию определенных клавишь на клавиатуре помещаем в нее определенное значение (как на экране, так и в массиве level)

Автор: ratgunter 5.12.2009, 16:35
Вопрос: я все же не пойму, ну запустил я билдер, у меня появилась пустая форма. И мне прям на ней создавать уровень? 

Автор: vikaz 5.12.2009, 22:16
Цитата(ratgunter @  5.12.2009,  18:35 Найти цитируемый пост)
Вопрос: я все же не пойму, ну запустил я билдер, у меня появилась пустая форма. И мне прям на ней создавать уровень?  

Что значит прям здесь? Вам нужно написать еще одну небольшую программу, или встроить в игру, редактор уровней. Для этого нужно найти подходящий компонент для реализации массива 10х10 и на его базе и писать всю визуализацию..... Для этого можно ,попробовать, динамически построить сетку из TImage. Тем самым Вы сможете графически отображать что будет находиться в каждой клетке , ну а выбор, что может быть в определенной ячейке, можно сделать через PopupMenu. 

Автор: ratgunter 5.12.2009, 22:52
Да я уже голову сломал, никак не могу редактор сделать, мож у кого-нибудь есть готовый пример....?

Автор: vikaz 5.12.2009, 22:55
сек

Добавлено через 7 минут
ни у кого под тебя готового редактора не будет

Автор: vikaz 5.12.2009, 23:13
Я думаю, что должно быть примерно так!

user posted image

Вот код кнопки заполнения Image:
Код

 int PosX = 0, PosY = 0, k = 0;
 TImage * Image[100];

 for (int i=1; i <= 10; i++)
 {
  for (int j = 1; j <= 10; j++)
  {
   Image [k] = new TImage (Form1);
   Image [k]->Height = 40;
   Image [k]->Width = 40;
   Image [k]->Left = PosX + ((i-1) * Image [k]->Width);
   Image [k]->Top = PosY + ((j-1) * Image [k]->Height);
   if (i == 1 || i == 10 || j == 1 || j == 10)
   {
    Image [k]->Picture->LoadFromFile("c:\\mole_2.bmp");
   }
    else Image [k]->Picture->LoadFromFile("c:\\null.bmp");

   Image [k]->PopupMenu = PopupMenu1;
   Image [k]->Parent = Form1;
   k++;
  }
 }
 Form1->AutoSize = true;


Ну и не нужно забывать очищать массив, который создали при помощи new

Автор: ratgunter 5.12.2009, 23:57
Ну вот просто нечеловеческое спасибо!!! Ща буду пробовать. кстати дизайн у меня похожий, а крот такойже(из польского мультика), только он в позе другой smile 

Автор: ratgunter 6.12.2009, 22:19
Значит я пока сделал возможность создавать уровень
http://pixs.ru/showimage/eskizjpg_7439707_372125.jpg
теперь мне надо как-то прочитать мой массив из Image'ов и при нажатии на кнопку сохранить он должен записаться в файл вот в таком виде
1111111111
1000000001
1000020201
1001111001
1003111201
1000331001
1000000001
1000000001
1400000001
1111111111
где 
0-пустота
1-стена
2-ящик
3-место для ящика
4-крот
Вопрос: а как это сделать то??? 

Автор: vikaz 7.12.2009, 06:25
Если честно, я почему-то был уверен, что в Image сохраняется название загруженного изображения, но вроде это не так, в общем не нашел..... Наверное надо вводить еще один строковой массив в который параллельно будешь писать все изменения при построении уровня. Других предложений пока нет! smile

Добавлено через 1 минуту и 20 секунд
ЗЫ. Фон у всех картинок сделай одинаковым, очень сильно бросается в глаза.....

Добавлено через 5 минут и 34 секунды
зы. зы А почему ты сразу не отображаешь в массиве изменения? Вот сразу как устанавливаешь картинку и пока ты знаешь, что и где ты размещаешь, сразу же и  массиве отмечай, в чем сложность? 

Автор: ratgunter 7.12.2009, 10:58
Действительно, надо сразу записывать в массив smile А вот мой самый нелюбимый момент в билдере. Чтобы сохранить мой массив(кстати его делать int'овским или char'овским?) что использовать: fprintf или что??? И как сделать чтобы при нажатии на мою кнопку "Сохранить" текстовый файл создавался автоматически???

Автор: vikaz 7.12.2009, 11:52
Цитата(ratgunter @  7.12.2009,  12:58 Найти цитируемый пост)
Действительно, надо сразу записывать в массив smile А вот мой самый нелюбимый момент в билдере. Чтобы сохранить мой массив(кстати его делать int'овским или char'овским?) что использовать: fprintf или что??? И как сделать чтобы при нажатии на мою кнопку "Сохранить" текстовый файл создавался автоматически??? 


Конечно int [i][j]; Автоматически ничего не бывает, пока не напишешь или кто-то не напишет! smile
Тебе надо сохранять не только сам массив, но и доп. информацию: Имя создателя (автора),  и название уровня. Я бы порекомендовал создать структуру, в ней описать все типы и сохранять саму структуру. Ну а при чтении уровня, все записываем в структуру, а потом уже и визуализируем на форме, все что было в файле! Извини, весь механизм описать не могу, нет у меня этого под рукой, а так не помню.
Код

struct 
{
  int [10][10];
  String Name_Level;
  String Name_Autрor;
};

Вроде как-то так!
После чего открываешь файл на запись как двоичный и записываешь всю структуру целиком. 

ЗЫ. Делал такое очень давно, и не все помню... Только идея!

Автор: ratgunter 7.12.2009, 12:40
Дело в том что структуры я не знаю((((

Автор: vikaz 7.12.2009, 12:42
А там нет ничего сложного. ИМХО так будет правильнее... Ну тогда через printf выводи посимвольно в файл.

Добавлено через 1 минуту и 23 секунды
ЗЫ. Как в мультфильме: "...Лучше день потерять, а потом за 5 минут долететь....."

Автор: xvr 7.12.2009, 16:17
Цитата(ratgunter @ 6.12.2009,  22:19)
теперь мне надо как-то прочитать мой массив из Image'ов и при нажатии на кнопку сохранить он должен записаться в файл 

Вопрос: а как это сделать то???

Я тебе уже писал как, вплоть до функций чтения и записи - http://forum.vingrad.ru/index.php?showtopic=276181&view=findpost&p=2038552


Автор: ratgunter 7.12.2009, 16:43
Да я это помню, а как массив то записать?

Автор: xvr 7.12.2009, 17:11
Цитата(ratgunter @ 7.12.2009,  16:43)
Да я это помню, а как массив то записать?

Функция SaveLevelToFile в моем посте

Автор: ratgunter 7.12.2009, 18:46
а можно показать пример как массив через printf записать в файл, а тоя делаю а у меня только одна цифра записывается(((

Автор: xvr 7.12.2009, 20:43
Цитата(ratgunter @ 7.12.2009,  18:46)
а можно показать пример как массив через printf записать в файл, а тоя делаю а у меня только одна цифра записывается(((

Массив - только поэлементно, в цикле. Сразу весь можно ТОЛЬКО в том случае, если этот массив есть символьная строка (т.е. массив char'ов, содержащий только печатаемые символы и завершенный кодом 0)

Автор: ratgunter 7.12.2009, 21:42
Типа вот этого?
Код

for (int i=0; i<10; i++)
{
    for (int j=0; j<10; j++)
    {
          FILE* f=fopen("level.txt","wt");
          fprintf(f,"%s\n",j);
          fprintf(f,"\n");
          fclose(f);

Я говорю, не умею работать с файлами((((

Автор: xvr 7.12.2009, 23:32
Цитата(ratgunter @ 7.12.2009,  21:42)
Типа вот этого?
Код

for (int i=0; i<10; i++)
{
    for (int j=0; j<10; j++)
    {
          FILE* f=fopen("level.txt","wt");
          fprintf(f,"%s\n",j);
          fprintf(f,"\n");
          fclose(f);

Я говорю, не умею работать с файлами((((

Не совсем, типа вот этого
Код

FILE* f=fopen("level.txt","wt");
for (int i=0; i<10; i++)
{
    for (int j=0; j<10; j++)
    {
     fprintf(f,"%d ",level[i][j]);
    }
 fprintf(f,"\n");
}
fclose(f);
(Это если в массиве level дежат числа, если же там лежат символы, то центральный fprintf должен быть такимsmile
Код

     fprintf(f,"%c ",level[i][j]);


Автор: ratgunter 7.12.2009, 23:42
спасибо smile  буду дальше эксперементировать smile 

Автор: ratgunter 8.12.2009, 21:00
Не судите строго, но я записал массив в файл smile 


 ! 
dumb
ratgunter, эта тема и без этих оффтопичных постов нарушает правила форума. "живет" она только потому, что вопросы твои не имеет смысла(и интереса) оформлять в виде отдельных тем - слишком элементарны. а если б ты удосужился прочитать(вдумчиво) хоть какую-нибудь литературу по С++(Builder), то и у тебя бы их не возникло.

Автор: xvr 8.12.2009, 22:17
Цитата(ratgunter @ 8.12.2009,  21:00)
Не судите строго, но я записал массив в файл smile

Код

 XXXXXXX                                                                                             X       X       X
  X   X                                                                                              X       X       X
  X   X  XX XX    XXXXX  X XXXX  XXXXXX  XX XX    XXXXX  XXXXXX   XXXXXX  XXXXXX   XXXX  XXX  XXX    X       X       X
  X   X   XX  X       X   XXXX    X  X    XX  X       X   XXXX     X  X   XXXXX   XXXXXX  XX  XX     X       X       X
  X   X   X   X  XXXXXX       X   X  X    X   X  XXXXXX   X   XX   X  X   X   X   X       X XX X
 XXX XXX  XXXX   XXXX XX XXXXX  XXXXXXX   XXXX   XXXX XX XXXXXXX XXX XXX XX  XXX   XXXXX XXXXXXXX    X       X       X
          X                     X     X   X
         XXX                             XXX


Автор: ratgunter 10.12.2009, 18:19
Вот код:
Код

for (i=0;i<10;i++)
          {
             for (j=0;j<10;j++)
             {
                if (level[i][j]==4)
                {
                   if (Key==68)
                   {
                      if (level[i][j+1]==0)
                      {
                         level[i][j+1]=4;
                         level[i][j]=0;
                         Image1324->Left+=40;
                      }
                   }
                   if (Key==65)
                   {
                      if (level[i][j-1]==0)
                      {
                         level[i][j-1]=4;
                         level[i][j]=0;
                         Image1324->Left-=40;
                      }
                   }
                   if (Key==87)
                   {
                      if (level[i-1][j]==0)
                      {
                         level[i-1][j]=4;
                         level[i][j]=0;
                         Image1324->Top-=40;
                      }
                   }
                   if (Key==83)
                   {
                      if (level[i+1][j]==0)
                      {
                         level[i+1][j]=4;
                         level[i][j]=0;
                         Image1324->Top+=40;
                      }
                   }
                }
             }
          }

Когда я жму клавишу D (Key==68)  у меня Image сразу передвигается к правому краю, хотя по идее еге координаты должны увеличиться лишь на 40.
Такая же ситуация с S(Key==83). 
Другие клавиши A и W работают нормально. Ничего не понимаю smile 

Автор: xvr 10.12.2009, 18:28
Цитата

Когда я жму клавишу D (Key==68)  у меня Image сразу передвигается к правому краю, хотя по идее еге координаты должны увеличиться лишь на 40.
По идее они должны вылезти вообще за границу массива. Абсолютно непонятно, что ты пытался тут сделать, но память оно порушит точно  smile 
Твой  if (level[i][j+1]==0) внутри  if (Key==68) будет срабатывать на каждой итерации цикла по j

Автор: ratgunter 10.12.2009, 18:37
У меня по краям карты стоят стены и за них он не выходит, так что память в порядке  smile 
Просто влево идет нормально : на одно нажатие клавиши Image смещается на 40 влево, а когда иду вправо, то Image сразу уходит до стены вправо(((( 
А вообще уровень я сохранил в файл успешно, загрузил из него тоже успешно. Вот теперь пытаюсь сделать, чтобы уровень был рабочим. Но что-то не могу понять как это сделать без огромных циклов smile 

Автор: xvr 10.12.2009, 21:29
Цитата(ratgunter @ 10.12.2009,  18:37)
У меня по краям карты стоят стены и за них он не выходит, так что память в порядке  smile 

Он не по стенам, а по памяти фигачит  smile 
Цитата

Просто влево идет нормально : на одно нажатие клавиши Image смещается на 40 влево, а когда иду вправо, то Image сразу уходит до стены вправо(((( 
Так уж программа написанна  smile 
Цитата

Вот теперь пытаюсь сделать, чтобы уровень был рабочим. Но что-то не могу понять как это сделать без огромных циклов smile
Там вообще циклы не нужны. Нужно хранить (в отдельных переменных) координаты крота (0-10 по х и у). При нажатии клавишь вычислять новые координаты и смотреть в массиве с уровнем, можно ли туда перейти. Если можно - перемещать Image и обновлять координаты

Автор: ratgunter 11.12.2009, 18:37
Нужно хранить (в отдельных переменных) координаты крота (0-10 по х и у). При нажатии клавишь вычислять новые координаты и смотреть в массиве с уровнем, можно ли туда перейти. Если можно - перемещать Image и обновлять координаты
Я так и делаю smile , но что-то не так работает smile 

Автор: xvr 11.12.2009, 18:59
Тот кусок кода, который ты приводил, делает явно не так  smile Там никаких циклов (а тем более двойных) быть не должно

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)