Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2004.07.04;
Скачать: CL | DM;

Вниз

Arcanoid => Тормоза => Need help!   Найти похожие ветки 

 
Servelat ©   (2004-03-10 23:03) [0]

Народ, помогите!
Пишу игру типа арканоид, используются Windows"овские средства вывода (GetDC(от хэндла окна) и  создание канваса), окно на Win Api. Так вот, при перерисовке карты возникают большие тормоза. Я знаю, что это не удивительно, что лучше использовать DirectX, OpenGl и т.д. , но здесь надо именно Bitmap"ами обойтись. Приведу участки кода:


procedure TMap.Draw;
begin
 Display.Canvas.Draw(OffsetX-1, OffsetY-1, Bitmap);
end;


Display - TBitmap, который постоянно блитается (BitBlt) на канву формы (созданную так:

 DC:=GetDC(hWindow);
 Canvas:=TCanvas.Create;
 Canvas.Handle:=DC;
)

В Bitmap"е (том, что в TMap.Draw) нарисована карта (так как она изменяется относительно редко, то рисуется она один раз при загрузке, а потом удаляются "раздолбаные" кирпичи:

procedure TMap.DelOne(i, j: integer);
begin
 i:=i*C_TILE_WIDTH+1;
 j:=j*C_TILE_HEIGHT+1;
   with Bitmap.Canvas do
   begin
     Brush.Style:=bsSolid;
     Brush.Color:=clWhite;
     FillRect(Bounds(i, j, C_TILE_WIDTH, C_TILE_HEIGHT));
   end;
end;


Так вот, после выполнения Map.DelOne (после удара шарика о кирпич), процедура map.Draw занимает в 10 раз больше времени. Почему - никак не могу понять. Может у кого будут идеи?

).


 
Mihey ©   (2004-03-10 23:22) [1]

Использование методов канвы, особенно для рисования примитивов, например, FillRect, очень снижает скорость. Если давать простой совет, то посмотри функцию BitBlt, её можно вставить в TMap.Draw заместо Canvas.Draw. Кроме того, BitBlt ты можешь использовать и для стирания кирпичей - создай белый TBitmap (в графическом редаткоре или программно), а затем используй тот же BitBlt, например:

procedure TMap.DelOne(i, j: integer);
begin
i:=i*C_TILE_WIDTH+1;
j:=j*C_TILE_HEIGHT+1;
BitBlt(Bitmap.Canvas.Handle, i, j, i+C_Tile_Width, j+C_Tile_Height, WhiteBitmap, 0, 0, SrcCopy);
end;

Тоже быстрее будет.


 
lyeh ©   (2004-03-11 00:29) [2]

2 Mihey ©
>> Кроме того, BitBlt ты можешь использовать и для стирания кирпичей - создай белый TBitmap (в графическом редаткоре или программно), а затем используй тот же BitBlt

хе-хе :)

2 Servelat ©


procedure TMap.Draw;
begin
  BitBlt(Display.Canvas.Handle, 0, 0, Display.Width, Display.Height, Bitmap.Canvas.Handle, OffsetX-1, OffsetY-1, SRCCOPY);
end;

procedure TMap.DelOne(i, j: integer);
begin
  i:=i*C_TILE_WIDTH+1;
  j:=j*C_TILE_HEIGHT+1;
 BitBlt(Bitmap.Canvas.Handle, i, j, C_TILE_WIDTH, C_TILE_HEIGHT, 0, 0, 0, WHITENESS);
end;


 
lyeh ©   (2004-03-11 00:38) [3]

2 Servelat ©
Кстати, с методом TCanvas.Draw я не знаком, т.к. всегда использую BitBlt, поэтому не знаю, что ты передаешь в Display.Canvas.Draw(OffsetX-1, OffsetY-1, Bitmap) переменными OffsetX и OffsetY. Если координаты в Display ("куда" рисовать) то пиши
BitBlt(Display.Canvas.Handle, OffsetX-1, OffsetY-1, Display.Width, Display.Height, Bitmap.Canvas.Handle, 0, 0, SRCCOPY), а если в Bitmap ("откуда"), то используй тот код, который я описал выше.


 
Servelat ©   (2004-03-11 07:52) [4]

2 lyeh ©
Спасибо, конечно, я попробую сделать так и проверить скорость вывода.
Однако фокус в том, что у Bitmap"а стоит Transparent Color (чтобы те места, где нет кирпичей не затирали задний фон). При таком BitBlt не выйдет, придется делать маску, и сначала ее выводить...
Поэтому я и писал

 Display.Canvas.Draw(OffsetX-1, OffsetY-1, Bitmap);

Только почему-то эта процеду ра занимает 200 мсек вместо 20 после того, как Bitmap изменилась я не понял.


 
Servelat ©   (2004-03-11 08:25) [5]

Попробовал реализовать, как здесь написано, оставив процедуру TMap.Draw прежней, изменяя только DelOne. Время выполнения DelOne уменьшилось, но на экране появлялись белые пятна, вместо "прозрачных". Я выяснил, что чтобы это устранить, надо в DelOne присваивать: Bitmap.Modified:=True;  . Тогда все рисуется правильно, но со старыми тормозами (Map.Draw до 250 мсек после DelOne"а, остальные Map.Draw<=20 мсек).
Без создания маски для карты и блитания обоих не обойтись?


 
nexxiss ©   (2004-03-11 13:33) [6]

Зачем тебе Канва нужна, когда у тебя есть дескриптор графического устройства формы ( DC ) ? Зная дескриптор, можешь рисовать и так.


 
Servelat ©   (2004-03-11 16:28) [7]

Зачем тебе Канва нужна, когда у тебя есть дескриптор графического устройства формы ( DC ) ? Зная дескриптор, можешь рисовать и так.
Мне с канвой как-то привычнее, можно и без нее обойтись, но мне так удобнее.
Значит без создания маски никак не обойтись? Жаль.


 
WebErr ©   (2004-03-11 18:28) [8]

Самый быстрый способ отображения на экран картинки, которую сам же и создал - это SetDIBitsToDevice или на крайняк StretchDIBits. Это - всегда без тормозов!!! :))))


 
lyeh ©   (2004-03-12 00:37) [9]

2 Servelat ©
А у тебя вся карта в битмэпе? Памяти наверно пожирает немеренно... Скорость падает, наверно, из-за создания маски для такого огромного изображения...

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



Страницы: 1 вся ветка

Текущий архив: 2004.07.04;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.047 c
1-1087462750
MeF88
2004-06-17 12:59
2004.07.04
Преимущества property


14-1086979817
X9
2004-06-11 22:50
2004.07.04
Дрова на Lucent под Linux


14-1087280962
DimKa
2004-06-15 10:29
2004.07.04
Сколько в кубометре байтов?


14-1087370201
IceBeerg
2004-06-16 11:16
2004.07.04
2а вопроса


1-1087547319
Andrew2
2004-06-18 12:28
2004.07.04
Много процессов - одна DLL