Completing the Casual Game Move from QML to XNA

In my last post, I discussed how to build the “Kolobok” main
character in our casual game for Windows Phone 7 from the Kolobok.qml file from
the Symbian phone version.  I also
discussed the method my team used to animate the fire obstacle by rotating
through a list of texture images at a set frame rate.

In this blog, I will finish up the application by showing
how to map the QML MouseArea inputs for the navigation buttons into the input
handlers for the XNA game object. Next I will discuss how to play the sounds
associated with Kolobok’s movement and collision with obstacles.

Input in the QML version of the application is strictly
event driven. Normally we would place button images on the screen in the game
board object and over a MouseArea to catch a user mouse event using an
“anchors.fill” property. This would work for individual buttons but would not
detect two buttons pressed at the same time. For this we need a MouseArea that
would handle Multi-touch events.

QML does not have a predefined element for multi-touch,
however the C QDeclarativeItem provides multi-touch input events. Therefore
we chose to implement a QDeclarativeItem multi-touch object in C and bind it
to QML as a new element. To simplify the implementation we combined the image
and multi-touch elements into one element called MultiTouchItem that has an
image source property and delivers user events as pressed() and released()
signals. These signals are directly connected to the Kolobok characters key handling
methods.

In Windows Phone 7 we will use the event handling methods
and implement the multi-touch events as synchronous tests in the game object’s
Update method. Multi-touch inputs will be passed onto the Kolobok character
game piece’s KeyPressed and KeyReleased methods.

For each game action button in the QML game, we create a
MultiTouchItem object that overrides the QDeclarativeItem::sceneEvent method
and catches the QEvent::TouchBegin and QEvent::TouchEnd events.  The object also catches the Mouse Press and
Mouse Release events in case a non-touch screen input device is used. The
screenEvent method is shown below:

bool MultiTouchItem::sceneEvent(QEvent *event)

{

    switch (event->type()) {

    case QEvent::TouchBegin:

        emit pressed();

        break;

    case QEvent::TouchUpdate:

        break;

    case QEvent::TouchEnd:

        emit released();

        break;

    case QEvent::GraphicsSceneMousePress:

        emit pressed();

        break;

    case QEvent::GraphicsSceneMouseRelease:

        emit released();

        break;

    default:

        return QDeclarativeItem::sceneEvent(event);

    }

    return true;

}

The events emit the appropriate released() or pressed()
signals that are communicated to the Kolobok Element .

In the XNA Game object Update() method, we call the
buttonEvent() method that will poll for multi-touch input and then call the
input methods in the Kolobok.cs file. Multi-touch input is collected in a
TouchCollection container object that can be read using the touch panels
GetState() method. The buttonEvent method is shown below:

void buttonEvent()

        {

            // Windows phone controls

            TouchCollection state = TouchPanel.GetState();

            foreach(TouchLocation
tl in state)

            {

               
// Handle key pressed

               
if (tl.State == TouchLocationState.Pressed)

               
{

                   
if (positonInArea(tl.Position,
closeBtnArea))

                        this.Exit();

                   
else if
(positonInArea(tl.Position, leftBtnArea))

                        gameBoard.keyPressed(GameBoard.Key.Left);

                   
else if
(positonInArea(tl.Position, rightBtnArea))

                        gameBoard.keyPressed(GameBoard.Key.Right);

                   
else if
(positonInArea(tl.Position, upBtnArea))

                        gameBoard.keyPressed(GameBoard.Key.Up);

               
}

               
// Handle key released

               
else if
(tl.State == TouchLocationState.Released)

               
{

                   
if (positonInArea(tl.Position, leftBtnArea))

                        gameBoard.keyReleased(GameBoard.Key.Left);

                   
else if
(positonInArea(tl.Position, rightBtnArea))

                        gameBoard.keyReleased(GameBoard.Key.Right);

                   
else if
(positonInArea(tl.Position, upBtnArea))

                        gameBoard.keyReleased(GameBoard.Key.Up);

               
}

               
else if
(tl.State == TouchLocationState.Moved)

               
{

                   
TouchLocation previous;

                   
if (!tl.TryGetPreviousLocation(out previous))

                        return;

                   
if (positonInArea(previous.Position,
leftBtnArea) &&

                       
!positonInArea(tl.Position, leftBtnArea))

                        gameBoard.keyReleased(GameBoard.Key.Left);

                   
else if
(positonInArea(previous.Position, rightBtnArea) &&

                       
!positonInArea(tl.Position, rightBtnArea))

                        gameBoard.keyReleased(GameBoard.Key.Right);

             
      else
if (positonInArea(previous.Position, upBtnArea)
&&

                       
!positonInArea(tl.Position, upBtnArea))

                        gameBoard.keyReleased(GameBoard.Key.Up);

               
}

            }

 

        }

 

In both the QML and XNA versions of the game, we pass inputs
from the touch device into the Kolobok object’s input methods, and then call its
doMovement() method to update the Kolobok’s position on the screen and respond
to any collisions with other game pieces.

Once we handle input and process game action, the only thing
left to do is play the game sounds and music for each game action.

In the QML game, we create a SoundPlayer object that
contains QAudioPlayer objects from the multimedia APIs in Qt Mobility. The
SoundPlayer contains audio files that play the various sounds depending on the
type of game action. The two main sounds are “Groan” and “Boing” generated when
the Kolobok experiences health decreasing events or collisions with another
game piece.

Sound player APIs are usually very similar and easy to use.
We create the object, set the format, load the sound file, and when we are
ready, call the play or start method.  For QML we create a QAudioPlayer and a
QMediaFormat object. We then set the Format object’s media attributes, bind it
to the Player object, and then call play. The code looks something like this:

QAudioFormat m_format;

m_format.setSampleRate(22050);

m_format.setChannelCount(1);

m_format.setSampleSize(16);

m_format.setCodec("audio/pcm");

m_format.setByteOrder(QAudioFormat::LittleEndian);

m_format.setSampleType(QAudioFormat::SignedInt);

m_boingOutput = new QAudioOutput(m_format,this);

m_boingtFile.setFileName(":/sounds/boink.raw");

 

if (m_boingOutput)

    if (collided) {

        if(m_boingPlaying) return;

        m_boingOutput->start(&m_boingtFile);

        m_boingPlaying = true;

         }

For XNA we use a SoundEffect object
to accomplish the same thing. The following code provides support for the Boing
sound above:

SoundEffect boingSound = content.Load<SoundEffect>("sound/boink");

if (boingSound != null)

   if (collided) boingSound.Play();

 

Note that the SoundEffect object
doesn’t require us to set the format of the file. The reader figures this out
from the content .Load method. Once we know how to generate the sounds, we can
trigger them from the collision detection code discussed in the previous blog.

This posting completes my blog series
on reengineering a QML casual game to XNA. Next week I will begin the steps
necessary to port a simple twitter application to Silverlight.

Updated SVG2Go and PlayBook Icon Maker now live!

Finally I got some time to do the most requested updates to our online icon makers, SVG2Go for Symbian devices and PlayBook Icon Maker.

They are really helping a lot of developers and we have been receiving many suggestions and appreciation from around the world. And we thank all you all.

We have so far 1800+ SVG-Tiny icons created for Symbian apps, and they include icon for games like Angry Birds Free version as well. And 2700+ icon for the PlayBook apps.

There are two major new things in this update.

  1. Option to enable a background fill color. This is also useful when you are dealing with a transparent icon which is hard to see on that checker-box in the preview area.
  2. Icon selection box and loaded image is opened centered by default. We have noticed many users confused that the selection box doesn’t move from the top-right corner. Well, it does and user can use Arrow Keys to fine –tune the selection.

Click the screenshots below to start SVG2Go for Symbian or Icon Maker for PlayBook.

iconmaker-svg2go

iconmaker-playbook

Do let us know what you think about these new updates and any more suggestion you may have for future updates. Also, we’d be glad to hear for which of your apps you used our icon makers.

// chall3ng3r //

Passing Data between Pages in Windows Phone 7

Passing data among pages is something which needs to be given a little care in terms what approach you follow . Since each approach has its own benefits and side effects. I’ll try to explain each of them one by one.

For illustration of this concept I’ve created a sample code which is attached at the end of the article. In this project I’ve various project each corresponds to one approach which I’ve described below. Each project has two pages. Touching on the coloured part of one page takes you to another page. First page will display a text string which is provided by the second page. You can simply go to second page add some text into TextBox and you can touch the coloured part to go back to first page which displays the string which you entered on first page.

So here are the approaches one by one:

1. Using Global Variable: This is the easiest and quickest procedure to pass your data among various pages.

Define a “Global Variable” in your App.xaml file as:

public string SecondPageText { get; set; }

After that on your Second page on ManipulationStarted event for the coloured Border use this code:

App.Current as App).SecondPageText = txtBox.Text; // add value to Global variable
NavigationService.GoBack(); // Navigate to first page

PhonePageOne page add this:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
txtBlock.Text = (App.Current as App).SecondPageText;
}


2. Using Query String: This procedure is good when we just need to share string based data between two pages.

Add this code in your PhonePageTwo:

private void Border_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
string uri = "/PhonePageOne.xaml?Text=";
uri += txtBox.Text;
NavigationService.Navigate(new Uri(uri, UriKind.Relative));
}

Use this code in your PhonePageTwo:

protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
IDictionary<string, string> parameters = this.NavigationContext.QueryString;
if (parameters.ContainsKey("Text"))
{
txtBlock.Text = parameters["Text"];
}
}

3. Using PhoneApplicationSerivce States: Every application has a PhoneApplicationService defined Microsoft.Phone.Shell. Each application has one PhoneApplicationService defined in its App.xaml file. We can use this service’s property called “State”. These “States” are all transient data which means they are available only for one instant of your application which means once you restart your application these states will be lost. Also we should not try to create a new PhoneApplicationService instead we must try to use the service from the current instant. Which can be retrieved using this code:

PhoneApplicationService.Current.State

Now, lets look how can we really use it in our sample.

PhonePageTwo add this code:

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
PhoneApplicationService.Current.State["Text"] = txtBox.Text;
}
private void Border_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
NavigationService.GoBack();
}

PhonePageOne add this code:

private void LayoutRoot_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
NavigationService.Navigate(new Uri("/PhonePageTwo.xaml", UriKind.Relative));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if(PhoneApplicationService.Current.State.ContainsKey("Text"))
txtBlock.Text = (string)PhoneApplicationService.Current.State["Text"];
}

4. Using NextPage intance: Whenever we call “Navigate” using a “/PageOne.xaml” or ”/PageTwo.xaml” the OnNavigatedFrom method in current page is called with event arguments with a  Uri property indicating other page and a Content property of type that page (Navigating to) . After that OnNavigatedTo of other page will be called with same arguments. So we have an opportunity to fix the set the value for next page prior to navigating to it. Just take a look at the sample code:

PageTwo add this code:

protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
if (e.Content is PageOne)
{
(e.Content as PageOne).txtBlock.Text = txtBox.Text;
}
}
private void Border_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
NavigationService.GoBack();
}

PageOne add this code: (Basically no need to do any thing just use this)

private void LayoutRoot_ManipulationStarted(object sender, System.Windows.Input.ManipulationStartedEventArgs e)
{
NavigationService.Navigate(new Uri("/PageTwo.xaml", UriKind.Relative));
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
}

Source Cod

Installing Symbian Anna on N8, E7, C7 and C6

You might have already read about the recent announcement by Nokia that Symbian Anna is now being pushed to all the Symbian ^3 capable devices, like Nokia N8, E7, C7 and C6-01. To read more visit the official announcement on Nokia Conversations blog here.

In this post, I will give you some pointers, if you are unable to install Symbian Anna on your device.

The first thing you need to do is find out if the update is pushed for your region or not. Start SW Update app on your device, and wait for it to refresh the list of available updates. Once the list is refreshed, it will show you if the device update is available.

On my brother’s Nokia C7, the update was offered as OTA (Over The Air) 28mb update. Once updated, the SW Update now shows two more updates named as Symbian Anna 1/2 and Symbian Anna 2/2. Both updates are about 30mb each. I did not continue with the updates yet because the battery was not fully charged. So, will update it later.

Update for Nokia C7: Okay, I continued the updates on my brother’s C7, and both of the updates installed fine. Remember, that after update 1/2 is installed, it will ask you to restart device, DO NOT restart, as update 2/2 is already being in installing process. Just wait till the updates are installed (about 20 mins).

Then I checked for the update on my Nokia E7 development device, SW Update app showed me the update on device, but it asked me to install the update via Ovi Suite or Nokia Software Updater.

When checked via Ovi Suite, it always showed update for Here and Now app, but not the device update. So, after many tries in 2 hours, I downloaded Nokia Software Updater.

SymbianAnna-install

The Nokia Software Updater reminded me that I’m using the device without a SIM, so I have to put a SIM to make the updater work. So, remember developers, you need to put any SIM in device before trying update, otherwise the update will fail. Maybe Ovi Suite was also failing because of no SIM.

For my E7, the update size is 325mb, and it’s still downloading. I will update this post with my success, and might write another post to review the new things in Symbian Anna update.

Update 1

Okay, after the download and installation of Device Update for my Nokia E7 via Nokia Software Updater, I got quite a bit of Symbian Anna feeling. The icons and browser have new look.

Just after few hours, I checked for updates via SW Update app, and to my surprise, there were two more updates, like I seen on my brother’s Nokia C7. I checked and started the updates. The interesting thing to note is, the first 325mb update was only available via PC, and these two updates are OTA.

WP_000035

They took about 30 minutes to install. During the installation, I was asked two time for EULA for MS Communicator and JoikuSpot. I think these later updates are new version of built-in apps like Mail for Exchange and couple of new apps.

For me, both of these updates went fine on the first go. It restarted my E7, and everything seems to be working alright.

Important note, that after update 1/2 is installed, DO NOT restart your device manually. Just wait for the 2nd update to be installed as well.

Thanks to Nokia for this much needed update.

// challn3g3r //

Highway Racer – Now On Nokia Ovi Store

I am excited to announce our first entry into Nokia Ovi Store with our first Adobe Flash Lite based game, Highway Racer. It’s a simple arcade style racing game, to take a fun break in your busy life.

Click the banner below to head over to Ovi Store and get it FREE now. It’s a limited time offer ;)

Here are some screenshots before I get to details and our experience so far in publishing to Ovi Store.

1-Splashscreen 2-MainMenu

5-InGame 3-About 

Game Development Experience

Highway Racer is a Flash Lite 3 based game developed using Adobe Flash CS5.5. The development experience is best you can get. We used traditional timeline for animations and scripts on frames for interactivity. Most of the resources are small components and reused to keep the runtime memory footprint small.

flash-cs55-highway-racer

Highway Racer runs on all Symbian 5th Edition (Nokia 5800XM, N97, etc.) devices as well, but the performance is not as good because these devices have slower processor.

For best experience, we recommend playing Highway Racer on any latest Symbian ^3 device like Nokia N8, E7, C7, X7 etc.

Packaging and Distribution

For Highway Racer, we used SWF2Go Pro 2.6 to compile a SIS file to post on Ovi Store for QA. SWF2Go is our most popular development toolkit used by tons of developers in more than 50 countries around the world.

Since SWF2Go allowed us to get past the SIS making process in less than 10 minutes, we were then quickly on the phase to make graphics for Ovi Store submission.

Ovi Publisher portal is now really easy to use, I must say. The submission wizard is easy follow, and it was like just 4 steps. And you are done.

The QA process took 2 days only, which was quite a surprise for us, we were not even quite ready :D

There’s one small complaint/ issue, which I like to point out. On the Distribution –> Language tab, there should clear note, if content is in English, select Works With All Languages / Publish To All Languages. We selected English (US) on first QA round, and later discovered that our game was only visible in US / Latin America. Ovi Store team, please add this note.

The After Shocks

It’s a complete surprise to us that Highway Racer is on #1 position in Sports category and #3 position in overall Games category for Pakistan region, just in 4 days!

We are very proud, and excited, as we have just stepped into Ovi Store, and finding such success in few days. It’s a big milestone for us.

We have already plans for follow up versions of Highway Racer as well as couple of cool new game ideas we are working on to publish on Ovi Store in coming months.

Download Highway Racer now from Ovi Store, and let us know your feedback and suggestions. And keep visiting Ovi Store for more of our exclusive games and apps to come ;)

BTW, Highway Racer is also our entry for Nokia and P@SHA MakeMyApp 2011 Challenge. Wish us luck!

// chall3ng3r //

Developing the Kolobok Game Piece

In my previous post, I developed the Kolobok game board for
Windows Phone 7 from the QML Bounce game posted on the
projects.developer.nokia.com site. In this blog posting, I will discuss how my
team developed the main Kolobok character along with the Cacti, Fire, and Brick
Wall obstacles. In my next posting, I will discuss the input buttons and
methods and how the game components are integrated into the final game.

The Kolobok character is the central component of the game.
Upon input from the user, the Kolobok will roll across the current tier or
bounce upward to a new tier. If the Kolobok encounters an obstacle, such as a
brick wall or cactus, the Kolobok will bounce backwards to a previous
position.  Fire will impede the
characters progress while reducing its health.

As we discussed in the previous posting, the Kolobok
character is defined in the class Kolobok in the file Kolobok.cs.  The class Kolobok is derived from the
GraphicItem class that holds important common properties such as object width,
height, position, texture, rotation angle, and opacity. All game pieces,
including characters and obstacles, are derived from this GraphicItem class.
The GraphicItem class also supports rudimentary animations for the moment of
the Kolobok or the flicker of the flame obstacle.

The original QML file kolobok.qml is an Ellipse Element that
contains the “Kolobok’s” properties and its Image, a non visible Timer element,
Key handlers, and javascript methods that respond to user events, moves the Kolobok
character, detects collisions, and updates the game statistics based on the
collisions with obstacles.

import QtQuick 1.0

import Shapes 1.0 

Ellipse
{

    id: kolobok

    // properties
   

    Image {

        id: kolobok_image

        objectName: "kolobok_image"

        x: 0; y: 0

        width: 100; height: 100

        source: ":/images/face-smile.png"

        smooth: true

        opacity: 1.0

    }

   

    Timer {

        id: timer

        interval: 25; running: false; repeat: true

        onTriggered: doMovement()
    }

       Keys.onPressed: { 

        if (event.isAutoRepeat)

            return;

        keyPressed(event.key);

    }

    Keys.onReleased: {

        if (event.isAutoRepeat)

            return;

        keyReleased(event.key);

        }

        // methods
       
}

QML does
not have an Ellipse Item defined, so we have defined an EllipseItem class that
draws an Ellipse in the C file level.cpp and registered this class in the
“Shapes” library as an Item named Ellipse.

The
KeyPressed and KeyReleased methods referenced above will respond to use input
events. If the input is one of the arrow keys, then the doMovement() method is
called, which will move the Kolobok character accordingly.

Collision
detection in the QML application is handled by the Qt Graphics View built-in
collision detection mechanism. The doMovement() method in kolobok.qml will call
into a method in the level.cpp file that will extract the list of items that
collide with the Kolobok and then update the state of the Kolobok accordingly.

The newly
created Kolobok.cs file will also contain the Ellipse, the Kolobok’s properties
and its image, key handlers, and support methods. The timer is an integral part
of the main event loop in XNA and so it is not explicitly defined in C#.
Because graphics objects are not implicitly self drawn or updated in XNA, we
will need to implement the Kolobok’s Initialize, Draw, and Update methods. The
remaining support methods are based on the original Javascript code, but
rewritten in C# using the XNA libraries.

The Initialize
method is very simple and merely initializes the Kolobok’s properties to their
starting values. The Update method will call doMovement() which will check the
user input for an arrow key press and will move the Kolobok character
accordingly. The update() and Draw() methods are shown here:

        public override void Update(GameTime gameTime)

        {

            base.Update(gameTime);

 

            // TODO: Add your update logic here

            doMovement();

 

            if (health <= 0)

                health = 100;

        }

 

        public override void Draw(SpriteBatch spriteBatch)

        {

            // Set up the color

            Color color = new Color(opacity, opacity, opacity, opacity);

 

            // Set up the origin point

            Vector2 origin = new Vector2();

            origin.X = Texture.Width / 2;

            origin.Y = Texture.Height / 2;

 

            // Set up the render rectangle

            Rectangle rect = new Rectangle(Rect.X + Rect.Width / 2,

                                           Rect.Y + Rect.Height / 2,

                                           Rect.Width, Rect.Height);

 

            spriteBatch.Draw(Texture, rect, null, color, RotationAngle, origin,

                              SpriteEffects.None, 0f);

 

            // Draw the health

            spriteBatch.DrawString(healthFont, "Health:" + health,

                                    new Vector2(20, 20), Color.White);

        }  

Key input
is handled through the KeyPressed() in KeyReleased() called by the input
handler in the game object’s update method. The remainder of the method, called
collisionDetection(), uses the XNA collision detection library to determine if
the Kolobok character is colliding with an obstacle and then updates the Kolobok
state.

The
doMovement(), keyPressed() and keyReleased(), and updateCollisions() methods
from kolobok.qmls javascript code are simply re-implemented in C#.

In QML,
the code to read the game layout database and present it to the game board is
written in C in the file level.cpp. The method load() in the C file uses
the Qt QXmlStreamReader to parse an XML database file and for each vertical
level on the game board stores a string containing a character for each
obstacle. The vertical level strings are stored in QVector container called
“map”. These level strings are used to build the game board as described in the
previous blog. The load method is shown below:

bool Level::load()

{

   

    m_rowCount = m_columnCount = 0;

    m_map.clear();

   

    QFile file(":/level/level.xml");

    if (!file.open(QFile::ReadOnly | QFile::Text)) {

        qDebug() << Q_FUNC_INFO << file.errorString();

        return false;

    }

   

    QXmlStreamReader xml(&file);

    if (xml.readNextStartElement()) {

        if (xml.name() == "level") {

            while (xml.readNextStartElement()) {

                if (xml.name() == "layer") {

                    const QString text = xml.readElementText();

                    m_map.append(text);

                    m_rowCount;

                    m_columnCount = qMax(m_columnCount, text.count());

                }

            }

        }

    }

In the
Windows Phone version of the game, level.cs contains a very similar load function.
Here we use the XmlReader class to read the XML data file and a List container
class to store the level strings. Note the similarities between the two
methods:

public static bool load(string
filePath)

        {

            // Clear the level’s old data.

           
mRowCount = 0;

           
mColumnCount = 0;

           
mMap.Clear();

 

            // Open the level xml file

            XmlReader reader = XmlReader.Create(filePath);

            while (reader.Read())

            {

               
if (reader.Name == "layer")

               
{

                   
string text = reader.ReadInnerXml();

                   
mMap.Add(text);

                   
mRowCount ;

                   
mColumnCount = Math.Max(mColumnCount,
text.Count<char>());

                }

            }

            return true;

        }

 

Now that
we implemented the Kolobok character and the movement logic behind the game,
the only remaining parts are to process input from the user and play background
music and sounds. In my next blog, I will pull the rest of the application
together and show how I completed the port.

 

Access Templated Child in Silverlight and Windows Phone 7


Accessing a templated child is way too simple in WPF but for SilverLight which is even being used in Windows Phone 7 needs a little extra work to the work being done. Well there are two ways to achieve it. I’ll try to explain both of them one by one. Before getting into explanations of these methods we need a sample template to get a better picture.

A sample template for a ListBoxItem :

So, now when we have custom style :-)   we can start looking into the options to retrieve an element (myTextBox) from Style at run time.


First Approach
  1.  Make sure you have defined names for the items you are going to acess in your template let say it “myTextBox”.
  2. Now you must have ListBoxItem for which you are going to find your TemplateChild lets say it “lbi”.

After going through these initial check now use the following code to find element:

//Enforce Style to apply in case if it's not yet applied
lbi.ApplyTemplate();
FirstApproach(lbi);

void FirstApproach(ListBoxItem lbi)
{
StackPanel stkTemplatedChild = VisualTreeHelper.GetChild((DependencyObject)lbi, 0) as StackPanel;
TextBlock txtBlk = stkTemplatedChild.FindName("myTextBlk") as TextBlock;
txtBlk.Text = "First Approach CLicked";
}
So, “txtBlk ” is your desired element 
Second Approach:
This approach is to itrerate through all the elements in style’s template. which can be done by using this code:

//Enforce Style to apply in case if it's not yet applied
lbi.ApplyTemplate();
SecondApproach(lbi);

void SecondApproach(ListBoxItem lbi)
{
TextBlock templatedTextBlk;
int childCount = VisualTreeHelper.GetChildrenCount((DependencyObject)lbi);
for (int i = 0; i < childCount; i++)
{
DependencyObject childObj = VisualTreeHelper.GetChild(lbi, i);
int subChild = VisualTreeHelper.GetChildrenCount(childObj);
for (int n = 0; n < subChild; n++)
{
DependencyObject dpChild = VisualTreeHelper.GetChild(childObj, n);
if (dpChild is TextBlock && (dpChild as TextBlock).Name == "myTextBlk")
{
templatedTextBlk = dpChild as TextBlock;
templatedTextBlk.Text = "Second Approach Clicked";
break;
}
}
}
}
templatedTextBx” is your result.

Third Approach (using helper function):  This approach may look catchy but it has some down sides. In this approach you have to iterate through VisualTree which could be a resource intensive. But this one is good if you have a inline template.

//Enforce Style to apply in case if it's not yet applied
lbi.ApplyTemplate();
TextBlock txtbx = FindVisualChildByType(lbi, "myTextBlk");
if (txtbx != null)
txtbx.Text = "Third Approach Clicked";

T FindVisualChildByType(DependencyObject element, String name) where T : class
{
if (element is T && (element as FrameworkElement).Name == name)
return element as T;
int childcount = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < childcount; i++)
{
T childElement = FindVisualChildByType(VisualTreeHelper.GetChild(element, i), name);
if (childElement != null)
return childElement;
}
return null;
}

So, txtbx is your desired result.
Source Code