Форум: "Игры";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];
ВнизDelphiX - Рождение и смерть спрайтов. Найти похожие ветки
← →
jab~ (2004-02-13 15:17) [0]За основу взял примерчик
DXSprites (http://delphigfx.mastak.ru/samples/samp17.rar)
Добавил свой класс
TDiablo = class(TImageSprite)
private
procedure SetAnim(AName : String);
procedure SetAnimAngle;
function FinishStep : Boolean;
function FinishMove : Boolean;
function FinishFollow : Boolean;
function HitBy(ASprite : TDiablo) : Boolean;
procedure Move;
protected
procedure DoDraw; override;
procedure DoMove(MoveCount: Integer); override;
procedure DoCollision(Sprite: TSprite; var Done: Boolean); override;
public
FDrawE : Boolean;
FStatus : TStatus; // Что делаем (идём, стоим, ...)
FTarget : TSprite; // Кого атакуем
FEnergy,
FAttackRadius, // Радиус атаки
FDestX, // Координаты куда
FDestY, // прийти
FMapX, // Координаты
FMapY, // на карте
FNextX, // Координаты
FNextY, // следующей клетки
FAngle, // Угол вектора скорости
FSpeed : Integer; // Скорость спрайта
FX,
FY : Double;
constructor Create(AParent: TSprite); override;
procedure SetDest(AX, AY : Integer);
procedure SetTarget(ATarget : TSprite);
end;
Ну естественно в маине для клика прописал:
procedure TMainForm.DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
// Когда я кликаю правой клавишей мыши
If ssRight in Shift then
If Selected<>nil then begin
Target:=Nil;
TCursor(MyCursor).Action:=aTarget;
TCursor(MyCursor).Collision;
If (Target=Nil) or (Target=Selected) then
begin
If Selected is TDiablo then TDiablo(Selected).SetDest(MouseMapX,MouseMapY);
If Selected is THero then THero(Selected).SetDest(MouseMapX,MouseMapY);
end Else
begin
If Selected is TDiablo then TDiablo(Selected).SetTarget(Target);
If Selected is THero then THero(Selected).SetTarget(Target);
end;
Target:=Nil;
end;
...
...
Сам класс TDiablo описал так же как и класс THero за исключением имен картинок подгружаемых (спарайтов)
Всё заработало практически сразу! У меня бегают 2 типа монстров и мочат друг друга, но вот незадача.. смерть монстра отображается не тем спрайтом. Смерть показывает именно тем кто убил, а не того кого убили...
Я думаю что нужно что то изменить в процедуре
function THero.HitBy(ASprite : THero) : Boolean;
begin
FEnergy:=FEnergy - 1;
If (FTarget=Nil) and (FStatus=stStop) Then SetTarget(ASprite);
If FEnergy<0
Then
begin
FStatus:=stDead;
Collisioned:=False;
SetAnim("Dead");
Result:=True;
end
Else
Result:=False;
end;
А начал менять то у меня ничего не вышло.... Может кто сможет помочь?
← →
ZAROLF © (2004-02-13 15:38) [1]Ты бы по понятней описал, возможно помогу тебе. Или демку хотябы выложи, чтоб не вслепую можно было над проектом работать.
← →
jab~ (2004-02-13 17:18) [2]ZAROLF
Уже в принципе разобрался...
Могу демку по почте выслать если интересно!?
И ещё проблемка..
Есть у меня в обработчике (таймер) такая штука
If isButton5 in MainForm.DXInput.States
Then
begin
TThin.Create(DXSpriteEngine.Engine);
end;
Ну тут понятно всё... создаётся класс. Вот только проблемка есть, как можно немного замедлить создание, а то я не успеваю нажать на кнопку как у меня вываливается груда монстров... если ставлю sleep() то уменя вся игра замирает... Это ведь й меня основной таймер... Может что подскажеш?
← →
ZAROLF © (2004-02-13 18:25) [3]jab~ (13.02.04 17:18) [2]
Ну тут понятно всё... создаётся класс. Вот только проблемка есть, как можно немного замедлить создание, а то я не успеваю нажать на кнопку как у меня вываливается груда монстров... если ставлю sleep() то уменя вся игра замирает... Это ведь й меня основной таймер... Может что подскажеш?
-----------------------------------------------------------------
var speed:shortint;
If isButton5 in MainForm.DXInput.States Then
begin
if speed>0then Dec(speed);
if speed>0then Exit;
speed:=10; //задержка
TThin.Create(DXSpriteEngine.Engine);
end;
Попробуй так.
← →
jab~ (2004-02-16 09:28) [4]Что то не работает такая задержка...
Попробывал вместо шортинтеджера влепить интеджер так вообще всё подвисать стало...
*************************
К слову:
Я начал использовать Random(10)
if random(10)=1 then
begin
Тут выполняется то что мне нужно задержать.
end
Такого рода задержка конечно полный абзац, но
работает и ничего не тормозит!
*************************
Есть вопрос:
В формкреате у меня происходит наполнение имэджлиста
ImageList.Items[0].Picture.LoadFromFile("main\Flur.bmp");
ImageList.Items[1].Picture.LoadFromFile("fatc\Go.bmp");
ImageList.Items[2].Picture.LoadFromFile("fatc\Stand.bmp");
ImageList.Items[3].Picture.LoadFromFile("fatc\Attack.bmp");
ImageList.Items[4].Picture.LoadFromFile("fatc\Dead.bmp");
ImageList.Items[6].Picture.LoadFromFile("main\Energy.bmp");
и т.д.
И наполнению этому нет конца и края...
Каким образом выводить картинку того что происходит лоадинг?
И ещё вопрос:
Когда у меня убивается монстр, то происходит смертельный ролик из спрайтов (он падает на землю весь окровавленный) и класс этого монстра принимает статус "sDead", но вот незадача... я нарубил груду монстров и у меня начинает тормозить комп по страшному так как у меня уже накопилась куча "мертвых" классов. Если им (классам) давать Dead по смертно, то тормозов нет, но классы умирают (и картинки тоже), а я бы хотел чтоб у меня на экране оставалась посмертная картина (куча трупов, кровище, оторванные конечности). Т.е. как рисовать на общий фон последний спрайт или может есть другой способ?
← →
m-AAA-d © (2004-02-16 09:55) [5]попробуй перед тем как удалишь спрайт убитого монстра получив его координаты и угол поворота нарисовать прямо на DXDraw.Surface соответствующий паттерн из DXImageCollection
← →
ZAROLF © (2004-02-16 11:05) [6]>jab~ (16.02.04 09:28) [4]
> Что то не работает такая задержка...
> Попробывал вместо шортинтеджера влепить интеджер так вообще
> всё подвисать стало...
>
var speed:shortint;
If isButton5 in MainForm.DXInput.States Then
begin
if speed>0then Dec(speed);
if speed>0then Exit;
speed:=10; //задержка
//ну так точно должно заработать
with TThin.Create(DXSpriteEngine.Engine)do
begin
....
end;
end;
> Если им (классам) давать Dead по смертно, то тормозов нет,
> но классы умирают (и картинки тоже), а я бы хотел чтоб у
> меня на экране оставалась посмертная картина (куча трупов,
> кровище, оторванные конечности). Т.е. как рисовать на общий
> фон последний спрайт или может есть другой способ?
-----------------------------------------------------------------
Может тебе останавливать спрайт на последнем кадре(посмертный).
← →
nexxiss © (2004-02-16 11:36) [7]Можно к тайлу добавить свойство с дополнительным изображением или какое другое свойство, по которому можно определить тип изображения для вывода поверх тайла
← →
jab~ (2004-02-17 11:05) [8]to m-AAA-d
Хм интересная идея... я об этом задумывался, но очень понимаю как этореализовать. В общем для полноты картины приведу кусок из проги:
// Загружаю карту
constructor TFlur.Create(AParent: TSprite; AX, AY : Integer);
var
i, j : Integer;
begin
inherited Create(AParent);
SetMapSize(AX,AY);
Image := MainForm.ImageList.Items.Find("GFlur");
X := 0; // Начальная координата по иксу
Y := 0; // Начальная координата по игрику
Z := -2; // Глубина
Width := MapWidth * Image.Width;
Height:= MapHeight * Image.Height;
//Случайное заполнение карты
For i:=0 to AX-1 do
For j:=0 to AY-1 do
Chips[i,j]:=Random(20);
end;
, где TFlur = class(TBackgroundSprite)
В общем тут всё просто.. я случайным образом заполняю фон квадратиками 32х32 (спрайтами). Указываю размер карты AX, AY : Integer
В формкреате после загрузки картинок в имэдж лист у меня выполняется:
Flur:=TFlur.Create(DXSpriteEngine.Engine,50,50);
А после я уже играюсь со спрайтами юнитов!
Посмертно классу юнита я присваиваю статус stDead и для всех классов имеющих этот статус отрабатывает следующее:
begin
SetAnimAngle;
If Round(AnimPos)=AnimCount
then begin
AnimSpeed:=0;
Z:=-1;
end;
end;
Это просто показываю последний спрайт из посмертного ролика!
Таким образом у меня разбросану по карте куча классов монстров которые показывают последнюю картинку их смерти.
Когда у меня накапливается некоторое колличество этих классов то у меня начинает жудко тормозить комп! (ведь они сидят в оперативке), а ещё я слышал о некой кривизне DXSpriteEngine который иногда проглючивает и меня выкидывает без предупреждения (но это если у меня "мертвых" спрайтов накапливается куча)
>>>>>>>>>>>>>
Как реализовать прорисовку посмертной картинки спрайта поверх фона(карты) TFlur или может есть другой способ?
>>>>>>>>>>>>>
← →
jab~ (2004-02-17 11:13) [9]to ZAROLF
Да нет... мне не нужно:
with TThin.Create(DXSpriteEngine.Engine)do
begin
....
end;
У меня всё описано в самом креате вся внутренность..
А для куска:
If isButton5 in MainForm.DXInput.States Then
begin
if speed>0then Dec(speed);
if speed>0then Exit;
...
У меня не происходит задержки... почемуто...
>Может тебе останавливать спрайт на последнем кадре(посмертный).
Это так и реализовано:
stDead :
begin
SetAnimAngle;
If Round(AnimPos)=AnimCount
then begin
AnimSpeed:=0;
Z:=-1;
end;
end;
Для статуса stDead я прорисовываю последнюю картинку смерти...
Вот если бы её прорисовать на карте, а спрайт командой Dead убить напроч... только я не знаю как это реализовать.
← →
jab~ (2004-02-17 11:23) [10]to nexxiss
Я так понял ты предлогаеш менят саму картинку куска карты на котором умер класс монстра или героя!?
Просто спрайт ячейки карты меньше спрайта монстра и умирая он занимает несколько кусков карты... Там картинку придется резат и раздавать... наверно есть более простой вариант...
Сам фон Z:=-10
Живой юнит Z:=2
Мертвый юнит Z:=-1
Может можно создать ещё какой то слой карты на котором будут картинки мертвых персонажей??? Если этот вариант возможен, то очень хотелось бы посмотреть на код реализации! :)
З/Ы я не очень здорово разбираюсь с DelphiX и если какой код есть, то коментарии к нему мне очень помогут! :)
← →
jab~ (2004-02-17 11:28) [11]И ещё если можно, примерчик по подсветке персонажей!
При наводке на персонажа мышы чтоб он обводился по контуру зеленой или красной канвой в зависимости от статуса агресивности.
А при хождении героя по карте чтоб он просвечивал стену за которой стоит (чтоб его можно было видеть сквозь стену и кликать на нем) как к примеру это в fallout или джагет алиансе и им подобных игрушек.
Оочень хочется смотреть реальные примеры а не просто на словах... :):):)
← →
ZAROLF © (2004-02-17 11:49) [12]>jab~ (17.02.04 11:13) [9]
>Для статуса stDead я прорисовываю последнюю картинку смерти...
>Вот если бы её прорисовать на карте, а спрайт командой Dead >убить напроч... только я не знаю как это реализовать.
-----------------------------------------------------------------
Ну попробуй при удалении спрайта, задать координаты(см. ниже) для
вывода простого image, соответственно и ресурсов будет жрать меньше, если конечно монстров будет не 1000.
X:=Self.X+Self.Width-10;
Y:=Self.Y+Self.Height-10;
Image:=MainForm.ImageList.Items.Find("Trup"); //простой пример
А вообще Delphix для данной цели не годиться.
← →
jab~ (2004-02-17 11:55) [13]to ZAROLF
Просто я хочу сделать игру по типу мысорубки...
Груда трупов, кровища, кишки, конечности...
..ладно, это всё из-за трудовых будней! :)
← →
nexxiss © (2004-02-17 12:21) [14]RE: Я так понял ты предлогаеш менят саму картинку куска карты на котором умер класс монстра или героя!?
Просто спрайт ячейки карты меньше спрайта монстра и умирая он занимает несколько кусков карты... Там картинку придется резат и раздавать... наверно есть более простой вариант...
Ничего резать не надо, дастаточно просто вывести картинку мертвого унита поверх тайла. Так тебе не нужно будет хранить объекты мертвых унитов, соответсвенно расход памяти меньше.
пример:
type
TAddedImage = record
...
...
...
dX,
dY,
ID: integer;
end;
...
...
...
TTile = record
...
...
...
AddedImage: TAddedImage;
end;
При создании карты AddedImage каждого тайла присваиваем несуществующий ID ( например -1), а при выводе тайла проверяем на наличие данного ID. Если <>-1, тогда выводим картинку мертвого юнита с индексом ID и смещением dX,dY.
Это только лишь идея по решению данной проблемы. Немного подумав, можно создать более оптимальный способ.
← →
jab~ (2004-02-17 12:34) [15]Хм... так так... есть пару мыслей... счас буду проверять.
← →
jab~ (2004-02-17 14:46) [16]В общем так!
Создал я класс:
TDead = class(TImageSprite)
protected
public
constructor Create(AParent: TSprite); override;
end;
constructor TDead.Create(AParent: TSprite);
begin
inherited Create(AParent);
Image := MainForm.ImageList.Items.Find("??????");
X := 10;
Y := 10;
Z := -1;
Width := Image.Width;
Height := Image.Height;
end;
Он будет у меня отображать дохлых юнитов в виде картинки!
Но каким образом мне узнать какую картинку подгружать?
← →
nexxiss © (2004-02-17 14:52) [17]А это задавай уже в живом юните. Когда он умирает, соответственно выбирается нужное изображение для дохлого
← →
jab~ (2004-02-17 16:48) [18]Вроде вышло... Полностью избавится от создания "мертвого" класса не вышло. Оказалось что просто так нарисовать картинку на карте не выходит... Пришлось создать облегченный класс с анимацией смерти. Таким образом во время смерти юнита я вызываю махонький классик в который передаю координаты смерти + угол разворота + тип юнита. Здохни злобный монстр... :):):) Таким образом я удовлетворил свою кровожаднось.... :):):) Теперь на экране запросто вмещается пару сотен трупов в различных позах (навалом), всё в крови и комп практически не тормозит.. так немножко заметно падение FPS но не сильно.
>>>>>>>>>>>>>>>>>>>>
Как мне создать экран загрузки..
Ну типа когда игра грузится, чтоб отображалась шкала на фоне какой то картинки (а то у меня сейчас просто черный экран), а после загрузки показывалось меню!?
>>>>>>>>>>>>>>>>>>>>
← →
nexxiss © (2004-02-18 17:00) [19]Заводим следующее дело:
type
TGameState = set of [ gs_Play, gs_Pause, gs_MainMenu, gs_InGameMenu, gs_Active ];
...
...
var
GameState: TGameState;
...
...
begin
GameState:=[gs_Active];
...
...
в процедуре вывода графики:
if not (gs_Active in GameState) then exit; // если приложение не активно то ничего не делаем
if gs_Play in GameState then <Играем дальше>
if gs_Pause in GameState then <Пауза>
и так далее
← →
jab~ (2004-02-19 09:13) [20]to nexxiss
Идея достойная! Наверно так буду делать.
Но тогда позникает опять таки не решенная проблема с этими дурацкими isButton"ami
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
begin
if not DXDraw.CanDraw then exit;
If isButton1 in MainForm.DXInput.States
Then
begin
GameState:=[gs_Pause];
end;
// Таким образом мне нужно писать ещё один клик
If isButton2 in MainForm.DXInput.States
Then
begin
GameState:=[gs_Play];
end;
end;
То есть у меня как бы 2 клавиши... одна ставит паузу, а другая её снимает, а как это в других играх реализовано на одной клавише?
Просто isButton сабака сробатыват до тех пор пока удержываеш клавишу... если бы было для него что то вроде KeyUp - KeyDown то можно было бы запросто переключать режимы. В данном случае просто KeyPress :(
А с задержкой описанной выше ничего не вышло.
← →
nexxiss © (2004-02-19 12:23) [21]Можно по-другому:
if isButton in MainForm.DXInput.States then
if gs_Pause in GameState then GameState:=GameState-[gs_Pause]
else GameState:=GameState+[gs_Pause];
вроде как таким образом, а gs_Play это для главного меню игры, т.е. если игра начата, тогда этот флаг есть, если нет, то нету
← →
jab~ (2004-02-19 15:00) [22]to nexxiss
У тебя if isButton in MainForm.DXInput.States then ...
устанавливает и снимает этот флаг?
процедура
procedure TMainForm.DXTimerTimer(Sender: TObject; LagCount: Integer);
отрабатывает 40 раз в секунду! .. соответственно этот влаг установится и снимется по 20 раз... и в конечном итоге не известно что получится.
← →
jab~ (2004-02-19 18:02) [23]Вот выложил:
http://gauss2k.narod.ru/mb.rar
Исправте кто то кривизну кода, а то я уже не знаю как это можно...
← →
nexxiss © (2004-02-19 18:18) [24]Это работать будет только в случае нажатия на кнопку, соответсвенно вызовов не будет 20-40, а только 1.
← →
jab~ (2004-01-23 13:36) [25]to nexxiss
Что то наверно не так, но у меня не получилось обьявить тип твоим способом...
Получилось так:
type
TGameState = (gs_Play, gs_Pause, gs_MainMenu, gs_InGameMenu, gs_Active );
← →
jab~ (2004-02-20 15:33) [26]Мда и ещё...
Если я прирываю вывод графики
if GameState=gs_Pause then begin
If isButton3 in MainForm.DXInput.States
then begin
GameState:=gs_Play;
end;
exit;
end;
или сворачиваю окно Alt+Tab то потом даже если возобнавляю (возвращаюсь в окно), то оно у меня не продолжает отрисовывать...
Что делать?
← →
nexxiss © (2004-02-20 16:11) [27]Хм, я пытался скачать твои исходники, но с narod.ru скорость совсем никакая, вышли на меил. Заодно гляну, что у тебя там выходит в общем. Тип не получается объявить, т.к. значения не определены
Высылай сурскод.
← →
jab~ (2004-02-23 09:02) [28]to nexxiss
Это автоматически сгенерированное сообщение почтового сервера UkrNet.
Посланное Вами сообщение не может быть доставлено одному или нескольким
получателям. Следующие адреса не были обработаны:
nexxiss@one.lv
SMTP error from remote mailer after end of data:
host mail2.one.lv [62.85.54.8]: 552 Mailbox <nexxiss@one.lv> does not have
enough space
------ Это копия сообщения, включая все заголовки. ------
------ Размер сообщения был 1179051 байт; только первые
------ 16384 байт показаны ниже.
← →
nexxiss © (2004-02-23 13:16) [29]Тогда попробуй отправить на nexxiss@mail.ru
У меня на том майле места не осталось, поэтому такая беда вышла
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2004.06.20;
Скачать: [xml.tar.bz2];
Память: 0.56 MB
Время: 0.044 c