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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.03.2011, 12:17   #521
AngelOfFate
Пользователь
 
Аватар для AngelOfFate
 
Регистрация: 02.03.2011
Сообщений: 12
По умолчанию

AlDelta, не очень вас понял, поясните пожалуйста
Гром, не очень хороший вариант, на форме полоски появляются, см. исходники
Вложения
Тип файла: rar Animate.rar (165.4 Кб, 19 просмотров)
AngelOfFate вне форума Ответить с цитированием
Старый 03.03.2011, 12:44   #522
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,876
По умолчанию

а если не надо ему всё перерисовывать ??? тогда можно сделать так - копируется кусок из буфера фона, сохраняется, рисуется нужный объект на итоговое изображение, при необъодимости двигать объект на то же место рисуется сохраненный буфер, и вся процедура повторяется (только координаты вставки объекта и всё сопуствующее меняется)

пример во вложении, не моё , но я переделывал часть (ать )) не нашел переделанного проекта куда-то засунул... так что исходный кладу)
Вложения
Тип файла: rar 2D Game.rar (295.8 Кб, 46 просмотров)
phomm вне форума Ответить с цитированием
Старый 03.03.2011, 12:59   #523
AngelOfFate
Пользователь
 
Аватар для AngelOfFate
 
Регистрация: 02.03.2011
Сообщений: 12
По умолчанию

phomm, хороший пример, спасибо, то что нужно
AngelOfFate вне форума Ответить с цитированием
Старый 03.03.2011, 13:27   #524
AlDelta
Реанимируюсь...
Участник клуба
 
Аватар для AlDelta
 
Регистрация: 19.07.2007
Сообщений: 1,445
По умолчанию

1. Для формы DoubleBuffered в true
2. Все рисование на подложке.
3. На канве формы рисовать только полностью сформированный кадр.

Элементарный ример:
На форму TPaintBox, TTimer.
Код:

type
  TPlayer = record // Record описывающий игрока 
  X,Y: Integer;
  Size: Integer;
  Color: TColor;
  Speed: Integer;
end;

const
    cUp=38; 
    cDown=40;
    cLeft=37;
    cRight=39;

var Frame: TBitmap;
    Player: TPlayer;


procedure TForm1.FormCreate(Sender: TObject);
begin
  Frame:=TBitmap.Create; // создаем TBitmap, который будет выступать буфером
  Frame.Width:=PaintBox1.Width;
  Frame.Height:=PaintBox1.Height;
  Randomize;

  // Инициализация игрока
  Player.Size:=Random(50);
  Player.X:=Random(Frame.Width)-Player.size;
  Player.Y:=Random(Frame.Height)-Player.size;
  Player.Color:=clYellow;
  Player.Speed:=Random(5);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Frame.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin

  // Рисуем фон кадра, тем самым затирая предыдущий кадр
  Frame.Canvas.Brush.Color:=clGreen;
  Frame.Canvas.Rectangle(0,0,Frame.Width,Frame.Height);

  /////////////////////////////////
  //Рисуем остальную графику игры//
  /////////////////////////////////

  // Рисуем игрока
  Frame.Canvas.Brush.Color:=Player.Color;
  Frame.Canvas.Ellipse(Player.X,Player.Y,Player.X+Player.size,Player.Y+Player.size);


  // Рисуем готовый кадр на канву PaintBox'a
  BitBlt(Canvas.Handle,0,0,PaintBox1.Width,PaintBox1.Height,Frame.Canvas.Handle,0,0,SrcCopy);
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  // Движение горизонтальное и вертикальное движение игрока
  case Key of
    cLeft: Player.X:=Player.X-Player.Speed;
    cRight: Player.X:=Player.X+Player.Speed;
    cUp: Player.Y:=Player.Y-Player.Speed;
    cDown: Player.Y:=Player.Y+Player.Speed;
  end;
end;
Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живёте.
Правила форума => Правила раздела => Для общего развития => Помощь студентам => Перед тем, как создавать тему, скачайте себе...
P.S.: форум не песочница (с)
название статьи на сайте MS: "Отмена принудительного отключения автоматического запуска в реестре Windows"
AlDelta вне форума Ответить с цитированием
Старый 03.03.2011, 14:20   #525
AlDelta
Реанимируюсь...
Участник клуба
 
Аватар для AlDelta
 
Регистрация: 19.07.2007
Сообщений: 1,445
По умолчанию

Пример с анимацией:
Код:
  type
    TPlayer = record
    X,Y: Integer;
    Size: Integer;
    texture: TBitmap;
    frame: Integer;
    Speed: Integer;
  end;



const
    cUp=38;
    cDown=40;
    cLeft=37;
    cRight=39;

var Frame: TBitmap;
     Player: TPlayer;


procedure TForm1.FormCreate(Sender: TObject);
begin
  Frame:=TBitmap.Create;
  Frame.Width:=PaintBox1.Width;
  Frame.Height:=PaintBox1.Height;
  Randomize;

  Player.Size:=Random(50);
  Player.X:=Random(Frame.Width)-Player.size;
  Player.Y:=Random(Frame.Height)-Player.size;
  Player.texture:=TBitmap.Create; // создаем источник анимации
  Player.texture.LoadFromFile('attack.bmp');  // загружаем в него файл анимации
  Player.Speed:=Random(5);
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  Player.texture.Free;
  Frame.Free;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin

  // Рисуем фон
  Frame.Canvas.Brush.Color:=clGreen;
  Frame.Canvas.Rectangle(0,0,Frame.Width,Frame.Height);


  // Функция TransparentBlt выполняет передачу битовых блоков данных о цвете,
  // соответствующих прямоугольнику пикселей заданного исходного контекста
  // устройства в целевой контекст устройства.
  TransparentBlt(Frame.Canvas.Handle, //  куда выводится изображение
                 Player.X, Player.Y,// координаты места в кадре, где будет нарисован кадр анимации
                 128, 68, // ширина и высота кадра анимации
                 Player.texture.Canvas.Handle, // откуда берем анимацию
                 Player.frame*128, 0, // определяем текущее расположение кадра анимации в источнике
                 128, 68, // ширина и высота кадра анимации
                 Player.texture.Canvas.Pixels[0,0] // получаем цвет, который будет прозрачным
                 );

  BitBlt(Canvas.Handle,0,0,PaintBox1.Width,PaintBox1.Height,Frame.Canvas.Handle,0,0,SrcCopy);
end;

procedure TForm1.FormKeyDown(Sender: TObject; var Key: Word;
  Shift: TShiftState);
begin
  case Key of
    cLeft: Player.X:=Player.X-Player.Speed;
    cRight: Player.X:=Player.X+Player.Speed;
    cUp: Player.Y:=Player.Y-Player.Speed;
    cDown: Player.Y:=Player.Y+Player.Speed;
  end;
end;

procedure TForm1.Timer2Timer(Sender: TObject);
begin
  // Таймер, который меняет номер текущего кадра на следующий
  Player.frame:=Player.frame+1;
  if Player.frame=12 then
    Player.frame:=0;
end;
Исходник: game PRIMER.rar
Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живёте.
Правила форума => Правила раздела => Для общего развития => Помощь студентам => Перед тем, как создавать тему, скачайте себе...
P.S.: форум не песочница (с)
название статьи на сайте MS: "Отмена принудительного отключения автоматического запуска в реестре Windows"
AlDelta вне форума Ответить с цитированием
Старый 04.03.2011, 10:51   #526
AngelOfFate
Пользователь
 
Аватар для AngelOfFate
 
Регистрация: 02.03.2011
Сообщений: 12
По умолчанию

всем спасибо за вчерашние примеры, подскажите ещё пожалуйста, как сделать замедление движения, решил начать с простого и написать классический packman, код движения в таймере приведён ниже:

Код:
procedure TForm1.Timer1Timer(Sender: TObject);
var tm:integer;
begin
  case moving of
    1:
    begin
    while f[packi,packj-1].value <> '1' do
    begin
      // закрашиваем участок, где только что были
      Form1.Canvas.Brush.Color:=clBlack;
      Form1.Canvas.Pen.Color:=clBlack;
      Form1.Canvas.Rectangle(f[packi,packj].x1,f[packi,packj].y1,f[packi,packj].x2,f[packi,packj].y2);
      f[packi,packj].value:='0';
      packj:=packj-1;
      f[packi,packj].x1:=x1;
      f[packi,packj].y1:=y1-20;
      f[packi,packj].x2:=x2;
      f[packi,packj].y2:=y2-20;
      f[packi,packj].value:='5';
      x1:=x1;
      y1:=y1-20;
      x2:=x2;
      y2:=y2-20;
      // рисуем колобка на новом месте
      Form1.Canvas.Brush.Color:=clYellow;
      Form1.Canvas.Pen.Color:=clYellow;
      Form1.Canvas.Ellipse(f[packi,packj].x1,f[packi,packj].y1,f[packi,packj].x2,f[packi,packj].y2);
    end;
    end;
    2:
    begin
    while f[packi,packj+1].value <> '1' do
    begin
      Form1.Canvas.Brush.Color:=clBlack;
      Form1.Canvas.Pen.Color:=clBlack;
      Form1.Canvas.Rectangle(f[packi,packj].x1,f[packi,packj].y1,f[packi,packj].x2,f[packi,packj].y2);
      f[packi,packj].value:='0';
      packj:=packj+1;
      f[packi,packj].x1:=x1;
      f[packi,packj].y1:=y1+20;
      f[packi,packj].x2:=x2;
      f[packi,packj].y2:=y2+20;
      f[packi,packj].value:='5';
      x1:=x1;
      y1:=y1+20;
      x2:=x2;
      y2:=y2+20;
      Form1.Canvas.Brush.Color:=clYellow;
      Form1.Canvas.Pen.Color:=clYellow;
      Form1.Canvas.Ellipse(f[packi,packj].x1,f[packi,packj].y1,f[packi,packj].x2,f[packi,packj].y2);
    end;
    end;
    3:
    begin
    while f[packi-1,packj].value <> '1' do
    begin
      Form1.Canvas.Brush.Color:=clBlack;
      Form1.Canvas.Pen.Color:=clBlack;
      Form1.Canvas.Rectangle(f[packi,packj].x1,f[packi,packj].y1,f[packi,packj].x2,f[packi,packj].y2);
      f[packi,packj].value:='0';
      packi:=packi-1;
      f[packi,packj].x1:=x1-20;
      f[packi,packj].y1:=y1;
      f[packi,packj].x2:=x2-20;
      f[packi,packj].y2:=y2;
      f[packi,packj].value:='5';
      x1:=x1-20;
      y1:=y1;
      x2:=x2-20;
      y2:=y2;
      Form1.Canvas.Brush.Color:=clYellow;
      Form1.Canvas.Pen.Color:=clYellow;
      Form1.Canvas.Ellipse(f[packi,packj].x1,f[packi,packj].y1,f[packi,packj].x2,f[packi,packj].y2);
    end;
    end;
    4:
    begin
    while f[packi+1,packj].value <> '1' do
    begin
      Form1.Canvas.Brush.Color:=clBlack;
      Form1.Canvas.Pen.Color:=clBlack;
      Form1.Canvas.Rectangle(f[packi,packj].x1,f[packi,packj].y1,f[packi,packj].x2,f[packi,packj].y2);
      f[packi,packj].value:='0';
      packi:=packi+1;
      f[packi,packj].x1:=x1+20;
      f[packi,packj].y1:=y1;
      f[packi,packj].x2:=x2+20;
      f[packi,packj].y2:=y2;
      f[packi,packj].value:='5';
      x1:=x1+20;
      y1:=y1;
      x2:=x2+20;
      y2:=y2;
      Form1.Canvas.Brush.Color:=clYellow;
      Form1.Canvas.Pen.Color:=clYellow;
      Form1.Canvas.Ellipse(f[packi,packj].x1,f[packi,packj].y1,f[packi,packj].x2,f[packi,packj].y2);
    end;
    end;
  end;
end;
AngelOfFate вне форума Ответить с цитированием
Старый 04.03.2011, 11:51   #527
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,876
По умолчанию

первое : в каждой ветке case не надо прописывать все те команды, которые и так повторяются (как я понял это команды заливки и рисовки), их надо вынести за case, даже для "неповторяющихся" команд можно определить закономерности, и уменьшить код
второе: для заливки области не надо использовать rectangle, а надо использовать fillrect , и тогда цвет пера не понадобится задавать
третье: лишний бегин-енд в каждой ветке кейса, ведь в while и так уже делаешь блок кода

ускорение - замедление - делается выставлением значения Interval для таймера, если у тебя всё по таймеру происходит

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

Последний раз редактировалось phomm; 04.03.2011 в 11:55.
phomm вне форума Ответить с цитированием
Старый 04.03.2011, 12:01   #528
AngelOfFate
Пользователь
 
Аватар для AngelOfFate
 
Регистрация: 02.03.2011
Сообщений: 12
По умолчанию

phomm, нашёл ошибку, вместо while надо было if использовать, тогда он задержка таймера работает, за fillrect и ссылку спасибо, а код ещё будет оптимизирован, просто в целях экономии времени я копипастил участки кода, а в целом ещё раз спасибо за советы
AngelOfFate вне форума Ответить с цитированием
Старый 08.03.2011, 01:10   #529
TLabel
Пользователь
 
Аватар для TLabel
 
Регистрация: 02.01.2011
Сообщений: 30
По умолчанию

привет вам!

я в этот раз пишу pacman и у меня такой вопрос:
как можно сделать так, чтобы призрак находил дорогу к pacman в лабиринте и за ним гонялся?
TLabel вне форума Ответить с цитированием
Старый 08.03.2011, 01:25   #530
ImmortalAlexSan
Участник клуба
 
Аватар для ImmortalAlexSan
 
Регистрация: 13.01.2009
Сообщений: 1,353
По умолчанию

Координаты: пакмэн - (Px, Py), злой дух (ZDx, ZDy). Злой знает где пакмэн, и дальше думаем, применяем формулу кратчайшего пути из точки А в точку Б, и начинаем двигать призрака по задуманым координатам (получившейся линии), координата точки линии равна координате стены лабиринта, то смещаем х или у на определенное число (Это если призрак сам не знает своего лабиринта) Но идея понятна я думаю.
"Тебе то может на меня и насрать, но твои глаза меня обожают!"
ImmortalAlexSan вне форума Ответить с цитированием
Ответ


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

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

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Хорошие уроки Render Общие вопросы Delphi 9 15.09.2012 07:13
Акцесс вопросы новичков Yaga Помощь студентам 4 02.06.2008 00:16
Учебники для новичков в програмировании Рар Общие вопросы Delphi 6 08.01.2007 08:07