Форум по Delphi программированию

Delphi Sources



Вернуться   Форум по Delphi программированию > Все о Delphi > Графика и игры
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 02.06.2013, 22:51
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
Восклицание Быстрая прорисовка массива из цветных пикселей

Очень прошу помочь. На форумах общался мало, поэтому - сразу прошу прощения, что может не совсем по правилам.

Написал игру, что-то вроди лодерунора (KOLOBOK FOREVER), назвал, пишу уже скоро как 6- месяцев. Со временем из допотопной бродилки по лабиринтам, стала получаться полноценная игра со своим сюжетом и предисторией, но лучьше о главном.

Дано: лабиринт 400 Х 400 клеток, каждая клетка - либо кирпичи, броня, вода, дерево, огонь и мн.другое. По этому лабиринту ходит-бродит КОЛОБОК, стреляет вирусы, прыгает сквозь порталы, собирает различные вещи и т.п.

САМА ПРОБЛЕМА : карта лабиринта постоянно должна прорисовываться, кирпичи - один цвет пикселя, броня - другой, и остальное. В этом лабиринте живут и другие существа БОТЫ, одни лабиринт копают (доделывают), другие гоняются за колобком, и т.д. Нужно постоянно прорисовывать карту и выводить её на Image. Всё хорошо работает, до тех пор пока не включаешь эту самую карту, как только это делаешь, процес игры тормозит сразу на все 98%.

Если возможно помогите мне, ну или хотя-бы подскажите в какую сторону копать. Заранее спасибо. Если кто заинтересуется - буду рад любой помощи. Жалко просто - игра получается действительно интерестной.

Создавал прорисовку так :
массив q[0..500, 0..500];
for f:= 0 to 500 do begin
for i:= 0 to 500 do begin
if q[i,f] = 2 then (так объясню... дальше на Image ставлю пиксель Pixel[i,f]:= clGreen 2- кирпичный блок
if q[i,f] = 0 then ... чёрный пиксель
end;
end;

Последний раз редактировалось RobinStone, 02.06.2013 в 23:47.
Ответить с цитированием
  #2  
Старый 03.06.2013, 01:01
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Не нужно рисовать напрямую на TImage, рисуй в буферном битмапе и после полной отрисовки выводи в TImage. К тому же нет нужды перерисовывать каждый раз с нуля, если есть неизменяемая часть лабиринта, то она один раз отрисовывется на битмапе оригинале, при запросе на отрисовку с битмапа оригинала копируем во 2-ой битмап, где дорисовываем необходимое и копируем в TImage.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Этот пользователь сказал Спасибо angvelem за это полезное сообщение:
RobinStone (03.06.2013)
  #3  
Старый 03.06.2013, 01:38
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,048
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от angvelem
Не нужно рисовать напрямую на TImage, рисуй в буферном битмапе и после полной отрисовки выводи в TImage. К тому же нет нужды перерисовывать каждый раз с нуля, если есть неизменяемая часть лабиринта, то она один раз отрисовывется на битмапе оригинале, при запросе на отрисовку с битмапа оригинала копируем во 2-ой битмап, где дорисовываем необходимое и копируем в TImage.

А лучше отририсуй начальные битмапы уровней заранее и просто подгружай их. Поверь, так будет самое простое и самое быстрое.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
RobinStone (03.06.2013)
  #4  
Старый 03.06.2013, 02:33
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Так не совсем подойдет так как
Цитата:
...В этом лабиринте живут и другие существа БОТЫ, одни лабиринт копают (доделывают)...
всё равно дорисовывать придётся.
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
Этот пользователь сказал Спасибо angvelem за это полезное сообщение:
RobinStone (03.06.2013)
  #5  
Старый 03.06.2013, 05:56
lmikle lmikle вне форума
Модератор
 
Регистрация: 17.04.2008
Сообщения: 8,048
Версия Delphi: 7, XE3, 10.2
Репутация: 49089
По умолчанию

Цитата:
Сообщение от angvelem
Так не совсем подойдет так как

всё равно дорисовывать придётся.

Ну дык дорисовывать, а не рисовать полностью.
Тем более, что боты изначально могут двигаться, соответсвенно их все-равно отрисовывать, так что сначала выводим битмап уровня, потом просто поверх него отрисовываем всех персонажей. Кстати, для отрисовки персонажей можно использовать ту же технику - сделать заранее все нужные картинки и потом их выводить в нужном месте.

ЗЫ. Такая технология отрисовки называется "спрайты", использовалась при создании игрушек до появления 3D движков. Кстати, Diablo I и WarCraft II еще спрайтовые. Это к вопросам о возможностях такой отрисовки. Там движок конечно более сложный, но факт остается фактом - это спрайтовые игры.
Ответить с цитированием
Этот пользователь сказал Спасибо lmikle за это полезное сообщение:
RobinStone (03.06.2013)
  #6  
Старый 03.06.2013, 10:23
icWasya icWasya вне форума
Местный
 
Регистрация: 09.11.2010
Сообщения: 499
Репутация: 10
По умолчанию

И вместо ..Canvas.Pixels[X,Y] научись работать со Bitmap.ScanLine
Ответить с цитированием
Этот пользователь сказал Спасибо icWasya за это полезное сообщение:
RobinStone (03.06.2013)
  #7  
Старый 03.06.2013, 12:20
Аватар для angvelem
angvelem angvelem вне форума
.
 
Регистрация: 18.05.2011
Адрес: Омск
Сообщения: 3,970
Версия Delphi: 3,5,7,10,12,XE2
Репутация: выкл
По умолчанию

Цитата:
Сообщение от lmikle
Ну дык дорисовывать, а не рисовать полностью...
Ну так это я и предложил с самого начала.
Цитата:
то она один раз отрисовывется на битмапе оригинале
__________________
Je venus de nulle part
55.026263 с.ш., 73.397636 в.д.
Ответить с цитированием
  #8  
Старый 03.06.2013, 12:59
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от angvelem
Не нужно рисовать напрямую на TImage, рисуй в буферном битмапе и после полной отрисовки выводи в TImage. К тому же нет нужды перерисовывать каждый раз с нуля, если есть неизменяемая часть лабиринта, то она один раз отрисовывется на битмапе оригинале, при запросе на отрисовку с битмапа оригинала копируем во 2-ой битмап, где дорисовываем необходимое и копируем в TImage.

Спасибо, что уделили мне время, но я не сказал, что мои познания видимо сильно отличаются от Ваших. Я понял, что Вы сразу поняли как исправить мою ошибку, но не могли бы Вы подсказать где можно прочитать про эти самые битмапы, но только, если можно, с азов. Типа что вообще это такое?
Не прошу написать код, т.к. хочу именно сам разобраться и написать...

И ещё раз прошу извинить за беспокойство.
Ответить с цитированием
  #9  
Старый 03.06.2013, 13:12
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию


procedure TForm2.SpeedButton5Click(Sender: TObject);
var a,s: integer;
begin
for a:= 1 to 500 do begin
for s:= 1 to 500 do begin
if q[a,s] <> 1 then form4.Image1.Canvas.Pixels[a,s]:= clBlack;
if (q[a,s] = 1) or (q[a,s] = 101) then form4.Image1.Canvas.Pixels[a,s]:= clBlue;
if q[a,s] = 3 then form4.Image1.Canvas.Pixels[a,s]:= clWhite;
if q[a,s] = 0 then form4.Image1.Canvas.Pixels[a,s]:= clRed;
if q[a,s] = 8091 then form4.Image1.Canvas.Pixels[a,s]:= clNavy;
if q[a,s] = 117 then form4.Image1.Canvas.Pixels[a,s]:= clMaroon;
if (q[a,s] = 333) or (q[a,s] = 777) then form4.Image1.Canvas.Pixels[a,s]:= clTeal;

end;
end;

end;

вот код (то до чего я дорос) он рисует карту, по виду она меня очень даже устраивает, но скорости нет совершенно.
Ответить с цитированием
  #10  
Старый 03.06.2013, 13:17
Аватар для poli-smen
poli-smen poli-smen вне форума
Профессионал
 
Регистрация: 06.08.2012
Адрес: Кривой Рог
Сообщения: 1,791
Версия Delphi: Delphi 7, XE2
Репутация: 4415
По умолчанию

Цитата:
Сообщение от RobinStone
вот код (то до чего я дорос) он рисует карту, по виду она меня очень даже устраивает, но скорости нет совершенно.
Естественно скорости нет. Canvas.Pixels работает очень медленно. Как тебе уже писали, для ускорения тебе нужно работать через TBitmap.ScanLine, т.е. напрямую записывать в память.
Ответить с цитированием
  #11  
Старый 03.06.2013, 14:23
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от poli-smen
Естественно скорости нет. Canvas.Pixels работает очень медленно. Как тебе уже писали, для ускорения тебе нужно работать через TBitmap.ScanLine, т.е. напрямую записывать в память.

Всё понял, СПАСИБО ! А теперь, если можно - как?!!!!
Мой браузер уже выучил комбинации клавишь по которым я делаю запросы в гугл и яндекс, по поводу этих битмапав, но мозг крайне негативно относится к способам там изложеным и ни в какую не желает идти на компромис по УСВАЯЕМОСТИ изложеной там информации...
Если кто может --- помогите понять...
Ответить с цитированием
  #12  
Старый 03.06.2013, 16:23
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Цитата:
Сообщение от angvelem
Не нужно рисовать напрямую на TImage, рисуй в буферном битмапе и после полной отрисовки выводи в TImage. К тому же нет нужды перерисовывать каждый раз с нуля, если есть неизменяемая часть лабиринта, то она один раз отрисовывется на битмапе оригинале, при запросе на отрисовку с битмапа оригинала копируем во 2-ой битмап, где дорисовываем необходимое и копируем в TImage.

ЗАДАЧА (это что б я понял) : есть массив
q: array[1..500,1..500] of integer;

этот массив уже заполнен нужными мне значениями

теперь нужно выводить на Image 500 x 500 этот массив в виде точек определённых цветов, т.е.
for a:= 1 to 500 do begin
for s:= 1 to 500 do begin
if q[a,s] = 3 then form1.Image1.Canvas.Pixels[a,s]:= clWhite;
if q[a,s] = 0 then form1.Image1.Canvas.Pixels[a,s]:= clRed;
end;
end;

примерно 1 раз в секунду хотя-бы...

вот как-то так...

ПОМОГИТЕ...
Ответить с цитированием
  #13  
Старый 03.06.2013, 16:56
Аватар для YVitaliy
YVitaliy YVitaliy вне форума
Местный
 
Регистрация: 14.12.2011
Сообщения: 481
Версия Delphi: Borland Delphi7
Репутация: 17
По умолчанию

Тут нечего больше объяснять. X и Y - аналоги вашего "f" и "i'. X - позиция пиксела по горизонтали, Y - по вертикали. Проходя в цикле Y от 0 до высоты Bitmap'a (или 500 в вашем случае, главное, чтобы высота картинки была не меньше), сканируем строку битмапа (заносим в память последовательность байт, которые и составляют одну строку). Теперь, проходя во втором цикле X, уже работаем со строкой, по-горизонтали. Здесь Rows[X] - это позиция [X] пиксела в строке[Y]. rgbtRed, rgbtGreen, rgbtBlue - красная, зеленая и синяя составляющие цвета. Их можно получить системными ф-циями
GetRValue(цвет) - красная составляющая,
GetGValue - зеленая.
GetBValue - синяя.
RGB(красная составляющая, зел. сост, син. сост) - получаем цвет TColor из его составляющих.
Bitmap - в вашем случае Form1.image1.Picture.Bitmap.
Чтобы этот код работал, желательно при создании формы (в OnCreate формы) прописать
Код:
Form1.image1.Picture.Bitmap.PixelFormat:=pf24bits;
Вот примерчик
Вложения
Тип файла: rar tst21.rar (2.2 Кбайт, 8 просмотров)

Последний раз редактировалось YVitaliy, 03.06.2013 в 17:38.
Ответить с цитированием
Этот пользователь сказал Спасибо YVitaliy за это полезное сообщение:
RobinStone (04.06.2013)
  #14  
Старый 04.06.2013, 11:14
RobinStone RobinStone вне форума
Прохожий
 
Регистрация: 02.06.2013
Сообщения: 27
Версия Delphi: Delphi 7
Репутация: 10
По умолчанию

Я не програмер, я ОЛЕНЬ !
ВСЁ НАСТОЛЬКО ДОСТУПНО объяснил, что даже я ПОНЯЛ. Всё ПОЛУЧИЛОСЬ.
СТОЛЬКО РАДОСТИ БЫЛО !!! Даже жене позвонил, сказал, что люблю!

И ЕЩЁ РАЗ - ГРОМАДНЕЙШЕЕ ВАМ ЧЕЛОВЕЧЕСКОЕ СПАСИБО !!!
Ответить с цитированием
  #15  
Старый 09.07.2013, 10:38
forum.sources.ru forum.sources.ru вне форума
Прохожий
 
Регистрация: 22.04.2013
Сообщения: 31
Версия Delphi: d2,4,6,7,8,xe
Репутация: 10
По умолчанию

Цитата:
Сообщение от RobinStone
Всё ПОЛУЧИЛОСЬ.

А результат-то где? Дайте поиграть?!))
Ответить с цитированием
Ответ


Delphi Sources

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра
Комбинированный вид Комбинированный вид

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 12:10.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources" by BrokenByte Software, 2004-2023

ВКонтакте   Facebook   Twitter