Форум: "Игры";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];
Внизdirectinput. Найти похожие ветки
← →
beginner136 (2005-05-07 18:45) [0]Помогите с написанием проги, плиз!
Мне нужно чтобы по форме двигались две кнопки с использованием directinput. С меня респект
← →
XProger © (2005-05-07 21:32) [1]А без него точно никак?
← →
beginner136 (2005-05-07 22:21) [2]без респекта или инпута :)
Нет, это я хочу модельку маленькую забабахать... я потом просто вместо кнопок вставлю то, что мне нужно. Инпут никак не могу осилить, ламо я позорное... хелп, комрады :)
← →
parovoZZ © (2005-05-07 22:43) [3]А кнопки как хочешь двигать - с помощью мыши или клавы?
← →
Sphinx © (2005-05-07 22:55) [4]
{==============================================================================
| |
| оболочка над DirectInput позволяющая обеспечить быстрый доступ к |
| мышке и клавиатуре в любых приложениях |
| при использовании Direct3D позволяет визуализировать курсор мыши |
| для различных состояний |
| |
==============================================================================}
unit uTDIControls;
interface
{==============================================================================
подключаемые модули
==============================================================================}
uses
Windows,
DirectInput,
uGameTypes;
{==============================================================================
константы модуля
==============================================================================}
const
{ признак нажатой или отжатой клавиши }
Key_Is_Down = $80;
Key_Is_Up = 0;
type
{ класс контроллера - оболочки для DirectInput }
TDIController = class (TObject)
private
// дополнительные данные класса
FappWindowHandle : THandle; // указатель на ассоциированное окно
FhInstance : Cardinal; // указатель на основное приложение
// переменные зоны ограничения мыши
FBoundsSet : Boolean; // признак ограничения движения мыши
FBoundsLeft, // размеры
FBoundsTop, // области ограничений
FBoundsWidth, // движения
FBoundsHeight : Integer; // мыши
// основной интерфейс DirectInput
FDirectInput8 : IDirectInput8; // основной интерфейс DI
FDirectInputAcquire : Boolean; // признак захвата интерфейса
// мышь
FDirectInputMouse : IDirectInputDevice8; // интерфейс устройства
FDirectInputMouseAcquire : Boolean; // признак захвата мыши
FMouseX, // координаты мыши
FMouseY, // X и Y - координаты курсора на экране
FMouseZ : Integer; // Z - координата связанная с колесом мыши
FMouseDX, // приращения координат
FMouseDY, // на предыдущем опросе
FMouseDZ : Integer; //
FKMouseMove : Real; // коэф. влияющий на величину смещения мыши
FDirectInputMouseKeyStat : TMouseKeyStat; // массив состояний клавишь
// клавиатура
FDirectInputKeyb : IDirectInputDevice8; // интерфейс устройства
FDirectInputKeybAcquire : Boolean; // признак захвата клавиатуры
FDirectInputKeybKeyStat : TKeyboardStat; // массив состояний кнопок
protected
FHRErrorCode : HResult; // переменная результатов
procedure UpdateMouseData;
procedure UpdateKeybData;
function ResetKeybKey: TKeyboardStat;
function GetMouseKeys: TMouseKeyStat;
function GetKeybKeys: TKeyboardStat;
public
constructor Create(aHInstance: Cardinal; iHandle: THandle);
destructor Destroy; override;
property CurrentError: HResult read FHRErrorCode;
property DirectInputAcquire: Boolean read FDirectInputAcquire;
property DirectInputMouseAcquire: Boolean read FDirectInputMouseAcquire;
property MouseX: Integer read FMouseX;
property MouseY: Integer read FMouseY;
property MouseZ: Integer read FMouseZ;
property LastMouseDX: Integer read FMouseDX;
property LastMouseDY: Integer read FMouseDY;
property LastMouseDZ: Integer read FMouseDZ;
property DirectInputKeyboardAcquire: Boolean read FDirectInputKeybAcquire;
property MouseKeysStats: TMouseKeyStat read GetMouseKeys;
property KeyboardKeysStats: TKeyboardStat read GetKeybKeys;
procedure Update;
function AcquireDirectInput: HResult;
function AcquireMouse(startX, startY, startZ: Integer; KMove: Real): HResult;
function UnAcquireMouse: HResult;
procedure ResetMouseKey;
procedure SetMouseBound(aLeft, aTop, aWidth, aHeight: Integer);
procedure UnSetMouseBound;
function AcquireKeyboard: HResult;
function UnAcquireKeyboard: HResult;
procedure ResetKeyboardKey;
end;
implementation
////////////////////////////////////////////////////////////////////////////////
// //
// FUNCTION //
// //
////////////////////////////////////////////////////////////////////////////////
{==============================================================================
==============================================================================}
function KeyIsDown(aKey: WORD): Boolean;
begin
if (aKey and Key_Is_Down) = Key_Is_Down then
Result := True
else
Result := False;
end;
← →
Sphinx © (2005-05-07 22:59) [5]
////////////////////////////////////////////////////////////////////////////////
// //
// TDIController //
// //
////////////////////////////////////////////////////////////////////////////////
{==============================================================================
конструктор класса
============================= входные величины =============================
aHInstance - указатель на основное приложение
iHandle - указатель на окно, ассоциируемое с DirectInputDevice
==============================================================================}
constructor TDIController.Create(aHInstance: Cardinal; iHandle: THandle);
begin
{ проверка и защита от повторного создания }
if Assigned(FDirectInput8) then
begin
FHRErrorCode := DIERR_ALREADYINITIALIZED; // заносится код что уже создано
Exit;
end;
if (aHInstance = 0) or (iHandle = 0) then Exit;
inherited Create;
{ обнуление некоторых переменных }
FappWindowHandle := iHandle;
FhInstance := aHInstance;
FDirectInput8 := nil;
FDirectInputMouse := nil;
FDirectInputAcquire := False;
FDirectInputMouseAcquire := False;
{ обнуление переменных мыши }
FMouseX := 0;
FMouseY := 0;
FMouseZ := 0;
FMouseDX := 0;
FMouseDY := 0;
FMouseDZ := 0;
FKMouseMove := 1.0;
FBoundsSet := False;
FBoundsLeft := 0;
FBoundsTop := 0;
FBoundsWidth := 0;
FBoundsHeight := 0;
{ все кнопки задаются отжатыми }
ResetMouseKey;
ResetKeyboardKey;
{ устанавливаем связь с DirectInput }
FHRErrorCode := DirectInput8Create(aHInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, FDirectInput8, nil);
if Succeeded(FHRErrorCode) then
FDirectInputAcquire := True
else
FDirectInput8 := nil;
end;
{==============================================================================
повторное создание связи с объектом DirectInput
==============================================================================}
function TDIController.AcquireDirectInput: HResult;
begin
{ проверка не создан ли уже интерфейс }
if Assigned(FDirectInput8) then
begin
FHRErrorCode := DIERR_ALREADYINITIALIZED;
Result := FHRErrorCode;
Exit;
end;
{ устанавливаем связь с DirectInput }
FHRErrorCode := DirectInput8Create(FhInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, FDirectInput8, nil);
if Succeeded(FHRErrorCode) then
FDirectInputAcquire := True
else
FDirectInput8 := nil;
Result := FHRErrorCode;
end;
{==============================================================================
деструктор класса
==============================================================================}
destructor TDIController.Destroy;
begin
UnAcquireMouse;
UnAcquireKeyboard;
FDirectInputMouseAcquire := False;
if Assigned(FDirectInputMouse) then FDirectInputMouse := nil;
FDirectInputKeybAcquire := False;
if Assigned(FDirectInputKeyb) then FDirectInputKeyb := nil;
FDirectInputAcquire := False;
if Assigned(FDirectInput8) then FDirectInput8 := nil;
inherited;
end;
{==============================================================================
захват мыши
============================= входные величины =============================
startX - начальная горизонтальная позиция
startY - начальная вертикальная позиция
KMove - коэффициент приращения позиции курсора
==============================================================================}
function TDIController.AcquireMouse(startX, startY, startZ: Integer; KMove: Real): HResult;
begin
{ проверяем не создан ли уже объект мыши }
if Assigned (FDirectInputMouse) then
begin
FHRErrorCode := DIERR_ALREADYINITIALIZED; // объект уже существует
Result := FHRErrorCode;
Exit;
end;
{ установка начальных значений }
FDirectInputMouseAcquire := False;
FMouseX := startX;
FMouseY := startY;
FMouseZ := startZ;
FKMouseMove := KMove;
{ создать объект - мышь }
FHRErrorCode := FDirectInput8.CreateDevice(GUID_SysMouse, FDirectInputMouse, nil);
if Failed(FHRErrorCode) then
begin
FDirectInputMouse := nil;
Result := FHRErrorCode;
Exit;
end;
{ установить формат принимаемых данных, уровень кооперации и связать с устройством }
FHRErrorCode := FDirectInputMouse.SetDataFormat(c_dfDIMouse2);
if Succeeded(FHRErrorCode) then
FHRErrorCode := FDirectInputMouse.SetCooperativeLevel(FappWindowHandle, DISCL_NONEXCLUSIVE or DISCL_FOREGROUND);
if Succeeded(FHRErrorCode) then
FHRErrorCode := FDirectInputMouse.Acquire;
if Failed(FHRErrorCode) then
FDirectInputMouse := nil
else
FDirectInputMouseAcquire := True;
Result := FHRErrorCode;
end;
{==============================================================================
освобождение мыши
==============================================================================}
function TDIController.UnAcquireMouse: HResult;
begin
Result := S_OK;
if FDirectInputMouseAcquire then
begin
if Assigned(FDirectInputMouse) then
begin
FHRErrorCode := FDirectInputMouse.Unacquire;
Result := FHRErrorCode;
FDirectInputMouse := nil;
end;
FDirectInputMouseAcquire := False;
end;
{ все кнопки мыши задаются отжатыми }
ResetMouseKey;
end;
{==============================================================================
сброс сосотояния всех кнопок мыши
==============================================================================}
procedure TDIController.ResetMouseKey;
begin
FDirectInputMouseKeyStat[0] := False;
FDirectInputMouseKeyStat[1] := False;
FDirectInputMouseKeyStat[2] := False;
FDirectInputMouseKeyStat[3] := False;
FDirectInputMouseKeyStat[4] := False;
FDirectInputMouseKeyStat[5] := False;
FDirectInputMouseKeyStat[6] := False;
FDirectInputMouseKeyStat[7] := False;
end;
{==============================================================================
установка прямоугольника, ограничивающего движение курсора мыши
==============================================================================}
procedure TDIController.SetMouseBound(aLeft, aTop, aWidth, aHeight: Integer);
begin
FBoundsLeft := aLeft;
FBoundsTop := aTop;
FBoundsWidth := aWidth;
FBoundsHeight := aHeight;
FBoundsSet := True;
end;
{==============================================================================
убрать ограничения на перемещение мыши
==============================================================================}
procedure TDIController.UnSetMouseBound;
begin
FBoundsSet := False;
end;
← →
Sphinx © (2005-05-07 23:00) [6]
{==============================================================================
обновление данных мыши
==============================================================================}
procedure TDIController.UpdateMouseData;
var
DirectInputMouseKey : TDIMouseState2;
begin
{ если связь и мышью не установлена }
if not(Assigned(FDirectInputMouse)) then
begin
FHRErrorCode := DIERR_NOTINITIALIZED; // объект не создан
Exit;
end;
{ подготовка переменной }
ZeroMemory(@DirectInputMouseKey, SizeOf (TDIMouseState2));
{ получить данные от мыши }
FHRErrorCode := FDirectInputMouse.GetDeviceState(SizeOf(TDIMouseState2), @DirectInputMouseKey);
{ проверка не потеряна ли связь с устройством }
if Failed(FHRErrorCode) then
begin
while ((FHRErrorCode = DIERR_INPUTLOST) or (FHRErrorCode = DIERR_NOTACQUIRED)) do
FHRErrorCode := FDirectInputMouse.Acquire;
Exit;
end;
if Failed(FHRErrorCode) then Exit;
{ проверяем состояние клавишь мыши }
FDirectInputMouseKeyStat[0] := KeyIsDown(DirectInputMouseKey.rgbButtons[0]);
FDirectInputMouseKeyStat[1] := KeyIsDown(DirectInputMouseKey.rgbButtons[1]);
FDirectInputMouseKeyStat[2] := KeyIsDown(DirectInputMouseKey.rgbButtons[2]);
FDirectInputMouseKeyStat[3] := KeyIsDown(DirectInputMouseKey.rgbButtons[3]);
FDirectInputMouseKeyStat[4] := KeyIsDown(DirectInputMouseKey.rgbButtons[4]);
FDirectInputMouseKeyStat[5] := KeyIsDown(DirectInputMouseKey.rgbButtons[5]);
FDirectInputMouseKeyStat[6] := KeyIsDown(DirectInputMouseKey.rgbButtons[6]);
FDirectInputMouseKeyStat[7] := KeyIsDown(DirectInputMouseKey.rgbButtons[7]);
{ записываем текущие смещения }
FMouseDX := DirectInputMouseKey.lX;
FMouseDY := DirectInputMouseKey.lY;
FMouseDZ := DirectInputMouseKey.lZ;
{ вычисляем координаты мыши }
FMouseX := FMouseX + round(DirectInputMouseKey.lX * FKMouseMove);
FMouseY := FMouseY + round(DirectInputMouseKey.lY * FKMouseMove);
FMouseZ := FMouseZ + round(DirectInputMouseKey.lZ); // нет умножения на коэф. !!!
{ если движения мыши ограничены - проверить }
if FBoundsSet then
begin
if FMouseX < FBoundsLeft then
FMouseX := FBoundsLeft;
if FMouseX > (FBoundsLeft + FBoundsWidth) then
FMouseX := (FBoundsLeft + FBoundsWidth);
if FMouseY < FBoundsTop then
FMouseY := FBoundsTop;
if FMouseY > (FBoundsTop + FBoundsHeight) then
FMouseY := (FBoundsTop + FBoundsHeight);
end;
end;
{==============================================================================
"захват" клавиатуры
==============================================================================}
function TDIController.AcquireKeyboard: HResult;
var
DIPDW: TDIPropDWord;
begin
{ проверка не существует ли уже объект }
if Assigned(FDirectInputKeyb) then
begin
FHRErrorCode := DIERR_ALREADYINITIALIZED;
Result := FHRErrorCode;
Exit;
end;
{ создаем интерфейс устройства }
FHRErrorCode := FDirectInput8.CreateDevice(GUID_SysKeyboard, FDirectInputKeyb, nil);
{ задаем формат данных }
if Succeeded(FHRErrorCode) then
FHRErrorCode := FDirectInputKeyb.SetDataFormat(c_dfDIKeyboard);
{ устанавливаем уровень кооперации }
if Succeeded(FHRErrorCode) then
FHRErrorCode := FDirectInputKeyb.SetCooperativeLevel(FappWindowHandle, DISCL_NONEXCLUSIVE or DISCL_FOREGROUND);
{ устанавливаем параметры буфера }
if Succeeded(FHRErrorCode) then
begin
ZeroMemory(@DIPDW, Sizeof(DIPDW));
with DIPDW do
begin
diph.dwSize := Sizeof(TDIPropDWord);
diph.dwHeaderSize := Sizeof(TDIPropHeader);
diph.dwObj := 0;
diph.dwHow := DIPH_DEVICE;
dwData := DIKeyboardBuffer;
end;
FHRErrorCode := FDirectInputKeyb.SetProperty(DIPROP_BUFFERSIZE, DIPDW.diph);
end;
{ устанавливаем связь с клавиатурой }
if Succeeded(FHRErrorCode) then
FHRErrorCode := FDirectInputKeyb.Acquire;
{ если какая-то операция была провалена - обнуляем объект }
if Failed(FHRErrorCode) then
FDirectInputKeyb := nil
else
FDirectInputKeybAcquire := True;
Result := FHRErrorCode;
end;
{==============================================================================
"освобождаем" клавиатуру
==============================================================================}
function TDIController.UnAcquireKeyboard: HResult;
begin
Result := S_OK;
if FDirectInputKeybAcquire then
begin
if Assigned(FDirectInputKeyb) then
begin
FHRErrorCode := FDirectInputKeyb.Unacquire;
Result := FHRErrorCode;
FDirectInputKeyb := nil;
end;
FDirectInputKeybAcquire := False;
end;
ResetKeyboardKey;
end;
{==============================================================================
сброс всех кнопок клавиатуры
==============================================================================}
function TDIController.ResetKeybKey: TKeyboardStat;
var
i: Byte;
begin
for i := 0 to 255 do
Result[i] := False;
end;
← →
Sphinx © (2005-05-07 23:01) [7]
{==============================================================================
надстройка над функцией сброса состояния кнопок клавиатуры
==============================================================================}
procedure TDIController.ResetKeyboardKey;
begin
FDirectInputKeybKeyStat := ResetKeybKey;
end;
{==============================================================================
обновление данный о состоянии кнопок клавиатуры
==============================================================================}
procedure TDIController.UpdateKeybData;
var
DirectInputKeybKey: array[0..DIKeyboardBuffer - 1] of TDIDeviceObjectData;
dwElements: Cardinal;
i: Cardinal;
begin
{ проверка на существование объекта }
if not(Assigned(FDirectInputKeyb)) then
begin
FHRErrorCode := DIERR_NOTINITIALIZED;
Exit;
end;
{ подготовка данных }
ZeroMemory(@DirectInputKeybKey, Sizeof(DirectInputKeybKey));
dwElements := DIKeyboardBuffer;
{ получить данные из буфера клавиатуры }
FHRErrorCode := FDirectInputKeyb.GetDeviceData(SizeOf(TDIDeviceObjectData), @DirectInputKeybKey, dwElements, 0);
{ проверка на наличае связи с устройством и её установление }
if Failed(FHRErrorCode) then
begin
while ((FHRErrorCode = DIERR_INPUTLOST) or (FHRErrorCode = DIERR_NOTACQUIRED)) do
FHRErrorCode := FDirectInputMouse.Acquire;
Exit;
end;
{ если связь с устройством не восстановлена - выйти }
if Failed(FHRErrorCode) then Exit;
{ обновление статуса кнопок }
if dwElements <> 0 then
for i := 0 to dwElements - 1 do
FDirectInputKeybKeyStat[DirectInputKeybKey[i].dwOfs] := KeyIsDown(DirectInputKeybKey[i].dwData);
end;
{==============================================================================
обновить данные класса
==============================================================================}
procedure TDIController.Update;
begin
UpdateMouseData; //
UpdateKeybData; //
end;
{==============================================================================
получить ланные о состоянии клавишь мыши
==============================================================================}
function TDIController.GetMouseKeys: TMouseKeyStat;
begin
Result := FDirectInputMouseKeyStat;
end;
{==============================================================================
получить данные о кнопках клавиатуры
==============================================================================}
function TDIController.GetKeybKeys: TKeyboardStat;
begin
Result := FDirectInputKeybKeyStat;
end;
end.
← →
Sphinx © (2005-05-07 23:03) [8]Из модуля
uGameTypes.pas
нужны:TMouseKeyStat = array[0..7] of Boolean;
TKeyboardStat = array[0..255] of Boolean;
DIKeyboardBuffer = 16;
Много лишнего, но показано почти всё что можно для работы с DI.
Разбирайся :)
← →
Sphinx © (2005-05-07 23:11) [9]И еще забыл...
данные с мыши считываются непосредственно, а с клавиатуры - буфферизованно.
← →
beginner136 (2005-05-08 10:33) [10]%)
Пасиб)
з.ы. Однако, что странно. В разных источниках ВСЕ по разному написано. Например на podgoretsky.com 24 страницы про DI
На Gamedev - 3 абзаца, и все равно работает. Но только у них...
← →
cyborg © (2005-05-08 10:38) [11]
> [10] beginner136 (08.05.05 10:33)
У меня тоже есть :)
← →
beginner136 (2005-05-08 11:02) [12]2parovoZZ
с помощью клавы.
← →
beginner136 (2005-05-08 11:18) [13]2Sphinx
Не компилится. грит, не найден DirectInput.dcu
(не смотря что у меня на Делфе стоит ДелфиХ...)
← →
Sphinx © (2005-05-08 14:47) [14]> beginner136 (08.05.05 11:18) [13]
А с DelphiX и не скомпилирует. Он тут как говорится - из другой оперы.
Это написано с заголовками DX9 с сайта http://clootie.narod.ru/ правда всё будет работать и с заголовками от DX8.
И еще...написано на Д7, так что если пользуешь версии ниже шестой - придетсе немного переработать.
← →
beginner136 (2005-05-08 15:57) [15]у меня седьмая дельфа, так что все нормально... пошел искать directinput.dcu
← →
XProger © (2005-05-08 17:12) [16]Это конечно всё хорошо, но я в своём новом проекте предвочёл не юзать DI, ибо никаких плюсов в этом не вижу по сути :)
var
Keys : array [0..255] of boolean;
...
procedure ResetKeys;
begin
ZeroMemory(@Keys, 255);
end;
...
WM_KEYDOWN : Keys[wParam] := true;
WM_KEYUP : Keys[wParam] := false;
...
function KeyDown(idx: Byte): boolean;
begin
Result := Keys[idx];
end;
← →
beginner136 (2005-05-08 17:47) [17]хочешь сказать, что твой метод тоже имеет абсолютный контроль над клавиатурой?)
← →
Sphinx © (2005-05-08 18:11) [18]> XProger © (08.05.05 17:12) [16]
Кесарю - кесарево...
Если твой метод может заполнить следующую запись в реальном времени и именно в момент нажатия кнопки:PDIDeviceObjectData = ^TDIDeviceObjectData;
DIDEVICEOBJECTDATA = packed record
dwOfs: DWORD;
dwData: DWORD;
dwTimeStamp: DWORD;
dwSequence: DWORD;
uAppData: Pointer;
end;
TDIDeviceObjectData = DIDEVICEOBJECTDATA;
в частности поля dwTimeStamp & dwSequence.
DXSDK:
dwTimeStamp
System time at which the input event was generated, in milliseconds.
dwSequence
Microsoft DirectInput sequence number for this event. All input events are assigned an increasing sequence number. This enables events from different devices to be sorted chronologically.
Тогда я соглашусь - что DI не нужен совершенно...если конечно не сапера делаем...То есть зависит от конкретной задачи и конкретной реализации...
← →
beginner136 (2005-05-08 22:05) [19]так ладно...
А что в программе нужно написать, чтобы она смотрела нажата ли какая-то определенная клавиша?
И, кстати, почему вы не используете DelphiX?
← →
XProger © (2005-05-09 01:47) [20]Sphinx, такими веами не пользуюсь и не надо то особо...
beginner136, я написал ;) DelphiX - а зачем?
← →
Zak3D[@Tm] © (2005-05-09 11:09) [21]beginner136 - DelphiX вещь немного устаревшая =), да и не может реализовать всех потребностей местного люда.
← →
beginner136 (2005-05-09 13:28) [22]2 xproger
WM_KEYDOWN : Keys[wParam] := true;
WM_KEYUP : Keys[wParam] := false;
Это как и где понимать?)
А насчет DelphiX -
Ну я просто думал, там все так просто, компонент разместил, пару строчек написал (опять же - каких?:) ) и все готово...
← →
XProger © (2005-05-12 22:05) [23]beginner136,
Гражданин, если бы Вы знали о существвании окон без VCL Вы бы не задавали столь неприличных вопросов...
Для Вас вполне сойдёт onKeyDown и onKeyUp события формы...
← →
Sphinx © (2005-05-12 23:24) [24]> XProger © (12.05.05 22:05) [23]
:)
← →
beg188 (2005-05-13 21:49) [25]критику принял
← →
П7 (2005-05-14 01:23) [26]
> XProger © (12.05.05 22:05) [23]
хм... а что мешает то же самое запихнуть в VCL?
← →
XProger © (2005-05-14 02:33) [27]П7, а кто сказал что что-то мешает?
Страницы: 1 вся ветка
Форум: "Игры";
Текущий архив: 2005.09.11;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.011 c