XNA, VB.NET, business intelligence, data mining, excel, sql server Luki Ishwara's journal

MEMBANGUN SISTEM MANAJEMEN INPUT PADA WINDOWS PHONE 7

Project Menggunakan Visual Basic .NET dan XNA Framework 4.0

Source Code bisa di download  {belum di upload}

Video hasil project bisa di lihat {belum di upload}

Pada saat mengembangkan games untuk berbagai platforms, anda dengan cepat akan menemukan situasi dimana  game anda membutuhkan beberapa cara yang berbeda untuk menampilkan suatu aksi yang sama berdasarkan pada batasan dari masing- masing platform.

Kebalikan dari situasi tersebut dapat terjadi bila anda mengembangkan game untuk satu platform saja. Sejalan dengan game anda secara progresif menjadi semakin kompleks, anda mungkin akan butuh untuk memetakan aksi pada yang berbeda pada game anda dengan tombol yang sama, berdasrkan pada layar yang aktif.

Tidak masalah pada situasi yang mana sekarang anda berada, ada suatu jawaban yang sangat sederhana. Seperti yang telah dideskripsikan pada tulisan ini, sebuah sistem manajemen input yang baik akan menyediakan kebebasan untuk memetakan berbagai macam aksi pada satu kontrol dan memetakan berbagai macam kontrol untuk sebuah aksi.

Langkah pertama saat membuat sebuah sitem manajemen input adalah melepaskan atau memutuskan aksi-aksi yang menyebabkan control input terpakai. Dengan cara ini membuat anda dapat memetakan berbagai tipe input menjadi untuk sebuah aksi dan juga membuatnya lebih mudah untuk mengubah pemetaan (apabila dibutuhkan) dari satu screen ke screen berikutnya.


Input.vb

Tujuan dari input.vb class adalah untuk menyimpan informasi mengenai setiap tipe input yang akan anda terapkan pada game anda. Class ini akan digunakan pada Inputs collection pada GameInput.vb class yang akan dijelaskan kemudian.

Mulailah dengan membuat sebuah Windows Game Project yang baru dan namakan InputHandlerDemo

image.

Setelah itu pilih versi target windows phone OS

image

Masukkan sebuah SpriteFont pada Content Project

image

dan biarkan nama defaultnya SpriteFont1.spritefont

image

Aturlah property Size menjadi 20 supaya lebih dapat terbaca.

image

Sebelum memasukkan class-class baru apapun, anda diharuskan untuk melakukan sedikit pekerjaan. Mulailah dengan meng-klik kanan nama project tersebut pada window Solution Explorer dan menambahkan sebuah new folder.

image

Namakan folder ini dengan nama Inputs.

image

Saat anda melakukan ini, class apapun yang anda masukkan ke folder Inputs akan berada pada namespace InputHandlerDemo.Inputs

Anda juga butuh untuk menambahkan sebuah referensi namespace Microsoft.Devices.Sensors. Anda dapat melakukan ini dengan mengklik menu Project dan memilih Add Reference.

image

Kemudian klik namespace Microsoft.Devices.Sensors kemudian klik OK

image

Selanjutnya, masukkan sebuah class baru didalam folder Inputs

image

dan namakan Input.vb

image

Pastikan statement berikut ini berada pada bagian paling atas dari Input.vb class :

Imports System
Imports System.Collections.Generic
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Input.Touch
Imports Microsoft.Xna.Framework
Imports Microsoft.Devices.Sensors

Didalam Input class anda, buatlah 6 buah Object Dictionary berikut untuk menyimpan input- input dari keyboard, gamepad, touch (tap), touch (slide), gesture, dan accelerometer, secara berturut- turut:

    Private keyboardInputs As New Dictionary(Of Keys, Boolean)
    Private gamepadInputs As New Dictionary(Of Buttons, Boolean)
    Private touchTapInputs As New Dictionary(Of Rectangle, Boolean)
    Private touchSlideInputs As New Dictionary(Of Direction, Single)
    Private gestureInputs As New Dictionary(Of Integer, GestureDefinition)
    Private accelerometerInputs As New Dictionary(Of Direction, Single)

Buttons merupakan tabel yang berisikan semua daftar tombol, sticks, dan triggers yang dapat ditemukan pada gamepad dan berada pada namespace Microsoft.Xna.Framework.Input. Anda dapat melihat definisi komplitnya disini:

<Flags()> _

Public Enum Buttons

    DPadUp = 1

    DPadDown = 2

    DPadLeft = 4

    DPadRight = 8

    Start = 16

    Back = 32

    LeftStick = 64

    RightStick = 128

    LeftShoulder = 256

    RightShoulder = 512

    BigButton = 2048

    A = 4096

    B = 8192

    X = 16384

    Y = 32768

    LeftThumbstickLeft = 2097152

    RightTrigger = 4194304

    LeftTrigger = 8388608

    RightThumbstickUp = 16777216

    RightThumbstickDown = 33554432

    RightThumbstickRight = 67108864

    RightThumbstickLeft = 134217728

    LeftThumbstickUp = 268435456

    LeftThumbstickDown = 536870912

    LeftThumbstickRight = 1073741824

End Enum

Untuk mengingatkan kembali pada arti dari <Flags()> attribute, maupun alasan atas mengapa semua values merupakan kelipatan dari 2, cobalah lihat di pembahasan sebelumnya disini.

Direction berisikan daftar dari 4 buah arah (atas/up, bawah/down, kanan/right, dan kiri/left) dan akan di jelaskan nanti.

Anda akan membuat GestureDefinition.vb class setelah Input.vb class selesai. Untuk sekarang, anda hanya perlu untuk mengetahui bahwa class tersebut menyimpan informasi GestureSample dan menyediakan cara-cara untuk menargetkan sebuah area tertentu dengan gestures anda. Lalu, tambahkan lagi dua buah objek Dictionary, kali ini untuk menyimpan objek dari GamePadState yang sekarang maupun yang sebelumnya. Anda mungkin ingin melakukan hal ini agar anda dapat membedakan antara menekan tombol sekali dan menahan tombol tersebut, dan menspesifikasikan bagaimana game anda akan merespon pada masing- masing aksi.

Public Shared CurrentGamePadState As New Dictionary(Of PlayerIndex, GamePadState)

Public Shared PreviousGamePadState As New Dictionary(Of PlayerIndex, GamePadState)

 

 

Walupun anda tidak dapat menyambungkan gamepad Xbox 360 ke device windows phone anda, Tujuan dari GamePadState adalah digunakan untuk mendeteksi apakah tombol Back sedang ditekan atau tidak. Dan juga membuat semua code yang terdapat di Xbox dan Windows game sedikit lebih mudah untuk dijaga dan dipertahankan, karena hal tersebut digunakan dengan cara yang sama.

Anda ingin melakukan hal yang sama untuk menyimpan states sekarang dan states sebelumnya dari TouchLocation dan Keyboard states :

    Public Shared CurrentTouchLocationState As TouchCollection

    Public Shared PreviousTouchLocationState As TouchCollection

    Public Shared CurrentKeyboardState As KeyboardState

    Public Shared PreviousKeyboardState As KeyboardState

 

Hal selanjutnya yang harus anda masukkan kedalam bagian ini ialah baris berikut ini untuk memeriksa state dari koneksi Gamepad:

Public Shared GamepadConnectionState As New Dictionary(Of PlayerIndex, Boolean)

 

Bukan sesuatu hal yang diwajibkan untuk mengecek state dari koneksi Gamepad pada game yang hanya berbasis windows phone. Akan tetapi, dikarenakan XNA ini mendukung segala bentuk platforms, anda nantinya mungkin ingin melakukannya untuk Xbox 360 dan Windows games.

Windows Phone Games secara sederhana akan terus mengevaluasi state yang tersambung. Selanjutnya, masukkan baris berikut untuk menyimpan gestures yang terdeteksi pada saat single pass terjadi. Variabel ini akan dikosongkan pada awal dari rutinitas Update.

Private Shared detectedGestures As New List(Of GestureDefinition)

 

Sekarang masukkan support untuk sensor accelerometer dan hasil pembacaan accelerometer saat ini:

    Private Shared accelerometerSensor As Accelerometer

    Private Shared _currentAccelerometerReading As Vector3

 

Terakhir, anda akan memasukkan sebuah list yang menyimpan segala jenis arah yang memungkinkan untuk custom TouchSlide gesture. Ini akan digunakan oleh TouchSlide dictionary yang telah anda tetapkan sebelumnya.

Public Enum Direction

        Up

        Down

        Left

        Right

End Enum

 

Nama lain yang lebih baik dari custom TouchSlide gesture mungkin adalah Swipe, sebenarnya lebih enak menyebutnya dengan swipe J. Walaupun Swipe Gesture tidak terdapat pada XNA 4.0 sekarang ini, mungkin saja gesture tersebut akan ada pada versi XNA yang selanjutnya. Karena itu, untuk menghindari kebingungan dan konflik yang mungkin terjadi, sang penulis memutuskan untuk menggunakan nama TouchSlide.

Melihat sekarang anda sudah menyingkirkan semua class level variabel, anda sudah dapat membuat constructor untuk Input.vb class. Code dibawah ini akan menginisialisasikan bentuk sekarang dan sebelumnya dari GamePadState Dictionaries, GamepadConnectionState, dan Accelerometer sensor.

Public Sub New()

        If CurrentGamePadState.Count = 0 Then

            CurrentGamePadState.Add(PlayerIndex.One, GamePad.GetState(PlayerIndex.One))

            CurrentGamePadState.Add(PlayerIndex.Two, GamePad.GetState(PlayerIndex.Two))

            CurrentGamePadState.Add(PlayerIndex.Three, GamePad.GetState(PlayerIndex.Three))

            CurrentGamePadState.Add(PlayerIndex.Four, GamePad.GetState(PlayerIndex.Four))

 

            PreviousGamePadState.Add(PlayerIndex.One, GamePad.GetState(PlayerIndex.One))

            PreviousGamePadState.Add(PlayerIndex.Two, GamePad.GetState(PlayerIndex.Two))

            PreviousGamePadState.Add(PlayerIndex.Three, GamePad.GetState(PlayerIndex.Three))

            PreviousGamePadState.Add(PlayerIndex.Four, GamePad.GetState(PlayerIndex.Four))

 

            GamepadConnectionState.Add(PlayerIndex.One, CurrentGamePadState(PlayerIndex.One).IsConnected)

            GamepadConnectionState.Add(PlayerIndex.Two, CurrentGamePadState(PlayerIndex.Two).IsConnected)

            GamepadConnectionState.Add(PlayerIndex.Three, CurrentGamePadState(PlayerIndex.Three).IsConnected)

            GamepadConnectionState.Add(PlayerIndex.Four, CurrentGamePadState(PlayerIndex.Four).IsConnected)

        End If

 

        If accelerometerSensor Is Nothing Then

            accelerometerSensor = New Accelerometer

            AddHandler accelerometerSensor.ReadingChanged, AddressOf AccelerometerReadingChanged

        End If

End Sub

 

Anda mungkin bertanya-tanya kenapa anda memasukkan code untuk 4 orang player padahal Windows Phone 7 hanya mensupport PlayerIndex.One. Sistem manajemen input yang sedang anda buat didesain untuk dapat bekerja dengan semua jenis platform yang ter-support. Hal ini akan membuat nya secara signifikan lebih mudah untuk membagikan lebih banyak code base yang sama, tak perduli platform mana yang anda targetkan apakah windows phone, xbox ataupun windows game.

Sekarang, masukkan dua buah methods berikut. Methods-methods ini akan menset states sekarang dan sebelumnya untuk gamepad, touch panel, dan keyboard, dan mengosongkan gestures apapun yang terdeteksi sebelumnya, sebelum akhirnya akan memasukkan gestures lain yang baru saja terdeteksi. Sebuah versi yang sedikit lebih diabstraksikan dari dua methods ini akan diakses sebagai bagian dari Update() method dari game anda, yang mana terbungkus oleh code untuk mendeteksi aksi dari player.

Public Shared Sub BeginUpdate()

        CurrentGamePadState(PlayerIndex.One) = GamePad.GetState(PlayerIndex.One)

        CurrentGamePadState(PlayerIndex.Two) = GamePad.GetState(PlayerIndex.Two)

        CurrentGamePadState(PlayerIndex.Three) = GamePad.GetState(PlayerIndex.Three)

        CurrentGamePadState(PlayerIndex.Four) = GamePad.GetState(PlayerIndex.Four)

 

        CurrentTouchLocationState = TouchPanel.GetState()

        CurrentKeyboardState = Keyboard.GetState(PlayerIndex.One)

 

        detectedGestures.Clear()

        Do While TouchPanel.IsGestureAvailable

            Dim gesture = TouchPanel.ReadGesture()

            detectedGestures.Add(New GestureDefinition(gesture))

        Loop

 

End Sub

 

 

Public Shared Sub EndUpdate()

        PreviousGamePadState(PlayerIndex.One) = CurrentGamePadState(PlayerIndex.One)

        PreviousGamePadState(PlayerIndex.Two) = CurrentGamePadState(PlayerIndex.Two)

        PreviousGamePadState(PlayerIndex.Three) = CurrentGamePadState(PlayerIndex.Three)

        PreviousGamePadState(PlayerIndex.Four) = CurrentGamePadState(PlayerIndex.Four)

 

        PreviousTouchLocationState = CurrentTouchLocationState

        PreviousKeyboardState = CurrentKeyboardState

End Sub

 

Method selanjutnya untuk ditambahkan adalah target dari event yang anda letakkan pada bagian bawah dari Input.vb class constructor. Method ini akan diakses untuk menset currentAccelerometerReading

Private Sub AccelerometerReadingChanged(ByVal sender As Object, ByVal e As AccelerometerReadingEventArgs)

        _currentAccelerometerReading.X = CSng(e.X)

        _currentAccelerometerReading.Y = CSng(e.Y)

        _currentAccelerometerReading.Z = CSng(e.Z)

End Sub

 

Method berikutnya yang akan anda tambahkan akan digunakan untuk memetakan sebuah aksi dari game pada input yang spesifik. Kelebihan dari pendekatan ini adalah besarnya ke fleksibilitas yang ditawarkannya. Bila anda ingin memetakan banyak inputs untuk menampilkan aksi yang sama, yang harus anda lakukan adalah menentukan aksi tersebut sekali dalam game anda, dan kemudian anda dapat memetakannya dengan input- input yang berbeda sebanyak mungkin yang anda butuhkan.

Public Sub AddKeyboardInput(ByVal theKey As Keys, ByVal isReleasedPreviously As Boolean)

        If keyboardInputs.ContainsKey(theKey) Then

            keyboardInputs(theKey) = isReleasedPreviously

            Return

        End If

        keyboardInputs.Add(theKey, isReleasedPreviously)

End Sub

 

Public Sub AddGamepadInput(ByVal theButton As Buttons, ByVal isReleasedPreviously As Boolean)

        If gamepadInputs.ContainsKey(theButton) Then

            gamepadInputs(theButton) = isReleasedPreviously

            Return

        End If

        gamepadInputs.Add(theButton, isReleasedPreviously)

End Sub

 

Public Sub AddTouchTapInput(ByVal theTouchArea As Rectangle, ByVal isReleasedPreviously As Boolean)

        If touchTapInputs.ContainsKey(theTouchArea) Then

            touchTapInputs(theTouchArea) = isReleasedPreviously

            Return

        End If

        touchTapInputs.Add(theTouchArea, isReleasedPreviously)

End Sub

 

Pekerjaan Ini mungkin terlihat seperti anda sedang melakukan banyak pekerjaan infrastruktur saat ini, tetapi jangan khawatir! Semua nya akan terbayar kalau anda sudah mulai bekerja pada Game class dan lihat lah hasil dari kerja anda.

Sadarkah anda bahwa ke tiga method tersebut mengikuti pola yang serupa?

Pada method AddKeyboardInput(), anda memasukkan dua buah parameter.

  • Yang pertama mengandung kunci mana yang digunakan untuk pemetaan, dan
  • yang ke dua adalah sebuah Boolean flag yang mengindikasikan apakah dengan menahan tombol tersebut dihitung sebagai aksi tunggal (false) atau mengulang aksi yang sama sampai anda melepaskannya (true).

Hampir sama dengan AddKeyboardInput method, method AddGamepadInput() menerima dua parameter:

  • tombol mana untuk pemetaan, dan
  • sebuah flag untuk mengetahui apakah dengan menahan tombol tersebut dihitung sebagai aksi tunggal (false) atau mengulang aksi yang sama sampai anda melepaskannya (true).

Pada AddTouchTapInput() method, anda juga akan memasukkan 2 buah parameter.

  • Parameter pertama mengandung sebuah bujursangkar atas area layar yang bertanggung jawab atas aksi, dan
  • yang kedua adalah auto-repeat flag yang sama seperti yang telah dikatakan. Pada kasus ini, mempertahankan jari anda berada pada layar setelah melakukan tapping, secara efektif dikatakan sama dengan menahan sebuah tombol.

Pada inti nya, ke 3 method secara dasarnya bekerja dengan cara yang sama :

  1. Apakah aksi yang anda tambahkan sudah ada pada dictionary yang bersangkutan?
  2. Bila YA, update flag pada value yang telah dimasukkan dan keluar.
  3. Bila TIDAK, tambahkan aksi tersebut pada dictionary yang benar, set flag nya dan keluar.

Sekarang masukkan dua buah methods berikut untuk menangani TouchSlide gesture custom dan XNA provided gestures :

Public Sub AddTouchSlideInput(ByVal theDirection As Direction, ByVal slideDistance As Single)

        If touchSlideInputs.ContainsKey(theDirection) Then

            touchSlideInputs(theDirection) = slideDistance

            Return

        End If

        touchSlideInputs.Add(theDirection, slideDistance)

End Sub

 

Public PinchGestureAvailable As Boolean = False

 

Public Sub AddTouchGesture(ByVal theGesture As GestureType, ByVal theTouchArea As Rectangle)

        TouchPanel.EnabledGestures = theGesture Or TouchPanel.EnabledGestures

        gestureInputs.Add(gestureInputs.Count, New GestureDefinition(theGesture, theTouchArea))

        If theGesture = GestureType.Pinch Then

            PinchGestureAvailable = True

        End If

    End Sub

 

Method AddTouchSlideInput() juga menerima dua parameter. Tetapi kali ini, mereka sedikit berbeda.

  • Yang pertama mengandung arah (direction) kemana anda menslide jari anda, dan
  • yang kedua mengandung sebuah nomor floating point yang memeberitahu harus sejauh mana anda harus mengarahkan/ men-slide jari anda untuk mengkatifkan aksi tersebut.

AddTouchGesture() method menerima GestureType() dan sebuah objek bujursangkar, yang menetapkan area touch yang memungkinkan.

Anda juga akan mengekspos variabel dari PinchGestureAvailable, yang akan di cek pada GameInput.vb class.

Dua buah methods yang berikutnya, yang digabungkan dengan isAccelerometerStarted flag, memverifikasikan bahwa accelerometernya dimulai. Anda kemudian diizinkan untuk memasukkan atau mengeluarkan input accelerometer dari accelerometerInputs Dictionary.

Pada method yang pertama, anda akan mensuplai sebuah direction dan sebuah data bertipe single yang melambangkan batas kemiringan untuk input tersebut :

Private Shared isAccelerometerStarted As Boolean = False

 

Public Sub AddAccelerometerInput(ByVal direction As Direction, ByVal tiltThreshold As Single)

        If Not isAccelerometerStarted Then

            Try

                accelerometerSensor.Start()

                isAccelerometerStarted = True

            Catch e As AccelerometerFailedException

                isAccelerometerStarted = False

                System.Diagnostics.Debug.WriteLine(e.Message)

            End Try

        End If

 

        accelerometerInputs.Add(direction, tiltThreshold)

End Sub

 

Public Sub RemoveAccelerometerInputs()

        If isAccelerometerStarted Then

            Try

                accelerometerSensor.Stop()

                isAccelerometerStarted = False

            Catch e As AccelerometerFailedException

                ' The sensor couldn't be stopped.

                System.Diagnostics.Debug.WriteLine(e.Message)

            End Try

        End If

 

        accelerometerInputs.Clear()

End Sub

 

Sekarang, masukkan method IsConnected(), yang mana menghasilkan sebuah Boolean yang menandakan apakah PlayerIndex yang dimasukkan sekarang terhubung :

Public Shared Function IsConnected(ByVal thePlayerIndex As PlayerIndex) As Boolean

        Return CurrentGamePadState(thePlayerIndex).IsConnected

End Function

 

Berikutnya, anda masukkan overloaded method IsPressed dan method individual control input. Hal-hal tersebut akan melengkapi setengah bagian lainnya dari class ini, mengingat mereka bertanggung jawab dalam menentukan keberadaan apakah ada input yang telah ditetapkan benar-benar sudah ada.

Public Function IsPressed(ByVal thePlayerIndex As PlayerIndex) As Boolean

        Return IsPressed(thePlayerIndex, Nothing)

End Function

 

Method berikut ini mengandung 6 blok code yang bertanggung jawab untuk mendeteksi dan menangani :

  • keyboard input
  • gamepad input
  • touch (tap) input
  • touch (slide) input
  • gesture input (pada lokasi yang spesifik), dan
  • accelerometer input

secara berturut-turut. Bila tidak ada dari ke enam input ini yang terdeteksi, method IsPressed() secara sederhana akan menghasilkan kesalahan (false)

Public Function IsPressed(ByVal thePlayerIndex As PlayerIndex,

                              ByVal theCurrentObjectLocation? As Rectangle) As Boolean

        If IsKeyboardInputPressed() Then

            Return True

        End If

 

        If IsGamepadInputPressed(thePlayerIndex) Then

            Return True

        End If

 

        If IsTouchTapInputPressed() Then

            Return True

        End If

 

        If IsTouchSlideInputPressed() Then

            Return True

        End If

 

        If IsGestureInputPressed(theCurrentObjectLocation) Then

            Return True

        End If

 

        Return False

    End Function

 

Melihat sekarang IsPressed method sudah berada di tempatnya, Visual Studio akan protes mengenai semua method yang belum anda buat J. Mulailah dengan menambahkan method berikut ini untuk mendeteksi apakah ada dari tombol- tombol yang telah anda masukkan pada keyboardInputs dictionary telah ditekan. Anda juga akan mengecek untuk Boolean value (yang sewajarnya dimasukkan pada AddKeyboardInput() method melalui parameter isReleasedPreviously) untuk menentukan apakah hanya menerima penekanan tombol yang baru (new press), atau untuk mengenali saat suatu tombol sedang ditahan (hold)

Private Function IsKeyboardInputPressed() As Boolean

        For Each aKey In keyboardInputs.Keys

            If keyboardInputs(aKey) AndAlso

                CurrentKeyboardState.IsKeyDown(aKey) AndAlso

                (Not PreviousKeyboardState.IsKeyDown(aKey)) Then

                Return True

            ElseIf (Not keyboardInputs(aKey)) AndAlso CurrentKeyboardState.IsKeyDown(aKey) Then

                Return True

            End If

        Next aKey

 

        Return False

End Function

 

Method selanjutnya mengecek untuk melihat apkah game anda telah menerima suatu input dari gamepad yang berhubungan dengan player tertentu. Pada Windows Phone 7 game, input ini akan selalu menjadi PlayerIndex.One, akan tetapi hal ini bisa saja salah satu dari empat controller yang tersedia pada Xbox 360 atau Windows game.

Method ini juga bergantung pada teknik yang sama dengan method sebelumnya untuk membedakan input yang baru dengan input yang sedang berlangsung.

Private Function IsGamepadInputPressed(ByVal thePlayerIndex As PlayerIndex) As Boolean

        For Each aButton In gamepadInputs.Keys

            If gamepadInputs(aButton) AndAlso

                CurrentGamePadState(thePlayerIndex).IsButtonDown(aButton) AndAlso

                (Not PreviousGamePadState(thePlayerIndex).IsButtonDown(aButton)) Then

                Return True

            ElseIf (Not gamepadInputs(aButton)) AndAlso

                CurrentGamePadState(thePlayerIndex).IsButtonDown(aButton) Then

                Return True

            End If

        Next aButton

 

        Return False

End Function

 

Method berikutnya ini bekerja hampir sama seperti dengan dua method sebelumnya. Method ini menentukan apakah suatu touch input telah ada pada area bujursangkar yang anda sediakan saat menempatkan input ( dengan memasukkannya ke touchTapInputs dictionary).

Private Function IsTouchTapInputPressed() As Boolean

        For Each touchArea In touchTapInputs.Keys

            If touchTapInputs(touchArea) AndAlso

                touchArea.Intersects(CurrentTouchRectangle) AndAlso

                PreviousTouchPosition() Is Nothing Then

                Return True

            ElseIf (Not touchTapInputs(touchArea)) AndAlso

                touchArea.Intersects(CurrentTouchRectangle) Then

                Return True

            End If

        Next touchArea

 

        Return False

End Function

 

Kemungkinan yang dapat diwujudkan dalam menggunakan method ini tidak terbatas. Mungkin anda memiliki onscreen buttons, atau mungkin bujursangkar tersebut melambangkan sasaran atau potongan puzzle. Dapat membandingkan lokasi dari touch dengan lokasi dari sebuah item onscreen.

Method selanjutnya mendeteksi apakah custom gesture TouchSlide dilakukan atau tidak, dan juga arah dari slide dan apakah panjang minimum dari slide memenuhi syarat. Anda menentukan arah dan panjang pada parameter yang dimasukkan ke AddTouchSlideInput() method.

Private Function IsTouchSlideInputPressed() As Boolean

        For Each slideDirection In touchSlideInputs.Keys

            If CurrentTouchPosition() IsNot Nothing AndAlso

                PreviousTouchPosition() IsNot Nothing Then

                Select Case slideDirection

                    Case Direction.Up

                        If CurrentTouchPosition().Value.Y + touchSlideInputs(slideDirection) <

                            PreviousTouchPosition().Value.Y Then

                            Return True

                        End If

                        Exit Select

 

                    Case Direction.Down

                        If CurrentTouchPosition().Value.Y - touchSlideInputs(slideDirection) >

                            PreviousTouchPosition().Value.Y Then

                            Return True

                        End If

                        Exit Select

 

                    Case Direction.Left

                        If CurrentTouchPosition().Value.X + touchSlideInputs(slideDirection) <

                            PreviousTouchPosition().Value.X Then

                            Return True

                        End If

                        Exit Select

 

                    Case Direction.Right

                        If CurrentTouchPosition().Value.X - touchSlideInputs(slideDirection) >

                            PreviousTouchPosition().Value.X Then

                            Return True

                        End If

                        Exit Select

                End Select

            End If

        Next slideDirection

 

        Return False

End Function

 

Sekarang, anda masukkan sebuah method untuk mendeteksi input gesture. Method ini looping melalui dictionary gestures anda dan membandingkannya dengan daftar gestures yang terdeteksi pada akses yang sekarang ke Update() method. Bila kecocokan ditemukan, anda kemudian akan mengecek apakah gesture tersebut di lakukan dengan benar pada layar.

Private Function IsGestureInputPressed(ByVal theNewDetectionLocation? As Rectangle) As Boolean

        currentGestureDefinition = Nothing

 

        If detectedGestures.Count = 0 Then

            Return False

        End If

 

        ' Check to see if any of the Gestures defined in the gestureInputs

        ' dictionary have been performed and detected.

        For Each userDefinedGesture In gestureInputs.Values

            For Each detectedGesture In detectedGestures

                If detectedGesture.Type = userDefinedGesture.Type Then

                    ' If a Rectangle area to check against has been passed in, then

                    ' use that one, otherwise use the one originally defined

                    Dim areaToCheck = userDefinedGesture.CollisionArea

                    If theNewDetectionLocation IsNot Nothing Then

                        areaToCheck = CType(theNewDetectionLocation, Rectangle)

                    End If

 

                    ' If the gesture detected was made in the area where users were

                    ' interested in Input (they intersect), then a gesture input is

                    ' considered detected.

                    If detectedGesture.CollisionArea.Intersects(areaToCheck) Then

                        If currentGestureDefinition Is Nothing Then

                            currentGestureDefinition = New GestureDefinition(detectedGesture.Gesture)

                        Else

                            ' Some gestures like FreeDrag and Flick are registered many,

                            ' many times in a single Update frame. Since there is only

                            ' one variable to store the gesture info, you must add on

                            ' any additional gesture values so there is a combination

                            ' of all the gesture information in currentGesture

                            currentGestureDefinition.Delta += detectedGesture.Delta

                            currentGestureDefinition.Delta2 += detectedGesture.Delta2

                            currentGestureDefinition.Position += detectedGesture.Position

                            currentGestureDefinition.Position2 += detectedGesture.Position2

                        End If

                    End If

                End If

            Next detectedGesture

        Next userDefinedGesture

 

        If currentGestureDefinition IsNot Nothing Then

            Return True

        End If

 

        Return False

End Function

 

Method selanjutnya berikut ini adalah yang terakhir untuk Input.vb class. Sekali anda memasukkannya dan beberapa properti, anda akan selesai dengan Input class ini.

Tujuan dari method ini adalah untuk membandingkan bacaan accelerometer pada saat ini dengan tingkat/batas kemiringan untuk arah yang sudah ditentukan dan untuk mengembalikan value true bila telepon nya dimiringkan dengan benar pada arah yang tepat.

Private Function IsAccelerometerInputPressed() As Boolean

        For Each input In accelerometerInputs

            Select Case input.Key

                Case Direction.Up

                    If Math.Abs(_currentAccelerometerReading.Y) > input.Value AndAlso

                        _currentAccelerometerReading.Y < 0 Then

                        Return True

                    End If

                    Exit Select

 

                Case Direction.Down

                    If Math.Abs(_currentAccelerometerReading.Y) > input.Value AndAlso

                        _currentAccelerometerReading.Y > 0 Then

                        Return True

                    End If

                    Exit Select

 

                Case Direction.Left

                    If Math.Abs(_currentAccelerometerReading.X) > input.Value AndAlso

                        _currentAccelerometerReading.X < 0 Then

                        Return True

                    End If

                    Exit Select

 

                Case Direction.Right

                    If Math.Abs(_currentAccelerometerReading.X) > input.Value AndAlso

                        _currentAccelerometerReading.X > 0 Then

                        Return True

                    End If

                    Exit Select

            End Select

        Next input

 

        Return False

    End Function

 

Pada tahapan ini anda telah selesai dengan semua method pada class input.vb ini, tapi ada beberapa properties yang harus di tambahkan.

Ini adalah rangkaian awal properties yang akan di gunakan untuk menyediakan informasi dan delta axis ke GameInput.vb class, yang nantinya akan anda bangun.

Private currentGestureDefinition As GestureDefinition

    Public Function CurrentGesturePosition() As Vector2

        If currentGestureDefinition Is Nothing Then

            Return Vector2.Zero

        End If

 

        Return currentGestureDefinition.Position

    End Function

 

    Public Function CurrentGesturePosition2() As Vector2

        If currentGestureDefinition Is Nothing Then

            Return Vector2.Zero

        End If

 

        Return currentGestureDefinition.Position2

    End Function

 

    Public Function CurrentGestureDelta() As Vector2

        If currentGestureDefinition Is Nothing Then

            Return Vector2.Zero

        End If

 

        Return currentGestureDefinition.Delta

    End Function

 

    Public Function CurrentGestureDelta2() As Vector2

        If currentGestureDefinition Is Nothing Then

            Return Vector2.Zero

        End If

 

        Return currentGestureDefinition.Delta2

    End Function

 

Dua properties selanjutnya akan me-loop melalui touch location yang terkandung dalam State object dan memperlihatkan lokasi sekarang dan sebelumnya dari screen touch points, secara berturut- turut.

Public Function CurrentTouchPosition() As Vector2?

        For Each location In CurrentTouchLocationState

            Select Case location.State

                Case TouchLocationState.Pressed

                    Return location.Position

 

                Case TouchLocationState.Moved

                    Return location.Position

            End Select

        Next location

 

        Return Nothing

    End Function

 

    Private Function PreviousTouchPosition() As Vector2?

        For Each location In PreviousTouchLocationState

            Select Case location.State

                Case TouchLocationState.Pressed

                    Return location.Position

 

                Case TouchLocationState.Moved

                    Return location.Position

            End Select

        Next location

 

        Return Nothing

    End Function

Property berikutnya di dalam class input.vb ini adalah property CurrentTouchRectangle, yang memberikan informasi rectangle yang mana yang disentuh:

Private ReadOnly Property CurrentTouchRectangle As Rectangle

        Get

            Dim touchPosition? = CurrentTouchPosition()

            If touchPosition Is Nothing Then

                Return Rectangle.Empty

            End If

 

            Return New Rectangle(CInt(touchPosition.Value.X) - 5,

                                 CInt(touchPosition.Value.Y) - 5,

                                 10,

                                 10)

        End Get

End Property

 

Terakhir, masukkan property CurrentAccelerometerReading, yang memperlihatkan value dari pembacaan accelerometer yang sekarang berjalan:

Public ReadOnly Property CurrentAccelerometerReading As Vector3

        Get

            Return _currentAccelerometerReading

        End Get

End Property

 

Anda telah menyelesaikan Input.vb class.

Seperti yang sudah anda lihat, disamping input yang telah ditetapkan sejak awalnya (seperti keyboard, gamepad, accelerometer, dan sistem gesture), class ini dapat diperluas lebih lanjut untuk memasukkan custom gesture dari anda sendiri.


GestureDefinition.vb

GestureDefinition.vb class digunakan untuk menyimpan informasi mengenai tipe dari gesture yang sedang dilakukan, target rectangle mana gestures seharusnya di lakukan, dan informasi dari object GestureSample yang sesungguhnya. GestureDefinition.vb class digunakan disepanjang Input.vb class.

Untuk menciptakan class ini, masukkan sebuah class baru ke Inputs folder anda dan namakan GestureDefinition.vb

image

Pastikan bahwa statement berikut ini ada pada bagian atas dari class file yang baru dibuat:

Imports System

Imports Microsoft.Xna.Framework

Imports Microsoft.Xna.Framework.Input.Touch

 

Selanjutnya, tambahkan Public Class variabel berikut ini untuk menyimpan semua informasi yang Anda butuhkan nanti:

    Public Type As GestureType

    Public CollisionArea As Rectangle

    Public Gesture As GestureSample

    Public Delta As Vector2

    Public Delta2 As Vector2

    Public Position As Vector2

    Public Position2 As Vector2

 

Berikutnya, tambahkan Overloaded Constructors berikut ini kedalam GestureDefinition.vb class.

Public Sub New(ByVal theGestureType As GestureType,

                   ByVal theGestureArea As Rectangle)

        Gesture = New GestureSample(theGestureType,

                                    New TimeSpan(0),

                                    Vector2.Zero,

                                    Vector2.Zero,

                                    Vector2.Zero,

                                    Vector2.Zero)

        Type = theGestureType

        CollisionArea = theGestureArea

End Sub

 

Public Sub New(ByVal theGestureSample As GestureSample)

        Gesture = theGestureSample

        Type = theGestureSample.GestureType

        CollisionArea = New Rectangle(CInt(theGestureSample.Position.X),

                                      CInt(theGestureSample.Position.Y), 5, 5)

 

        Delta = theGestureSample.Delta

        Delta2 = theGestureSample.Delta2

        Position = theGestureSample.Position

        Position2 = theGestureSample.Position2

End Sub

 

  • Overload yang pertama akan menerima sebuah Gesture type dan sebuah Rectangle yang menjelaskan dimana seharusnya gesture ini dilakukan. Dari sini, sebuah GestureSample objek yang baru dibuat dan dinisialisasikan dengan nilai awal untuk properties Position dan Delta.
  • Overload yang kedua menerima sebuah GestureSample objek yang sudah ada dan mengisi GestureDefinition properties dari informasi yang terkandung didalamnya. Itulah semua yang ada untuk GestureDefinition.vb class. Sekarang adalah saatnya untuk meletakkan nya dan Input class untuk digunakan pada GameInput.vb class.

GameInput.vb

GameInput.vb class membungkus fungsi dari Input dan GestureDefinition.vb class dan juga menyediakan sebuah dictionary dari tipe-tipe Input yang anda tentukan untuk game anda.

Tambahkan suatu class baru yang lain ke project anda (juga didalam Input folder) dan namakan GameInput.vb.

image

Pastikan statement berikut ini berada pada bagian atas dari GameInput.vb class file:

Imports System

Imports System.Collections.Generic

Imports Microsoft.Xna.Framework

Imports Microsoft.Xna.Framework.Input

Imports Microsoft.Xna.Framework.Input.Touch

 

Kemudian deklarasikan variabel Input ini kedalam Class GameInput.vb

Private Inputs As New Dictionary(Of String, Input)

 

Dictionary untuk Input akan menyimpan semua tipe Input yang anda gunakan pada game anda.

Method berikut ini menunjukkan tipe input atas aksi apapun yang anda masukkan. Sebagai tambahan, bila aksi tersebut belum berada pada dictionary, method tersebut akan membuat sebuah entri aksi yang baru secara otomatis dan kemudian menunjukkan tipe inputnya.

    Public Function GetInput(ByVal theAction As String) As Input

        'Add the Action if it doesn't already exist

        If Inputs.ContainsKey(theAction) = False Then

            Inputs.Add(theAction, New Input)

        End If

 

        Return Inputs(theAction)

    End Function

 

Dua method yang berikutnya dengan praktisnya membungkus method-method dengan nama yang sama di dalam Input class, membuat nya menjadi sederhana untuk Game class anda. Anda cukup untuk hanya menangani GameInput class daripada menangani Input dan GameInput.

Public Sub BeginUpdate()

        Input.BeginUpdate()

    End Sub

 

    Public Sub EndUpdate()

        Input.EndUpdate()

    End Sub

 

Method IsConnected() berikut ini menunjukkan hubungan dari controller Gamepad berdasarkan pada PlayerIndex yang dimasukkan:

Public Function IsConnected(ByVal thePlayer As PlayerIndex) As Boolean

        ' If there never WAS a gamepad connected, just say the gamepad is STILL connected

        If Input.GamepadConnectionState(thePlayer) = False Then

            Return True

        End If

 

        Return Input.IsConnected(thePlayer)

End Function

 

Berikutnya overloaded method IsPressed akan mengecek Inputs dictionary lokal untuk sebuah aksi. Bila aksi tersebut tidak berada didalam dictionary, akan memberitahukan suatu kesalahan. Bila tidak, hal tersebut akan mengakses IsPressed() method khusus untuk objek input yang berhubungan dengan aksi tersebut dan akan mengembalikan value true bila input yang benar diberikan si player; bila tidak akan menunjukkan value false.

Public Function IsPressed(ByVal theAction As String) As Boolean

        If Not Inputs.ContainsKey(theAction) Then

            Return False

        End If

 

        Return Inputs(theAction).IsPressed(PlayerIndex.One)

End Function

 

Public Function IsPressed(ByVal theAction As String, ByVal thePlayer As PlayerIndex) As Boolean

        If Inputs.ContainsKey(theAction) = False Then

            Return False

        End If

 

        Return Inputs(theAction).IsPressed(thePlayer)

End Function

 

Public Function IsPressed(ByVal theAction As String, ByVal thePlayer? As PlayerIndex) As Boolean

        If thePlayer Is Nothing Then

            Dim theReturnedControllingPlayer As PlayerIndex

            Return IsPressed(theAction, thePlayer, theReturnedControllingPlayer)

        End If

 

        Return IsPressed(theAction, CType(thePlayer, PlayerIndex))

End Function

 

Overload berikutnya adalah tantangan yang sebenarnya, maka perhatikanlah dengan saksama mengenai apa yang terjadi didalamnya. Disini, anda akan memasukkan sebuah Action objek dan mungkin sebuah PlayerIndex. (Perhatikan ?, yang mana mengartikan tipe nullable.)

 

  1. Bila Action objek yang anda masukkan tidak cocok dengan konten apapun pada Inputs dictionary, method tersebut akan mengembalikan value false dan keluar.
  2. Bila anda memasukkan Action objek yang benar, tetapi anda tidak memasukkan sebuah PlayerIndex, method tersebut akan mengecek ke empat player yang memungkinkan untuk melihat apakah salah satu darinya mengeluarkan aksi tersebut.
  3. Bila player yang mengeluarkan aksi tersebut ditemukan, set controlling player ke index dari player yang mengeluarkan aksi tersebut dan akan mengembalikan value true.
  4. Bila player yang bersangkutan tidak dapat ditemukan, set controlling player pada PlayerIndex.One dan akan mengembalikan nilai false.
  5. Bila sebuah PlayerIndex benar-benar dimasukkan, set controlling player pada index yang sesuai dan aktifkan satu dari overload IsPressed dengan parameter Action dan PlayerIndex.
  6. Berikut adalah code untuk melakukan ini:

Public Function IsPressed(ByVal theAction As String,

                              ByVal thePlayer? As PlayerIndex,

                              <System.Runtime.InteropServices.Out()> ByRef theControllingPlayer As PlayerIndex) As Boolean

        If Not Inputs.ContainsKey(theAction) Then

            theControllingPlayer = PlayerIndex.One

            Return False

        End If

 

        If thePlayer Is Nothing Then

            If IsPressed(theAction, PlayerIndex.One) Then

                theControllingPlayer = PlayerIndex.One

                Return True

            End If

 

            If IsPressed(theAction, PlayerIndex.Two) Then

                theControllingPlayer = PlayerIndex.Two

                Return True

            End If

 

            If IsPressed(theAction, PlayerIndex.Three) Then

                theControllingPlayer = PlayerIndex.Three

                Return True

            End If

 

            If IsPressed(theAction, PlayerIndex.Four) Then

                theControllingPlayer = PlayerIndex.Four

                Return True

            End If

 

            theControllingPlayer = PlayerIndex.One

            Return False

        End If

 

        theControllingPlayer = CType(thePlayer, PlayerIndex)

        Return IsPressed(theAction, CType(thePlayer, PlayerIndex))

    End Function

 

Enam Properties berikutnya dipanggil langsung dari game1.vb class, enam properties ini menyediakan pemetaan input kepada aksi dan perilaku game.

 

Public Sub AddGamePadInput(ByVal theAction As String,

                               ByVal theButton As Buttons,

                               ByVal isReleasedPreviously As Boolean)

        GetInput(theAction).AddGamepadInput(theButton, isReleasedPreviously)

End Sub

 

Public Sub AddTouchTapInput(ByVal theAction As String,

                                ByVal theTouchArea As Rectangle,

                                ByVal isReleasedPreviously As Boolean)

        GetInput(theAction).AddTouchTapInput(theTouchArea, isReleasedPreviously)

End Sub

 

 

   

Public Sub AddTouchSlideInput(ByVal theAction As String,

                                  ByVal theDirection As Input.Direction,

                                  ByVal slideDistance As Single)

        GetInput(theAction).AddTouchSlideInput(theDirection, slideDistance)

End Sub

 

 

   

Public Sub AddKeyboardInput(ByVal theAction As String,

                                ByVal theKey As Keys,

                                ByVal isReleasedPreviously As Boolean)

        GetInput(theAction).AddKeyboardInput(theKey, isReleasedPreviously)

End Sub

 

 

Public Sub AddTouchGestureInput(ByVal theAction As String,

                                    ByVal theGesture As GestureType,

                                    ByVal theRectangle As Rectangle)

        GetInput(theAction).AddTouchGesture(theGesture, theRectangle)

End Sub

 

   

Public Sub AddAccelerometerInput(ByVal theAction As String,

                                     ByVal theDirection As Input.Direction,

                                     ByVal tiltThreshold As Single)

        GetInput(theAction).AddAccelerometerInput(theDirection, tiltThreshold)

End Sub

 

 

Empat properties berikutnya seharusnya sudah terlihat akrab. Empat Properties ini memegang informasi Position dan Delta dari Input objek yang melekat pada Aksi yang anda masukkan dan mengembalikannya ke Game1.vb class:

 

    Public Function CurrentGesturePosition(ByVal theAction As String) As Vector2

        Return GetInput(theAction).CurrentGesturePosition()

    End Function

 

    Public Function CurrentGestureDelta(ByVal theAction As String) As Vector2

        Return GetInput(theAction).CurrentGestureDelta()

    End Function

 

    Public Function CurrentGesturePosition2(ByVal theAction As String) As Vector2

        Return GetInput(theAction).CurrentGesturePosition2()

    End Function

 

    Public Function CurrentGestureDelta2(ByVal theAction As String) As Vector2

        Return GetInput(theAction).CurrentGestureDelta2()

    End Function

 

Dua properties yang berikutnya menunjukkan touch point yang sekarang atau data touch position berdasarkan pada Action yang anda masukkan:

Public Function CurrentTouchPoint(ByVal theAction As String) As Point

        Dim currentPosition? = GetInput(theAction).CurrentTouchPosition()

        If currentPosition Is Nothing Then

            Return New Point(-1, -1)

        End If

 

        Return New Point(CInt(currentPosition.Value.X), CInt(currentPosition.Value.Y))

    End Function

 

Public Function CurrentTouchPosition(ByVal theAction As String) As Vector2

        Dim _currentTouchPosition? = GetInput(theAction).CurrentTouchPosition()

        If _currentTouchPosition Is Nothing Then

            Return New Vector2(-1, -1)

        End If

 

        Return CType(_currentTouchPosition, Vector2)

End Function

 

Property yang selanjutnya digunakan khususnya dengan tipe gesture Pinch. Properti ni menunjukkan Single value yang negatif atau positif yang melambangkan perubahan skala dari pinch itu sendiri (atau 0 bila tidak terjadi perubahan apapun).

Public Function CurrentGestureScaleChange(ByVal theAction As String) As Single

        ' Scaling is dependent on the Pinch gesture. If no input has been setup for

        ' Pinch then just return 0 indicating no scale change has occurred.

        If Not GetInput(theAction).PinchGestureAvailable Then

            Return 0

        End If

 

        ' Get the current and previous locations of the two fingers

        Dim currentPositionFingerOne = CurrentGesturePosition(theAction)

        Dim previousPositionFingerOne = CurrentGesturePosition(theAction) - CurrentGestureDelta(theAction)

        Dim currentPositionFingerTwo = CurrentGesturePosition2(theAction)

        Dim previousPositionFingerTwo = CurrentGesturePosition2(theAction) - CurrentGestureDelta2(theAction)

 

        ' Figure out the distance between the current and previous locations

        Dim currentDistance = Vector2.Distance(currentPositionFingerOne, currentPositionFingerTwo)

        Dim previousDistance = Vector2.Distance(previousPositionFingerOne, previousPositionFingerTwo)

 

        ' Calculate the difference between the two and use that to alter the scale

        Dim scaleChange = (currentDistance - previousDistance) * 0.00999999978F

        Return scaleChange

    End Function

 

sekarang anda sudah selesai berurusan dengan GameInput.vb class.


TouchIndicator.vb

TouchIndicator.vb class bukanlah sebuah keharusan dari sitem manajemen input, tetapi terdapat di sini karena class ini mengilustrasikan kegunaan yang sangat berguna. Anda akan menggunakan class ini untuk menyediakan petunjuk/penanda visual untuk user anda (atau player) mengenai dimana secara tepatnya mereka sedang menyentuh layar.

Game class yang akan anda buat nantinya pada bagian ini akan mendapatkan benefit dari TouchIndicator dan TouchIndicatorCollection class.

Mulailah dengan membuat sebuah class baru didalam namespace Inputs dan namakan TouchIndicator.vb.

image

Pastikan statement yang digunakan berikut ada pada bagian atas dari class file:

Imports System

Imports System.Collections.Generic

Imports Microsoft.Xna.Framework

Imports Microsoft.Xna.Framework.Graphics

Imports Microsoft.Xna.Framework.Input.Touch

Imports Microsoft.Xna.Framework.Content

 

Kemudian tambahkan variabel berikut ini:

Private alphaValue As Integer = 255

Public TouchID As Integer

 

alphaValue akan termodifikasi pada Update() routine dan juga digunakan pada Draw() routine untuk mengontrol memudarkan indikatornya masuk atau keluar.

TouchID ditetapkan didalam class constructor dan digunakan untuk menunjukkan posisi TouchLocation pada Game1.vb class.

Private touchCircleIndicatorTexture As Texture2D

Private touchCrossHairIndicatorTexture As Texture2D

 

Dua variabel ini digunakan untuk menyimpan gambar- gambar untuk indikator berbentuk circle atau crosshair. Mereka akan ditempatkan pada class constructor.

Private touchPositions As New List(Of Vector2)

 

Yang terakhir dari variabel class-level, touchPositions, mengandung sebuah daftar dari nilai Vector2 yang berhubungan dengan posisi dari suatu objek TouchLocation manapun. Sebelum membuat constructor nya, masukkan file Circle.png dan Crosshair.png pada ContentProject anda (file ada dalam sample code).

Selanjutnya, buatlah constructor tersebut untuk class ini. Constructor ini akan menerima sebuah integer touchID dan sebuah objek ContentManager, yang mana akan anda gunakan untuk meload sprites indikator menjadi dua variabel Texture2D yang anda tetapkan sebelumnya.

Public Sub New(ByVal touchID As Integer, ByVal content As ContentManager)

        Me.TouchID = touchID

 

        touchCircleIndicatorTexture = content.Load(Of Texture2D)("Circle")

        touchCrossHairIndicatorTexture = content.Load(Of Texture2D)("Crosshair")

End Sub

 

Pada method yang berikutnya, anda akan menerima sebuah TouchCollection object dan menunjukkan informasi posisi untuk TouchLocation yang sesuai dengan variabel TouchID. Bila tak ada yang sesuai dengan ID nya, anda akan mendapatkan value null / Nothing.

Private Function TouchPosition(ByVal touchLocationState As TouchCollection) As Vector2?

        Dim touchLocation As TouchLocation

        If touchLocationState.FindById(TouchID, touchLocation) Then

            Return touchLocation.Position

        End If

 

        Return Nothing

End Function

 

Berikutnya anda masukkan Update() method. Method ini menerima sebuah TouchCollection objek sebagai sebuah parameter. Update() method dan Draw() method yang akan anda buat keduanya secara singkat terakses melalui TouchIndicatorCollection class. {code}

Public Sub Update(ByVal touchLocationState As TouchCollection)

        Dim currentPosition? = TouchPosition(touchLocationState)

        If currentPosition Is Nothing Then

            If touchPositions.Count > 0 Then

                alphaValue -= 20

                If alphaValue <= 0 Then

                    touchPositions.Clear()

                    alphaValue = 255

                End If

            End If

        Else

            If alphaValue <> 255 Then

                touchPositions.Clear()

                alphaValue = 255

            End If

 

            touchPositions.Add(CType(currentPosition, Vector2))

        End If

    End Sub

 

Bila informasi posisi tidak tersedia dari touchLocationState, posisi touch tersimpan didalam daftar touchPosition, anda secara bertahap akan mengurangi alphaValue dan akhirnya mengosongkan daftar tersebut bersamaan dengan alphaValue yang turun dibawah 0. Sebaliknya, bila TouchPosition() method menunjukkan suatu data posisional, anda akan me-reset alphaValue ke value awal dan menambahkan posisi sekarang pada daftar dari posisi touch.

Dua method yang terakhir yang harus anda masukkan ke class ini adalah Draw() dan DrawLine(). Walaupun ke dua method ini dapat digabungkan, pendekatan ini membuat code tersebut lebih bersih dan lebih tertata.

Pertama, masukkan Draw() method, memasukkan sebuah parameter SpriteBatch. Bila ada suatu item yang berada pada daftar touchPositions, aturlah posisi yang sebelumnya dan loop melalui setiap item pada daftar touchPosition. Akses DrawLine() method pada masing-masing posisi dengan alpha channel value yang spesifik untuk tingkat ketransparanan.

Public Sub Draw(ByVal batch As SpriteBatch)

        If touchPositions.Count <> 0 Then

            Dim previousPosition = touchPositions(0)

            Dim offsetForCenteringTouchPosition As New Vector2(-25, 0)

 

            For Each aPosition In touchPositions

                DrawLine(batch,

                         touchCircleIndicatorTexture,

                         touchCrossHairIndicatorTexture,

                         previousPosition + offsetForCenteringTouchPosition,

                         aPosition + offsetForCenteringTouchPosition,

                         New Color(0, 0, 255, alphaValue))

 

                previousPosition = aPosition

            Next aPosition

        End If

End Sub

 

Terakhir, masukkan DrawLine() method. Method ini mengambil parameter dari Draw() method dan mengambarkan gambar crosshair dan sebuah garis yang muncul seiring dengan anda men-drag jari anda di atas layar:

Private Sub DrawLine(ByVal batch As SpriteBatch,

                         ByVal lineTexture As Texture2D,

                         ByVal touchTexture As Texture2D,

                         ByVal startingPoint As Vector2,

                         ByVal endingPoint As Vector2,

                         ByVal lineColor As Color)

        batch.Draw(touchTexture, startingPoint, lineColor)

 

        Dim difference = startingPoint - endingPoint

        Dim lineLength = difference.Length() / 8

 

        For i = 0 To CInt(lineLength) - 1

            batch.Draw(lineTexture, startingPoint, lineColor)

            startingPoint.X -= difference.X / lineLength

            startingPoint.Y -= difference.Y / lineLength

        Next i

 

        batch.Draw(touchTexture, endingPoint, lineColor)

    End Sub

 

Anda mungkin bertanya-tanya apa yang terjadi dengan akses ke batch.Begin() dan batch.End(), yang biasanya akan membungkus batch.Draw() calls.

Dalam kasus ini, SpriteBatch tersebut sesungguhnya sedang dibuka dan ditutup lebih rendah pada tumpukan akses, sebelumnya paga Game1.vb class, yang akan anda buat sesaat lagi. Tinggal satu bagian dari sitem manajemen input yang tersisa yaitu TouchIndicatorCollection.vb class, yang akan anda tambahkan selanjutnya.


TouchIndicatorCollection.vb

Pertama, buatlah sebuah class baru pada namespace Inputs dan namakan TouchIndicatorCollection.vb.

image

Pastikan namespace–namespace berikut ada:

Imports System

Imports System.Collections.Generic

Imports Microsoft.Xna.Framework

Imports Microsoft.Xna.Framework.Content

Imports Microsoft.Xna.Framework.Input.Touch

Imports Microsoft.Xna.Framework.Graphics

 

Sekarang, masukkan variabel class-level berikut, yang memiliki sebuah daftar object TouchIndicator:

Private touchPositions As New List(Of TouchIndicator)

 

Hapir sama dengan TouchIndicator.vb class yang anda buat sebelumnya, class ini juga memilki Update() dan Draw() method. Keduanya diakses dari method mereka masing- masing pada Game class anda. Pada Update() method, anda mendapatkan keadaan sekarang dari touch panel dan men-loop melalui TouchCollection, yang membandingkan TouchLocationID dengan seluruh TouchIndicator ID yang tersimpan di dalam daftar touchPositions.

Bila tidak ada kesesuaian yang ditemukan, masukkan sebuah TouchIndicator objek yang baru ke daftar TouchLocations. Terakhir, anda mengakses Update() method dari masing- masing TouchIndicator objek yang tersimpan pada daftar.

Public Sub Update(ByVal gameTime As GameTime, ByVal content As ContentManager)

        Dim currentTouchLocationState = TouchPanel.GetState()

        For Each location In currentTouchLocationState

            Dim isTouchIDAlreadyStored = False

            For Each indicator In touchPositions

                If location.Id = indicator.TouchID Then

                    isTouchIDAlreadyStored = True

                    Exit For

                End If

            Next indicator

 

            If Not isTouchIDAlreadyStored Then

                Dim indicator As New TouchIndicator(location.Id, content)

                touchPositions.Add(indicator)

            End If

        Next location

 

        For Each indicator In touchPositions

            indicator.Update(currentTouchLocationState)

        Next indicator

    End Sub

 

Method terakhir pada class ini adalah Draw() method. Method ini men-loop melalui daftar TouchPositions dan mengakses Draw() method dari masing- masing objek TouchIndicator pada daftar.

Public Sub Draw(ByVal batch As SpriteBatch)

        For Each indicator In touchPositions

            indicator.Draw(batch)

        Next indicator

    End Sub

 

Okay, Anda telah membuat sesuatu yang dapat berfungsi sebagai pondasi dari banyak games, tidak peduli platform mana yang anda targetkan.

Teknik-teknik menggabungkan sistem manajemen input ini dengan state management yang akan anda pelajari akan memberikan anda suatu start awal yang menguntungkan pada project game anda yang selanjutnya.

Sekarang, mari letakkan sistem ini untuk digunakan di dalam sebuah sampel game.


Bagian selanjutnnya ini tidaklah terlalu dibutuhkan, tetapi pada game yang besar atau kompleks, adalah suatu hal yang membuat pekerjaan anda menjadi lebih sederhana dengan memiliki semua aksi diletakkan di satu tempat dan dibagi menjadi beberapa class yang terpisah. Maka walau anda tidak membutuhkannya disini, hal ini merupakan kebiasaan yang baik untuk anda dalami.

Action.vb

Buatlah sebuah class baru pada solution anda, dan namakan Action.vb

image

Anda tidak membutuhkan statement apapun pada file ini, jadi singkirkanlah mereka. Karena ini akan menjadi kelas statis yang mengandung hanya suatu konstanta sebagai definisi untuk aksi anda, masukkan keyword statis tersebut menuju definisi class. Berikutnya anda masukkan aksi untuk game ini.

Friend NotInheritable Class Actions

        Public Const Jump As String = "Jump"

    Public Const [Exit] As String = "Exit"

    Public Const Up As String = "Up"

    Public Const Pause As String = "Pause"

End Class

 

Sample game ini mengandung hanya empat buah aksi, yang dapat diaktifkan dengan berbagai macam cara. Sebuah game yang lebih besar atau lebih kompleks mungkin memiliki segudang aksi yang dapat dimunculkan. Dengan didefinisikan nya hal tersebut dalam file class yang terpisah menjaga banyak kekacauan yang tidak perlu keluar dari Game class utama anda.Mengenai Game class, itulah yang berikutnya akan anda kerjakan.


Game1.vb

Anda sudah memiliki sebuah Game1.vb class pada project anda, maka sekarang lah waktunya untuk mengerjakannya. Class ini menggunakan SpriteFont untuk menampilkan teks pada layar. Maka klik kanan Content project pada Solution Explorer anda dan masukkan sebuah Spritefont. Namakan display.spritefont.

Kemudian tambahkan juga file Pixel.png (file tersedia dalam sample code yg bisa di download)

Sekarang bukalah file Game1.vb anda dan pastikan anda memilki statement berikut di bagian atas dari file tersebut:

Imports System

Imports Microsoft.Xna.Framework

Imports Microsoft.Xna.Framework.Content

Imports Microsoft.Xna.Framework.Graphics

Imports Microsoft.Xna.Framework.Input

Imports Microsoft.Xna.Framework.Input.Touch

 

Berikutnya, masukkan variabel berikut pada class level. Ini akan digunakan untuk menyediakan feedback visual bahwa code input nya bekerja dengan benar.

    Private font As SpriteFont

    Private square As Texture2D

    Private action As String = ""

 

Kemudian tambahkan variabel untuk Object GameInput dan TouchIndicatorCollection

    Private gameInput As GameInput

    Private touchIndicators As TouchIndicatorCollection

 

Terakhir, tambahkan definisi rectangle untuk ke empat area touch pada game anda. Rectangle-rectangle ini akan digunakan seperti tombol onscreen dalam demo.

    Private JumpRectangle As New Rectangle(0, 0, 480, 100)

    Private UpRectangle As New Rectangle(0, 150, 480, 100)

    Private PauseRectangle As New Rectangle(0, 500, 200, 100)

    Private ExitRectangle As New Rectangle(220, 500, 200, 100)

 

Setelah semua class-level variabel berada ditempat nya, masukkan code berikut di dalam constructor:

        graphics.PreferredBackBufferWidth = 480

        graphics.PreferredBackBufferHeight = 800

 

Ke dua baris kode ini digunakan untuk membuat game anda menggunakan mode Portrait.

Pada Initialize() method dari Game1.vb class anda, sebelum akses ke MyBase.Initialize(), masukkan baris berikut untuk menginstansiasikan GameInput.vb class dan TouchIndicatorCollection.vb class tetapkanlah game inputs:

        gameInput = New GameInput

        touchIndicators = New TouchIndicatorCollection

 

        AddInputs()

 

VisualStudio akan sedikit mengeluh karena anda belum membuat AddInputs() method. Karena itu, masukkan code dibawah ini:

Private Sub AddInputs()

        ' Add keyboard, gamepad and touch inputs for Jump

        gameInput.AddKeyboardInput(Actions.Jump, Keys.A, True)

        gameInput.AddKeyboardInput(Actions.Jump, Keys.Space, False)

        gameInput.AddTouchTapInput(Actions.Jump, JumpRectangle, False)

        gameInput.AddTouchSlideInput(Actions.Jump, Input.Direction.Right, 5.0F)

 

        ' Add keyboard, gamepad and touch inputs for Pause

        gameInput.AddGamePadInput(Actions.Pause, Buttons.Start, True)

        gameInput.AddKeyboardInput(Actions.Pause, Keys.P, True)

        gameInput.AddTouchTapInput(Actions.Pause, PauseRectangle, True)

        gameInput.AddAccelerometerInput(Actions.Pause, Input.Direction.Down, 0.1F)

 

        ' Add keyboard, gamepad and touch inputs for Up

        gameInput.AddGamePadInput(Actions.Up, Buttons.RightThumbstickUp, False)

        gameInput.AddGamePadInput(Actions.Up, Buttons.LeftThumbstickUp, False)

        gameInput.AddGamePadInput(Actions.Up, Buttons.DPadUp, False)

        gameInput.AddKeyboardInput(Actions.Up, Keys.Up, False)

        gameInput.AddKeyboardInput(Actions.Up, Keys.W, True)

        gameInput.AddTouchTapInput(Actions.Up, UpRectangle, True)

        gameInput.AddTouchSlideInput(Actions.Up, Input.Direction.Up, 5.0F)

        gameInput.AddAccelerometerInput(Actions.Up, Input.Direction.Up, 0.1F)

 

        ' Add keyboard, gamepad and touch inputs for Exit

        gameInput.AddGamePadInput(Actions.Exit, Buttons.Back, False)

        gameInput.AddKeyboardInput(Actions.Exit, Keys.Escape, False)

        gameInput.AddTouchTapInput(Actions.Exit, ExitRectangle, True)

 

        ' Add some Gestures too, just to show them off?

        gameInput.AddTouchGestureInput(Actions.Jump, GestureType.VerticalDrag, JumpRectangle)

        gameInput.AddTouchGestureInput(Actions.Pause, GestureType.Hold, PauseRectangle)

    End Sub

 

Tujuan dari method ini adalah untuk memetakan berbagai aksi game ke input- input yang mengaktifkan mereka.

Anda tidak perlu mengelompokkan code anda berdasarkan aksi bila anda tidak menginginkannya, tetapi dengan melakukannya dapat membuatnya lebih teratur dan membuatnya lebih mudah untuk menemukan suatu baris yang anda cari bila anda ingin mengubah sesuatu.Lihatlah pada baris code, dan perhatikan pemetaan untuk input Keyboard dan Gamepad.

Walaupun maksud dari contoh ini adalah untuk memperlihatkan berbagai jenis platform, ingatlah bahwa beberapa Device Windows Phone 7 memilki slide-out hardware keyboard, dan code ini akan bekerja dengan cara yang bnar- benar sama pada device-device tersebut layaknya dengan keyboard biasa yang ada pada box 360 atau Windows PC.

Pada LoadContent() method dari Game1.vb class anda, masukkan dua buah baris berikut untuk meload asset-asset game anda:

        font = Content.Load(Of SpriteFont)("Display")

        square = Content.Load(Of Texture2D)("Pixel")

 

Di dalam Update() method dari Game1.vb class, masukkan blok code berikut:

        gameInput.BeginUpdate()

 

        ' Allows the game to exit

        If gameInput.IsPressed(Actions.Exit, PlayerIndex.One) Then

            Me.Exit()

        End If

 

        If gameInput.IsPressed(Actions.Jump, PlayerIndex.One) Then

            action = Actions.Jump

        End If

 

        If gameInput.IsPressed(Actions.Pause, PlayerIndex.One) Then

            action = Actions.Pause

        End If

 

        If gameInput.IsPressed(Actions.Up, PlayerIndex.One) Then

            action = Actions.Up

        End If

 

        touchIndicators.Update(gameTime, Content)

 

        gameInput.EndUpdate()

 

Akses untuk BeginUpdate() dan EndUpdate() ada untuk mendapatkan state saat ini dari berbagai macan tipe input yang berbeda, dan juga untuk mengatur keadaan sebelumnya ke keadaan yang sekarang. Perhatikan kode yang biasanya untuk mendeteksi tombol Back telah digantikan dengan code yang dengan sederhana mengecek untuk melihat apakah ada dari Inputs yang dipetakan untuk aksi Exit telah diaktifkan. Hal ini lebih bersih dibandingkan dengan memilki begitu banyak kode yang membuat Update() method menjadi kacau.

Tiga kode blok code lainnya bekerja dengan cara yang sama. Daripada mengecek semua kemungkinan input untuk aksi yang sama dan kemudian melanjutkan ke aksi yang berikutnya, lebih baik anda diharuskan untuk mengecek hanya sekali dari setiap aksi. Method terakhir yang harus anda update adalah Draw() method. Masukkan baris dari kode berikut setelah GraphicsDevice.Clear() dan sebelum MyBase.Draw():

Empat buah blok kode yang pertama yang anda masukkan setelah memulai SpriteBatch anda menetapkan representasi visual dari touch rectangles yang anda letakkan sebelumnya. Baris yang berikutnya akan menuliskan nama dari aksi yang terdeteksi. Terakhir, touch indicator akan terpanggil setiap kali sebuah touch ter-register.

Oke, codingnya. Sekarang waktunya untuk menjalankan dan mencobanya.

Bila anda tidak memilki sebuah device windows phone 7, anda tetap dapat menjalankan dan mengetes code ini, tetapi anda tidak akan dapat mengaktifkan aksi dari Acceloremeter apapun.

Saat anda menjalankan sebuah demo pada telepon anda, seharusnya akan terlihat seperti gambar dibawah ini:

image

Posted by Luki Ishwara | with no comments
Filed under: , ,

Cara load file XAP ke Windows Phone Emulator

1. pastikan anda telah memiliki windows phone 7 SDK yang sudah terinstall pada development machine anda.

2. buka file "XapDeploy.exe" di C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v7.1\Tools\XAP Deployment

image

3. jalankan XapDeploy.exe

4. ubah targetnya ke Windows Phone Emulator

image
5. browse file xap anda, kemudian klik open

image

6. klik tombol deploy, dan aplikasi anda akan berjalan di emulator windows phone

image

 

Video Tutorial bisa dilihat disini http://www.youtube.com/watch?v=ZLCkjVjKOa4&feature=youtu.be

Kalender Jawa yang didemokan disini adalah Windows Phone Application karya Ahmad Masykur

17. Soft Input Panel Pada Windows Phone 7 dan XNA

Project Menggunakan Visual Basic .NET dan XNA Framework 4.0

Source Code bisa di download disini

Video hasil project bisa di lihat disini

Soft Input Panel (SIP) secara otomatis akan ditampilkan oleh OS dari Windows Phone 7, setiap kali suatu text input control (seperti misalnya textbox) mendapatkan fokus. Sayangnya, XNA tidak memiliki text input control apapun, tapi bukan berarti anda tidak dapat menggunakan SIP (Soft Input Panel).

Bila anda bekerja menggunakan Emulator, anda dapat menggunakan keyboard dari komputer anda, tetapi hanya bila SIP tersebut tidak tampil pada layar (tidak on screen). Untuk beralih antara SIP dan keyboard hardware, tekanlah tombol Pause pada keyboard komputer anda.  ini berjalan hanya pada situasi dimana anda memang akan menampilkan SIP tersebut, karena bila tidak, melakukan hal ini tidak akan memunculkan keyboard-nya.

Mari kita lihat bagaimana cara untuk mengakses SIP tersebut secara terprogram.

Buatlah sebuah Windows Phone Game project yang baru, dan namakan SIPSample.

clip_image002

Setelah itu pilih versi target windows phone OS

clip_image004

Masukkan sebuah SpriteFont pada Content project.

clip_image006

Biarkan namanya SpriteFont1

clip_image008

tetapi ubahlah ukuran fontnya menjadi 20 seperti yang biasa kita lakukan pada sample project sebelum ini.

clip_image010

Pada file Class Game1.vb, pada bagian atas, pastikan bahwa namespaces berikut ini terdapat didalamnya :

Imports System
Imports System.Collections.Generic
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.GamerServices
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Input.Touch


clip_image012

Hampir dari semuanya seharusnya sudah terlihat biasa kita kerjakan, tetapi kali ini adalah pertama kalinya anda memasukkan namespace GamerServices.

Untuk pengembang Xbox Live indie Games, GamerServices adalah merupakan cara bagaimana mereka mengakses banyak fitur- fitur keren pada Xbox Live. GamerServices juga merupakan cara bagaimana anda mengakses SIP tersebut.

Masukkan deklarasi SpriteFont pada class level:

Private spriteFont As SpriteFont

clip_image014

Selanjutnya, masukkan kode yang anda sudah akrab dengan berikut ini menuju LoadContent() method anda untuk meload SpriteFont tersebut:

spriteFont = Content.Load(Of SpriteFont)("SpriteFont1")

clip_image016

Untuk menampilkan SIP, anda gunakan BeginShowKeyboardInput() method, dan EndShowKeyboardInput() method untuk menutup SIP. Keduanya dapat ditemukan pada GamerServices.Guide class.

Guide class tersebut bersifat statis, sehingga anda tidak perlu menginstasiasikannya untuk menggunakannya.

Bagaimanapun juga, method yang akan anda gunakan membutuhkan beberapa hal tambahan untuk dapat bekerja dengan baik. Anda akan membutuhkan hal- hal berikut ini untuk SIP tersebut, maka masukkannlah strings variabel berikut pada class level :

Private sipTitle As String = "Ini Judulnya"
Private sipDescription As String = "ini deskripsi, berlokasi di bawah judul"
Private sipResult As String = "silakan ketik disini."


clip_image018

Anda bebas untuk mengisi value String tersebut dengan apa yang anda sukai, dan bahkan anda boleh saja mengisikan value String yang kosong (saya beri isi value supaya nanti bisa terlihat hasilnya ketika di run).

Pada contoh ini, akan lebih baik untuk mengetahui apa yang akan di tampilkan disini. Untuk mengembalikan sebuah rangkaian string dari SIP menuju game anda, anda harus men-set sebuah callback delegate untuk digunakan oleh BeginShowKeyboardInput() method setelah-nya selesai di jalankan.

Callback delegate adalah sebuah pointer pada suatu method yang akan terakses pada saat suatu jenis event yang telah ditentukan dijalankan.

Dalam kasus ini, hal tersebut akan terakses pada saat anda meng-klik tombol OK pada SIP.

Berikutnya, masukkan method berikut pada Game1.vb class anda :

 

Private Sub keyboardCallback(ByVal result As IAsyncResult)
        Dim retval = Guide.EndShowKeyboardInput(result)

        If retval IsNot Nothing Then
            sipResult = retval
        End If
End Sub

clip_image020

keyboardCallback() method menghasilkan result yang asinkron.

Berikutnya, masukkan hasil ini menuju EndShowKeyboardInput() method, yang mana akan menutup SIP dan mendapatkan kembali sebuah string value yang telah anda tetapkan kembali pada variabel sipResult yang baru saja anda tentukan.

Sekarang anda sudah memiliki delegasi yang berada di tempat yang benar, sekarang saatnya untuk memasukkan blok code berikut ini pada Update() method anda, diantara check untuk tombol Back dan MyBase.Update(gameTime) di bagian bawah:

 

clip_image022

Hal yang pertama kali akan anda lakukan ialah mengatur bagaimana anda akan mengakses SIP. Anda juga akan memasukkan variabel sipResult. Didalamnya akan terdapat suatu initial text untuk ditampilkan pada textbox dari SIP, begitu juga dengan apapun yang anda ketikan pada SIP. Setelah itu, masukkan nama dari method untuk diakses pada saat si player menyentuh tombol OK pada SIP. Akhirnya, suatu object akan digunakan untuk menyimpan keadaan pada kondisi SIP Open.

Hal terakhir yang harus dimasukkan adalah code berikut untuk Draw() method anda:

spriteBatch.Begin()
        spriteBatch.DrawString(spriteFont,
                               sipResult,
                               New Vector2 With {.X = 50, .Y = 200},
                               Color.Black)
spriteBatch.End()

clip_image024

Kode ini akan menampilkan value dari sipResult setelah anda menetapkannya pada class level. Apapun yang anda ketik pada SIP, hasil ketikan itu akan ditampilkan.

Itu saja untuk SIP! Sekarang, jalankan kodenya dan cobalah mainkan. Coba tuliskan nama anda atau nama dari hewan peliharaan  anda atau apapun yang anda ***. Saat anda selesai, anda dapat menekan tombol Back ( atau tombol Esc bila anda menggunakan Emulator).

image

clip_image026

image

Posted by Luki Ishwara | with no comments
Filed under: ,

Mendesain Touch Games

Saat mendesain UI scheme untuk game berbasis touch, sangat penting untuk membuat kontrol anda mudah untuk digunakan. Anda tidak dapat memastikan bahwa semua device pasti memilki sebuah keypad, atau tombol pengatur yang dapat memetakan semua opsi-opsi dan command anda yang beragam.

Bagian dari daya tarik dalam pengembangan games menggunakan .NET, XNA, dan Windows phone 7 andalah: anda dapat membuat game anda hanya sekali dan dapat menjalankannya pada beberapa platforms dengan sedikit pengubahan code penyesuaian.

Tulisan berikut ini akan mendiskusikan beberapa latihan yang terbaik untuk diingat pada saat membuat karya besar anda:

Ingatlah Platform Anda

  • Windows Phone Device tidak memilki dukungan untuk dipasangi mouse. Ini berarti bahwa tidak akan ada cursor, tidak ada ada event hover dan tidak ada right-click, tidak ada controller gamepad maupun hardware keyboard . Semua yang biasa anda lakukan dengan hardware keyboard pada game anda harus bisa dilakukan dengan menggunakan sentuhan.
  • Anda mungkin akan dapat mengkompilasi ulang games-games yang didesain untuk PC dan Xbox dan membuatnya berjalan pada windows Phone 7. Tetapi bila anda menginginkan player game anda bisa mendapatkan pengalaman bermain yang baik pada saat memainkan game anda, anda masih memiliki cukup banyak pekerjaan dalam mendesain ulang games anda supaya cocok dimainkan pada windows phone device.

 

Desain Untuk Resolusi Yang Tepat

  • Setidak-tidaknya, anda harus mempertimbangkan secara serius untuk menyetel resolusi layar anda pada 480 x 800 (atau 480 x 320 untuk device windows phone tertentu).
  • Gunakan font yang mudah dibaca, atur setidaknya font tersebut berukuran 20. Teks yang kecil atau unik akan telihat baik-baik saja pada HD platform seperti Xbox360 atau komputer, akan tetapi teks tersebut seringkali dapat menjadi tidak terbaca saat ditampilkan pada device windows phone.
  • Bila anda sedang membuat game yang ditargetkan untuk bermacan-macam platforms, pastikan anda mengecek semua lokasi dimana anda menampilkan teks, untuk memastikan bahwa teks tersebut tidak meleber ke luar sisi layar atau bekerja dengan tidak semestinya.
  • Dan juga pastikan bahwa semua tombol anda atau UI element lainnya yang dapat disentuh memilki ukuran yang tepat. Jari normal berukuran kurang lebih satu inci setengah, akan tetapi ujung jari sesungguhnya dapat memberikan titik sentuh yang jauh lebih kecil. Maka dari itu tombol yang besar tidaklah dibutuhkan pada game anda (mengingat ukuran layar yang terbatas).
  • Sebaliknya, janganlah juga membuat UI element terlalu kecil.
  • Bila game anda memilki tempo yang cukup cepat, beberapa hal lebih mengesalkan dibandingkan ketidakmapuan untuk menekan tombol yang benar karena tombol tersebut terlalu kecil.
  • Jangan gunakan tombol yang mirip dengan tombol tradisional Windows Forms. Teks apapun pada tombol ini akan sangat sulit sekali untuk dibaca, kecuali tombol tersebut berukuran cukup besar.
  • Anda memilki kebebasan seni berkreasi yang tidak terbatas dalam menciptakan game. Buatlah tombol pada layar anda terlihat seperti aksi yang akan dilakukan oleh tombol tersebut. Sebuah menu buy/sell (jual / beli) dapat direpresentasikan dengan sebuah icon Rp., atau sebuah tombol Pause dapat bertipe toggle yang mengalihkan antara permainan dengan gaya stereo dan tombol Pause. Anda bebas untuk memasukkan apapun yang anda rasa cocok terhadap gaya game anda; cukup membuatnya menjadi intuitif.
  • Bila desain anda mendukung nya, buatlah angka dari UI elemen interaktif (dapat disentuh) pada layar seminimal mungkin. Daripada selalu memilki satu atau lebih kolom ikon pada layar, perhitungkanlah untuk menampilkan pop up menu pada saat player menekan sebuah bagian noninteraktif pada layar. Anda bahkan dapat membuat menu context ini menjadi sensitif dan hanya menampilkan opsi- opsi yang valid untuk suatu unit yang telah terpilih.
  • Cobalah untuk tidak meletakkan area kecil yang di-klik terlalu dekat satu sama lain. Bila player anda memilki masalah pda kontrol motorik, mereka akan mendapatkan kesulitan dalam memainkan game anda bila kontrol nya terlalu kecil atau teralu dekat satu sama lain.

 

Jadilah Konsisten dan Dapat Diprediksi

Walaupun tidak ada standar UI yang harus di ikuti oleh setiap game, terdapat ekspektasi-ekspektasi dasar mengenai apa yang akan dilakukan oleh suatu aksi tertentu. Beberapa dari player game anda mungkin tidak lagi mau membaca buku manual atau panduannya, tidak perduli sebagaimana bagusnya manual tersebut. Yang lainnya mungkin akan membacanya hanya karena sebagai solusi terakhir. Bila interface game anda sulit untuk dimengerti, hampir semua player game anda tidak akan dapat menyelesaikan permainan dari game anda tersebut dengan lancar.

Hal yang paling penting ialah untuk anda menjadi konsisten. Setelah player game anda mempelajari bagaimana untuk berinteraksi dengan game anda, mereka akan mengharapkan semua game anda untuk bekerja dengan cara yang sama, maka dari itu, janganlah mengubahnya tanpa alasan yang benar-benar baik, dan biarkan pemain anda tahu bila anda mengubahnya.

Apabila anda memutuskan untuk membuat gestures anda sendiri, pastikan untuk mengajari sang player game anda bagaimana menggunakannya. Sebuah level tutorial atau sebuah mode latihan adalah cara yang biasanya di lakukan untuk mengatasi masalah ini.

Posted by Luki Ishwara | with no comments
Filed under: ,

[Source Code Games] Shooter

ini adalah porting game shooter (dari c# ke vb.net) yang di jadikan basis tutorial 2d games development di app hub dengan beberapa improvement yang akan terus ditambah.

VB XNA

games ini sementara memanfaatkan fitur gesture  free drag pada touchpanel  yang saya bahas disini 

nanti akan saya bahas langkah demi langkah pembuatannya pada postingan blog tersendiri, dan sebelum tulisan blog selesai, bagi yang tertarik boleh mendownload dan mempelajarinya terlebih dahulu.

Demo: www.youtube.com/watch?v=WK1uX0fBwK4

ya memang saya tahu belum sempurna, tapi mari kita belajar bersama sempurnakan bersama-sama :)

Source code dan resource terkait bisa di download disini (30 MB)

Posted by Luki Ishwara | with no comments
Filed under: ,

16. Mendeteksi Gestures Pada Windows Phone

Source Code Project ini dapat didownload di sini

Project ini menggunakan Visual Basic .NET dan XNA Framework 4.0

Demo Video: http://www.youtube.com/watch?v=iDu5EQnlY9U

 

 

Sebagai tambahan dari dukungan untuk single atau multiple touch points pada layar, XNA menyediakan satu set atas gestures umum yang bisa anda program pada game anda.

Kalau sebuah sentuhan sederhana biasanya menunjukkan sebuah pilihan atau click event, gestures dapat menunjukkan aksi yang lebih kompleks dan mencontoh berdasrkan gerakan alami manusia.

Gestures yang bervariasi yang terdapat dalam XNA dapat ditemukan pada list GestureType. Pada bahasan berikut ini, anda akan belajar mengenai gestures yang tersedia dan bagaimana gesture tersebut dimplementasikan pada XNA.

Cara terbaik untuk belajar ialah dengan melakukannya. Maka dari itu, buatlah sebuah Project Windows Phone Game yang baru; nantinya anda akan menambahkan setiap gestures seiring anda belajar mengenai gesture tersebut.

Namakan Gestures pada project baru ini

clip_image002

Seperti biasa, kita akan diminta untuk memilih os, pilih Windows Phone OS 7.1

clip_image003

Klik kanan pada Project Content (GesturesContent), pilih add, kemudian pilih new item

clip_image004

Kemudian Masukkan sebuah SpriteFont pada ProjectContent.

clip_image006

Biarkan nama tersebut SpriteFont1, tetapi ubahlah ukurannya huruf menjadi 20 untuk membuat teks anda lebih bisa terbaca.

clip_image007

Import beberapa class ini pada game1.vb anda: 
Imports System
Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Content
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Input.Touch

clip_image008

Berikutnya, deklarasikan variabel ini untuk memproses dan menginstansiasi SpriteFont anda. Pada class level, masukkan baris berikut :

Private spriteFont As SpriteFont
Private message As String = "klik dan drag pada layar"
Private color As Color = color.Black
Private messagePos As Vector2 = Vector2.Zero

clip_image009

Tiga baris terakhir (Private message As String = "klik dan drag pada layar" , Private color As Color = color.Black dan Private messagePos As Vector2 = Vector2.Zero ) mungkin membingungkan anda pada awalnya, untuk apa itu? Tapi tiga baris code tersebut akan segera akan menjadi mudah dipahami , apabila anda sudah memahami gesture–handling code (code yang menangani gestures), maka dari itu ,untuk saat ini jangan bingung dulu, ketik saja sekarang. Anda akan menggunakannya untuk menampilkan message / pesan berdasarkan pada gesture yang anda jalankan.

Oke kita lanjut, di dalam method LoadContent(), ketik baris code berikut ini :

spriteFont = Content.Load(Of SpriteFont)("SpriteFont1")

clip_image010

Sekarang adalah saatnya untuk memasukkan list gestures yang telah diaktifkan. Anda diharuskan untuk memberitahu si Touchpanel tentang gestures apa yang akan digunakan oleh game anda, mengingat tak ada gestures yang telah aktif secara default, maka masukkan blok code berikut pada method Initialize(), tepat sebelum MyBase.Initialize():

TouchPanel.EnabledGestures =
   GestureType.Tap Or
   GestureType.DoubleTap Or
   GestureType.Hold Or
   GestureType.HorizontalDrag Or
   GestureType.VerticalDrag Or
   GestureType.FreeDrag Or
   GestureType.DragComplete Or
   GestureType.Pinch Or
   GestureType.PinchComplete Or
   GestureType.Flick

 

clip_image011

Apabila anda ingin tahu mengenai syntax ini, coba lihat GestureType enumerator yang dibawah ini:

<Flags()> _
Public Enum GestureType
    None = 0
    Tap = 1
    DoubleTap = 2
    Hold = 4
    HorizontalDrag = 8
    VerticalDrag = 16
    FreeDrag = 32
    Pinch = 64
    Flick = 128
    DragComplete = 256
    PinchComplete = 512
End Enum

attribut <Flags> tersebut digunakan oleh enumerator untuk mengindikasikan bahwa bitwise operations akan didukung.

Agar bitwise operations ini dapat bekerja dengan benar, value dari enumerator haruslah merupakan kelipatan 2. Dengan mengkombinasikan values dengan bitwise, anda memberikan kemungkinan untuk mendapatkan kembali salah satu dari value yang berbeda tersebut dari properti EnabledGestures, meskipun anda tidak akan melakukan apapun terhadap properti ini, XNA yang akan menangani bagian tersebut untuk anda.

Sebelum menjalankan code untuk merespon kepada gestures tertentu, anda harus memeriksa untuk melihat apakah ada touch gestures yang tersedia. Masukkan blok code berikut ini pada method Update() dalam Game1.vb class anda. Pastikan anda meletakkan nya pada sebelum MyBase.Update()

If TouchPanel.IsGestureAvailable Then

End If

clip_image012

Ini mungkin terlihat seperti sebuah hall yang aneh untuk dicheck melalui kondisi if then mengingat anda tidak benar- benar mengambil sebuah gesture, tapi, TouchPanel.IsGestureAvailable akan memberitahu anda apabila ada gestures yang telah anda aktifkan yang siap untuk dibaca.

Bila tidak ada gesture aktif yang tersedia, anda tidak dapat memanggil TouchPanel.ReadGesture(), dikarenakan tidak adanya gestures untuk dibaca. Tanpa baris ini, segala upaya untuk membaca gestures akan mengeluarkan exception InvalidOperation, dan game anda akan gagal untuk dijalankan.

Di dalam if block yang baru saja anda buat tersebut, masukkan baris berikut ini:

Dim gesture = TouchPanel.ReadGesture()

clip_image013

Baris ini akan membaca touchPanel tersebut dan menghasilkan sebuah GestureSample Structure (Microsoft.Xna.Framework.Input.Touch.GestureSample) yang terisi yang mengandung data dari multitouch gestures dalam range waktu tertentu.

Berikut ini adalah property yang terdapat di dalam GestureSample Structure :

Public Structure GestureSample
    ' Holds delta of first touchpoint in a multitouch gesture.
    Public ReadOnly Property Delta() As Vector2
        Get
        End Get
    End Property

    ' Holds delta of second touchpoint in a multitouch gesture.
    Public ReadOnly Property Delta2() As Vector2
        Get
        End Get
    End Property

    ' The type of gesture in a multitouch gesture sample.
    Public ReadOnly Property GestureType() As GestureType
        Get
        End Get
    End Property

    ' Holds current position of first touchpoint in gesture sample.
    Public ReadOnly Property Position() As Vector2
        Get
        End Get
    End Property

    ' Holds current position of second touchpoint in gesture sample.
    Public ReadOnly Property Position2() As Vector2
        Get
        End Get
    End Property

    ' Holds span of time represented by multitouch gesture sample.
    Public ReadOnly Property Timestamp() As TimeSpan
        Get
        End Get
    End Property
End Structure

 

Meskipun Windows Phone 7 mendukung minimal 4 touch point secara bersamaan, gesture system yang termasuk didalamnya saat ini tidak mengunakan atau mendukung lebih dari dua buah touch points.

Sekarang masukkan Select Case Statement berikut ini di bawah baris yang membaca TouchPanel, untuk menangani setiap nilai yang dikembalikan oleh gesture.GestureType

Select Case gesture.GestureType

End Select

clip_image014

Tap

Gestures sentuhan/ touch gestures yang paling sederhana, sebuah tap terdiri dari satu sentuhan pendek pada layar. Ini sama dengan aksi meng-klik (click action) pada Windows.

Untuk mendukung Tap gestures, masukkan blok code berikut:

Case GestureType.Tap
     message = "Ini Tap"
     color = color.Red

clip_image015

Double Tap / Tap Ganda

Untuk mengaktifkan gestures ini, user diharuskan men-tap layar sebanyak dua kali dengan cepat. Double Tap gesture selalu diawali dengan sebuah Tap gestures pada lokasi yang sama. Apabila value TimeSpan antara Tap terlalu jauh, gestures DoubleTap tidak akan terdeteksi

Case GestureType.DoubleTap
     Message = "Ini Double Tap"
     color = color.Orange

clip_image016

Hold

Hold Ini bekerja mirip dengan single Tap, bedanya anda menekan layar-nya sekitar 1 detik sebelum akhirnya melepaskannya atau menggerakkan jari anda. Dalam game, gestures ini mungkin digunakan untuk menyediakan konteks menu pada suatu unit yang spesifik, seperti yang bertentangan dengan Tap gesture, yang mana mungkin akan digunakan untuk memilih unit-nya. Untuk mendukung Hold gesture, masukkan blok code berikut didalam select case blok :

Case GestureType.Hold
     message = "That was a Hold"
     color = Color.Yellow

clip_image017

Horizontal Drag

Gesture ini mirip dengan Tap gesture, akan tetapi disini anda tidak melepaskan jari anda kemudian anda memindahkan jari anda yg masih tertempel pada layar secara horizontal ( terserah mau dari kiri ke kanan atau dari kanan ke kiri). Masukkan code berikut untuk mendukung Horizontal Drag gesture:

Case GestureType.HorizontalDrag
     message = "Ini Horizontal Drag"
     color = color.Blue

clip_image018

Vertical Drag

Vertical Drag gesture bekerja hampir sama dengan cara Horizontal Drag gesture, bedanya Vertical Drag menggunakan gerakan vertical ( dari bawah ke atas atau dari atas ke bawah).

Masukkan blok code berikut untuk mendukung Vertical Drag gesture :

Case GestureType.VerticalDrag
     message = "That was a Vertical Drag"
     color = Color.Indigo

clip_image019

Pada games yang memiliki fitur touch screen, Drag gestures biasanya digunakan untuk menggerakkan suatu unit dari satu tempat ke tempat lainnya, yang menunjukkan pengaturan sliding / penggeseran, menarik garis, dan lainnya.

Pada saat menggunakan Drag gesture, ingatlah bahwa hanya gerakan awal yang dibutuhkan untuk merekam gesture tersebut. Bila anda menggunakan Vertical Drag gesture dan kemudian sebuah Horizontal Drag gesture tanpa melepaskan jari anda diantara mereka, hanya satu GestureSample yang akan dihasilkan,yang mengadung data untuk gesture pertama. Ini juga berlaku pada Free Drag gesture.

Free Drag

Anda menjalankan Free drag gesture dengan menyentuh layar dan menggerakkan jari anda dalam sebuah gerakan bebas ( seperti menggambar lingkaran). Masukkan blok code berikut untuk mendukung Free Drag gesture :

Case GestureType.FreeDrag
     message = "ini Free Drag"
     color = color.Green


clip_image020

Saat coding mendukung Free Drag gesture pada game anda, pikirkanlah dengan cermat bagimana anda akan menggunakannya, dan apakah juga untuk mendukung HorizontalDrag dan VerticalDrag gestures. Bila tujuan utama anda adalah untuk memperbolehkan menggambar pada game anda, anda dapat melakukannya cukup hanya dengan mendukung Free Drag gesture

Drag Complete

Drag Complete gesture akan dihasilkan saat salah satu dari Drag gestures telah terselesaikan ( dengan melepaskan Touch Location-nya). Gesture Type ini diadakan hanya untuk menunjukkan selesainya Drag gesture tersebut. Tidak ada Position atau Delta data lainnya yang disediakan untuk tipe ini.

Untuk mendapatkan notifikasi pada saat salah satu dari gesture berbasis Drag tersebut telah terselesaikan, masukkan blok code berikut ini pada Select Case statement :

Case GestureType.DragComplete
     Message = "Drag gesture complete"
     color = color.Gold


clip_image021

Flick

Anda melakukan Flick gestures dengan menyentuh layar dan membuat sebuah ayunan cepat menuju arah mana pun. Tak ada data posisional yang dihasilkan dari Flick gesture, sehinggai membuatnya berpotensi terbatas untuk games. Tapi anda dapat menggunakannya untuk menggerakkan view yang ada pada game anda, mungkin untuk menjelajah pada sebuah peta dunia yang besar. Penggunaan lainya adalah untuk men-scroll teks. Anda bisa mendapatkan tempo kecepatannya dengan membaca properti Delta dari Gesture Sample yang dihasilkan dan kemudian meng-apply nya sebagai bantuan untuk kalkulasi anda. Masukkan blok code berikut ini untuk menyediakan dukungan untuk Flick gesture :

Case GestureType.Flick
     message = "ini Flick"
     color = Color.Violet

clip_image022

 

Pinch

Semua gesture yang telah dibahas di atas adalah single-finger gestures.

Pinch gestures membutuhkan dua jari, dengan keduanya menyentuh layar dan kemudian menggerakkannya mendekati atau menjauhi satu sama sama lain. Pinch dianggap sama seperti dengan two-finger drag secara internal dan mengutamakan gestures berbasis Drag dengan menggunakan dua jari. Pinch gestures tersebut biasanya digunakan untuk men-zoom in atau men-zoom out. Hal ini dilakukan dengan menyentuh layar menggunakan dua buah jari dan menggeser nya terpisah untuk men-zoom in atau dengan mempertemukan ke duanya untuk men-zoom out.

Untuk menambahkan dukungan untuk Pinch gesture, masukkan blok code berikut didalam Select case statement anda :

Case GestureType.Pinch
     message = "ini Pinch"
     color = color.Violet

clip_image023

Pinch Complete

Sama seperti gesture berbasis Drag dan pelengkapnya yaitu Drag Complete gesture, Pinch memiliki gesture yang sama. PinchComplete gesture tidak menghasilkan Position atau data Delta apapun. Ini digunakan hanya untuk menandakan selesainya Pinch gesture, tanpa memperdulikan arah dari pinch tersebut.

Case GestureType.PinchComplete
      message = "Pinch gesture complete"
      color = Color.Silver

clip_image024

Melihat Hasil

karena sekarang anda sudah memasukkan semua nya ke sampel, sekarang adalah saatnya untuk memasukkan code yang dapat membuat anda bisa melihat hasil dari aksi gesture anda.

Masukkan baris kode berikut kedalam if statement, tepat setelah end select statement :

messagePos = gesture.Position

Variabel dari messagePos digunakan untuk menyimpan posisi gesture pada saat ini yang akan digunakan pada saat menciptakan message pada layar. Untuk melihatnya bekerja, buka Draw() dan masukkan block code berikut tepat sebelum MyBase.Draw(gameTime) :

spriteBatch.Begin()
spriteBatch.DrawString(spriteFont, message, messagePos, color)
spriteBatch.End()


clip_image025

Selesai!

Tekan F5 untuk menjalankan kode tersebut dan cobalah untuk menjalankan gesture yang anda telah tetapkan. Bila anda menggunakan Emulator, beberapa gestures mungkin akan sedikit lebih sulit untuk dilakukan dibanding dengan yang lain, terutama Flick dan Pinch.

Posted by Luki Ishwara | 1 comment(s)
Filed under: ,

15. Contoh Programming Multi Touch pada Windows Phone

Source Code Project ini dapat didownload di sini

Bahasa pemrograman menggunakan Visual Basic .Net dan XNA Framework 4.0

Mulailah dengan membuat sebuah proyek game yang baru, dan namakan MultiTouchMe

clip_image002

Seperti biasa, kita akan diminta untuk memilih os, pilih Windows Phone OS 7.1

clip_image003

Klik kanan pada Project Content (MultiTouchMeContent), pilih add, kemudian pilih new item

clip_image004

Kemudian Masukkan sebuah SpriteFont pada ProjectContent.

clip_image006

Biarkan nama tersebut SpriteFont1, tetapi ubahlah ukurannya huruf menjadi 20 untuk membuat teks anda lebih bisa terbaca.

clip_image007

Deklarasikan variabel ini pada game:

Private spriteFont As SpriteFont

 

Private touchCollection As TouchCollection


clip_image008

Berikutnya, masukkan baris berikut ini pada method LoadContent() untuk me-load SpriteFont anda ke memory :

spriteFont = Content.Load(Of SpriteFont)("SpriteFont1")


clip_image009

Pada method Update(), masukkan kode berikut sebelum MyBase.Update

touchCollection = TouchPanel.GetState()


clip_image010

Terakhir, didalam method Draw(), masukkan code berikut ini tepat sebelum MyBase.Draw()

 spriteBatch.Begin()

 

        For Each touch As TouchLocation In touchCollection

 

            spriteBatch.DrawString(spriteFont, "ID: " &

 

                                   touch.Id.ToString() &

 

                                   " (" & CInt(touch.Position.X) &

 

                                   "," & CInt(touch.Position.Y) &

 

                                   ")", touch.Position, Color.White)

 

        Next touch

 

spriteBatch.End()


clip_image011

Selesai, tekanlah F5 untuk menjalankan code ini pada Emulator.

Saat anda menjalankan code tersebut, klik / sentuhlah layar-nya dan tahan. Anda akan melihat sebuah angka pada touch point anda. Lepaskan dan klik / sentuhlah lagi di tempat lainnya pada layar. Angka tersebut yang anda lihat adalah properti ID dari TouchLocation

Sentuh / kliklah layar tersebut sekali lagi. Kali ini, tanpa melepaskan sentuhan nya, drag ke seluruh layar. Lihatlah bagaimana angka Id tidak berubah, walaupun kordinat Lokasi jelas berubah.

Ini merupakan sebuah konsep penting, dan hal tersebut mengilustrasikan perbedaan utama antara TouchLocationState.Pressed dan TouchLocationState.Moved states. Walaupun properti Position dari TouchLocation berubah, tapi objek TouchLocation tetap sama — sampai pada akhirnya anda melepaskannya.

Sentuh layar tersebut beberapa kali lagi. Lihatlah bagaimana angka Id terus meningkat sebesar 65536 setiap kalinya. Alasannya berhubungan dengan struktur internal atas bagaimana objek TouchLocation terisimpan. Akan tetapi hal tersebut tidaklah penting, karena anda sebaiknya tidak bergantung pada angka-angka ini untuk dan dalam hal apapun — selain untuk membandingkan-nya dengan TouchLocation ID yang lainnya untuk memastikan bahwa mereka berbeda satu sama lain.

Menjalankan project ini pada Emulator hanya memberikan anda sebuah touch point. Akan tetapi, bila anda menjalankan code tersebut pada windows phone 7 anda, anda dapat melihat beberapa touch point di layar pada waktu yang bersamaan, masing- masing dengan Id unik nya.

Satu hal yang menarik untuk diingat mengenai Emulator tersebut ialah apabila anda memiliki layar multitouch, Emulator tersebut akan merespon input multitouch.

Posted by Luki Ishwara | with no comments
Filed under: ,

14. Contoh Programming Single Touch pada Windows Phone

Source Code Project ini dapat di download disini

Contoh Code Menggunakan VB.NET dan XNA Framework 4.0

Video Demo Project bisa dilihat disini

Mulailah dengan membuat project baru Windows Phone Game

clip_image002[4]

Setelah itu pilih versi target windows phone OS, pilih Windows Phone OS 7.1 dan klik OK

clip_image003[4]

Kemudian tambahkan sebuah image pada Content proyek anda. Terserah image apa yang anda gunakan, asalkan masih dalam format jpeg, png, atau gif, cukup simetris, dan berukuran kecil (kurang dari 200 x 200 pixels).

Caranya klik kanan pada DetectTouchContent, pilih Add, pilih Existing Item

clip_image005[4]

Kemudian pilih file gambarnya, kebetulan saya sudah menyiapkan logo.png di my documents saya, klik file logo dan klik tombol Add

clip_image007[4]

Masukkan tiga variabel berikut ini pada declaration class level:

Private logo As Texture2D

 

Private logoPosition As Vector2

 

Private displayLogo As Boolean

clip_image008[4]

Berikutnya, tambahkan baris ini pada method LoadContent() untuk meload sprite anda di memory:

logo = Content.Load(Of Texture2D)("logo")

clip_image009[4]

Baris kode berikutnya akan mendapatkan state (keadaan) saat ini dari touch screen tersebut.

Letakkan ini pada method Update(), sebelum MyBase.Update:

Dim touchCollection = TouchPanel.GetState()

clip_image010[4]

Setelah itu, masukkan potongan kode berikut ini untuk membaca touch data dari masing-masing object TouchLocation pada Collection tersebut, memeriksa state (keaadaannya) seiring anda mengganti titik dimana layar device disentuh:

For Each touch As TouchLocation In touchCollection

 

            If (touch.State = TouchLocationState.Pressed) OrElse

 

                (touch.State = TouchLocationState.Moved) Then

 

                ' update a sprite to be drawn at the touch location

 

                logoPosition.X = touch.Position.X

 

                logoPosition.Y = touch.Position.Y

 

            End If

 

Next touch

clip_image011[4]

Anda mungkin bertanya-tanya dengan hanya adanya dua buah states (touch.State = TouchLocationState.Pressed dan touch.State = TouchLocationState.Moved) pada contoh diatas, tetapi daftar TouchLocationState tersebut sebenarnya memiliki 4 buah values yang memungkinkan kondisi terjadi seperti berikut :

  • TouchLocationState.Invalid — Biasanya value ini muncul ketika sebuah lokasi sentuhan yang baru mencoba untuk mengakses state (keadaan) sebelumnya dari lokasi sentuhan itu sendiri.
  • TouchLocationState.Moved — Posisi dari lokasi sentuhan ini ter-update dari frame sebelumnya (atau secara terus- menerus ditekan pada posisi yang sama).
  • TouchLocationState.Pressed — Lokasi sentuhan ini baru mulai dari frame ini. Dimana tidak ada pada frame sebelumnya. Kalau anda mengangkat jari anda dan kemudian menyentuh pada posisi yang sama persis tetap menghasilkan sebuah lokasi sentuhan yang baru.
  • TouchLocationState.Released — Lokasi sentuhan ini ditekan pada frame yang sebelumnya, tetapi tidak lagi ditekan pada frame yang ini.

Blok kode sebelumnya mengatur koordinat x– dan y– sprite anda setara dengan touch point anda.

Bila anda lebih memilih untuk memusatkan sprite tersebut pada touch point anda, hal tersebut merupakan hal yang mudah. Cukup dengan temukan dua buah baris berikut ini :

logoPosition.X = touch.Position.X

 

logoPosition.Y = touch.Position.Y

clip_image012[4]

Ubahlah agar menjadi seperti ini:

logoPosition.X = touch.Position.X - (logo.Width \ 2)

 

logoPosition.Y = touch.Position.Y - (logo.Height \ 2)

clip_image014[4]

Tambahkan line berikut ini pada method Draw():

spriteBatch.Begin()

 

spriteBatch.Draw(logo, logoPosition, Color.White)

 

spriteBatch.End()

clip_image015[4]

Sprite anda seharusnya akan terbawa memusat pada touch point anda (titik dimana anda menyentuh layar device / mengklik layar emulator anda).

Saya katakan seharusnya, karena ini merupakan salah satu kasus yang mana pada saat bekerja menggunakan Emulator, berbeda dengan bekerja menggunakan device yang sesungguhnya.

Anda mungkin tidak memiliki komputer yang dilengkapi dengan monitor touchscreen. Ini berarti bahwa pada saat anda bekerja pada Emulator, anda mensimulasikan sentuhan-nya dengan menggunakan cursor mouse dan mengklik layar anda dimana anda ingin menyentuhnya.

Kecuali jika anda telah mengubah atau mengganti cursor anda dari default arrow, sentuhannya akan menjadi sedikit lebih kecil dibanding dengan jari manusia pada umumnya. Untuk menangani hal ini, anda dapat menentukan dan menambahkan sebuah offset di akhir dari kode posisi nya, seperti:

logoPosition.X = touch.Position.X - (logo.Width \ 2) + HorizontalOffset

 

logoPosition.Y = touch.Position.Y - (logo.Height \ 2) + VerticalOffset

dari percobaan yang sudah dilakukan, value bernilai 20 untuk offset vertical dan value bernilai 0 untuk offset horisontalnya, akan meletakkan point dari cursor sedekat mungkin pada centernya.

Jangan lupa deklarasikan variabel HorizontalOffset dan Variabel VerticalOffset

Dim HorizontalOffset = 0

 

Dim VerticalOffset = 20

clip_image016[4]

Kalau anda penasaran, boleh bereksperimen dengan menggunakan value anda sendiri, tetapi ingatlah untuk menonaktifkan offset-offset tersebut pada saat mendeploy aplikasi ini ke device windows phone, karena jika tidak anda akan menemukan beberapa keanehan :)

Bila anda menginginkan untuk membuat sprite tersebut (logo.png) terlihat hanya pada saat anda menyentuh layar, anda juga dapat melakukannya. Buatlah sebuah variabel Boolean pada class level (kita beri nama displayLogosaja) dan bawalah hanya bila benar. Lihatlah kode berikut ini:

        spriteBatch.Begin()

 

        If displayLogo Then

 

            spriteBatch.Draw(logo, logoPosition, Color.White)

 

        End If

 

        spriteBatch.End()

Tentu saja, untuk menyelesaikan pekerjaan ini anda pertama-tama diharuskan untuk memasukkan beberapa kode lagi pada method Update().

For Each loopanda akan menjadi sedikit lebih besar. Lengkapi Method Update anda dengan kode seperti dibawah ini :

Protected Overrides Sub Update(ByVal gameTime As GameTime)

 

        ' Allows the game to exit

 

        If GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed Then

 

            Me.Exit()

 

        End If

 

        ' TODO: Add your update logic here

 

        Dim touchCollection = TouchPanel.GetState()

 

        Dim HorizontalOffset = 0

 

        Dim VerticalOffset = 20

 

        For Each touch As TouchLocation In touchCollection

 

            If (touch.State = TouchLocationState.Pressed) OrElse

 

                (touch.State = TouchLocationState.Moved) Then

 

                ' kalau layar dipencet atau di drag logo akan di tampilkan

 

                logoPosition.X = touch.Position.X - (logo.Width \ 2) + HorizontalOffset

 

                logoPosition.Y = touch.Position.Y - (logo.Height \ 2) + VerticalOffset

 

                displayLogo = True

 

            End If

 

            ' kalau pencetan dilepas, maka logo akan menghilang dari layar

 

            If touch.State = TouchLocationState.Released Then

 

                displayLogo = False

 

            End If

 

        Next touch

 

        MyBase.Update(gameTime)

 

    End Sub

Nah setelah selesai, silakan anda run project ini, dan coba klik layar emulator anda, maka di titik mana anda mengklik maka logo tersebut akan muncul.

Contoh diatas adalah contoh single touch pada layar device windows phone,

untuk mendeteksi multi touch, saya akan memberikan contoh lain pada postingan selanjutnya.

Posted by Luki Ishwara | with no comments
Filed under: ,

13. Mendeteksi Touch Input pada windows phone

Semua yang anda butuhkan untuk menggunakan touch input pada game di Windows Phone 7 dapat anda temukan di namespace Microsoft.Xna.Framework.Input

Untuk membaca touch input, anda diharuskan untuk memanggil TouchPanel.GetState pada bagian Update dari loopgame.

Pemanggilan TouchPanel.GetState ini menghasilkan sebuah TouchCollection yang didalamnya terdapat objek TouchLocationuntuk setiap sentuhan yang terdeteksi pada saat itu.

Bila anda sudah memiliki TouchCollection, anda dapat men-loop masuk dan membaca semua properti- properti atas setiap objek TouchLocation untuk menemukan keadaan dan lokasi object tersebut.

Fakta yang menyatakan bahwa TouchPanel.GetState() menghasilkan sebuah objek KeyboardState merupakan salah satu dari ketidak konsistenan kecil yang agak aneh pada framework XNA 4.0.

Keyboard.GetState() menghasilkan sebuah objek KeyboardState.

Gamepad.GetState() menghasilkan sebuah objek GamepadState .

Mungkin saja ada alasan masuk akal yang menjelaskan mengapa TouchPanel.GetState() menghasilkan TouchCollection, dimana saya menduga seharusnya TouchPanel.GetState() akan menghasilkan sebuah objek TouchPanelState.

Pada postingan berikutnya, anda akan belajar bagaimana cara mendapatkan kondisi (state) dari touchpanel anda dan kemudian melakukan looping masuk melalui collection dari touch points.

kemudian, anda akan mengecek untuk melihat apakah keadaan (state) dari salah satu touch points tersebut sama dengan Pressed atau Moved.

Terakhir, anda akan belajar cara meng-update lokasi dari sprite onscreen, berdasarkan pada lokasi sentuhan anda.

Posted by Luki Ishwara | with no comments
Filed under: ,

12. Touch Input Windows Phone 7

nokia-lumia-latest-smartphone-reviewTouch input merupakan bagian vital dari user experience (UX) Windows Phone 7, dan kapasitas untuk mendukung sampai dengan 4 touch points secara bersamaan memberikan anda begitu banyak opsi untuk pengembangan game.

Sekarang, anda akan belajar bagaimana untuk mendeteksi dan merespon kepada touch input dalam bentuk yang sederhana sampai pada gestrures yang lebih rumit. Anda juga akan belajar bagaimana untuk membuat gestures anda sendiri. Juga pada bab ini terdapat sebuah pengujian atas beberapa latihan- latihan terbaik untuk menjadi referensi pada saat anda mendesain games berbasis touch screen milik anda sendiri.

Sebelumnya, salah satu dari rintangan terbesar dalam mengembangkan games untuk ponsel adalah tidak ada nya kemampuan untuk memprediksi pada tipe hardware apakah mobile game anda akan berjalan.

Device Windows Mobile pun dulu tidak menjadi jaminan memiliki standar hardware :). Beberapa device ada yang memiliki dua tombol pada bagian depan, dan device lain ada yang memiliki enam tombol yang tersebar pada device tersebut.

Dengan hadirnya Windows Phone 7, masalah ini telah terhapuskan. Meskipun Microsoft menyediakan para produsen device mobile phone beberapa fleksibilitas yang terbatasi dalam faktor bentuk, pengalaman menggunakan secara keseluruhannya tersebut konsisten dan dapat diprediksi dari satu device ke device yang berikutnya.

Touch screen menawarkan begitu besar dan banyaknya fleksibilitas, dan bagaimana cara anda menggunakannya, semuanya bergantung pada anda. Anda dapat membuat skema kontrol game anda sesimple mungkin atau serumit mungkin sebagaimana layaknya untuk game anda.

Touch-based interfaces sebenarnya sudah ada sekitar tiga perempat abad lamanya, dengan implementasi sederhana yang muncul pada pertengahan tahun 1940. IBM menciptakan layar yang dapat menerima multi-touch untuk pertama kalinya di akhir- akhir tahun 1960.

Walaupun klaim Apple pada tahun 2007 yang menyatakan bahwa “apple menemukan multi touch” dengan iPhone–nya merupakan kebohongan marketing, Apple dapat mengambil credit atas pembuatan mainstream multitouch Gaming devices portabel, dan tentunya ponsel.

Posted by Luki Ishwara | with no comments
Filed under:

11. Contoh Programming dengan memanfaatkan Accelerometer

Berikut ini kita akan belajar bagaimana mendeteksi pergerakan dengan memanfaatkan sensor akselerometer.

Source Code bisa di download disini

Video hasil project bisa dilihat disini

Buatlah sebuah proyek Windows phone Game (4.0) yang baru, dan namakan AccelerometerSample.

clip_image002

Kemudian pilih versi OS mobile phone, dan klik OK

clip_image003

Tambahkan satu SpriteFont, dengan cara klik kanan pada bagian content di solution explorer

clip_image004

Masukkan sebuah SpriteFont yang bernama readings.spritefont ke proyek AccelerometerSampleContent anda sehingga anda dapat menampilkan bacaan akselerometer anda pada layar.

clip_image006

Seperti biasa, Atur ukuran fontnya menjadi 20.

clip_image007

saat menambahkan content external, pastikan anda deklarasikan variabel class-level untuk SpriteFont anda, seperti yang ditunjukkan disini :

Private readingsFont As SpriteFont

clip_image008

Sekarang, modifikasikan method LoadContent()untuk memproses font anda pada memory:

readingsFont = Content.Load(Of SpriteFont)("readings")

clip_image010

Sebelum anda memulai menuliskan suatu kode akselerometer, tambahkanlah sebuah referensi untuk namespace Microsoft.Devices.Sensors

clip_image012

Klik Project -> Add Reference

Tambahkan Reference Microsoft.Devices.Sensors

clip_image014

Setelah itu tambahkan deklarasi pada class Game1.vb

Imports Microsoft.Devices.Sensors

clip_image015

Setelah itu deklarasikan variabel accelerometer

Private accelerometer As Accelerometer

clip_image016

Akselerometer tersebut mengekspos properti dari X,Y, dan Z yang mana menyimpan akselerasi untuk arah- arah tersebut. Masukkan variabel class-level berikut untuk menyimpan nilai-nilai tersebut untuk digunakan pada proyek AccelerometerSample :

Private X As Double

 

Private Y As Double

 

Private Z As Double

clip_image017

Anda diharuskan untuk membentuk Accelerometer class tersebut, maka masukkanlah baris ini pada Initialize() method dari Game1 class anda :

accelerometer = New Accelerometer

clip_image018

Pada saat ini anda memiliki sebuah objek akselerometer dalam memory, akan tetapi anda belum bisa melakukan apapun dengan object tersebut.

Anda diharuskan untuk menyiapkan sebuah event handler untuk event ReadingChanged()-nya.

Anda akan melakukan hal ini juga pada method Initialize()tersebut, tepat di sebelah kode yang baru saja anda ketik:

AddHandler accelerometer.ReadingChanged, AddressOf AccelerometerReadingChanged

clip_image019

Dengan terdefinisikannya event handler tesebut, Visual Studio akan menunjukkan anda akan suatu error yang menyatakan bahwa AccelerometerReadingChanged() method belum ada. Tapi itu tidak apa- apa, karena anda akan mebuatnya sekarang.

Private Sub AccelerometerReadingChanged(ByVal sender As Object, ByVal e As AccelerometerReadingEventArgs)

 

    System.Windows.Deployment.Current.Dispatcher.BeginInvoke(Sub() NewReading(e))

 

End Sub

Masukkan method diatas kedalam class Game1.vb anda.

Seperti yang dikatakan sebelumnya, Method AccelerometerReadingChanged() tersebut akan terpanggil setiap kali sensor akselerometer-nya memiliki data baru.

Event handler tersebut dipanggil dari thread yang berbeda dan bukan dari thread game utama anda. Karena itu, anda diharuskan menggunakan Dispatcher class untuk menjalankan Method NewReading() pada thread utama game tersebut melalui AccelerometerReadingEventArgs sebagai suatu parameter.

Saat ini Visual Studio tidak mengetahui dimana untuk menemukan Deployment namespace, tetapi itu adalah hal yang mudah untuk diperbaiki.

Pada Visual Studio anda, klik menu Project, dan klik add reference

clip_image020

dan masukkan sebuah referensi pada System.Windows namespace.

clip_image021

Sekarang, masukkan statement berikut di bagian atas dari class Game1.vb anda:

Imports System.Windows

clip_image022

Anda masih meemiliki suatu error pada saat ini, dikarenakan Visual Studio tidak mengetahui apa atau dimana method NewReading()

Tambahkan baris code ini ke class Game1.vb anda

Private Sub NewReading(ByVal e As AccelerometerReadingEventArgs)

 

        X = e.X

 

        Y = e.Y

 

        Z = e.Z

 

End Sub

clip_image023

Pada method ini, anda mengambil nilai-nilai yang dikembalikan dan meletakkan-nya pada variabel yang telah anda buat sebelumnya.

Sekarang kita akan membuat si Accelerometer dapat menampilkan nilai-nilai X, Y, Z sesuai dengan gerakan yang dideteksinya, nah silakan tambahkan code:

accelerometer.Start()

pada method Initalize()

clip_image024

Untuk mendemonstrasikan akselerometer dan menunjukkan bagaimana mendapatkan nilai dari akselerometer tersebut, anda akan melakukan sesuatu disini yang normalnya tidak anda lakukan pada game anda.

Untuk meminimalisasikan penggunaan baterai dan memaksimalkan kinerja, nyalakanlah akselerometer hanya pada suatu saat dari game dimana anda secara spesifik memerlukan akselerometer untuk mendapatkan nilainya. Jika ternyata tidak butuh akselerometer, biarkanlah saja seperti biasa.

Masukkan baris berikut ini pada Method UnloadContent()

accelerometer.Stop()

clip_image025

Satu-satunya pekerjaan kita yang tersisa adalah menampilkan koordinat X,Y,Z tersebut pada layar.

Sekarang, modifikasikanlah Method Draw()

Protected Overrides Sub Draw(ByVal gameTime As GameTime)

 

        GraphicsDevice.Clear(Color.CornflowerBlue)

 

        ' TODO: Add your drawing code here

 

        spriteBatch.Begin()

 

        spriteBatch.DrawString(readingsFont,

 

                               "X: " & X.ToString("0.00"),

 

                               New Vector2(50, 50),

 

                               Color.White)

 

        spriteBatch.DrawString(readingsFont,

 

                               "Y: " & Y.ToString("0.00"),

 

                               New Vector2(50, 75),

 

                               Color.White)

 

        spriteBatch.DrawString(readingsFont,

 

                               "Z: " & Z.ToString("0.00"),

 

                               New Vector2(50, 100),

 

                               Color.White)

 

        spriteBatch.End()

 

        MyBase.Draw(gameTime)

 

    End Sub

Okay sekarang sudah selesai, saatnya kita mencobanya.

image
image
Posted by Luki Ishwara | with no comments
Filed under: ,

10. Accelerometer Pada Windows Phone

Device Windows Phone memiliki sebuah sensor akselerometer yang mengukur dan mendeteksi gravitasi dan pergerakan. API Akselerometer sesungguhnya dibangun pada framework sensor yang umum. Ini berarti apabila ada sensor-sensor tambahan yang ditambahkan kemudian, cara mengaksesnya tidak akan jauh berbeda.

Pada XNA Framework, anda dapet mengakses sensor seperti accelerometer tersebut pada namespace Microsoft.Devices.Sensors

Class Accelerometer tersebut merupakan kunci untuk mengakses sensor akselerometer pada device windows phone anda. Kalau kita intip kedalam Class Accelerometer, kita akan melihatnya sebagai berikut:

Public NotInheritable Class Accelerometer

 

    Implements IDisposable

 

    ' Creates a new instance of the Accelerometer object.

 

    Public Sub New()

 

    End Sub

 

    ' Gets the current state of the accelerometer. The value is a member of

 

    ' the Microsoft.Devices.Sensors.SensorState enumeration.

 

    Public ReadOnly Property State() As SensorState

 

        Get

 

        End Get

 

    End Property

 

    ' Occurs when new data arrives from the accelerometer.

 

    Public Event ReadingChanged As EventHandler(Of AccelerometerReadingEventArgs)

 

    ' Releases the managed and unmanaged resources used by the Accelerometer

 

    Public Sub Dispose()

 

    End Sub

 

    ' Starts data acquisition from the accelerometer

 

    Public Sub Start()

 

    End Sub

 

    ' Stops data acquisition from the accelerometer

 

    Public Sub Stop()

 

    End Sub

 

    Public Sub Dispose() Implements System.IDisposable.Dispose

 

    End Sub

 

End Class

Method Dispose(),Start() dan Stop() dilihat dari namanya saja sudah cukup jelas fungsinya .

Properti dari ReadOnly State mengembalikan daftar SensorState yang mengandung salah satu dari enam value berikut :

  • NotSupported
  • Ready
  • Initializing
  • NoData
  • NoPermissions
  • Disabled

Event ReadingChanged tersebut muncul setiap kali sebuah data baru muncul dari sensor.

Objek AccelerometerReadingEventArgs tersebut yang masuk ke dalam handler anda dan menyediakan sarana untuk mengakses data akselerometer yang telah dikembalikan.

Sekarang coba kita intip isi dari Class AccelerometerReadingEventArgs

Public Class AccelerometerReadingEventArgs

 

    Inherits EventArgs

 

    ' A timestamp indicating the time at which the accelerometer reading was

 

    ' taken.

 

    Public ReadOnly Property TimeStamp() As DateTimeOffset

 

        Get

 

        End Get

 

    End Property

 

    ' The acceleration in the X direction.

 

    Public ReadOnly Property X() As Double

 

        Get

 

        End Get

 

    End Property

 

    ' The acceleration in the Y direction.

 

    Public ReadOnly Property Y() As Double

 

        Get

 

        End Get

 

    End Property

 

    ' The acceleration in the Z direction.

 

    Public ReadOnly Property Z() As Double

 

        Get

 

        End Get

 

    End Property

 

End Class

Property X, Y, dan Z tersebut masing- masing akan mengembalikan nilai bertipe Double dengan kisaran -2 sampai dengan 2 unit gravitasional, yang mengindikasikan arah akselerasi untuk masing-masing axis.

Unit (satuan) yang dbiasanya digunakan dalam menggambarkan akselerasi gravitasional adalah MilliGals. Sebuah Gal didefinisikan sebagai: 1 centimenter/detik2 , Nah Microsoft mendefiniskan Gal ini sebagai unit Gravitasional.

Gambaran di atas saya rasa cukup untuk menggambarkan class utama yang akan nanti digunakan. Nah berikutnya kita akan masuk kedalam contoh penggunaan accelerometer ini.

Posted by Luki Ishwara | with no comments
Filed under:

9. Area Title-Safe dari device windows phone

Project ini akan menampilkan sebuah panel merah pada area dimana sytem tray biasanya akan muncul. Dengan ini, anda dapat mengecek game anda untuk memastikan bahwa tidak ada informasi penting yang tertutupi pada saat anda menjalankan game anda.

Source Code pembahasan ini bisa anda download disini

Buatlah sebuah Project Windows Phone Game yang baru, dan namakan PhoneTitleSafe.

clip_image002

Pada Class Game1.vbanda, masukkan kode berikut di bagian deklarasi variabelnya :

Private titleSafe As Texture2D

image

Pada constructor, masukkan kode berikut untuk mengontrol apakah area title-safe tersebut ditampilkan pada game anda.

graphics.IsFullScreen = True

image

Disini saya tambahkan image dua dimensi berupa file png yang nama filenya PhoneTitleSafe.png berukuran 480x800 ke dalam Content

Pada method LoadContent(), masukkan baris berikut untuk men-load image PhoneTitleSafe yang anda masukkan kedalam project PhoneTitleSafeContent anda sebelumnya :

titleSafe = Content.Load(Of Texture2D)("PhoneTitleSafe")

image

Cukup itu saja. Coba lah jalankan project anda dan lihatlah pada layar.

Anda akan melihat sebuah panel merah pada bagian atas yang menandakan bahwa area tersebut adalah area title-safe yang aman untuk digunakan, dan karena kita melakukan set Graphics Full Screen, maka area system tray tertutup oleh area backbuffer (berwarna biru) dan area title-safe (bar merah). Tidak ada lagi area system tray yang tersedia.

clip_image009

Bar merah di atas akan digunakan oleh system tray

Sekarang, stop project tersebut dan kembalilah menuju kode. Ubah nilai dari graphics.IsFullScreen menjadi False.

graphics.IsFullScreen = False

image

Anda akan melihat system tray berada pada bagaian atas layar (dimana berisi signal bar dan informasi lainnya)

clip_image012

Gambar emulator dengan system tray di bagian atas

Sekilas, contoh-contoh ini mungkin terasa seperti pendekatan programming yang bolak balik, tapi saya maksudkan disini supaya anda memahami bahwa apabila ketika anda mendesain game untuk berjalan dengan system tray yang terlihat, sebaiknya anda mengembangkan dan melakukan test pada mode-full screen yang menampilkan area title-safe.

Posted by Luki Ishwara | with no comments
Filed under: ,

8. Mode Full-Screen pada Windows Phone

Pada saat mendesain sebuah Game XNA untuk Windows Phone 7, anda harus memperhitungkan sistem tray anda. Ini merupakan area dengan lebar dan tinggi 480 x 32 pixel pada bagian atas layar anda (di mode Portrait), dan system tray ini menyediakan status dari berbagai macam hal seperti kekuatan sinyal, baterai, status charging, apakah device windows phone 7 berada pada airplane mode, dan lainnya. Semuanya terserah kepada anda sebagai developer game untuk menentukan apakah anda ingin membuat area ini dapat terlihat pada saat game anda sedang aktif atau tidak.

Defaultnya, game anda akan berjalan pada mode full-screen, yang berarti system tray akan tersembunyi, dan banyak games yang melakukan hal ini. Mempertahankan sebuah system tray yang visible (atau dapat terlihat) pada saat game anda sedang berjalan cukuplah mudah. Cukup masukkan kode berikut pada constructor pada class Game1.vb anda :

graphics.IsFullScreen = False

Saat anda menjalankan game anda, system tray tersebut akan berada di bagian atas. Karena itu, sebaiknya anda tidak meletakkan informasi penting apapun pada bagian itu, karena player game anda tidak akan bisa melihatnya.

Belakangan ini, pengembang Xbox Live Indie Games (XBLIG) telah membuat sebuah sample code yang disebut dengan Safe Area Sample.

sample code ini digunakan untuk melihat title-safe area tersebut (area yang dijamin dapat terlihat) pada monitor dan layar TV.

Mengingat semua device Windows Phone 7 diharuskan untuk memilih salah satu dari dua resolusi yang konsisten (480 x 800pixels atau 320 x 480 pixels), tentunya akan sangat mempermudah anda.

Tapi apabila anda menginginkan untuk tetap membuat system tray tersebut terlihat pada saat game play atau pada saat game berlangsung, anda mungkin saja ingin memasukkan sebuah Safe Area Sample kedalam baris code anda.

Posted by Luki Ishwara | with no comments
Filed under: ,

7. Mendeteksi Orientasi Device Windows Phone

Kapanpun orientasi device windows phone anda berubah (ketika anda bolak balik device anda, Accelerometer akan menyesuaikan orientasi device anda), event GameWindow.OrientationChanged akan bangkit (raised). Dan, apabila anda memasukkan orentasi yang baru tersebut kedalam properti SupportedOrientations, graphic device akan ter-reset untuk mendukung orientasi baru.

Kapan pun anda ingin memeriksa orientasi windows phone anda pada saat itu, properti CurrentOrientation dari class GameWindow akan mengembalikan nilai dari enumeration DisplayOrientation.

Class GameWindow tersebut akan terekspos sebagai sebuah Window pada game XNA anda. Sehingga, kode yang digunakan untuk mengecek properti CurrentOrientationpada game anda akan ditunjukkan seperti pada potongan code sebagai berikut :

If Window.CurrentOrientation <> DisplayOrientation.Portrait Then

 

' letakkan perintah-perintah yang ingin anda lakukan disini

 

End If


Untuk melihatnya berjalan, kembalilah pada project RotationSample dan modifikasi method Draw(), seperti yang ditunjukkan pada Listing dibawah ini:

Protected Overrides Sub Draw(ByVal gameTime As GameTime)

 

        GraphicsDevice.Clear(Color.CornflowerBlue)

 

        ' TODO: Add your drawing code here

 

        spriteBatch.Begin()

 

        spriteBatch.DrawString(rotationFont,

 

                               "Orientasi : " & Window.CurrentOrientation.ToString() & ".",

 

                               New Vector2(50, 50),

 

                               Color.White)

 

        spriteBatch.End()

 

        MyBase.Draw(gameTime)

 

        graphics.IsFullScreen = False

 

    End Sub

Sekarang, coba anda build project anda dan jalankan, anda akan melihat teks nya berubah pada saat orientasi anda ubah.

Berikut adalah tips yang membantu saat berhadapan dengan orientasi device:

Gunakan properti DeviceOrientasi dari Class GraphicsDevice.PresentationParameters untuk memeriksa bagaimana game anda ditampilkan.

clip_image002

Orientasi Portrait

clip_image004

Orientasi Landscape Right

clip_image006

Orientasi Landcape Left

Posted by Luki Ishwara | with no comments
Filed under: ,
More Posts Next page »