从.net发送反馈/效果到操纵杆

感谢这个答案https://stackoverflow.com/a/13734766/637142我能够知道按下按钮的时间或旋转方向盘的时间。 现在我的问题是如何将效果发送到设备? 例如,当我正在玩游戏时,如果我发生碰撞,车轮会振动。 我怎么能让方向盘振动?

我相信我需要做的是Start()一个效果( http://sharpdx.org/documentation/api/t-sharpdx-directinput-effect )。 SharpDX.DirectInput.Joystick类似乎没有一个方法可以返回所有效果。 有一个名为GetEffects的方法,但该方法返回一组EffectInfo对象。 游戏如何向操纵杆发送命令?

源代码从此处复制粘贴。

要使用此源,您需要一个“ 强制效果文件 ”( C:\ MyEffectFile.ffe ),以在操纵杆上“播放”它。

根据本书创建的“强制效果”文件,您需要使用DirectX SDK附带的“ 强制编辑器 ”。

(同一本书,或者说,你可以在代码中从头开始创建效果……在答案中,我发现另一段代码创建并起诉效果而不从文件中加载它:-))

 using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using Microsoft.DirectX; using Microsoft.DirectX.DirectInput; namespace JoystickProject { ///  /// Summary description for Form1. ///  public class Form1 : System.Windows.Forms.Form { private System.Windows.Forms.Label label1; ///  /// Required designer variable. ///  private System.ComponentModel.Container components = null; private Device device = null; private bool running = true; private ArrayList effectList = new ArrayList(); private bool button0pressed = false; private string joyState = ""; public bool InitializeInput() { // Create our joystick device foreach(DeviceInstance di in Manager.GetDevices(DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly | EnumDevicesFlags.ForceFeeback)) { // Pick the first attached joystick we see device = new Device(di.InstanceGuid); break; } if (device == null) // We couldn't find a joystick return false; device.SetDataFormat(DeviceDataFormat.Joystick); device.SetCooperativeLevel(this, CooperativeLevelFlags.Exclusive | CooperativeLevelFlags.Background); device.Properties.AxisModeAbsolute = true; device.Properties.AutoCenter = false; device.Acquire(); // Enumerate any axes foreach(DeviceObjectInstance doi in device.Objects) { if ((doi.ObjectId & (int)DeviceObjectTypeFlags.Axis) != 0) { // We found an axis, set the range to a max of 10,000 device.Properties.SetRange(ParameterHow.ById, doi.ObjectId, new InputRange(-5000, 5000)); } } // Load our feedback file EffectList effects = null; effects = device.GetEffects(@"C:\MyEffectFile.ffe", FileEffectsFlags.ModifyIfNeeded); foreach(FileEffect fe in effects) { EffectObject myEffect = new EffectObject(fe.EffectGuid, fe.EffectStruct, device); myEffect.Download(); effectList.Add(myEffect); } while(running) { UpdateInputState(); Application.DoEvents(); } return true; } private void PlayEffects() { // See if our effects are playing. foreach(EffectObject myEffect in effectList) { //if (button0pressed == true) //{ //MessageBox.Show("Button Pressed."); // myEffect.Start(1, EffectStartFlags.NoDownload); //} if (!myEffect.EffectStatus.Playing) { // If not, play them myEffect.Start(1, EffectStartFlags.NoDownload); } } //button0pressed = true; } protected override void OnClosed(EventArgs e) { running = false; } private void UpdateInputState() { PlayEffects(); // Check the joystick state JoystickState state = device.CurrentJoystickState; device.Poll(); joyState = "Using JoystickState: \r\n"; joyState += device.Properties.ProductName; joyState += "\n"; joyState += device.ForceFeedbackState; joyState += "\n"; joyState += state.ToString(); byte[] buttons = state.GetButtons(); for(int i = 0; i < buttons.Length; i++) joyState += string.Format("Button {0} {1}\r\n", i, buttons[i] != 0 ? "Pressed" : "Not Pressed"); label1.Text = joyState; //if(buttons[0] != 0) //button0pressed = true; } public Form1() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } ///  /// Clean up any resources being used. ///  protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); } #region Windows Form Designer generated code ///  /// Required method for Designer support - do not modify /// the contents of this method with the code editor. ///  private void InitializeComponent() { this.label1 = new System.Windows.Forms.Label(); this.SuspendLayout(); // // label1 // this.label1.BackColor = System.Drawing.SystemColors.ActiveCaptionText; this.label1.Location = new System.Drawing.Point(8, 8); this.label1.Name = "label1"; this.label1.Size = new System.Drawing.Size(272, 488); this.label1.TabIndex = 0; // // Form1 // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.BackColor = System.Drawing.SystemColors.ControlText; this.ClientSize = new System.Drawing.Size(288, 502); this.Controls.AddRange(new System.Windows.Forms.Control[] { this.label1}); this.Name = "Form1"; this.Text = "Joystick Stuff"; this.ResumeLayout(false); } #endregion ///  /// The main entry point for the application. ///  [STAThread] static void Main() { using (Form1 frm = new Form1()) { frm.Show(); if (!frm.InitializeInput()) MessageBox.Show("Couldn't find a joystick."); } } } } 

我刚刚在这里找到另一段可能有用的代码。 此示例似乎从头开始创建效果,因此您不需要“效果文件”。

  DeviceList xDeviceList = Manager.GetDevices(DeviceClass.GameControl, EnumDevicesFlags.AttachedOnly); DeviceInstance someDeviceInstance; foreach (DeviceInstance deviceInstance in xDeviceList) { someDeviceInstance = deviceInstance; break; } Device someDevice = new Device(someDeviceInstance.InstanceGuid); someDevice.SetCooperativeLevel(this.Handle, CooperativeLevelFlags.Exclusive | CooperativeLevelFlags.Background); int[] axis = new int[0]; foreach (DeviceObjectInstance doi in someDevice.Objects) { if((doi.Flags & (int)ObjectInstanceFlags.Actuator) != 0) { axis = new int[axis.Length + 1]; axis[axis.Length - 1] = doi.Offset; } } someDevice.Acquire(); Effect effect = new Effect(); effect.SetDirection(new int[axis.Length]); effect.SetAxes(new int[axis.Length]); effect.ConditionStruct = new Condition[axis.Length]; effect.Flags = EffectFlags.Cartesian | EffectFlags.ObjectOffsets; effect.Duration = int.MaxValue; effect.SamplePeriod = 0; effect.Gain = 10000; effect.TriggerButton = (int)Microsoft.DirectX.DirectInput.Button.NoTrigger; effect.TriggerRepeatInterval = 0; effect.UsesEnvelope = false; effect.EffectType = Microsoft.DirectX.DirectInput.EffectType.ConstantForce; effect.StartDelay = 0; effect.Constant = new Microsoft.DirectX.DirectInput.ConstantForce(); effect.Constant.Magnitude = -5000; EffectObject effectObject = null; foreach (EffectInformation ei in someDevice.GetEffects(EffectType.ConstantForce)) { effectObject = new EffectObject(ei.EffectGuid, effect, someDevice); } effectObject.SetParameters(effect, EffectParameterFlags.Start ); 

这里是另一个链接,然后可能是有用的力反馈样本