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

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

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

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 04.06.2009, 22:59   #91
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Это верно, что каждому свое. Методы по оптимизации и скорости равноценны, но по изменению взаимотношений между классами не фонтан, ...нужно все сразу продумать, или погружаться в движок по первому требованию.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 05.06.2009, 13:21   #92
Shadow_1329
Форумчанин
 
Аватар для Shadow_1329
 
Регистрация: 23.02.2009
Сообщений: 237
По умолчанию

Этож весь код переделывать надо(:Beep:, :beep:, ну ваще :beep! Ладно я это сделаю ну только вы мне про проходимость расскажите чтобы все сразу сделать и не переделывать по
for i:=1 to 100 do
begin
раз[i]:= optimizate code
end; свой код!
Shadow_1329 вне форума Ответить с цитированием
Старый 05.06.2009, 15:00   #93
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
Вот пример общего типа.
Код:
// тип игрового объекта GUnit (G - game, Unit - юнит)
type
  GUnit = packed record
    GTUnitType: Byte;       // тип юнита
    GTType:      Byte;      // раса (1 - RUS, 2 - GER, 3 - USA)
    GTStatus:    Byte;      // состояние (0 - стоит, 1 - едет, 2 - стреляет, 4 - погибает)
    GTUses:      Boolean;   // использование танка (в игре/не в игре)
    GTSelected:  Boolean;   // выделение танка

    GTPosX:      Word;      // позиция по-X
    GTPosY:      Word;      // позиция по-Y
    GTPointX:    Word;      // конечная позиция по-X
    GTPointY:    Word;      // конечная позиция по-Y
    GTMoveX:     ShortInt;  // смещение по карте на пиксел по-X
    GTMoveY:     ShortInt;  // смещение по карте на пиксел по-Y

    GTWidth:     Word;      // длина текстуры танка
    GTHeight:    Word;      // ширина текстуры танка
    GTDispX:     ShortInt;  // смещение статичное по-X
    GTDispY:     ShortInt;  // смещение статичное по-Y

    GTAnimType:  Byte;      // тип анимации (движение, стрельба, гибель)
    GTKadr:      Byte;      // текущий кадр
    GTMaxKadr:   Byte;      // максимальное число кадров
    GTRound:     Word;      // поворот на угол

    GTSpeed:     Real;      // скорость танка
    GTArmor:     Byte;      // броня
    GTWeapon:    Byte;      // сила пушки
    GTHPMax:     Word;      // количество жизней
    GTHP:        Word;      // текущее количество жизней
  end;
// --------------------------------------------------
Таки на классах красивее было бы.
Да и перечисления не мешало бы использовать, а то все эти Byte можно чем угодно заполнить и расу в 5 установить - не проблема, хотя по игровой логике такой не предусмотрено.
Опять же несколько нарушена логика "объединения" данных.
Выделение танка, его использование, параметры текстуры - всё это не относится к танку как таковому. Я бы сделал как-то так:
Код:
ТТанк = класс
  состояние: TСостояние;
  раса: ТРаса;
  позиция: ТПозиция;
  скорость: real;
  оружие: ТОружие;
  броня: ТБроня;
  жизни: word;
  модель: ТМодель;
конец;
ну жизни и скорость тоже можно вынести в отдельный класс, ведь по пашне скорость одна, а по асфальту другая и башню может оторвать, но гусеницы целёхонькие останутся. Всё зависит от предусматриваемых возможностей.

Причины выноса в отдельные типы:
Состояние: набор состояний банально может измениться и нолики все эти и единицы искать по коду не интересно
Раса: допустим, захотелось миссию, где 3 расы присутствует и 2 между собой союзники. Как Вы эту проверку реализуете? А так добавили в класс ТРаса список союзников и в методе: ЭтоВраг поправили определение враждебности. А для танка соответственно определение враждебности будет: если (танк1.раса.ЭтоВраг(танк2)) значит враг

оружие: ну опять же решите добавить какую-то новую характеристику оружия и добавлять новую запись к танку? а ведь у танка сразу и пушка и пулемет, а может фантастическая стратегия и у танка 3 пушки будет? Так просто объявить у танка:
Код:
ТРусскийТанк = класс (ТТанк)
  пулемёт: ТОружие;
  пушка: ТОружие;
конец;
выстрел из пушки по танку врага соответственно будет:
танк1.пушка.выстрел(танк2);

броня: опять же можно решить сделать более разнообразно, что у этого танка броня невосприимчива к огню, а вот у этого её и из автомата прострелишь, соответственно всё это в классе ТБроня будет прописана и изменения в броне не повлекут изменений в танке.
расчет повреждений выносится в класс брони:
танк1.жизни := танк1.жизни - танк1.броня.повреждения(оружие: ТОружие);

ну модель - это просто к танку, как игровому объекту, никакого отношения не имеет и потому не должны параметры текстуры быть размазаны по игровой логике. И возможно вообще её стоит выкинуть из класса ТТанк и хранить где-нибудь отдельно.

В общем как-то так примерно я бы сделал
pu4koff вне форума Ответить с цитированием
Старый 05.06.2009, 17:06   #94
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Сразу повторю, система древовидная, главное - в типе, это всего лишь универсальные указатели на ресурсы. Оружие типа Byte означает, что у вас может быть 256 модификаций оружия с разными параметрами, какими? ...смотрим файл с номером, в нем параметры и ссылка на графику, как выглядит, как стреляет и как попадает, что с противником должно делаться, такая же ссылка на тип повреждения. Андерстенд? )))

Кто кому враг записывается не в коде и его классах, а в файле карты и триггерах сценария. От вас требуется только написать движок поведения, ориентация на данные значения GTType, ...если в сценарии написано, что расы 3, то другим просто взяться неоткуда.
Цитата:
Сообщение от pu4koff
Да и перечисления не мешало бы использовать, а то все эти Byte можно чем угодно заполнить и расу в 5 установить - не проблема, хотя по игровой логике такой не предусмотрено.
В том то и дело, что все предусмотрения в сценарии, отдельном от кода. В любой момент можно устанавливать что-угодно и куда-угодно.

Shadow_1329, ...постараюсь помочь с проходимостью.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 05.06.2009, 17:22   #95
Shadow_1329
Форумчанин
 
Аватар для Shadow_1329
 
Регистрация: 23.02.2009
Сообщений: 237
По умолчанию

Спасибо!
З.Ы. На данный момент я делаю 3 игры - это вот эта стратегия, вторая стратегия и РПГ. В общем эти дискуссии мне только на пользу. Я во второй стратегии делаю все то что я знаю и то что мне сказали здесь и получается то ого-го! Код компактный, аккуратный, понятный(во всяком случае для меня). Ну а в РПГ были бы мучения с этими классами в обработке предметов.
Shadow_1329 вне форума Ответить с цитированием
Старый 05.06.2009, 19:38   #96
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Beermonza Посмотреть сообщение
Сразу повторю, система древовидная, главное - в типе, это всего лишь универсальные указатели на ресурсы. Оружие типа Byte означает, что у вас может быть 256 модификаций оружия с разными параметрами, какими? ...смотрим файл с номером, в нем параметры и ссылка на графику, как выглядит, как стреляет и как попадает, что с противником должно делаться, такая же ссылка на тип повреждения. Андерстенд? )))
Вы вероятно не поверите, но данные, хранимые в объекте, можно читать из файла и "зашивать" в коде, что-либо нет необходимости. У Вас только характеристики оружия и брони записаны в самом "танке". Это для каждого юнита прописывать, что хоть это и танк т90, но уточняем, что у него сила оружия вот такая-то, а броня вот такая вот, хотя у всех танков этого типа оружие и броня одинаковые?
Так же и для текстур - для каждого юнита заново читаются все параметры и для каждого из них создаётся новая копия текстуры в памяти?
Цитата:
Сообщение от Beermonza Посмотреть сообщение
Кто кому враг записывается не в коде и его классах, а в файле карты и триггерах сценария. От вас требуется только написать движок поведения, ориентация на данные значения GTType,
Опять же никто не мешает и с классами реализовать чтение параметров из файла.

Если кто-то не понимает ООП, то это не значит, что на записях Ваш вариант универсальнее, нежели можно на ООП замутить. Ага?
С ООП, при грамотном его использовании, код будет стройным, красивым и понятным
pu4koff вне форума Ответить с цитированием
Старый 05.06.2009, 19:42   #97
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,065
По умолчанию

Цитата:
Сообщение от Shadow_1329
На данный момент я делаю 3 игры
Что же так мало? Сразу бы уж штук 10
ЗЫ. Я даже боюсь представить что там у Вас за игры такие, что аж сразу 3 штуки делаете
pu4koff вне форума Ответить с цитированием
Старый 05.06.2009, 22:12   #98
Beermonza
Инженер ИС
Старожил
 
Аватар для Beermonza
 
Регистрация: 13.12.2006
Сообщений: 2,671
По умолчанию

Цитата:
Сообщение от pu4koff Посмотреть сообщение
Вы вероятно не поверите, но данные, хранимые в объекте, можно читать из файла и "зашивать" в коде, что-либо нет необходимости. У Вас только характеристики оружия и брони записаны в самом "танке". Это для каждого юнита прописывать, что хоть это и танк т90, но уточняем, что у него сила оружия вот такая-то, а броня вот такая вот, хотя у всех танков этого типа оружие и броня одинаковые?
Так же и для текстур - для каждого юнита заново читаются все параметры и для каждого из них создаётся новая копия текстуры в памяти?
Если автор топа позволяет, то подискутируем, ...ему вроде как на пользу.
Данные менять можно везде, а вот что можно изменить взаимотношения между классами, хоп предка вниз, потомка наверх, короче изменить дерево я честно сказать не знал.
Ну, если взять игры, где берется тип корпуса, тип башни, и навешиваются оружия, то ни о каких классах "T-90" со стандартами внутри в коде речи быть не может. В любой момент можно считать готовый файл конфигурации, он сам заполнит для юнитов все параметры, или если не нравится, по ходу меняем параметры, как в сборочном цехе, сохраняем в новый файл конфигурации или в памяти по ходу игры.
На счет текстур. Тут есть тип и подтип, создаются они по требованию, по "номеру" юнита берутся данные для этого типа юнита, нужные кадры анимации, дублирования для каждого нет и не может быть, только индексы. Поскольку все в памяти хранится, то выдернуть анимацию нет проблем, достаточно опросить динамический массив по номерам ячеек.
В сущности, мой метод аналогичен реляционной модели базы данных, доступ есть в любое место данных, можно скрестить поезд с носорогом, не заглядывая в код. По сути выходит универсальный движок.
Здесь же я предлагаю наипростейший и понятный упрощенный вариант, он сам по себе логичен.
Руководитель проекта MMO 2D RPG: Настоящее имя Денис Стрижак (10.05.1981-6.02.2019) Мир духу его
Beermonza вне форума Ответить с цитированием
Старый 05.06.2009, 23:43   #99
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
Лампочка

Ну вот по моим наблюдениям процедуры + записи действительно будет (намного) легче реализовать, пока проект не дорастёт до определённого уровня сложности, потом ситуация резко меняется, и начинается жуткая путанница, костыли, заплатки. Этот неприятный момент можно сколь угодно долго оттягивать, правильно структурируя код, раскидывая его части по разным модулям, и если удасться успеть воплотить всё задуманное до него - браво, вы постигли тайну Хлопка Одной Рукой, но так получается редко (опять же, это у меня ). То есть как для начинающего - вполне подходит, тем более классы, грубо говоря, похожи на записи, склеенные с процедурами.

Если писать классами - нужно с самого начала хорошо продумать структуру, как ни крути, выйдет уже игровой движок, и если добавить недостающий функционал - элементарно, то вырезание лишнего кода из класса-родителя затронет потомков, скорее всего будут проблемы. Опять же, наделав классов-болванок, можно увидеть полусырой движок/игру в действии, и отладить все ошибки до того, как они проявят себя в готовом продукте. Я вот тут состряпал буквально за 10 минут топором на коленке страшный быдлокод, и тем не менее довольно наглядно работает и легко расширяем


(компиляемо, извиняюсь за размер, аттач не цепляется)
Где-то через час доберусь домой - перезалью, напишу почему он страшный и что не так
пыщь
JTG вне форума Ответить с цитированием
Старый 05.06.2009, 23:44   #100
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Код:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls;

const maxTanks = 30;

type
  TForm1 = class(TForm)
    DrawTimer: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure DrawTimerTimer(Sender: TObject);
    procedure Render;
  private
    { Private declarations }
  public
    { Public declarations }
  end;

  TDirection = (dirLeft, dirUp, dirRight, dirDown);

  TTank = class(TObject)
    fX, fY:integer;      
    fWidth, fHeight: integer; 
    fDirection: TDirection;    
    fDC: HDC;         
    fHP: integer;       
    fTexture: TBitmap;
    speed:  integer;
  public
    constructor create(DC: HDC);
    destructor destroy; override;
    procedure SetTexture(bmp: TBitmap);
    procedure move;
    procedure collide;
    procedure draw;
    procedure dead;
    property x:integer read fx write fx;
    property y:integer read fy write fy;
  end;

  TGoodTank = class(TTank)
  end;

  TBadTank = class(TTank)
  end;

  TBullet = class(TObject)
  end;

var
  Form1: TForm1;
  maxX, maxY: integer;
  tanks: array[0..maxTanks] of TTank;
  map:   array[0..24, 0..24] of TObject;
  GoodTankTexture, BadTankTexture, BackBuffer: TBitmap;

implementation

uses Math;

{$R *.dfm}

{ TTank }

constructor TTank.create(DC: HDC);
begin
  inherited Create;
  fx:=random(24)*26;
  fy:=random(24)*26;
  speed:=random(3)+1;
  fDirection:=TDirection(random(4));
  fTexture := TBitmap.Create;
end;

destructor TTank.destroy;
begin
  fTexture.Free;
  inherited
end;

procedure TTank.SetTexture(bmp: TBitmap);
begin
  fTexture.Assign(bmp);
end;

procedure TTank.draw;
begin
  BackBuffer.Canvas.Pen.Color:=clLtGray;
  BackBuffer.Canvas.Pen.Style:=psDot;
  BackBuffer.Canvas.Brush.Style:=bsClear;

  Case fDirection of
    dirup:    begin
                BackBuffer.Canvas.Rectangle(fx,fy-(fy mod 26),fx+26,fy+26-(fy mod 26));
                BitBlt(BackBuffer.Canvas.Handle,fx,fy,26,26,fTexture.Canvas.Handle,1,1,SRCCOPY);
              end;
    dirright: begin
                BackBuffer.Canvas.Rectangle(fx+26+26-(fx mod 26),fy,fx+26-(fx mod 26),fy+25);
                BitBlt(BackBuffer.Canvas.Handle,fx,fy,26,26,fTexture.Canvas.Handle,26,1,SRCCOPY);
              end;
    dirdown:  begin
                BackBuffer.Canvas.Rectangle(fx,fy+26+26-(fy mod 26),fx+26,fy+26-(fy mod 26));
                BitBlt(BackBuffer.Canvas.Handle,fx,fy,26,26,fTexture.Canvas.Handle,52,1,SRCCOPY);
              end;
    dirleft:  begin
                BackBuffer.Canvas.Rectangle(fx-(fx mod 26),fy,fx+26-(fx mod 26),fy+25);
                BitBlt(BackBuffer.Canvas.Handle,fx,fy,26,26,fTexture.Canvas.Handle,78,1,SRCCOPY);
              end;
  end;
end;

procedure TTank.collide;
begin
  //
end;

procedure TTank.move;
begin
  Case fdirection of
    dirup:    y := y-speed;
    dirright: x := x+speed;
    dirdown:  y := y+speed;
    dirleft:  x := x-speed;
  end;
  
  if x<=0 then fDirection:=dirright;
  if x+26>=600 then fDirection:=dirleft;
  if y<=0 then fDirection:=dirdown;
  if y+26>=600 then fDirection:=dirup;
  if random(50)=0 then
    begin
      fDirection:=TDirection(random(4));
      if (x mod 26)<=(x div 2) then x:=x-(x mod 26) else x:=x+26-(x mod 26);
      if (y mod 26)<=(y div 2) then y:=y-(y mod 26) else y:=y+26-(y mod 26);
    end;
end;

procedure TTank.dead;
begin
//
end;

procedure TForm1.FormCreate(Sender: TObject);
var i:integer;
begin
  randomize;
  maxX := ClientWidth;
  maxY := ClientHeight;
  
  GoodTankTexture := TBitmap.Create;
  BadTankTexture  := TBitmap.Create;
  BackBuffer      := TBitmap.Create;

  GoodTankTexture.LoadFromFile('goodtank.bmp');
  BadTankTexture.LoadFromFile('badtank.bmp');

  BackBuffer.Width:=ClientWidth;
  BackBuffer.Height:=ClientHeight;
  BackBuffer.Canvas.Brush.Color:=clBlack;

  for i:=0 to maxTanks do
     begin
       tanks[i] := TTank.create(BackBuffer.Canvas.Handle);
       if odd(i) then tanks[i].SetTexture(GoodTankTexture)
                 else tanks[i].SetTexture(BadTankTexture)
     end;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var i:integer;
begin
  for i:=0 to maxTanks do tanks[i].Free;
  GoodTankTexture.Free;
  BadTankTexture.Free;
  BackBuffer.Free;
end;

procedure TForm1.DrawTimerTimer(Sender: TObject);
begin
  Render
end;

procedure TForm1.Render;
var i:integer;
begin
  BackBuffer.Canvas.Brush.Style:=bsSolid;
  BackBuffer.Canvas.Brush.Color:=clBlack;
  BackBuffer.Canvas.FillRect(ClientRect);

  for i:=0 to maxTanks do
    begin
      tanks[i].collide;
      tanks[i].move;
      tanks[i].draw;
    end;

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

end.
пыщь
JTG вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создаю "тестирующую систему" для проверки задач. Программисты, нужна ваша помощь! alexfmf Помощь студентам 12 30.04.2009 20:19
Создаю диаграмму "Bar". Подскажите как убрать растояние между "столбами" MAcK Компоненты Delphi 11 24.10.2007 10:49