Форум: "Игры";
Текущий архив: 2004.12.12;
Скачать: [xml.tar.bz2];
ВнизНе много о Sprite, подскажите. Найти похожие ветки
← →
MonoLife (2004-08-08 06:56) [0]Привет всем профессионалам и любителям Delphi!
Купил, чуть ли не на последние деньги, Интернет-карту.
И, конечно же, в первую очередь - на форум.
Отрадно видеть, что форум живее всех живых. Судя по вопросам,
задаваемых на форуме, участие принимают как профи, так и
новички в деле разработок приложений, игр и др. прогр. в среде Delphi.
И также, радует то, что НЕ ВСЕ умельцы отвечают на вопросы
новичков и "не совсем умельцев" одним ответом: "У Вас проблемы с
ДНК"... А причины, на первый взгляд, "глупых вопросов" - нехватка
информации (в городе, где "мы" живем, нет нужной литературы, Интернет
монополизирован и дорог до чертиков, время-деньги в сети
убегают со скоростью звука), ну и, в виде совсем запущенных
случаев, ДНК тоже. Вот и сейчас, прежде, чем написать на форум,
для экономии, я вынужден сперва набрать этот текст в Note...
Да простят меня за отнимаемое время гости и хозяева форума.
Хочется успеть попробовать в Delphi если не все, то многое.
Вот и сейчас, пытаюсь состряпать что-нибудь, похожее на 2-мерную
игрушку, используя DelphiX. Да простят меня приверженцы чистого
DirectXа и API.
Извините, затянул вступление. Поправьте меня, если я не прав. Подчерпывая
информацию в т.ч. из форума:
я понимаю действие Sprite(ов) и SpriteEngine - это отрисовка на экране
заданной картинки. То есть, Sprite не является объектом на форме как,
например, кнопка (TButton) или панель (TPanel), а только прорисованная
картинка? А значит, у Sprite нет собственных процедур, типа MouseDown,
MouseMove и т.д. Да, их нет в DXSprite.pas. Они есть у DXDraw...
Происходит все это при сравнении Rect картинки и позиции курсора мыши с
помощью какой-нибудь функции или проверки BoudsRect самого Sprite.
Но в моей будущей программе создается массив из TImageSprite(ов),
например, из 50 элементов, и после прорисовки, Sprites располагаются Random(ом)
на поверхности и с Z-координатой, например, от -2 до 2. Вот тут и
я столкнулся с проблемой, как "зацепить" мышкой верхний спрайт?
Ведь все, находящиеся под низом спрайты, тоже "сообщают" о совпадении
Rect с курсором мыши. А при проверке массива при щелчке "мыши", например,
от 0 до 49, "зацепится" не верхний спрайт (с максимальной Z-координатой),
а первый (последний, если downto) в списке массива. Пытаюсь решить эту
проблему несколько дней, но только больше запутался и поломал начатое.
Видно, не хватает мне знаний, и, самое страшное -
логики, для решения поставленной задачи. Почему я и обращаюсь на форум.
Есть ли решение в подобном случае? Или придется "писать" собственные компоненты, в чем, я боюсь, не мастак.
Спасибо за терпение при прочтении данного опуса.
← →
MonoLife (2004-08-08 12:30) [1]ЗЫ: Если на мой вопрос ответа не существует,
или "долго объяснять", то хоть подскажите тогда,
можно ли полностью избавиться от мерцания
TImage, при перемещении по форме?
Thank.
← →
Kruel (2004-08-08 14:19) [2]А что сложного. Перебирай сам в цикле все спрайты, и тот у которого Z больше (и при этом мышка в него попала), тот и будет верхним..
А насчет перемещения TImage забудь. Это компонент не для этого. Рисуй на Canvas формы.
← →
MonoLife (2004-08-08 15:46) [3]< Перебирай сам в цикле все спрайты, и тот у которого Z больше (и при этом мышка в него попала), тот и будет верхним..>>
Я пытался так сделать, но, видимо, и впрямь с логикой не все впорядке. Запутался. Тем более, что иногда Z-координата совпадает
← →
aprm (2004-08-08 17:39) [4]
> ЗЫ: Если на мой вопрос ответа не существует,
> или "долго объяснять", то хоть подскажите тогда,
> можно ли полностью избавиться от мерцания
> TImage, при перемещении по форме?
Вообще-то так не делают, но если очень хочется, можно timage засунуть в Tpanel, установить TPanel.fullrepaint:=false; и таскать уже за панель. Мерцать не будет
← →
Servelat © (2004-08-08 21:56) [5]Во-первых, если у спрайта нет прозрачных кусков (то есть у картинки Transparent=False), то это даром: DXSpriteEngine.Engine.GetSpriteAt(X, Y), вернет тебе нужный спрайт, и делай с ним что хошь.
Когда есть прозрачные участки - сложнее, я поковырялся (делать нефиг было :) ) и написал примерчик, там учитываются прозрачные области. Правда, там я не рассматривал варианта, когда Z одинаковые, если тебе охота - поковыряйся, я уверен, что сделать можно. Но я рассуждал так: Z может принимать значения от
-2147483648 до 2147483647.
Соответственно при названном тобой количестве в 50 спрайтов, проблемы в том, чтобы у каждого спрайта был свой Z, нет никакой.
Так что не парься и сделай Z не от -2 до 2, а от -20000 до 20000, и вероятность совпадения Z практически никакая.
Да, мой примерчик мона взять тут:
http://pavel-k.fromru.com/Sample.zip
Подсказка: там левой кнопкой мыши можно таскать спрайты (в этом весь смысл примера).
← →
MonoLife (2004-08-09 03:04) [6]arm >>
Обязательно попробую, спасибо.
Servelat >>
Спасибо. Я уж думал, совсем ничего нет по этому вопросу.
Все опробую и сообщу.
← →
MonoLife (2004-08-09 04:09) [7]Servelat>>>
Спасибо, я просмотрел и опробовал твой
код - просто и со вкусом! Оказалось все проще, чем я думал.
"Проверка пузырьком" - вот чего я не смог сделать.
Подозреваю, что это простейший ход, который обязан
знать начинающий кодер. Ну, и конечно, по больше разброс по Z,
это надо было мне сделать в первую очередь.
Тем не менее, при проверке работы программы, из
6 загрузок (51 спрайт) у 2 спрайтов 2 раза из 6, совпали
Z-координаты. Можно добавить разброс, но я думаю, это не
существенно, разброс, все равно получается большой.
← →
Megabyte-CeerCop © (2004-08-09 06:30) [8]Присваивай по Рандому только координаты. А Z по порядку от 0 до 50. Поверь этого будет достаточно для того чтобы комбинации не выглядели повторяющимися. Тогда проверяя спрайты с конца (от 50 к 0) ты обязательно в первую очередь наткнешься на самый верхний.
А еще можно вообще всем присвоить Z:= 0; Эффект будет тот же.
← →
MonoLife (2004-08-09 08:31) [9]>> Эффект будет тот же >>[8]
Тот, да не тот же. Смотря для каких целей. Причина в том, что при создании спрайтов, например, от 0 до 50, "больший" спрайт
будет перекрывать меньший. И в куче разных спрайтов их
можно спокойно "узнать". К чему клоню? Например, для создания
pazzle. Но, все равно, спасибо.
← →
MonoLife (2004-08-09 08:32) [10]>>>
Используя не прозрачные спрайты и
функцию DXSprite.Engine.GetSpriteAt(X, Y),
спасибо Servelat(у), у меня вот что получилось:
//*-*-*-*-*-*-*-*-*-*-*--dpr:
program MovSprite;
{Thank you for help SERVELAT}
uses
Forms,
SPMovi in "SPMovi.pas" {Form1};
{$R *.res}
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.
//*-*-*-*-*-*-*-*-*--pas:
unit SPMovi;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DXSprite, DXDraws, DXClass;
type
TMyPict= class(TImageSprite)
OX: double;
OY: double;
OZ: integer;
Lindex: Shortint;
end;
type
TForm1 = class(TForm)
DXDraw: TDXDraw;
ILfr: TDXImageList;
SEngi: TDXSpriteEngine;
DXTimer1: TDXTimer;
procedure FormCreate(Sender: TObject);
procedure DXTimer1Timer(Sender: TObject; LagCount: Integer);
procedure DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure DXDrawMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
private
{ Private declarations }
nW,nH: Shortint;
public
{ Public declarations }
end;
var
Form1: TForm1;
md: boolean;
SpCount: Shortint;
LindZ: integer;
MoviSpr: TImageSprite;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
var i: integer;
begin
DXDraw.Align:=alClient;
md:=false;
SpCount:=49;
LindZ:=0;
randomize;
SEngi.Engine.X:=0;
SEngi.Engine.Y:=0;
for i:=0 to SpCount-1 do
With TMyPict.Create(SEngi.Engine) do
begin
Image:=ILfr.Items.Find("nam");
Image.Transparent:=False;
Width:=Image.Width;
Height:=Image.Height;
X:=Random(DXDraw.Width-Width);
Y:=Random(DXDraw.Height-Height);
Z:=Random(500)-25;
OZ:=Z;
Lindex:=i;
end;
nW:=SEngi.Engine.Items[0].Width div 2;
nH:=SEngi.Engine.Items[0].Height div 2;
MoviSpr:=nil;
end;
procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer);
begin
if not DXDraw.CanDraw then exit;
DXDraw.Surface.Fill(0);
SEngi.Move(0);
SEngi.Draw;
with DXDraw.Surface.Canvas do
begin
if md then
begin
TextOut(1,20,IntToStr(LindZ));
TextOut(1,1,IntToStr((MoviSpr as TMyPict).Lindex));
end;
Release;
end;
DXDraw.Flip;
end;
procedure TForm1.DXDrawMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
i: integer;
P: TPoint;
begin
if Button<>mbLeft then exit;
p:=point(X,Y);
for i:=0 to SpCount-1 do
begin
if PtInRect(SEngi.Engine.Items[i].BoundsRect,P) then
begin
md:=true;
MoviSpr:=(SEngi.Engine.GetSpriteAt(X, Y) as TMyPict);
LindZ:= (MoviSpr as TMyPict).OZ;
(MoviSpr as TMyPict).Z:=600;
break
end;
Application.ProcessMessages;
end;
end;
procedure TForm1.DXDrawMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if md then
begin
md:=false;
(MoviSpr as TMyPict).Z:=(MoviSpr as TMyPict).OZ;
MoviSpr:=nil;
end;
end;
procedure TForm1.DXDrawMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if MoviSpr=nil then exit;
MoviSpr.X:=X-nW;
MoviSpr.Y:=Y-nH;
end;
end.
Наверное, нельзя в таком виде на форум выставлять?
Большое слишком сообщение?
← →
ASoft (2004-08-09 09:12) [11]>>спасибо Servelat(у)[10]>>
Присоединяюсь!
Была проблема...
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2004.12.12;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.042 c