Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > разработка игр, графический дизайн и моделирование > Gamedev - cоздание игр: Unity, OpenGL, DirectX
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 06.10.2008, 15:28   #1
AngelOfDeath
Delphi/C++/Asm
Форумчанин Подтвердите свой е-майл
 
Аватар для AngelOfDeath
 
Регистрация: 28.03.2008
Сообщений: 358
Вопрос Пишу Pacman. Нужна помощь.

В общем пишу Pacman
Собираюсь не использовать ни одного изображения
Всё с помощью Canvas
И возникла такая проблема
Всё начало ужасно мерцать
Код:
DoubleBuffered:=True;
Не помогает
Я думаю моя ошибка в том что я обновляю всё игровое поле в таймере
В общем вопрос такой:
Как мне сделать в данном коде
Обновление вокруг клетки с Pacman'ом
Если в коде что будет непонятно
Спрашивайте
Хотя всё построено довольно примитивно
Одни циклы и условия...
Вот сурсы и ехе:
Вложения
Тип файла: rar source.rar (7.1 Кб, 37 просмотров)
Тип файла: rar exe.rar (169.8 Кб, 41 просмотров)
AngelOfDeath вне форума Ответить с цитированием
Старый 06.10.2008, 16:33   #2
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

Так и думал, ты рисуешь сразу на форму. ЭТО НЕ ПРАВИЛЬНО!!! Никогда так не делай!
1. Удали все: DoubleBuffered:=True;
2. Заведи буфер

1. Думаю объяснений не требуется
2. В разделе глобальных переменных заведи переменную buf типа TBitMap;
Код:
var
  Form1: TForm1;
  buf: TBitMap;
создай ее и задай размеры равные размерам клиентской части формы;
Код:
procedure TForm1.FormCreate(Sender: TObject);
begin
  buf:=tbitmap.create;
  buf.width:=clientwidth;
  buf.height:=clientheight;
  CreateLevel;
end;
Далее везде где написано слово canvas, перед ним поставь buf.
и в конце процедуры(таймера) canvas.draw(buf,0,0);

Последний раз редактировалось Kostia; 06.10.2008 в 16:37.
Kostia вне форума Ответить с цитированием
Старый 06.10.2008, 19:23   #3
DeKot
Участник клуба
 
Аватар для DeKot
 
Регистрация: 12.08.2008
Сообщений: 1,977
По умолчанию

Посмотри здесь на форуме стр.2 - тему "Особенности программирования
движущихся объектов" и " Мастерская: Некоторые аспекты программирования".
И не сомневайся даже ... отдых - кайф, работа - лажа!
DeKot вне форума Ответить с цитированием
Старый 07.10.2008, 00:36   #4
AngelOfDeath
Delphi/C++/Asm
Форумчанин Подтвердите свой е-майл
 
Аватар для AngelOfDeath
 
Регистрация: 28.03.2008
Сообщений: 358
По умолчанию

Костя спасибо
Только не
Код:
canvas.draw(buf,0,0);
а
Код:
Canvas.Draw(0,0,buf);
И ещё один вопрос как сделать плавное хождение с клетки на клетку
AngelOfDeath вне форума Ответить с цитированием
Старый 07.10.2008, 09:28   #5
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

Заводишь переменную которая определяет направление и предел движения
Код:
var
  orientation: byte;
  limit: integer;
Далее проверяешь нажатие клавиш клавиатуры, проверяешь, можно ли идти в том направлении куда требуется. Если да, то заноси в переменную orientation число, которое определяет одно из 4-х направлений, а в переменную limit координаты клетки на которую нужно перейти(x или y в зависимости от направления).
1-влево (х)
2-вверх (y)
3-вправо (x)
4-вниз (y)

Далее в процессе игры проверяешь, если orientation = 1, то двигаешь персонажа влево и проверяешь не прошел ли он лимит
if (x>=limit) then orientation:=0;
Идентично с остальными направлениями.
Kostia вне форума Ответить с цитированием
Старый 07.10.2008, 10:22   #6
AngelOfDeath
Delphi/C++/Asm
Форумчанин Подтвердите свой е-майл
 
Аватар для AngelOfDeath
 
Регистрация: 28.03.2008
Сообщений: 358
По умолчанию

Что то не особо понятно
Как я это передвижение буду рисовать?
AngelOfDeath вне форума Ответить с цитированием
Старый 07.10.2008, 10:48   #7
Kostia
Участник клуба
 
Аватар для Kostia
 
Регистрация: 21.11.2007
Сообщений: 1,690
По умолчанию

Эх моя вина, не рассказал до конца.
Нужно завести еще две переменные
Код:
var
  x,y: integer;
Они определяют положение персонажа на экране. Далее
Код:
if orientation = 1 then 
begin 
  x:=x-1; 
{может есть еще переменные определяющие состояние персонажа(анимация), то их менять тоже следует здесь}
  if x<=limit then orientation:=0;
end;
C расчетом лимита думаю разберешься.
Kostia вне форума Ответить с цитированием
Старый 07.10.2008, 10:48   #8
DeKot
Участник клуба
 
Аватар для DeKot
 
Регистрация: 12.08.2008
Сообщений: 1,977
По умолчанию

Сделай управление движения циклом. Допустим у тебя клетки 50 х 50.
Сделай цикл For i:= 1 to 10 do и в каждой итерации цикла добавляй приращение координат в нужном направлении на 5 pixels.
За полный цикл получишь 5 * 10 = 50 - плавное перемещение на одну клетку. Ну, и естественно все изменения делать за пределами формы в
буфере и только затем выводить на форму.
И не сомневайся даже ... отдых - кайф, работа - лажа!
DeKot вне форума Ответить с цитированием
Старый 07.10.2008, 11:17   #9
AngelOfDeath
Delphi/C++/Asm
Форумчанин Подтвердите свой е-майл
 
Аватар для AngelOfDeath
 
Регистрация: 28.03.2008
Сообщений: 358
По умолчанию

Ладно придётся увеличить своё поле в несколько раз...
Чтоб были пиксели для перехода с одной клетки на другую...
Потому что
Вот уровень:
Код:
  MapXY: array [0..20,0..20] of Byte;  //Уровень
А вот прорисовка и ходьба:
Код:
procedure TForm1.PaintAndUpdateLevel;
var
X,Y,Pix:Integer;
I:Integer;
begin
i:=0;
for x := 0 to 20 do
  for y := 0 to 20 do
    begin
      if MapXY[x,y]=0  then
      begin
      i:=1;
      buf.Canvas.Brush.Color:=clBlack;
      buf.Canvas.Pen.Color:=clBlack;
      buf.Canvas.Rectangle(x*30,y*30,x*30+30,y*30+30);
      buf.Canvas.Font.Color:=clYellow;
      buf.Canvas.Ellipse(x*30+10,y*30+10,x*30+20,y*30+20);
      end;
      if MapXY[x,y]=5 then
      begin
            buf.Canvas.Brush.Color:=clBlack;
      buf.Canvas.Pen.Color:=clBlack;
      buf.Canvas.Rectangle(x*30,y*30,x*30+30,y*30+30);
      end;
      
      if MapXY[x,y]=1 then
      begin
        buf.Canvas.Pen.Width:=0;
        buf.Canvas.Pen.Color:=clBlack;
        buf.Canvas.Brush.Color:=clWhite;
        buf.Canvas.Rectangle(x*30,y*30,x*30+30,y*30+30);
      end;
      if MapXY[x,y]=2 then
      begin
      buf.Canvas.Pen.Width:=0;
      buf.Canvas.Pen.Color:=clBlack;
      buf.Canvas.Brush.Color:=clBlack;
      buf.Canvas.Rectangle(x*30,y*30,x*30+30,y*30+30);
      buf.Canvas.Brush.Color:=clYellow;
      buf.Canvas.Ellipse(x*30,y*30,x*30+30,y*30+30);
      PackX:=x;
      PackY:=y;
      end;
            if MapXY[x,y]=0 then
      begin
      buf.Canvas.Pen.Color:=clYellow;
      buf.Canvas.Pen.Width:=2;
      buf.Canvas.Ellipse(x*30+10,y*30+10,x*30+20,y*30+20);
      end;

    end;
Canvas.Draw(0,0,buf);
end;

Код:
OldPackX:=PackX;
OldPackY:=PackY;
if GoUp=true then   //Вверх
if MapXY[PackX,PackY-1]=1 then
Exit
else
begin
  OldPackY:=PackY;
  MapXY[PackX,PackY-1]:=2;
  MapXY[PackX,OldPackY]:=0;
  MapXY[OldPackX,OldPackY]:=5;






PaintAndUpdateLevel;
end;



if GoDown=true then    //Вниз
if MapXY[PackX,PackY+1]=1 then
Exit
else
begin
  OldPackY:=PackY;
  MapXY[PackX,PackY+1]:=2;
  MapXY[PackX,OldPackY]:=0;
  MapXY[OldPackX,OldPackY]:=5;
  PaintAndUpdateLevel;
end;


if GoLeft=true then    //Влево
if MapXY[PackX-1,PackY]=1 then
Exit
else
begin
  OldPackX:=PackX;
  MapXY[PackX-1,PackY]:=2;
  MapXY[OldPackX,OldPackY]:=5;
  PaintAndUpdateLevel;
end;


if GoRight=true then  //Вправо
if MapXY[PackX+1,PackY]=1 then
Exit
else
begin




  MapXY[PackX+1,PackY]:=2;
  MapXY[OldPackX,PackY]:=0;
  MapXY[OldPackX,OldPackY]:=5;
  PaintAndUpdateLevel;
end;





end;
Чтож доделаю пока такой пример

Последний раз редактировалось AngelOfDeath; 07.10.2008 в 11:26.
AngelOfDeath вне форума Ответить с цитированием
Старый 07.10.2008, 11:52   #10
AngelOfDeath
Delphi/C++/Asm
Форумчанин Подтвердите свой е-майл
 
Аватар для AngelOfDeath
 
Регистрация: 28.03.2008
Сообщений: 358
Вопрос Ещё один вопрос...

Вот собрался сделать редактор карт...
Короче как сделать проверку клика на канве?
пробовал такой метод:
Код:
procedure TForm1.FormMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var
a,b,c,x2,y2:Integer;
x3,y3:Integer;
begin
x3:=x;
y3:=y;

for a := 0 to 20 do
  for b := 0 to 20 do
    for c := 0 to 30 do

    begin
       if x3=b*30+c then
       if y3=a*30+c then
       begin
       Form1.Caption:='ok';
       exit;
       end;

    end;
end;
но ето работает далеко не всегда...
AngelOfDeath вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Делаю сайты, пишу маленькие/большие скрипты. Пишу веб-приложения и приложения под Windows. SkyM@n Фриланс 3 29.12.2007 16:21
Нужна помощь!!! Anil Помощь студентам 0 04.12.2007 17:32
Нужна помощь по Си. Coach Помощь студентам 3 08.11.2007 01:08