Graphics/DirectX

Direct X - 10. 키보드 입력

MOLOKINI 2014. 6. 8. 20:58
키보드 입력은 Direct Input을 사용하는게 좋지만 간단하게 C# API로 해보자



using System;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
using System.Windows.Forms;
using System.Drawing;

namespace MDXSample
{
    /// <summary>
    /// 메인 샘플 클래스
    /// </summary>
    public partial class MainSample : IDisposable
    {

        private bool[] _keys = new bool[256];
         
        public bool InitializeApplication(MainForm topLevelForm)
        {
            // 폼의 참조를 보관 유지
            this._form = topLevelForm;

            PresentParameters pp = new PresentParameters();
            pp.Windowed = true;
            pp.SwapEffect = SwapEffect.Discard;
            pp.EnableAutoDepthStencil = true;
            pp.AutoDepthStencilFormat = DepthFormat.D16;

            topLevelForm.KeyDown += new KeyEventHandler(this.form_KeyDown);
            topLevelForm.KeyUp += new KeyEventHandler(this.form_KeyUp);

            try
            {
                // Direct3D 디바이스 작성
                this.CreateDevice(topLevelForm, pp);
                // 폰트의 작성
                this.CreateFont();

            }
            catch (DirectXException ex)
            {
                // 예외 발생
                MessageBox.Show(ex.ToString(), "에러", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }

            this.SettingCamera();

            this._device.RenderState.Lighting = false;

            return true;
        }

        private void form_KeyDown(object sender, KeyEventArgs e)
        {
            if ((int)e.KeyCode < this._keys.Length)
            {
                this._keys[(int)e.KeyCode] = true;
            }
        }

        private void form_KeyUp(object sender, KeyEventArgs e)
        {
            if ((int)e.KeyCode < this._keys.Length)
            {
                this._keys[(int)e.KeyCode] = false;
            }
        }

        /// <summary>
        /// 메인 루프 처리
        /// </summary>
        public void MainLoop()
        {
            // 화면을 단색(파랑색)으로 클리어
            this._device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.DarkBlue, 1.0f, 0);

            // 「BeginScene」와「EndScene」의 사이에 화면에 출력할 내용을 코딩
            this._device.BeginScene();

            int height = 24;
            for (int i = 0; i < this._keys.Length; i++)
            {
                if (this._keys[i])
                {
                    this._font.DrawText(null, ((Keys)i).ToString(), 0, height, Color.White);
                    height += 24;
                }
            }

            // 좌표 x=0 y=0 의 위치에 흰색으로 출력
            this._font.DrawText(null, "키보드 입력받기", 0, 0, Color.White); 
            
            // 화면출력은 여기까지
            this._device.EndScene();

            // 실제의 디스플레이에 출력
            this._device.Present();

        }

        /// <summary>
        /// 자원의 파기
        /// </summary>
        public void Dispose()
        {
            // 폰트 자원을 해제
            if (this._font != null)
            {
                this._font.Dispose();
            }

            // Direct3D 디바이스의 자원 해제
            if (this._device != null)
            {
                this._device.Dispose();
            }
        }
    }
}


        private bool[] _keys = new bool[256];
어떤 키가 눌렸는지에 대한 플래그를 보관하고 유지하기 위해서 256개의 참과 거짓 배열을 작성한다. 왜 256이냐? System.Windows.Forms.Keys에서 열거형으로 정의된 키 속성에서 일반적으로 사용되는 키의 개수


            topLevelForm.KeyDown += new KeyEventHandler(this.form_KeyDown);
            topLevelForm.KeyUp += new KeyEventHandler(this.form_KeyUp);
키를 눌렀을 때의 이벤트 핸들러 작성. C#의 기본 이벤트 핸들러 문법이다
메인폼에 키 이벤트 핸들러를 포함시켜준다. (키 이벤트 핸들러는 아래 메서드)
실시간으로 처리하는 메서드를 작성하여 KeyEventHandler 구조체에 넘겨주고 있다


        private void form_KeyDown(object sender, KeyEventArgs e)
        {
            if ((int)e.KeyCode < this._keys.Length)
            {
                this._keys[(int)e.KeyCode] = true;
            }
        }

        private void form_KeyUp(object sender, KeyEventArgs e)
        {
            if ((int)e.KeyCode < this._keys.Length)
            {
                this._keys[(int)e.KeyCode] = false;
            }
        }
키의 이벤트를 받는 것으로, 키 이벤트를 받는것은 메인폼이기 때문에 폼의 이벤트를 추가하고 있는 메서드다.
단순하게 키를 누르면 참, 떼면 거~짓~으로 세팅하고 있다.
어느키가 눌렸는지는, KeyEventArgs.KeyCode에 보관되어 있으므로 이것을 int로 캐스트해서 인덱스의 플래그를 조작하고 있다.


            int height = 24;
            for (int i = 0; i < this._keys.Length; i++)
            {
                if (this._keys[i])
                {
                    this._font.DrawText(null, ((Keys)i).ToString(), 0, height, Color.White);
                    height += 24;
                }
            }
모든 키의 플래그를 조사해서 키가 눌린 경우엔 그 키를 문자로서 출력하고 있다.
동시에 키보드를 누를 경우 겹치지 않게 문자를 출력 할 때 마다 높이를 조정한다.
키의 문자열은 System.Windows.forms.Keys로 캐스트해 ToString 메서드로 받을 수 있다.