Force Feedback

Một phần của tài liệu Beginning DirectX9 pot (Trang 156 - 160)

Từ khi phóng thích sự khởi tạo của game đồ họa console trên thị trường, các gamer đã trở nên quen thuộc với khái niệm force feedback. Force feedback là khả năng gửi những mức chuyển động khác nhau tới một Input Device. Gamepad dành cho hệ thống console thường hỗ trợ force feedback, ngược lại, feedback trong Input Device của PC vẫn đang còn rất ít.

Hiu ng Force feedback

Force feedback Device thực hiện dao động của chúng dựa trên các hiệu ứng. Một hiệu ứng force feedback được làm từ một hoặc nhiều force thực hiện trên controller. Force trong DirectInput là nút nhấn hoặc resistance felt trên controller trong thời gian sử dụng một hiệu ứng. Các hiệu ứng có một vài kiểu khác nhau:

ƒ Constat Force – một force liên tục đều đặn trong một điều khiển đơn.

ƒ Ramp Force – một force làm tăng hoặc làm giảm cường độ một cách đều đặn trong mọi

thời điểm.

ƒ Pertodic Effect – a pulsating force

ƒ Conditional – một hiệu ứng được gây ra như một phản ứng tới một chuyển động riêng biệt.

Mỗi force có một độ lớn, hay còn gọi là cường độ và một khoảng thời gian tồn tại hay còn gọi là chiều dài của thời gian. Khi thay đổi độ lớn cho phép bạn tăng, giảm độ rung hoặc reinstance the user feels in your game.

Chú ý:

Lạm dụng quá nhiều force feedback hoặc sử dụng nó ở những thời điểm không thích hợp trong game sẽ làm người chơi có cảm giác khó chịu. Nên phải sử dụng force feedback một cách hợp lý Để sử dụng thiết bị force feedback như gamepad trong game của bạn, bạn cần làm những việc sau đây:

1. Tạo DirectInput Object

2. Liệt kê các thiết bị game controller đã cài đặt mà hỗ trợ force feedback. 3. Tạo một thiết bị trên cơ sở gamepad.

4. Tạo hiệu ứng force feedback bạn muốn sử dụng. 5. Bắt đầu hiệu ứng

Lit kê Input Device cho force feedback

Vì force feedback không phải là phổ biến trong game controller, nên bạn cần tìm kiếm một cách cụ thể các điểm đặc trưng này khi liệt kê Input Device. Trước đây chỉ có Flag mà bạn gửi tới

EnumDevicesDIED_ATTACHEONLY, chỉ ra rằng hàm này sẽ trả về các thiết bị đã cài đặt

cho callback. Nếu ta có cờ hiệu này, thì callback sẽ tiếp nhận cả các thiết bị force feedback và thiết bị nonfeedback. Vì bạn biết từ khi bắt đầu là bạn chỉ muốn tìm kiếm các thiết bị force feedback, nên bạn nên điền cờ hiệu DIEDFL_FORCEFEEDBACK cho hàm EnumDevices. Việc này báo cho EnumDevices chỉđược báo cáo lại các thiết bị force feedback hiện hành. Ví dụ chương trình sau chỉ ra gọi cập nhật tới EnumDevices.

LPDIRECTINPUTDEVICE8 FFDevice = NULL;

//liệt kê các thiết bị đã cài đặt, tìm kiếm game controller hoặc joystick //dùng hỗ trợ force feedback. HRESULT hr; Hr= g_pDI->EnumDevices (DI8DEVCLASS_GAMECTRL, FFDeviceCallback, NULL, DIEDFL_ATTACHEONLY | DIEDFL_FORCEFEEDBACK));

Hàm EnumDevices trên đã cập nhật lại với cờ hiệu DIEDFL_FORCEFEEDBACK.

Đoạn ví dụ sau chỉ ra hàm callback cần để tìm thiết bị force feedback /************************************************************ *FFDeviceCallback

************************************************************/

BOOL CALLBACK FFDeviceCallback( const DIDEVICEINSTANCE* pInst, VOID* pContext)

{

HRESULT hr; //tạo thiết bị

hr-g_pDI->CreateDevice(pInst->guidInstance, &FFDevice, NULL); //thiết bị này không tạo đựoc, thì giữ lại để tìm kiếm cái khác. If (FAILED (hr))

Return DIENUM_CONTINUE;

//chúng ta tìm thấy một thiết bị, ngưng lại liệt kê return DIENUM_STOP;

}

Ở đây chỉ những thiết bị force feedback hợp lệđược báo cho hàm callback. Callback sẽ thử tạo Device dựa trên cái đầu tiên mà nó gặp. Nếu callback thành công khi tạo Device, nó sẽ dừng lại liệt kê, còn nếu không thì liệt kê tiếp tục tìm một Device thích hợp.

To hiu ng force feedback

Sau khi bạn tìm thấy vàđã tạo một DirectInput Device cho controller bạn sẽ sử dụng nó. Bạn cần tạo một đối tượng hiệu ứng. Đối tượng hiệu ứng force feedback của DirectInput tạo ra dựa trên giao diện IdirectInputEffect. Mỗi đối tượng IdirectInputEffect trình bày chi tiết hiệu ứng cho hệ thống.

Hiệu ứng trước tiên được tạo bởi việc điền vào đầy đủ thông tin trong cấu trúc DIEFFECT. Cấu trúc này mô tả diện mạo bên ngoài khác nhau của hiệu ứng, như là thời gian tồn tại mà nó ảnh hưởng và độ mạnh của hiệu ứng.

Cấu trúc DIEFFECT sau đó được gán cho tham số của hàm CreateEffect. Hàm

CreateEffect đăng ký hiệu ứng với DirectInput và tải hiệu ứng xuống cho Device. sau khi

hiệu ứng đã được tải xuống cho force feedback Device, nó đã sẵn sàng để sử dụng. Chú ý:

Để một hiệu ứng tải xuống force deedback Device, Device phải được thiết lập cooperative level kiểu truy cập độc quyền. Force feedback Device không thể chia sẻ chức năng feedback giữa các ứng dụng khác nhau.

Tôi sẽ đưa cho bạn một mô tả ngắn gọn cấu trúc DIEFFECT và sử dụng hàm CreateEffect

vì thế bạn có thể nhìn thấy quá trình một cách cụ thể hơn.

Bạn phải khai báo cấu trúc DIEFFECT cho mỗi đối tượng hiệu ứng mà bạn muốn tạo. Cấu trúc

DIEFFECTđược định nghĩa dưới đây:

Typedef struct DIEFFECT{ DWORD dwSize; DWORD dwFlags; DWORD dwDuration; DWORD dwSamplePeriod; DWORD dwGain; DWORD dwTriggerRepeatInterval; DWORD cAxes; LPLONG lgdwAxes; LPDWORD rglDirection; LPDIENVELOPE lpEnvelope; DWORD cbTypeSpecificParams; LPVOID lpvTypeSpeciParams; DWORD dwStartDelay; } DIEFFECT, *LPDIEFFECT;

cấu trúc DIEFFECT gồm những giá trị sau:

ƒ dwSize – kích thước của cấu trúc DIEFFFECT tính theo byte

ƒ dwFlags – cờ hiệu mô tả một vài biến được sử dụng như thế nào

• DIEFF_CARTESIAN – giá trị trong biến rglDirectionđược xem như tọa độđề

các.

• DIEFF_OBJECTIDS – giá trị trong biến dwTriggerButtonrgdwAxes là các

đối tượng nhận biết

• DIEFF_OBJECTOFFSETS – giá trị trong biến dwTriggerButtonrgdwAxes

là các khoảng trống định dạng dữ liệu

• DIEFF_POLAR – giá trị trong biến rglDirectionđược xem như tọa độ cực.

• DIEFF_SPHERICAL – giá trị trong biến rglDirectionđược xem như tọa độ cầu.

ƒ dwDuration – khoảng thời gian tồn tại của hiệu ứng tính theo microsecond. Nếu khoảng

thời gian tồn tại này tiếp tục diễn ra, hãy sử dụng kiểu giá trịINFINITE

ƒ dwSampePeriod – tốc độ thử nghiệm của hiệu ứng playback. 0 chỉ ra rằng tốc độ thử

nghiệm mặc định được sử dụng.

ƒ dwGain – tốc độ của hiệu ứng.

ƒ dwTriggerButton – chỉ ra nút được dùng để gây ra hiệu ứng. Giá trị này phụ thuộc vào giá

trị trong biến dwFlags.

ƒ cAxes – số trục mà hiệu ứng sử dụng

ƒ rgdwAxes – con trỏ tới ma trận kiểu DWORD mà chứa IDs hoặc khoảng trống tới trục mà

hiệu ứng sử dụng

ƒ rglDirection – ma trận tọa độ tương ứng với kiểu tọa độ chọn cho biến dwFlags.

ƒ lpEnvelope – một con trỏ tùy ý trỏđến cấu trúc DIENVELOPE. Cấu trúc này xác định vỏ

bọc để áp dụng cho hiệu ứng này. Khi không có hiệu ứng nào cần kiểu này bạn có thể sử dụng giá trịNULL

ƒ cbTypeSpecificParams – số byte của tham số bổ xung cho mỗi kiểu hiệu ứng.

ƒ lpvTypeSpecificParams – biến này lưu tham sốđã thảo luận trong biến trước. Biến này có

thể lưu bất kỳ cấu trúc đã định nghĩa sau:

• DIEFT_CUSTOMFORCE – một cấu trúc kiểu DICUSTOMERFORCEđược truyền.

• DIEFT_CONSTANCTFORCE – một hằng số cấu trúc force, DICONSTANTFORCE

được truyền.

• DIEFT_RAMPFORCE – một cấu trúc ramp force của DIAMPFORCEđược sử dụng.

• DIEFT_CONDITION – một cấu trúc kiểu DICONDITIONđược truyền

ƒ dwStartDelay – thời gian tính theo microsecond mà thiết bịđợi trước khi chạy một hiệu

ứng.

Cấu trúc DIEFFECT hoàn thành được truyền cho hàm CreateEffect. Hàm

CreateEffect cần 4 tham số và được xác định giống như sau:

HRESULT CreateEffect( REFGUID rguid, LPCDEFFECT lpeff, LPDIRECTINPUTEFFECT *ppdeff, LPUNKNOWN punkOuter );

Tham số thứ nhất có kiểu GUID thuộc dạng force được tạo. Ví dụ nếu bạn đang thử tạo một hiệu ứng force cốđịnh, bạn hãy sử dụng GUID nhưGUID_ConstantForce. Tham số thứ hai được truyền cho cấu trúc DIEFFECT. Tham số thứ 3 là là địa chỉ của biến mà sẽ lưu hiệu ứng mới. Biến này phải thuộc dạng IdirectInputEffect. Tham số cuối cùng của CreateEffect

thường là NULL.

Sau khi bạn có hiệu ứng đã tạo và sẵn sàng đi tiếp, bước tiếp theo sẽ là khởi chạy nó.

Bt đầu mt hiu ng.

Trước kia người sử dụng có thể cảm thấy hiệu ứng của bạn trong những hành động trong game. Playback của hiệu ứng force feedback được điều khiển thông qua hàm Start, nó là hàm nhớ của hàm IdirectInputEffect.

Hàm Start cần hai tham số.Tham số thứ nhất là số lần mà hiệu ứng được diễn ra. Tham số thứ

hai là tập hợp các cờ hiệu mà gắn liền với cách diễn ra hiệu ứng như thế nào trong thiết bị. Có hai kiểu cờ hiệu hợp lệ cho tham số thứ hai. Cả hai có thểđược áp dụng. Nếu không cần có cờ hiệu nào bạn có thể thiết lập tham số này bằng 0.

ƒ DIES_SOLO – hiệu ứng khác bất kỳ mà hiện tại bị dừng lại khi hiệu ứng này diễn ra.

ƒ DIES_NODOWNLOAD – hiệu ứng không được tựđộng tải xuống thiết bị.

Chú ý:

Nếu hiệu ứng hiện tại đang diễn ra và hàm Startđược gọi, thì hiệu ứng này được bắt đầu over from beginning.

Ví dụ này gọi hàm start thông báo cho DirectInput thực hiện hiệu ứng này một lần và chỉ ra rằng không có cờ hiệu nào được áp dụng.

Sau khi gọi hàm Start, hiệu ứng bắt đầu diễn ra trên Device.Nếu hiệu ứng có một khoảng thời gian tồn tại, thì hiệu ứng kết thúc khi khoảng thời gian hoàn thành. Nếu khoảng thời gian tồn tại của hiệu ứng là vô hạn, bạn phải dừng ngay hiệu ứng.

Ngng hiu ng.

Như tôi đã nhắc trước, nếu một hiệu ứng có một khoảng thờ gian tồn tại, nó kết thúc khi khoảng thờ gian được hoàn thành. Nhưng vì một điều gì đó, khoảng thời gian tồn tại của hiệu ứng thành vô hạn, hoặc người sử dụng nhấn phải nút Pause. Cả hai trường hợp trên cần phải kết thúc hiệu ứng ngay.

Việc này được hoàn thành thông qua hàm Stop. Hàm này không cần tham số nào và trả về, nó chỉ ra hàm thực hiện thành công hay không. Hàm Stop được khai báo sau đây:

HRESULT Stop(VOID);

Giá trị trả về là DI_OK có nghĩa là việc gọi tới hàm Stopđã thành công.

Một phần của tài liệu Beginning DirectX9 pot (Trang 156 - 160)

Tải bản đầy đủ (PDF)

(178 trang)