3

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

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

4

1 回答 1

6

源代码是从这里复制粘贴的。

要使用此源,您需要一个“ Force Effect 文件”(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>
    /// Summary description for Form1.
    /// </summary>
    public class Form1 : System.Windows.Forms.Form
    {
        private System.Windows.Forms.Label label1;
        /// <summary>
        /// Required designer variable.
        /// </summary>
        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
            //
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        protected override void Dispose( bool disposing )
        {
            if( disposing )
            {
                if (components != null) 
                {
                    components.Dispose();
                }
            }
            base.Dispose( disposing );
        }

        #region Windows Form Designer generated code
        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        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

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [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 ); 

这是另一个链接,然后可能有用力反馈示例

于 2014-06-05T20:01:45.840 回答