Форум программистов, компьютерный форум, киберфорум
Delphi для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 135
1

Исправьте программу пожалуйсто. Неправильно рисует форму

06.02.2015, 21:40. Показов 1143. Ответов 17
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Снизу скрины текстового файла и при запуске программы что выводит помогите пожалуйсто!!!
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
unit Unit1;
//Игра Сокобан
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ImgList, Menus;
 
type
  TForm1 = class(TForm)
    il1: TImageList;
    dlgOpen1: TOpenDialog;
    imgScreen: TImage;
    imgBackBuffer: TImage;
    mm1: TMainMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    procedure N3Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
    procedure FormKeyDown(Sender: TObject;var Key:Word;Shift: TShiftState);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
const
 wall=8;
 space=0;
 boulder=2;
 place=1;
 placedboulder=3;
 sl=6;
 sr=7;
 su=4;
 sd=5;
var
  Form1: TForm1;
  Field:array[1..20,1..12] of integer; //Игровое поле
  Places:array[1..20,1..12] of Boolean; //Положение мест
  N_of_places:integer; //Общее число мест на уровне
  CurX:integer; //Текущее положение
  CurY:integer; //Сокобана
  Positioned:integer; //Количество размещённых камней
  Busy:Boolean=false;//Статус обработчика клавиш
implementation
 
{$R *.dfm}
 
procedure TForm1.N3Click(Sender: TObject);
begin
application.Terminate;
end;
 
function SymbolToCode(c:Char):integer; //Перевод символа в порядковый номер картинки
begin
 case c of
  'x':SymbolToCode:=WALL; //'x' - стена
  ' ':SymbolToCode:=SPACE; //' ' - пустое пространство
  'b':SymbolToCode:=BOULDER; //' ' - камень
  's':SymbolToCode:=Sl; //'s' - стартовая локация
 else
  SymbolToCode:=-1; //Неизвестный символ
end;
end;
procedure LoadLevel(FileName:string); //Загрузить уровень из файла
var
 f:textfile;
 i,j:integer;
 c:char;
begin
 AssignFile(f,FileName);
 Reset(f);
 N_of_places:=0;
 for j:=1 to 12 do
 begin
  for i:=1 to 20 do
  begin
   Read(f,c);
   if c='p' then  //Если это "место"
   begin
    Field[i,j]:=0; //В поле равнозначно пустому элементу
    Places[i,j]:=true;
    N_of_places:=N_of_places + 1;
   end
   else
   begin
    Places[i,j]:=false;
    Field[i,j]:=SymbolToCode(c);
    if c='s' then
    begin
     CurX:=i;
     CurY:=j;
    end;
   end;
  end;
  Read(f,c);
  Read(f,c);
 end;
 Closefile(f);
end;
procedure RedrawField; //Перерисовка уровня
var
 i,j:integer;
 code:Integer;
 bitmap:TBitmap;
begin
 bitmap:=TBitmap.Create; //Объект для временного хранения рисунка
 Positioned:=0; //Считаем что размещено 0 камней
 for i:=1 to 12 do
  for j:=1 to 20 do
  begin
   code:=field[i,j]; //Код текущего элемента
   if (Field[i,j]=SPACE) and Places[i,j] then
    code:=place
   else
   if (field[i,j]=boulder) and Places[i,j] then
   begin
    code:=placedboulder;
    Positioned:=Positioned+1; //При этом увеличиваем счётчик размещённых камней
   end;
   Form1.il1.GetBitmap(code,bitmap); //Достаём картинку и рисуем её на соответсвующем
   Form1.imgBackBuffer.Canvas.Draw((j-1)*32,(i-1)*32,bitmap); //месте виртуального экрана
  end;
 bitmap.Free;
 {Копируем содержимое виртуального экрана на основной}
 Form1.imgScreen.Canvas.CopyRect(Rect(0,0,640,384),Form1.imgBackBuffer.Canvas,Rect(0,0,640,384));
end;
procedure TForm1.N2Click(Sender: TObject);
begin
if dlgopen1.Execute then
 begin
  LoadLevel(dlgOpen1.Filename);
  RedrawField;
 end;
end;
procedure TForm1.FormKeyDown(Sender:TObject;var key:Word;Shift:TShiftState);
var
 dx,dy:integer;
 Spridx:integer;
begin
 if Busy then
 exit;
 Busy:=true;
 case key of
  VK_LEFT: //Идём влево
  begin
   dx:=-1;
   dy:=0;
   Spridx:=sl;
  end;
  VK_RIGHT:
  begin
   dx:=1;
   dy:=0;
   Spridx:=sr;
  end;
  VK_UP:
  begin
   dx:=0;
   dy:=-1;
   Spridx:=su;
  end;
  VK_DOWN:
  begin
   dx:=0;
   dy:=1;
   Spridx:=sd;
  end;
 else
 begin   //Никуда не идём
  dx:=0;
  dy:=0;
  Spridx:=Field[CurX,CurY];
 end;
 if Field[CurX+dx,CurY+dy]=SPACE then //Если целевая клетка пуста
 begin
  Field[CurX+dx,Cury+dy]:=Spridx; //Переходим в неё
  Field[CurX,CurY]:=space; //На старой позиции теперь ничего нет
  CurX:=CurX+dx;
  CurY:=CurY+dy;
 end
 else
 if (Field[CurX+dx,CurY+dy]=BOULDER) and (Field[CurX+2*dx,CurY+2*dy]=SPACE) then
 begin
  Field[CurX+dx,CurY+dy]:=Spridx;
  Field[CurX+2*dx,CurY+2*dy]:=BOULDER;
  Field[CurX,CurY]:=SPACE;
  CurX:=CurX+dx;
  CurY:=CurY+dy;
 end;
 RedrawField; //Перерисовываем уровень
 //Если все камни размещены
 if Positioned=N_of_places then
  Application.MessageBox('Уровень пройден!','Sokoban',MB_ICONEXCLAMATION);
 Application.ProcessMessages;
 Busy:=false; //Статус = свободно
 end;
end;
procedure TForm1.FormShow(Sender: TObject);
begin
 while not dlgOpen1.Execute do
  LoadLevel(dlgOpen1.FileName);
 RedrawField;
end;
end.
Снизу на скрине формы видно что как-то не так выводится стенка , помогите сделать чтобы стенка была со всех сторон.
Миниатюры
Исправьте программу пожалуйсто. Неправильно рисует форму  
Изображения
 
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.02.2015, 21:40
Ответы с готовыми решениями:

Замыкающийся Polygon неправильно рисует
Если я рисую один полигон и замыкающая линия строится вот так point = point (а вообще полюбому,...

Border-bottom неправильно рисует черту
Здравствуйте. При просмотре в браузере, border-bottom рисует горизонтальную черту, но не внизу...

Переведите пожалуйсто программу на Паскаль
Переведите пожалуйсто программу на Паскаль. Заранее огромное спасибо. #include <iostream.h>...

Диаграмма Вороного:функция матлаба voronoin неправильно рисует ячейки вороного вокруг заданных точек
А никто не сталкивался с проблемой того, что функция матлаба voronoin неправильно рисует ячейки...

17
Заблокирован
06.02.2015, 23:30 2
1 Код оформите как надо.
2 Есть готовая реализация. То есть процедура этой игры. Уровни можно создавать самому в текстовом файле.
3 Если хотите написать сами, помогу. Многие вещи можно делать проще. И потом массивы должен быть динамическим. Поскольку каждый раз игровое поле меняется.
И лучше всего чтобы был исходник. проверять удобнее на компе в собранном проекте чем в оторванном от проекта и формы тексте.

Добавлено через 7 минут
О боже, загрузка уровня это тихий ужас.
Вообще для загрузки даже цикл не нужен.
Отрисовка игрового поля делается намного проще.

Добавлено через 43 минуты
Ну вот посмотрите что собственно должно быть.
Откройте новый проект. На форму бросьте кнопку и листбокс.
В кнопку впишите вот этот код.
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  i:Integer;
  ar: array of integer;
  st: TFileStream;
begin
SetLength(ar,5);
 
ar[0]:=12345;
ar[1]:=2222222;
ar[2]:=55555;
ar[3]:=777777;
ar[4]:=88888;
 
st:=TFileStream.Create( '1.txt', fmCreate);
st.Position:=0;
st.Write(Ar,20);
st.Free;
st:=TFileStream.Create( '1.txt', fmOpenRead );
st.Position:=0;
st.Read(Ar,20);
st.Free;
for i:=0 to 4 do Listbox1.Items.Add(IntToStr(ar[i]));
end;
Здесь происходит следующее.
Создаётся динамический массив
В него вносятся данные.
Массив сохраняется в файл и файл закрывается.
Файл открывается, данные читаются в массив. и отображаются в листбоксе.
Собственно приблизительно так должно должно быть и у вас.

Добавлено через 5 минут
Ну скажем простейший вариант уровня.
вы пишите простейший редактор уровня, который сохраняет уровень в числовой файл
В начале файла заголовок, потом данные
В заголовке указывается уровень сложности, хотя не обязательно. Главное это размеры игрового поля.
По этим данным будет строится массив, в который будут считываться данные.

Добавлено через 3 минуты
Вот приблизительно как это выглядит.
11111111
10000041
10003001
10000001
10020001
10000001
10003041
11111111

0 - пол
1 - стена
2 - погрузчик
3 - груз
4 - место для груза

Добавлено через 3 минуты
Вот эти числа напрямую считываются в двухмерный динамический массив.
И рисуется исходная игровая фаза.
Почти одной строкой в циклах.
То есть мы читаем число, и по этому числу лепим тайл из менеджера картинок в нужное место.
Когда цикла закончится, игровое поле выводится на экран

Добавлено через 3 минуты
Что такое ход?
вы задаёте направление. Положение грузчика известно. Проверяется возможность хода. Если ход возможен, то на место где стоит грузчик записывается ноль туда куда он ходит записывается его код.
В массив.
И по этим данным рисуется новая игровая фаза аналогично со исходной, и по окончании всё выводится на экран

Добавлено через 2 минуты
То есть игра идёт в массиве. А на экране только отображается. И с экрана получаем номер клетки если игра ведётся мышкой.
Если вам больше нравятся клавиши, то тогда нажатие перерисовывает массив, и по этому массиву рисуется очередная фаза игры.

Добавлено через 4 минуты
По поводу рисования. Их менеджера картинок можно выводить спрайт в нескольких вариантах положения координат.
Нужно рассчитать виртуальную сетку и знать её координаты.
Координаты можно вычислять каждый раз, а можно составить вначале игры таблицу и брать координаты из неё.
1
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 135
07.02.2015, 16:26  [ТС] 3
Добавлено через 1 час 11 минут
Помогите пожалуйсто исправить и улучшить проект.
0
Заблокирован
07.02.2015, 18:47 4
Боюсь его придётся делать заново.
И начинать надо с редактора уровня


Хотя ладно. Предположим что уровень вы нарисовали в текстовом редакторе.
Будем тогда работать с текстом.


Подходов море.
Можно каждый раз читать символ из текста.
Можно преобразовать текстовое поле в цифровое.

Я предпочитаю работать с цифрами.


Работать будет с TStringList .
В него загружаем текстовый файл.

Delphi
1
2
Var
LayerTXT:TStringList;
.........................
Delphi
1
LayerTXT:= TStringList.Create;//Создаём список
...................................
Delphi
1
LayerTXT.LoafFromFile(Name);//Загружаем в список текстовый файл
Теперь надо определить габариты игрового поля. То есть его высоту и ширину.
H_ - высота
W_ - ширина


Высота определяется без проблем, но вот ширина.
Строки то могут быть разной длины.
А поскольку данные вносятся в массив, то ширину знать необходимо.
Поэтому нужно или сразу искать максимально длинную строку, или искать её по ходу дела а массив наращивать.


И опять возникает проблема. Как быть с данными?
Чтобы не было подобных коллизий, нужно на составление уровней в текстовом файле наложить жёсткие условия.
Чтобы в каждой строке было одинаковое число символов.
Тогда просто узнаём ширину по первой строке.
Зная высоту и ширину, задаём размеры массива.
Ну а далее составляем числовую копию текстового файла.
По аналогии с вашей функцией SymbolToCode

Теперь о грузчике. Грузчик может двигаться в любом направлении. И поэтому у него 4 тайла.
Начальное положение грузчика всегда одно и тоже. Но чтобы упростить программу и не делать кучу проверок,
координаты грузчика лишь запоминаются.
Сам он в массив не входит и накладывается отдельно, причём с прозрачностью по ключевому свету.
Иначе бы вместо 4 тайлов, нам нужно было бы 8. Поскольку грузчик движется не только по полу но и по зонам груза.
Поэтому на место грузчика в исходном положении ставим пустое поле.
Ну а когда массив заполнится.
Можно рисовать.
0
mss
07.02.2015, 19:01
  #5

Не по теме:

Цитата Сообщение от milz Посмотреть сообщение
Здесь происходит следующее.
..Массив сохраняется в файл .. данные читаются в массив
Ты опять несешь глупости в массы ?
Хоть бы проверить удосужился, прежде чем про тихий ужас рассуждать)

0
Заблокирован
07.02.2015, 19:08 6
2 mss
Дан конкретный код. Проверь.
0
3530 / 2270 / 279
Регистрация: 24.12.2010
Сообщений: 13,723
07.02.2015, 19:19 7
Зачем проверять то что заведомо неработоспособно ?)
0
Заблокирован
07.02.2015, 19:24 8
_____
0
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 135
07.02.2015, 19:41  [ТС] 9
Скажите можно ли пояснить для чего нужно стринг лист? Или вы видите ошибку у меня в текстовом редакторе?
я вот просто щас переделал код вроде бы стены вокруг есть , но с одной стороны 2-ная стена , если вам не трудно мб дадите свой скайп , я вам покажу проект так может более понятнее будет.
0
Заблокирован
07.02.2015, 21:07 10
У вас подход в принципе верный, но реализация оставляет желать лучшего.
Я пытаюсь выправить.
Всё что нужно, загрузить файл уровня.
Перевести его символы в код картинок.
Потом, считывая массив, получать готовые коды и лепить их на игровое поле.

У вас по-видимому проблема с расчётом координат виртуальной сетки.

Добавлено через 1 минуту
какую роль играет массив Places?

Добавлено через 10 минут
Delphi
1
2
3
4
5
6
7
8
9
10
for Y_:=1 to H do begin 
 for X_:=1 to W do  begin  
   //Получаем код тайла 
   s:=  sps[X_,Y_];
   //Координаты вывода на игровое поле.
   X:= X_ * T - T;
   Y:= Y_ * T - T;
   //> Здесь рисование тайла с кодом s в координаты X  Y
end;
end;
Добавлено через 2 минуты
Это вот всё что нужно чтобы нарисовать игровое поле.
Y_ и X_ координаты клетки
Y и X - физические координаты
sps - массив игрового поля

Добавлено через 3 минуты
Я не понимаю зачем определять что рисовать? Есть код в игровом поле, а что он означает это вообще пофиг.

Добавлено через 1 минуту
вот когда вы делаете ход, тогда и надо определять что означает код. а когда рисуется поле, что получил то и нарисовал.
0
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 135
07.02.2015, 22:24  [ТС] 11
Ну я вроде как уже сам со всем разобрался, только осталась одна мелочь, взгляните пожалуйсто на информацию которую я щас вам дам если что-то будет не понятно скажите мне, я объясню. Вопрос вот в чём у меня при выводе изображений правая стенка рисуется 2-ная мне бы это исправить и было бы всё хорошо.
КОД:
Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, ImgList, Menus;
 
type
  TForm1 = class(TForm)
    il1: TImageList;
    dlgOpen1: TOpenDialog;
    imgScreen: TImage;
    imgBackBuffer: TImage;
    mm1: TMainMenu;
    N1: TMenuItem;
    N2: TMenuItem;
    N3: TMenuItem;
    procedure N3Click(Sender: TObject);
    procedure N2Click(Sender: TObject);
    procedure FormKeyDown(Sender: TObject;var Key:Word;Shift: TShiftState);
    procedure FormShow(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
 
const
 wall=8;
 space=0;
 boulder=2;
 place=1;
 placedboulder=3;
 sl=6;
 sr=7;
 su=4;
 sd=5;
var
  Form1: TForm1;
  Field:array[1..12,1..20] of integer; //Игровое поле
  Places:array[1..12,1..20] of Boolean; //Положение мест
  N_of_places:integer; //Общее число мест на уровне
  CurX:integer; //Текущее положение
  CurY:integer; //Сокобана
  Positioned:integer; //Количество размещённых камней
  Busy:Boolean;//Статус обработчика клавиш
implementation
 
{$R *.dfm}
 
procedure TForm1.N3Click(Sender: TObject);
begin
application.Terminate;
end;
 
function SymbolToCode(c:Char):integer; //Перевод символа в порядковый номер картинки
begin
 case c of
  'x':SymbolToCode:=WALL; //'x' - стена
  ' ':SymbolToCode:=SPACE; //' ' - пустое пространство
  'b':SymbolToCode:=BOULDER; //' ' - камень
  's':SymbolToCode:=Sl; //'s' - стартовая локация
  'p':SymbolToCode:=Placedboulder; //'p' - место для камня
 else
  SymbolToCode:=-1; //Неизвестный символ
 end;
end;
procedure LoadLevel(FileName:string); //Загрузить уровень из файла
var
 f:textfile;
 i,j:integer;
 c:char;
begin
 AssignFile(f,'Filename.txt');
 Reset(f);
 N_of_places:=0;
 for i:=1 to 12 do
 begin
  for j:=1 to 20 do
  begin
   Read(f,c);
   if c='p' then  //Если это "место"
   begin
    Field[i,j]:=0; //В поле равнозначно пустому элементу
    Places[i,j]:=true;
    N_of_places:=N_of_places+1;
   end
   else
   begin
    Places[i,j]:=false;
    Field[i,j]:=SymbolToCode(c);
    if c='s' then
    begin
     CurX:=i;
     CurY:=j;
    end;
   end;
  end;
  Readln(f);
 end;
 Closefile(f);
end;
procedure RedrawField; //Перерисовка уровня
var
 i,j:integer;
 code:Integer;
 bitmap:TBitmap;
begin
 bitmap:=TBitmap.Create; //Объект для временного хранения рисунка
 Positioned:=0; //Считаем что размещено 0 камней
 for i:=1 to 12 do
  for j:=1 to 20 do
  begin
   code:=field[i,j]; //Код текущего элемента
   if (Field[i,j]=SPACE) and Places[i,j] then
    code:=place
   else
   if (field[i,j]=boulder) and Places[i,j] then
   begin
    code:=placedboulder;
    Positioned:=Positioned+1; //При этом увеличиваем счётчик размещённых камней
   end;
   Form1.il1.GetBitmap(code,bitmap); //Достаём картинку и рисуем её на соответсвующем
   Form1.imgBackBuffer.Canvas.Draw((j-1)*32,(i-1)*32,bitmap); //месте виртуального экрана
  end;
 bitmap.Free;
 {Копируем содержимое виртуального экрана на основной}
 Form1.imgScreen.Canvas.CopyRect(Rect(0,0,640,384),Form1.imgBackBuffer.Canvas,Rect(0,0,640,384));
end;
procedure TForm1.N2Click(Sender: TObject);
begin
if dlgopen1.Execute then
 begin
  LoadLevel(dlgOpen1.Filename);
  RedrawField;
 end;
end;
procedure TForm1.FormKeyDown(Sender:TObject;var key:Word;Shift:TShiftState);
var
 dx,dy:integer;
 Spridx:integer;
begin
 Busy:=false;
 if Busy then
 exit;
 Busy:=true;
 if Busy then
 begin
 if key=ord('W') then
  begin
   dx:=-1;
   dy:=0;
   Spridx:=su;
  end;
 if key=Ord('S') then
  begin
   dx:=1;
   dy:=0;
   Spridx:=sd;
  end;
 if key=Ord('A') then
  begin
   dx:=0;
   dy:=-1;
   Spridx:=sl;
  end;
 if Key=Ord('D') then
  begin
   dx:=0;
   dy:=1;
   Spridx:=sr;
  end;
 end
 else
 begin   //Никуда не идём
  dx:=0;
  dy:=0;
  Spridx:=Field[CurX,CurY];
 end;
 if Field[CurX+dx,CurY+dy]=SPACE then //Если целевая клетка пуста
 begin
  Field[CurX+dx,Cury+dy]:=Spridx; //Переходим в неё
  Field[CurX,CurY]:=space; //На старой позиции теперь ничего нет
  CurX:=CurX+dx;
  CurY:=CurY+dy;
 end
 else
 if (Field[CurX+dx,CurY+dy]=BOULDER) and (Field[CurX+2*dx,CurY+2*dy]=SPACE) then
 begin
  Field[CurX+dx,CurY+dy]:=Spridx;
  Field[CurX+2*dx,CurY+2*dy]:=BOULDER;
  Field[CurX,CurY]:=SPACE;
  CurX:=CurX+dx;
  CurY:=CurY+dy;
 end;
 RedrawField;
 //Перерисовываем уровень, если все камни размещены
 if Positioned=N_of_places then
  Application.MessageBox('Уровень пройден!','Sokoban',MB_ICONEXCLAMATION);
 Application.ProcessMessages; //Отражает результат действия уже выполненных операторов
 Busy:=false; //Статус = свободно
end;
procedure TForm1.FormShow(Sender: TObject);
begin
 while not dlgOpen1.Execute do
  LoadLevel(dlgOpen1.FileName);
 RedrawField;
end;
end.
Миниатюры
Исправьте программу пожалуйсто. Неправильно рисует форму  
Изображения
 
0
Заблокирован
08.02.2015, 12:35 12
Если проблема ещё не решена, скиньте весь проект. если он на 7 делфи. Намного удобнее разбираться с кодом в действии.
Но на первый взгляд у вас скорее всего где-то путаница с индексами. И потом. я хочу глянуть некоторые моменты.

Добавлено через 8 минут
Вот ещё один повод поскалить зубки любителям поглумиться.
Заведомо нерабочий код.

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
  i:Integer;
  ar: array of integer;
  rr: array of integer;
  st: TMemoryStream;
 
begin
 SetLength(ar,5);
 ar[0]:=1;
 ar[1]:=2;
 ar[2]:=3;
 ar[3]:=4;
 ar[4]:=5;
 
 st:=TMemoryStream.Create;
 st.Position:=0;
 st.Write(Ar[0],20);
 st.SaveToFile('1.txt');
 st.Free;
 
 SetLength(rr,5);
 
 st:=TMemoryStream.Create;
 st.Position:=0;
 st.LoadFromfile('1.txt');
 
 st.Read(rr[0],20);
 for i:=0 to 4 do ListBox1.Items.Add(IntToStr(rr[i]));
 
 st.Free;
end;
0
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 135
08.02.2015, 18:07  [ТС] 13
Ну вот пожалуйсто вам проект.
Вложения
Тип файла: rar сокобан(zbr).rar (192.7 Кб, 2 просмотров)
0
Заблокирован
08.02.2015, 19:14 14
Надеюсь там тайлы на месте?

Добавлено через 11 минут
Делфи у тебя какой?

Добавлено через 16 минут
в общем проект не собрать
Но ошибка у тебя вот в чём
Несоотвествие длины рисунка и игрового поля. это то, о чём я писал.
у тебя игровое 20 а рисунок 19
При считывании игрового поля у тебя доходит до 19, а потом считывается символ конца строки. В общем, скорее всего в 20 ячейку массива заносится предыдущий код, то есть код стенки.
Просто в текстовом файле добавь в каждую строчку пробел. чтоб символов стало 20
И у тебя всё будет нормально

Добавлено через 16 секунд
Должно быть нормально

Добавлено через 4 минуты
и вообще. разберись с игровым полем и форматами записи уровня.
1
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 135
08.02.2015, 20:13  [ТС] 15
Всё спасибо большое . А вот скажите , последний момент , пожалуйсто . Проблема с обработкой клавиш , я вот сделал чтобы клавиши работали ну как стандартно w,a,s,d , а вот при нажатии других клавиш у меня вылазят ошибки . Помогите как это можно исправить. Только доходчиво пожалуйсто )
0
Заблокирован
08.02.2015, 21:06 16
Ну так что у вас за делфи?
И потом. логика такая странная...
Надо посмотреть что там у вас к чему. но скорее всего нарушение цепочки else
Надо уточнить

Добавлено через 11 минут
Явный бред
Delphi
1
2
3
Busy:=false;
 if Busy then
 exit;
Добавлено через 56 секунд
Далее по коду

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
if Busy then
    begin
       if key=ord('W') then
           begin
              dx:=-1;
              dy:=0;
              Spridx:=su;
           end;
       if key=Ord('S') then
           begin
           dx:=1;
           dy:=0;
           Spridx:=sd;
           end;
       if key=Ord('A') then
           begin
           dx:=0;
           dy:=-1;
           Spridx:=sl;
           end;
       if Key=Ord('D') then
           begin
           dx:=0;
           dy:=1;
           Spridx:=sr;
           end;
        end
 else
       begin   //Никуда не идём
        dx:=0;
        dy:=0;
        Spridx:=Field[CurX,CurY];
        end;
Добавлено через 3 минуты
Busy:=false;
Но если после этого оно не false то exit;
Сделаем Busy true и проверим клавиши.
Но если вдруг оно окзалось не true
то ничего не делаем.

Добавлено через 2 минуты
в любом случае если вы нажмёте любую другую клавишу
строчки 29 - 33 неработоспособны. На них никогда не будет перeхода

Добавлено через 3 минуты
Но при этом дальнейший код продолжает выполняться.
И в какие дебри его заносит даже богу неведомо.
Отсюда и аксцес виолантис.
То бишь п....ц

Добавлено через 11 минут
Если эти строчки задают данные при нажатии другой клавиши то лучше вынести их в самое начало.
Тогда при начале проверки будут значения нажатия другой клавиши.
После этого если всё же нажата та клавиша. то значения изменятся. а если всё же не та. то значения останутся
0
1 / 1 / 0
Регистрация: 11.12.2014
Сообщений: 135
08.02.2015, 21:14  [ТС] 17
Блин , я что-то не понял , можете пожалуйсто исправить вот тут в процедуре.
procedure TForm1.FormKeyDown(Sender:TObject;var key:Word;Shift:TShiftState);
var
dx,dy:integer;
Spridx:integer;
begin
Busy:=false;
if Busy then
exit;
Busy:=true;
if Busy then
begin
if key=ord('W') then
begin
dx:=-1;
dy:=0;
Spridx:=su;
end;
if key=Ord('S') then
begin
dx:=1;
dy:=0;
Spridx:=sd;
end;
if key=Ord('A') then
begin
dx:=0;
dy:=-1;
Spridx:=sl;
end;
if Key=Ord('D') then
begin
dx:=0;
dy:=1;
Spridx:=sr;
end;
end
else
begin //Никуда не идём
dx:=0;
dy:=0;
Spridx:=Field[CurX,CurY];
end;
if Field[CurX+dx,CurY+dy]=SPACE then //Если целевая клетка пуста
begin
Field[CurX+dx,Cury+dy]:=Spridx; //Переходим в неё
Field[CurX,CurY]:=space; //На старой позиции теперь ничего нет
CurX:=CurX+dx;
CurY:=CurY+dy;
end
else
if (Field[CurX+dx,CurY+dy]=BOULDER) and (Field[CurX+2*dx,CurY+2*dy]=SPACE) then
begin
Field[CurX+dx,CurY+dy]:=Spridx;
Field[CurX+2*dx,CurY+2*dy]:=BOULDER;
Field[CurX,CurY]:=SPACE;
CurX:=CurX+dx;
CurY:=CurY+dy;
end;
RedrawField;
//Перерисовываем уровень, если все камни размещены
if Positioned=N_of_places then
Application.MessageBox('Уровень пройден!','Sokoban',MB_ICONEXCLAMATION);
Application.ProcessMessages; //Отражает результат действия уже выполненных операторов
Busy:=false; //Статус = свободно
end;
procedure TForm1.FormShow(Sender: TObject);
begin
while not dlgOpen1.Execute do
LoadLevel(dlgOpen1.FileName);
RedrawField;
end;
0
Заблокирован
08.02.2015, 21:29 18
вы так и не сказали что у вас делфи и почему семёрка не видит ни формы ни юнита.
Я не знаю что исправлять. я только сделал предположение и указал на явный бред и на заведомо пустой код, который никогда не будет исполняться и по этой причине дальнейший код получит чёрт знает какие данные.

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

Добавлено через 6 минут
И мне абсолютно ясно что код неработоспособен, поскольку будет затыкаться на допустимых операциях.
Дело в том, что существуют места для установки груза, который вы почему-то называете камень. По ним может ездит погрузчик. Существуют уровни когда такие места представляют цнлые группы. по ним можно двигать как и груз так и погрузчик. а у вас это в принципе исключено.и погрузчик может ездить лишь по пустому полю.
0
08.02.2015, 21:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.02.2015, 21:29
Помогаю со студенческими работами здесь

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

Написать программу, которая рисует 2 эллипса
Написать программу, которая рисует два эллипса, расположенных в центре окна размером 250x250 точек...

Написать программу, которая рисует треугольники
Здравствуйте! Помогите пожалуйста написать программу которая рисует треугольники по координатам...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
18
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru