keyboard

FullScreen Mode : Switch (Part 2)

posted on 14 Oct 2008 16:28 by ninetales in XNA

จากตอนที่แล้ว เราพบกับปัญหาเนื่องจาก
เราต้องการ สั่งให้ทำงานเพียงครั้งเดียวเมื่อมีการกดปุ่ม
แต่เกมขยันเช็คทุก loop ว่าเรา "กำลังกดอยู่" (ตอนนี้กด)
เพราะฉะนั้น...เราจะต้องเปลี่ยนไปเช็คว่า
"พึ่งจะเริ่มกด" (ก่อนหน้านี้ไม่กด แต่ตอนนี้กด)
หรือ "กดเสร็จแล้ว" (ก่อนหน้านี้กดอยู่ แต่ตอนนี้เลิกกดแล้ว)
ถ้าก่อนหน้านี้กดอยู่ แล้วตอนนี้ก็กดอยู่ ไม่ทำ!

ให้ประกาศในส่วนของ Globalดังนี้

        KeyboardState currentKeyBoard;
        KeyboardState previousKeyBoard;
เราจะใช้  KeyboardState2ตัว ในการเช็ค การกดในรอบนี้ และรอบก่อนหน้านี้

 

         protected override void Update(GameTime gameTime)
        {
            //GetState เพื่อเช็คปุ่มที่กำลังกดอยู่
           currentKeyBoard = Keyboard.GetState();      

            if (
currentKeyBoard .IsKeyDown(Keys.Escape))
            {
                Exit();
            }

            //ถ้ารอบนี้กดF10 และ รอบก่อนหน้านี้ไม่ได้กด
            if (currentKeyBoard.IsKeyDown(Keys.F10) && !previousKeyBoard.IsKeyDown(Keys.F10))
            {
                graphics.ToggleFullScreen();
            }

            //GetState การกดของรอบนี้ไว้ท้ายสุด เพื่อนำไปเช็คเป็นการกดของรอบที่แล้ว ในloopหน้า
          
currentKeyBoard = Keyboard.GetState();      


            base.Update(gameTime);
        }

 เท่านี้ ลองปักนิ้วลงไปบนปุ่ม F10 ดู โปรแกรมก็จะทำการ Toggle FulScreen 1ครั้ง แม้จะกดค้างไว้ก็ตาม

ลองอีกแบบหนึ่งบ้าง เปลี่ยนการเช็คปุ่ม F10 เป็น

             if (!currentKeyBoard.IsKeyDown(Keys.F10) && previousKeyBoard.IsKeyDown(Keys.F10))

แค่สลับเครื่องหมาย ! ให้เป็น  ก่อนหน้านี้กด แต่ตอนนี้ไม่กด
ลองใหม่ เสียบนิ้วลงไปบน F10ค้างไว้.... นิ่ง ไม่เกิดอะไรขึ้น
ดึงนิ้วออก! Toggle FulScreen ทันที!

edit @ 14 Oct 2008 17:18:28 by 『Ninetales』

Keyboard : ย่อ Code ให้สั้นลง

posted on 11 Oct 2008 23:29 by ninetales in XNA

จากเดิมที่เราต้องเขียนซะยืดยาวว่า

            if (Keyboard.GetState().IsKeyDown(Keys.Escape))

 ซึ่งอีกเดี๋ยวเราจะต้องเขียนคล้ายๆแบบนี้อีกหลายบรรทัด
เพราะฉะนั้นเขียนให้สั้นจึงดีที่สุด ยิ่งเขียนสั้นยิ่งเอาเวลาไปคิดเรื่องตัวเกมได้มาก

 ดังนั้นเราจะย่อ Keyboard.GetState() เหลือแค่ keyboard
(จำไว้ว่า ตัวแปรในภาษา C# ตัวเล็กใหญ่มีผลถือว่าเป็นคนละตัวกัน)

ดึง Keyboard.GetState(); ออกมา
เอา keyboard ยัดลงไปแทน
ก็จะกลายเป็น

 keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.Escape))

สั้นลงแล้ว แต่ยังใช้ไม่ได้ เพราะ ต้องมีการประกาศทุกๆตัวแปรที่ใช้ และ  keyboard จัดเป็นตัวแปรตัวหนึ่ง
ดังนั้น keyboard ต้องเป็นตัวแปร "อะไรสักอย่าง" ที่มารับค่าของ Keyboard.GetState(); ได้

???  keyboard = Keyboard.GetState();
if (keyboard.IsKeyDown(Keys.Escape))

ใน XNA นั้น Keyboard.GetState(); มีค่าเป็น object ประเภท KeyboardState
Code จึงต้องเขียนเป็น

        protected override void Update(GameTime gameTime)
        {

            KeyboardState keyboard = Keyboard.GetState();
            if (keyboard.IsKeyDown(Keys.Escape))
            {

                Exit();
            }

            base.Update(gameTime);
         }

เพียงแค่นี้ ก็ run ได้ ใช้งานได้แล้ว
ไม่ต้องมาเขียน Keyboard.GetState() ทุกบรรทัดที่เช็ค keyboard
ถึงแม้จะอยู่ใน loop ของ Update แต่สามารถประกาศตัวแปรไว้ได้ ไม่เป็นปัญหา
เพราะ C# อนุญาตให้ประกาศทับได้
แต่เอาออกไปประกาศ รอบเดียวดีกว่าใหม?
งั้นเราแยก การประกาศ ออกมาดีกว่า

        protected override void Update(GameTime gameTime)
        {
            KeyboardState keyboard;
            keyboard = Keyboard.GetState();
            if (keyboard.IsKeyDown(Keys.Escape))
            {

                Exit();
            }

            base.Update(gameTime); 

         }

Keyboard.GetState();จำเป็นต้องมีการUpdateทุกรอบ เพราะต้องคอยเช็ค Keyboard ตลอดเวลา
จึงต้องอยู่ใน Update()

จากนั้น ยก  KeyboardState keyboard; ออกไปไว้ข้างนอก ตรง Global (เหนื่อ Game1( ) )
ก็เป็นอันเสร็จสมบูรณ์

edit @ 13 Oct 2008 16:41:43 by 『Ninetales』

ExitGame by Keyboard

posted on 11 Oct 2008 21:08 by ninetales in XNA

ใส่ Code เข้าไปในส่วนของ Update ดังนี้

        protected override void Update(GameTime gameTime)
        {
            if(Keyboard.GetState().IsKeyDown(Keys.Escape))
            {
                Exit();
            }

            base.Update(gameTime);
        }

ลอง Runดู จะสามารถกด ESC เพื่อออกเกมได้
จะเห็นว่า Code จะค่อนข้างคล้ายของ GamePad

 Keyboard.GetState() เช็ค State ของ Keyboard ไม่จำเป็นต้องใส่ PlayerIndex เหมือนของ GamePad
ก็เครื่องปกติต่อ Keyboard อยู่อันเดียว จะมีไปทำไม = =;
ในเกมเครื่อง Console ปกติจะทำให้ต่อ GamePad หรือ JoyStick ได้ ตั้งแต่ 2 ตัวขึ้นไปการเล่นเกมโดย GamePad จึงมี Player
ส่วนเกมใน PC ที่ปกติมี Keyboard1 Mouse1 จึงนิยมเล่น Multiplayer แบบ 1คน:1เครื่อง มากกว่า

ลองใส่ Player ดูก็ไม่เสียหายอะไร
if(Keyboard.GetState(PlayerIndex.One).IsKeyDown(Keys.Escape))
if(Keyboard.GetState(PlayerIndex.Two).IsKeyDown(Keys.Escape))
if(Keyboard.GetState(PlayerIndex.Three).IsKeyDown(Keys.Escape))
if(Keyboard.GetState(PlayerIndex.Four).IsKeyDown(Keys.Escape))
กด ESC อย่างไงก็ยังออกเกมได้เหมือนเดิม
เพราะฉะนั้นอย่าใส่มันดีกว่า
(ใครค้นพบประโยชน์ของการใส่ Player ให้ Keyboard เมื่อใหร่ ช่วยบอกผมด้วยนะครับ)

.IsKeyDown( ) คือ เช็คว่า ปุ่มถูก กดไว้อยู่ รึเปล่า นอกจากนี้ยังมี
.IsKeyUp( ) คือ เช็คว่า ปุ่มถูกปล่อยอยู่รึเปล่า

(Keys.ปุ่มที่จะเช็ค)มีให้กดได้สารพัดปุ่ม ระดับที่ว่า เช็คปุ่มเพิ่มเสียง ลดเสียงบน Keyboard ได้ทีเดียว
ถึงแม้มันจะไม่ช่วยให้ Keyboard ของ Microsoft ขายดีขึ้นก็ตาม

ยังมีต่อ...

edit @ 13 Oct 2008 16:42:00 by 『Ninetales』

『Ninetales』 View my profile