Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

игра hitman


Страницы:   1 2

iliann ©   (2003-05-16 23:06:00) 

в игре(open lg) hitman главный персонаж находиться в 3-х мерном пространстве
упрвление осуществляется мышью и курсорн. клавишами
я хочу сделать подобную игру ,но не знаю с чего начать
пожалста подскажите основные функции для такой игры


3d[Power]   (2003-05-24 01:05:00) [1]

При инициализации DirectInput8 курсор пропадает вообще (сам), даже вне области окна.


cyborg   (2003-05-23 12:41:00) [2]

Кен в DirectInput ничего перемещать не нужно, получаешь смещение на которое передвинулся курсор и всё.

Uses
...
DirectInput8;
//+++++++DirectInput8 объекты (Клавиатура и мышь)+++++++++++++++
CONST
KEYBOARD_BUFFER_SIZE = 16; //Размер буффера клавишь DirectInput8
VAR
DInput : IDIRECTINPUT8 = nil; //Интерфейс DirectInput8
DIKeyboard : IDIRECTINPUTDEVICE8 = nil; //Интерфейс клавиатуры
DIMouse : IDIRECTINPUTDEVICE8 = nil; //Интерфейс мышки
Keyboard : Array [0..KEYBOARD_BUFFER_SIZE - 1] of TDIDEVICEOBJECTDATA; //Буффер клавишь DirectInput8
Mouse : TDIMOUSESTATE2; //Значения статуса мышки

//Координаты крсора мышки:
MouseX : LongInt = 100;
MouseY : LongInt = 100;
MouseZ : LongInt = 0; //Содержит значение прокрутки колёсика мышки

Function InitDirectInput : Cardinal;
Var
dipdw : TDIPROPDWORD;

Begin
//DirectInput8:
DInput := nil;
Result := DirectInput8Create (hInstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, DInput, nil);
if Result<>0 then Exit;
//Клавиатура:
DIKeyboard := nil;


Result := DInput.CreateDevice (GUID_SysKeyboard, DIKeyboard, nil);
if Result<>0 then Exit;

Result := DIKeyboard.SetDataFormat(@c_dfDIKeyboard);
if Result<>0 then Exit;

Result := DIKeyboard.SetCooperativeLevel(WindowHandle, DISCL_EXCLUSIVE or DISCL_FOREGROUND);
if Result<>0 then Exit;

FillChar(dipdw, SizeOf (dipdw),0);
with dipdw do begin
diph.dwSize := SizeOf(TDIPROPDWORD);
diph.dwHeaderSize := SizeOf(TDIPROPHEADER);
diph.dwObj := 0;
diph.dwHow := DIPH_DEVICE;
dwData := KEYBOARD_BUFFER_SIZE;
end;

Result := DIKeyboard.SetProperty(DIPROP_BUFFERSIZE, dipdw.diph);
if Result<>0 then Exit;

Result := DIKeyboard.Acquire;

//Мышка:
DIMouse:=nil;

Result := DInput.CreateDevice (GUID_SysMouse, DIMouse, nil);
if Result<>0 then Exit;

Result := DIMouse.SetDataFormat(@c_dfDIMouse2);
if Result<>0 then Exit;

Result := DIMouse.SetCooperativeLevel(WindowHandle, DISCL_EXCLUSIVE or DISCL_FOREGROUND);
if Result<>0 then Exit;

Result := DIMouse.Acquire;
End;

Procedure CloseDirectInput;
begin
//Освобождение мышки DirectInput8
if DIMouse<>nil then
begin
DIMouse.Unacquire;
DIMouse := nil;
end;

//Освобождение клавиатуры DirectInput8
if DIKeyboard<>nil then
begin
DIKeyboard.Unacquire;
DIKeyboard := nil;
end;

if DInput<>nil then DInput := nil;
end;

function ReadDirectInputData : Cardinal; //Чтение буффера нажатых клавишь и мышки
var
i : Cardinal;
hRet : Cardinal;
// s : String;
begin
//Чтение статуса клавиатуры:
if DIKeyboard = nil then begin
Result := DI_OK;
Exit
end;
hRet := DIKeyboard.GetDeviceData (SizeOf(TDIDEVICEOBJECTDATA),
@Keyboard, Result, 0);
if hRet<>0 then begin
hRet := DIKeyboard.Acquire;
while hRet = DIERR_INPUTLOST do
hRet := DIKeyboard.Acquire;
end;

//Чтение статуса мышки:
FillChar(Mouse, SizeOf(Mouse),0);
hRet := DIMouse.GetDeviceState(SizeOf(TDIMOUSESTATE2), @Mouse);
if hRet<>0 then begin
hRet := DIMouse.Acquire;
( mouseX,Mouse.lX) [23]

Кен в DirectInput ничего перемещать не нужно, получаешь смещение на которое передвинулся курсор и всё.

Uses
...
DirectInput8;
//+++++++DirectInput8 объекты (Клавиатура и мышь)+++++++++++++++
CONST
KEYBOARD_BUFFER_SIZE = 16; //Размер буффера клавишь DirectInput8
VAR
DInput : IDIRECTINPUT8 = nil; //Интерфейс DirectInput8
DIKeyboard : IDIRECTINPUTDEVICE8 = nil; //Интерфейс клавиатуры
DIMouse : IDIRECTINPUTDEVICE8 = nil; //Интерфейс мышки
Keyboard : Array [0..KEYBOARD_BUFFER_SIZE - 1] of TDIDEVICEOBJECTDATA; //Буффер клавишь DirectInput8
Mouse : TDIMOUSESTATE2; //Значения статуса мышки

//Координаты крсора мышки:
MouseX : LongInt = 100;
MouseY : LongInt = 100;
MouseZ : LongInt = 0; //Содержит значение прокрутки колёсика мышки

Function InitDirectInput : Cardinal;
Var
dipdw : TDIPROPDWORD;

Begin
//DirectInput8:
DInput := nil;
Result := DirectInput8Create (hInstance, DIRECTINPUT_VERSION,
IID_IDirectInput8, DInput, nil);
if Result<>0 then Exit;
//Клавиатура:
DIKeyboard := nil;


Result := DInput.CreateDevice (GUID_SysKeyboard, DIKeyboard, nil);
if Result<>0 then Exit;

Result := DIKeyboard.SetDataFormat(@c_dfDIKeyboard);
if Result<>0 then Exit;

Result := DIKeyboard.SetCooperativeLevel(WindowHandle, DISCL_EXCLUSIVE or DISCL_FOREGROUND);
if Result<>0 then Exit;

FillChar(dipdw, SizeOf (dipdw),0);
with dipdw do begin
diph.dwSize := SizeOf(TDIPROPDWORD);
diph.dwHeaderSize := SizeOf(TDIPROPHEADER);
diph.dwObj := 0;
diph.dwHow := DIPH_DEVICE;
dwData := KEYBOARD_BUFFER_SIZE;
end;

Result := DIKeyboard.SetProperty(DIPROP_BUFFERSIZE, dipdw.diph);
if Result<>0 then Exit;

Result := DIKeyboard.Acquire;

//Мышка:
DIMouse:=nil;

Result := DInput.CreateDevice (GUID_SysMouse, DIMouse, nil);
if Result<>0 then Exit;

Result := DIMouse.SetDataFormat(@c_dfDIMouse2);
if Result<>0 then Exit;

Result := DIMouse.SetCooperativeLevel(WindowHandle, DISCL_EXCLUSIVE or DISCL_FOREGROUND);
if Result<>0 then Exit;

Result := DIMouse.Acquire;
End;

Procedure CloseDirectInput;
begin
//Освобождение мышки DirectInput8
if DIMouse<>nil then
begin
DIMouse.Unacquire;
DIMouse := nil;
end;

//Освобождение клавиатуры DirectInput8
if DIKeyboard<>nil then
begin
DIKeyboard.Unacquire;
DIKeyboard := nil;
end;

if DInput<>nil then DInput := nil;
end;

function ReadDirectInputData : Cardinal; //Чтение буффера нажатых клавишь и мышки
var
i : Cardinal;
hRet : Cardinal;
// s : String;
begin
//Чтение статуса клавиатуры:
if DIKeyboard = nil then begin
Result := DI_OK;
Exit
end;
hRet := DIKeyboard.GetDeviceData (SizeOf(TDIDEVICEOBJECTDATA),
@Keyboard, Result, 0);
if hRet<>0 then begin
hRet := DIKeyboard.Acquire;
while hRet = DIERR_INPUTLOST do
hRet := DIKeyboard.Acquire;
end;

//Чтение статуса мышки:
FillChar(Mouse, SizeOf(Mouse),0);
hRet := DIMouse.GetDeviceState(SizeOf(TDIMOUSESTATE2), @Mouse);
if hRet<>0 then begin
hRet := DIMouse.Acquire;
while hRet = DIERR_INPUTLOST do hRet := DIMouse.Acquire;
end;
//Чтение координат курсора и проверка на выход из экрана:
inc(mouseX,Mouse.lX);
// mouseX := mouseX + Mouse.lX;
if mouseX < 0 then mouseX := 0;
if mouseX > WindowWidth then mouseX := WindowWidth;

inc(mouseY,Mouse.lY);
if mouseY < 0 then mouseY := 0;
if mouseY > WindowHeight then mouseY := WindowHeight;

mouseZ := mouseZ + Mouse.lZ;
end;


В начале программы InitDirectInput, в конце CloseDirectInput;

Для получения состояния клавишь и мышки делаешь ReadDirectInputData, после этого в MouseX, MouseY будут значения смещения курсора по осям, а в MouseZ значение прокрутки колёсика мышки.

Обработка например идёт так:

//++++++Обработка нажатых клавишь++++++
//Клавиатура:
NumKeys:=ReadDirectInputData;
if NumKeys <> 0 then
for i := 0 to NumKeys - 1 do
begin
Case Keyboard[i].dwOfs of
//Если нажата клавиша ESC, тогда выйти из проигрывания ролика
DIK_ESCAPE : if Keyboard[i].dwData and $80<>0 then
begin //Если клавиша нажата
QuitProgram:=True;
end else //Если отпущена
begin
end;
end; //case Keyboard[i].dwOfs
end;
//Мышка:
if Mouse.rgbButtons[0] = 128 then begin //Нажата левая кнопка
end;
if Mouse.rgbButtons[1] = 128 then begin //Нажата правая кнопка
end;
if Mouse.rgbButtons[2] = 128 then begin //Нажата средняя кнопка
end;
if Mouse.rgbButtons[3] = 128 then begin //Нажата левая дополнительная
end;
if Mouse.rgbButtons[4] = 128 then begin //Нажата правая дополнительная
end;


pasha676   (2003-05-23 10:03:00) [3]

У тебя вопросы просто зачипись. Надо отключать не перемещение, а изображение. Вопрос вполне посильный. Я сам не делал, но что такая фенька есть - это точно.


Кен   (2003-05-23 01:14:00) [4]

Ну так как же в DXInput отключать перемещение курсора мыши ?


pasha676   (2003-05-22 16:26:00) [5]

2DeadMeat
Да чем угодно можно. Хоть сам из порта читай. Только вот удобственнее и практичнее ДиректИнпута пожалуй еще не придумали.


DeadMeat   (2003-05-22 16:14:00) [6]

А нельзя-ли без DXInput-а с приславутым Timer1... Как сказал greenrul... 2)... А что-бы мыша не выходила за пределы экрана, то после считывания X и Y ставить её опять в центр через SetCursorPos... При потере окном фокуса, показывать её заново, и не теребить...


NailMan   (2003-05-22 15:25:00) [7]

Мдя, я делал такой финт ушами, но окно делал без бордеров и капшенов - чистое окно. Типа чтобы они не влияли на координаты.

Правда очень неудобно было при отладке, когда надо лазить в редактор и смореть какое значение а в какой переменной.


Кен   (2003-05-22 02:15:00) [8]


> ShowCursor(False); у меня решил вопрос

Когда программа в оконном режиме, то курсор невиден только когда он в окне программы. Когда же программа открыта полностью, а курсор сдвигается на край окна, то он вызывает появление Виндосовской панели.
То есть всёравно придётся делать SetCursorPos.


NailMan   (2003-05-21 09:46:00) [9]

ShowCursor(False); у меня решил вопрос


Кен   (2003-05-21 02:11:00) [10]

Вопрос номер 2 решается так :
DXInput1.Update - Обнуляет.
DXInput1.Mouse.X и DXInput1.Mouse.Y - насколько мышь сдвинули. Работает даже когда мышь на краях экрана.

Остаётся вопрос исчезновения курсора.
Можно конечно через SetCursorPos(Screen.Width, Screen.Heigth), но хочеться сделать это грамотно, без финтов. Может в DXInput есть чего для этих целей предназначеннео ?


greenrul   (2003-05-19 21:00:00) [11]

прошу прощения... сильно стормозил... извиняй кен, если обиделся :(


NailMan   (2003-05-19 09:58:00) [12]

To -> iliann
Для начала, определись на каком API писать собираешься.
- Если OpenGL, то можешь GLScene использовать.
- Если DirectX, то лучше свой написать.

В любом случае юзать VCL для 3Д-игр сложного уровня - это имхо взгляд преступление по отношению к юзверю.

Управление(снятие данных с устройств ввода) лучше организовывать через DirectInput - не тормозит и богатые и удобные возможности.

To -> greenrul ©
2) Насколько перемещена тебе так просто не получить. Делай таймер, по таймеру присваивай xx и yy текущим координатам мыши. При таймере ты сравниваешь текущий х и у и вычитаешь их них хх и уу - получаешь - по оси Х минус 2, по У - плюс 5 - значит на 2 влево и на 5 вниз.
А не проще DirectInput юзать - он сам тебе выдает смещение координат для мышки. Ни каких таймеров, ни калькуляций, просто и быстро.

To -> Кен ©
*** А как ты будешь поворачивать мышью ? Повернул чуть чуть, потом курсор вышел из окна программы и поворот прекратился.

Поэтому оконный режим(для 3Д игр) используют только для отладки и конечному юзверю дают только полноэкраный(и соотв. более быстрый) режим. И собсно при считывании данных посредством DInput такая проблема как выход за пределы окна отпадает сама собой, бо DInput что окно что фуллскрин - феолетово.


Кен   (2003-05-19 05:46:00) [13]

greenrul ©
> 2Кен - тебе многие, в том числе и я могут ответить на эти
> вопросы, но если задаются такие вопросы, то лучше почитать
> немного книг о Дельфи.
>
> 1) Form.Cursor:=crNone;

А если даются такие ответы, то стоит внимательно перечитать вопрос.

> невыезд за пределы программы - преступление против юзера.
> такие вещи по определению делать нельзя.

*** А как ты будешь поворачивать мышью ? Повернул чуть чуть, потом курсор вышел из окна программы и поворот прекратился.


Asteroid ©
Вот по всему по этому я и хочу какой-нибудь удобный компонент.


Asteroid   (2003-05-19 02:36:00) [14]

> greenrul © (19.05.03 02:31)
Проблема в том, что если мышь будет на правом краю экрана и ты двинешь ее вправо, смещения по x не будет.


Asteroid   (2003-05-19 02:34:00) [15]

> Кен © (19.05.03 01:23)
Для этого компоненты не нужны (хотя может даже есть). GetCursorPos и SetCursorPos, а также ShowCursor. При запуске ставишь курсор в середину экрана и пишешь ShowCursor( false );
На каждом кадре (для полноэкранного режима):
GetCursorPos( p );
dx := p.x - WindowWidth shr 1; // *
dy := p.y - WindowHeight shr 1; // *
p.x := WindowWidth shr 1; p.y := WindowHeight shr 1;
SetCursorPos( p );

В оконном в строчках * придется еще учесть смещение окна и его рамку, но на VCL это вообще дело техники. Для чистоты на выходе из программы не забудь поставить ShowCгrsor( true );


greenrul   (2003-05-19 02:31:00) [16]

2Кен - тебе многие, в том числе и я могут ответить на эти вопросы, но если задаются такие вопросы, то лучше почитать немного книг о Дельфи.

1) Form.Cursor:=crNone;
невыезд за пределы программы - преступление против юзера. такие вещи по определению делать нельзя.

2) Насколько перемещена тебе так просто не получить. Делай таймер, по таймеру присваивай xx и yy текущим координатам мыши. При таймере ты сравниваешь текущий х и у и вычитаешь их них хх и уу - получаешь - по оси Х минус 2, по У - плюс 5 - значит на 2 влево и на 5 вниз.

Правда. купи книгу. намного проще потом будет


Кен   (2003-05-19 01:23:00) [17]

Кстати по поводу мыши. Как действительно её контролировать ?
Нужно :
1) Чтобы курсора небыло. Ни небыло видно картинку курсора, а просто небыло. Чтобы он не выезжал за пределы программы когда она работает в окнном режиме, чтобы он не останавливался, доехав до края экрана или окна.
2) Снимать с мыши показания насколько она перемещена. То есть на лево 10 вперёд 5. Обратились к мыши ещё раз. И получили направо 4 назад 2. И всё. Просто с этим удобно работать.

Как это сделать ? Может есть компонент какой специальный ?


greenrul   (2003-05-18 22:41:00) [18]

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


TButton   (2003-05-18 18:06:00) [19]

2 Кен
он же ясно сказал "я хочу героем мышью управлять", а писать он будет Q4


Кен   (2003-05-18 01:53:00) [20]

iliann
А что ты хочешь получить в результате ? Свои миссии что ли к Хитману сделать ? Или улучшить его ? Или что вообще хочешь ?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо