Форум: "Игры";
Текущий архив: 2004.06.13;
Скачать: [xml.tar.bz2];
ВнизSplitScreen в DelphiX Найти похожие ветки
← →
KEHTABP (2004-01-23 23:38) [0]Подскажите, как реализовать SplitScreen в DelphiX (Тоесть когда экран делится на две части). Для этого нужно использовать 2 DXdraw? Или 2 DXspriteEngine? Однако, 2 DXDraw не хотят инициализироваться, со вторым DXspriteEngine тоже лажа. Да и вроде нерацианально. Надо, по идее, реализовать с одним DXdraw и одним DXspriteEngine. Но как???
← →
Iyeh (2004-01-25 03:04) [1]Ну ты блин даешь! В чем трабла то?
Если надо сплитскрин в сделать в фулскрине, то ессесно не будут 2 DXDraw работать. Потому, что фулскрин это эксклюзивный доступ к видеоресурсам...
А с одним DXDraw просто рисуй не во весь экран, а в половину, в 2 захода :)
← →
KEHTABP (2004-01-25 05:31) [2]Это я пробовал сделать, но так и не нашёл, как нарисовать только часть экрана в фулскрине, а тут ещё и привязка движка к 2-ум объектам через
Engine.X := -X+Engine.Width div 2-Width div 2 ;
Engine.Y := -Y+Engine.Height div 2-Height div 2;
Поэтому в голову и полезли всякие тупые мысли. Остаются 2 вопроса: Как нарисовать только часть экрана в фулскрине? Можно ли иначе заставить "камеру" двигаться за объекто?
← →
Iyeh (2004-01-26 01:36) [3]Наверно аркадку пишешь для 2-х игроков? По паре строк ничего не ясно, покажи код :) И что такое Engine? Если то, что рисовать зависит от него, то заведи 2 Engine"a...
← →
KEHTABP (2004-01-27 16:08) [4]Пишу я гонки. Трасса у меня создаётся в отдельном эдиторе, и следовательно границы трассы - спрайты размером 50х50. На один экран нормальная трасса естественно не влезет, а т. к. игроков 2, то нужен сплитскрин. Вот.
Код (сокращённо):
Procedure TPlayer1sprite.DoMove(MoveCount: Integer);
//движение игрока1
Begin
inherited DoMove(MoveCount);
changegear1;
x:=x+cos256(Angle)*speed1*0.002; //обработчик движения по X
y:=y+sin256(Angle)*speed1*0.002; //обработчик движения по Y
//LEFT
if isLeft in Form1.DXInput1.States then
begin
if (speed1>5) or (speed1<-5) then
begin
angle:=angle-1;
a1:=a1-1;
if a1<-45 then begin
angle:=angle-1;
speed1:=speed1-2;
x:=x+cos256(Angle+64)*speed1*0.001;
y:=y+sin256(Angle+64)*speed1*0.001;
end;
end;
end
else begin
a1:=0;
end;
//RiGHT
if isRight in Form1.DXInput1.States then
begin
if (speed1>5) or (speed1<-5) then
begin
angle:=angle+1;
a2:=a2+1;
if a2>45 then begin
angle:=angle+1;
speed1:=speed1-2;
x:=x+cos256(Angle-64)*speed1*0.001;
y:=y+sin256(Angle-64)*speed1*0.001;
end;
end;
end
else begin
a2:=0;
end;
//UP
if isup in Form1.DXInput1.States then
begin
speed1:=speed1+2+0.1*acc1;
reverse1:=false;
if gear1<1 then gear1:=1;end
else
if speed1 > 0 then speed1:=speed1-1;
//DOWN
if isDown in Form1.DXInput1.States then
begin
if reverse1=false then speed1:=speed1-4;
if gear1<1 then
begin
gear1:=-1;
reverse1:=true;
if speed1>-gearspeed1[1]*10 then speed1:=speed1-2;
end;
end
else if speed1<0 then speed1:=speed1+2;
if speed1>maxspeed1*10 then speed1:=speed1-6*10;
st:=floattostr(trunc(speed1/10));
collision;
{
Вот здесь к первому игроку привязывается изображение А Еngine здесь это DXSpriteEngine. Почему надо только Engine, я не знаю, но так написано в примере. Получается, что машина крутится на месте, а трасса двигается.
}
Engine.X := -X+Engine.Width div 2-Width div 2-250;
Engine.Y := -Y+Engine.Height div 2-Height div 2;
end;
end;
← →
KEHTABP (2004-01-27 16:11) [5]Как мне хотя бы заставить Dxdraw не зарисовываться полностью?
Ну есть ли что-нибудь вроде
Dxdraw1.намалевать_здесь(rect(0,400,0,600))?
← →
Iyeh (2004-01-28 01:09) [6]Нет, честно не понимаю, какая здесь может быть проблема...
У DXDraw есть Surface, у Surface есть Canvas - холст, а значит на нем можно рисовать как угодно. Функции "намалевать_здесь" у Canvas наверно не найдется :), но есть множество более востребованных функций :)
Можно так:
with DXDraw1.Surface do
begin
Fill(0); // Залить всю поверхность черным цветом.
FillRect(Bounds(0, 300, 800, 300), 0); // Залить облать (X 0, Y 300, W 800, H 300) черным цветом.
end;
или так:
with DXDraw1.Surface.Canvas do
begin
Brush.Color := clSilver;
Pen.Color := clBlack;
TextOut(0, 300, "Cool Programmer!");
Release; // Если использовать функции Canvas, то ОБЯЗАТЕЛЬНО пиши Release в конце кода.
end;
← →
KEHTABP (2004-01-31 23:55) [7]Тут всё гораздо сложней!
Какой для этого взять алгоритм? На 2 таймера вешать категорически нельзя. Значит получаем:
procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer);
begin
if not DXDraw1.CanDraw then exit;
DXInput1.Update;
DXSpriteEngine1.Move(LagCount);
DXSpriteEngine1.Dead;
DXSpriteEngine2.Move(LagCount);
DXSpriteEngine2.Dead;
//Теперь выводим то, что видно с первой "камеры"
DXSpriteEngine1.Draw;
with DXDraw1.Surface.Canvas do
begin
fillrect(rect(400,0,800,500)); //закрашиваем ненужную правую половину
release;
end;
//Теперь выводим то, что видно с второй "камеры"
DXSpriteEngine2.Draw;
with DXDraw1.Surface.Canvas do
begin
fillrect(rect(0,0,400,500)); //закрашиваем ненужную левую половину
Release;
end;
//выводим изображение на DXDraw
DXDraw1.Flip;
end;
После запуска, естественно, мы видим лишь вторую половину, т.к первая закрашивается до того, как выводится на DXDraw! Если использовать DXDraw1.Flip дважды, FPS падает вдвое и изображение моргает. Если за раз выводить лишь изображение с одной камеры за раз, то получим моргание с нормальным FPS. Если вдруг захочется, могу скинуть исходник на мыло, чтобы увидеть это самому.
Отсюда следует: нельзя выводить изображение на весь экран, а после убирать ненужную часть.
Значит надо, чтобы DXSpriteEngine.Draw рисовала только в определённом rect(x,y,w,h).
А может можно как нибудь заблокировать вывод на часть DXDraw?
А может можно создать для каждого DXSpriteEngine свой surfacе?
А может можно заблокировать часть экрана для рисования?
Если вдруг захочется, могу скинуть исходник на мыло.
← →
Mihey © (2004-02-01 00:13) [8]>У DXDraw есть Surface, у Surface есть Canvas - холст, а значит на нем можно рисовать как угодно.
А если рисовать на канве (холсте), то и DelphiX не нужен.
>А может можно создать для каждого DXSpriteEngine свой surfacе?
Можно отказаться от DXSpriteEngine и работать своими методами. Не такой уж он и удобный.
← →
KEHTABP (2004-02-04 01:07) [9]>>Можно отказаться от DXSpriteEngine
И весь проект писать сначала?
← →
KEHTABP (2004-02-16 23:22) [10]Я всё-таки смог создать сплитскрин!!!
Если кому-то интересно, то вот как это выглядит:
////////////////////////////
// в type формы:
private
FSurface1,Fsurface2: TDirectDrawSurface;
// главный таймер сработал
procedure TForm1.DXTimer1Timer(Sender: TObject; LagCount: Integer);
begin
if not DXDraw1.CanDraw then exit;
// обновляем
DXInput1.Update;
DXSpriteEngine1.Move(LagCount);
DXSpriteEngine1.Dead;
DXSpriteEngine2.Move(LagCount);
DXSpriteEngine2.Dead;
//рисуем на специально выделенных для каждого двигуна поверхностях
DXspriteEngine1.Engine.Surface:=FSurface1;
DXSpriteEngine1.Draw;
DXspriteEngine2.Engine.Surface:=FSurface2;
DXSpriteEngine2.Draw;
//заполняем DXDraw
Dxdraw1.Flip;
DXDraw1.Surface.Draw(0 ,0, FSurface1.ClientRect, FSurface1, True);
DXDraw1.Surface.Draw(400,0, FSurface1.ClientRect, FSurface2, True);
....
end;
//работа с поверхностями
//создаём
procedure TForm1.DXDraw1InitializeSurface(Sender: TObject);
begin
FSurface1 := TDirectDrawSurface.Create(DXDraw1.DDraw);
fsurface1.SetSize(400,500);
FSurface2 := TDirectDrawSurface.Create(DXDraw1.DDraw);
fsurface2.SetSize(400,500);
end;
//очищаем
procedure TForm1.DXDraw1FinalizeSurface(Sender: TObject);
begin
FSurface1.Free; FSurface1 := nil;
FSurface2.Free; FSurface2 := nil;
end;
//связываем с DXSpriteEngine
procedure TForm1.FormActivate(Sender: TObject);
begin
DxspriteEngine1.Engine.Surface:=fsurface1;
DxspriteEngine2.Engine.Surface:=fsurface2;
end;
Вот!
Спасибо тем, кто старался помочь!
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2004.06.13;
Скачать: [xml.tar.bz2];
Память: 0.48 MB
Время: 3.627 c