Creating a game using python and Silverlight 1.1


This tutorial assumes that you have a passing understanding of Silverlight and Microsoft’s .NET technologies. If you do you should have no trouble understanding everything in this code, and chances are you will understand some of it more then I do!

But to start it off here is a little bit of information straight from Microsoft’s website:

Silverlight is a new Web presentation technology that is created to run on a variety of platforms. It enables the creation of rich, visually stunning and interactive experiences that can run everywhere: within browsers and on multiple devices and desktop operating systems (such as the Apple Macintosh). In consistency with WPF (Windows Presentation Foundation), the presentation technology in Microsoft .NET Framework 3.0 (the Windows programming infrastructure), XAML (eXtensible Application Markup Language) is the foundation of the Silverlight presentation capability.
This white paper will step you through the basics of Silverlight and how you can use the Microsoft stack of tools, including Microsoft Expression Blend, Microsoft Visual Studio 2005, and XAML to build rich graphical sites. First, let’s take a primer on the background leading up to Silverlight and where it stands on the development landscape.

What we are going to do is create a simple game with falling targets that they user has to click on in order to “hit” them. Each time they hit a target they will get a point and another target will be created.

Python silverlight

You can try the “finished” product out here: http://www.learningpython.com/silverpy/index.htm

This first step is to download and install Silverlight 1.1 from here: http://msdn2.microsoft.com/en-us/silverlight/bb419317.aspx

Sadly at this point there is no plugin available for Linux, however the people over at the mono project are working on moonlight so we should see some movement in that direction soon.

The next step is to download the SilverLight 1.1 SDK from: http://go.microsoft.com/fwlink/?LinkID=89145&clcid=0×409

Once you have done that you should create a folder somewhere on your hard drive where you want to store your files. I created a folder called SilverPy.

Then browse to the DLR console sample located in this directory:

...Silverlight1.1SDK\Silverlight 1.1 Alpha Samples\DLRConsole\python

Note: The DLR sample appears to have gone missing in recent SDK releases, but it can be found on the samples page.

Then copy all of the files from that folder into your SilverPy folder. Now rename the DLRConsole.xaml to SilverPy.xaml and you can get rid of the DLRConsole.py, in its place create a SilverPy.py file. This will be the file that will contain our python code.

So once you are done you should be left with the following:

Python Silverlight

Now we want to edit the index.html so that it doesn’t say that it’s the DLR sample. Edit the html code to look something like:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title>SilverPy</title>
   <script src="silverlight.js" type="text/javascript" ></script>
   <script src="CreateSilverlight.js" type="text/javascript" ></script>
</head>
<body>
    <div id="WpfeControl1Host">
    <script type="text/javascript">
				var pe = document.getElementById("WpfeControl1Host");
				createSilverlight();
    </script>
    </div>
</body>
</html>

Now since we changed the name of our xaml file we need to edit the CreateSilverlight.js file:

function createSilverlight()
{
Sys.Silverlight.createObject("SilverPy.xaml", pe, "wpf",
{width:"100%", height:"100%",
inplaceInstallPrompt:false, background:'white', isWindowless:'true',
framerate:'30', version:'0.95'},
{onError:null, onLoad:null},
null);
}

We simply changed the first parameter to the createObject function to be “SilverPy.xaml” so that the correct file gets loaded. CreateSilverlight.js calls Silverlight.createObject to instantiate Silverlight and tell it to load our “Silver.xaml” file, it also controls other a few other option. I don’t want to explain this in too much detail since Microsoft has already done this for me:

CreateSilverlight.js:

Defines the CreateSilverlight method, which invokes either the CreateObject or CreateObjectEx method, which are defined in the Silverlight.js file.

Silverlight.js:

Defines the CreateObject and CreateObjectEx methods, which provide version checking support and generate the tag settings in the HTML file for hosting the Silverlight control.

If you want more information on the nitty gritty of these these two files and the html file please read the Microsoft website.

The next step is to edit our XAML file, this is going to be pretty simple but I will explain it later:

This is our XAML file, it’s used to create our “GUI”. The first step is to create the Canvas element:

<canvas x:Name="root_canvas"  Width="500" Height="300"
 xmlns="http://schemas.microsoft.com/client/2007"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 Background="Purple"
>
  <x :Code Source="Silver.py" Type="text/python" />
  <canvas x:Name="game_canvas"
         Loaded="on_canvas_loaded"
          Width="500" Height="300"/>
  <textblock Name="Score" Text="Targets Hit: 0"  FontSize="10" Canvas.Left="400" Canvas.Top="305"/>
</canvas>

Defines an area within which you can explicitly position child elements by using coordinates relative to the Canvas area.

So this where we will create all of our visible objects, you can think of it like the canvas that a painter uses. You can see in the XML that we give our canvas object a name: “root_canvas”, a height, a width, and a background colour: “purple”.

The next element that you see is an x:Code element which we use to load the “Silver.py” python file. Here we could load as many code files as we wanted.

The next element is another Canvas element named “game_canvas”, which serves no purpose except to provide us with the . The value that we assign to the loaded attribute is the name of the function in our python file that will be called when this canvas has been loaded.

For some reason (perhaps it is explained somewhere or someone can tell me why) I could not get the “root_canvas” to send the Loaded event, so I needed to created the sub-canvas as a work-around.

The next element is a TextBlock element that is used to display (yes you guessed it) text. We use this TextBlock to display the user’s score as they play our little game.

Now it’s time to work on our python code.

If you load the index.html file into Internet Explorer (you have to use Internet Explorer as there currently are some issues with loading external python modules when running local files, I’ve read that it will be fixed soon) you will get an obscure error. This is because we have not created the on_canvas_loaded function that we described in our xaml.

So let’s add this to our Silver.py file:

def on_canvas_loaded(sender, e):
	pass

The first thing that you will notice about out Loaded event handler is that it has two parameters, which is common will all event handlers. Sender is the object that fired the event, and e is the event arguments associated with the event. What is contained in the event arguments changes depending on what event is being caught.

Now if you load index.html into Internet Explorer you should see the following:

Python Silverlight

So far so good! So now lets get into some serious python coding, now most of this code is simply Python/IronPython so if you are familiar with both you shouldn’t have any problem.

The fist step is to import all of the stuff that we are going to need:

from System import *
import _random
import wpf
from wpf import *
import clr
clr.AddReference('agclr')
clr.AddReference('System.Silverlight')

Now we are going to work with two classes in our game, one class that will be the target that we are going to aim at and the other that will serve as out main game.

def __init__(self, game_canvas):
    """Init the Target Game
    @param game_canvas - The canvas for the game.
    """
    #Create a random object
    self.random = _random.Random()
    #Save the game canvas
    self.game_canvas = game_canvas
    #The score
    self.score = 0
    #The list of targets that we have
    self.targets = []
    #Make sure that we have the minimum number of targets
    self.ensure_targets()
    #hook into the keydown event
    self.game_canvas.KeyDown += EventHandler(self.on_key_down)
    #Not done yet
    self.done = False

Now the first thing that we do is we create a random object that we will use in the future to position our Target sprites. The next step is to save the game_canvas that was passed in to the __init__ function, game_canvas corresponds to a canvas object. Then we initialize our score to zero, this will be the number of canvas sprites that our user hits. Then we create an empty list, which will store references to the targets that are currently on the screen.

Finally we hook up our member function on_key_down to the game canvas objects KeyDown event and set our done flag to False, since we aren’t done.

def on_key_down(self, sender, e):
    """Check to see if they hit escape"""

    if (e.Key == 8):
        self.game_over()

This handler is pretty simple, it gets called when there is a key down event on the game_canvas, if the key is the Escape key (e.Key == 8) then we called self.game_over() to end the game. I added this so that someone could quit the game at any time.

The game_over function is as follows:

def game_over(self):
    """Called when the game should end"""
    self.game_over_text = TextBlock()
    self.game_over_text.FontSize = 50
    self.game_over_text.Text = "GAME OVER"
    self.game_canvas.Children.Add(self.game_over_text)
    wpf.SetPosition(self.game_over_text
        , 100
        , 100)
    #We are done
    self.done = True

The first think that we do is create a TextBlock object, set some of its properties, and add it to the game_canvas’s children making the object visible. Then we use a helper function in the wpf module to set the position of the TextBlock object. Finally we set done to True, done is simply a boolean flag that we use to know if the game is done or not.

The wpf modules SetPosition function is actually pretty simple and we could have done this ourselves:

def SetPosition(o, x, y):
    SetIntValue(o, Canvas.TopProperty, y)
    SetIntValue(o, Canvas.LeftProperty, x)

Another function that we called way back when in the __inti__ function is:

def ensure_targets(self):
    #Make sure that we have enough targets
    while (len(self.targets) < NUM_TARGETS):
        self.targets.append(self.create_target())

Pretty simply stuff, while the number of targets stored in our list is less then NUM_TARGETS we create and add targets to our list. NUM_TARGETS is defined as follows at the beginning of the source code:

NUM_TARGETS = 10

The ensure_targets function uses the create_target function to create new targets:

def create_target(self):
    #Create a new target and return it
    
    #Init to random size and position
    x = int(self.random.random()*400)
    width = int(self.random.random()*30) + 20
    height = int(self.random.random()*30) + 20
    y = 0 - height
    """Init the velocity to a random number based off of the 
    score so that more targets are hit, the game gets harder."""
    velocity = int(self.random.random()*(int(self.score / 15)+1))
    #The minimum velocity is 1
    if (velocity<=0):
        velocity = 1

    return TargetSprite(self.on_target_event
            , self.game_canvas, x, y,width, height
            , velocity)

This might seem slightly confusing, but basically what we are doing is using our random object to randomly position and size our new target sprite. We set the x position to be a random number between 0 and 400, the width and height a random number between 20 and 50. Then the Y position to be 0 – height, this is simply done to start the target off of the screen.

Next we set the velocity of the Target sprite to be between 1 and the current score divided by 15. This makes it so that the game increases in difficulty as the more targets are hit.

Finally we return the TargetSprite that we create.

Now that we have looked at how we create TargetSprites in the TargetGame class lets look at our TargetSprite object, here is the __init__ function from the Target Sprite class, notice that in create_target we pass the function self.on_target_event as the first parameter:

def __init__(self, notify_function, game_canvas, x, y, width, height, velocity=1):
    """Initialize the target sprite.
    @param notify_function - function - The function to call when an event happens.
    @param game_canvas - Canvas object - The canvas that the 
    TargetSprite will be added to.
    @param x - int - X position
    @param y - int - Y position
    @param width - int - The width
    @param height - int - The height
    @param velocity = 1 - int - How fast we are going to move down.
    """
    self.notify_function = notify_function
    self.game_canvas = game_canvas
    self.x = x
    self.y = y
    self.width = width
    self.height = height
    self.velocity = velocity
            
    self.add_to_canvas()

This function is pretty easy to understand, we save a reference to each parameter and then we add ourself to the canvas that was passed in. add_to_canvas is where we actually create the ellipse that will be displayed on the screen as our target:

def add_to_canvas(self):
    """Add yourself to the canvas"""
    
    #Create the Ellipse
    self.ellipse = System.Windows.XamlReader.Load('<Ellipse Stroke="Black" StrokeThickness="2" Fill="SlateBlue"/>')
    #Height, Width, and position
    self.ellipse.Height = self.height
    self.ellipse.Width = self.width
    #Add to canvase
    self.game_canvas.Children.Add(self.ellipse)
    #Set the position
    wpf.SetPosition(self.ellipse, self.x, self.y)
    """Connect out click event handler with the Let button down
    event."""
    self.ellipse.MouseLeftButtonDown += MouseEventHandler(self.on_ellipse_click)

Now here we do something interesting, we create an ellipse object using some in-line XAML code instead of creating the object directly like we did with the “game over” text.

After the ellipse has been created, we set the Height and Width, and then we add it to the canvas objects children. Then we use the SetPosition helper function in the wpf module to set the position of our ellipse.

Then we add a handler to the ellipse’s MouseLeftButtonDown event. We do this so that we know that the user has “hit” a target.

Our MouseLeftButtonDown function is pretty simple as well, we simply call the notify function that we were initialized with and tell them what happened:

def on_ellipse_click(self, sender, e):
    """We have been clicked on, call the notify function
    and tell them."""
    self.notify_function(TARGET_HIT, self)

Target hit is defined at the start of the program along with GAME_OVER like so:

TARGET_HIT = 0
GAME_OVER = 1

These are simply defines that we use to pass into the notify function in order to tell it what event has happened.

Now we switch back to the TargetGame clasas and the notify function that we passed to the TargetSprite():

def on_target_event(self, event, target_sprite):
    """Called when an event is sent from the target
    sprite
    @param event - number - What has happened?
    @param target_sprite -TargetSprite - The sprite that
    has sent this event"""
    
    if (self.done==True):
        #We are already done don't bother
        return
    
    if (event == GAME_OVER):
        #The game is over!
        self.game_over()
    elif (event == TARGET_HIT):
        """A target has been hit
        Remove the hit target from the list and from
        the canvass"""
        self.targets.remove(target_sprite)
        self.game_canvas.Children.Remove(target_sprite.ellipse)
        #Update the score and the score text
        self.score += 1
        Score.Text = "Targets Hit: %d" % (self.score)
        #Now make sure that we have enough targets
        self.ensure_targets()

Now I hope you can see what is happening, we don’t have any game play just yet, but we have started working on the interaction between our sprites and the main game object. This function is pretty straight forward, if we got the GAME_OVER event then we call the game_over function and everything finishes.

If the event is a TARGET_HIT event then we need to remove the target that was hit from the targets list and the game_canvas. Then we need to update the score and the score text. Now this is the first time that we have referenced our TextBlock object. If you remember the XAML you’ll remember that we created a TextBlock object in order to display the score:

[code lang=”xml”]

[/code]

So in order to set the text, we simply reference the object by it’s name and set its text property:

Score.Text = "Targets Hit: %d" % (self.score)

Which I think is some pretty cool and intuitive interaction between our xaml and our python code.

Now we have most of the game “architecture” in place, but we still need to create our game loop, and a way for outside callers to start the actual game, enter the run function:

def run(self):
    """Start the game."""
    #initialize the elements
    self.done = False
    self.score = 0
    #Our storyboard timer
    self.gameLoop = Storyboard()
   #Set the name property for the 1.1 refresh
    self.gameLoop.SetValue[System.String](self.gameLoop.NameProperty, "GameLoop")
    #Add to the canvas
    self.game_canvas.Resources.Add(self.gameLoop)
    #Add the completed event handler
    self.gameLoop.Completed += EventHandler(self.on_game_timer)
    #Start the game loop
    self.gameLoop.Begin()

Now because of the way that Silverlight works we cannot simply use a normal game loop, instead we use a Storyboard object which is generally used for animations. What we do is tell the storyboard object to Begin its set of animations, but since there are no animations set up, it promptly quits and the Completed event fires, which we handle with the self.on_game_timer function.

def on_game_timer(self, sender, e):
        """This is the main game loop that we are going to be
        using."""

        #Update the sprites
        for sprite in self.targets:
            sprite.update()
        #If we are not done, start the timer again    
        if (not self.done):
            self.gameLoop.Begin()

What we do when our Storyboard ends is we update all of our targets, then if the game has not finished we restart the Storyboard, and the game loops.

The update function in the TargetSprite pretty simple, it updates the position of the Target and if the target has hit the bottom of the canvas then it fires the GAME_OVER event:

def update(self):
    """This is called when the sprite is supposed to update
    itself."""
    self.y += self.velocity
    wpf.SetPosition(self.ellipse, self.x, self.y)
    
    if ((self.y + self.height) >= self.game_canvas.Height):
        #We have hit the bottom! Game over!
        self.notify_function(GAME_OVER, self)

Now all we need is to do is start the game when the page loads, to do that we go back to our trusty on_canvas_loaded function:

def on_canvas_loaded(sender, e):
    target_game = TargetGame(root_canvas)
    target_game.run()

Now if you’ve made it this far in the code there shouldn’t be anything surprising about this, we basically initialise our TargetGame using the root_canvas, and then we tell that game to run, that’s it.

So that’s it, you can go play the game here if you want: http://www.learningpython.com/silverpy/index.htm my highest score is 93.

Python silverlight

Here is all of the code:

from System import *
import _random
import wpf
from wpf import *
import clr
clr.AddReference('agclr')
clr.AddReference('System.Silverlight')

TARGET_HIT = 0
GAME_OVER = 1
NUM_TARGETS = 10

class TargetSprite(object):
    """The Target to hit"""
    
    def __init__(self, notify_function, game_canvas, x, y, width, height, velocity=1):
        """Initialize the target sprite.
        @param notify_function - function - The function to call when an event happens.
        @param game_canvas - Canvas object - The canvas that the 
        TargetSprite will be added to.
        @param x - int - X position
        @param y - int - Y position
        @param width - int - The width
        @param height - int - The height
        @param velocity = 1 - int - How fast we are going to move down.
        """
        self.notify_function = notify_function
        self.game_canvas = game_canvas
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.velocity = velocity
                
        self.add_to_canvas()
        
    def add_to_canvas(self):
        """Add yourself to the canvas"""
        
        #Create the Ellipse
        self.ellipse = System.Windows.XamlReader.Load('<ellipse Stroke="Black" StrokeThickness="2" Fill="SlateBlue"/>')
        #Height, Width, and position
        self.ellipse.Height = self.height
        self.ellipse.Width = self.width
        #Add to canvase
        self.game_canvas.Children.Add(self.ellipse)
        #Set the position
        wpf.SetPosition(self.ellipse, self.x, self.y)
        """Connect out click event handler with the Let button down
        event."""
        self.ellipse.MouseLeftButtonDown += MouseEventHandler(self.on_ellipse_click)
        
    def on_ellipse_click(self, sender, e):
        """We have been clicked on, call the notify function
        and tell them."""
        self.notify_function(TARGET_HIT, self)
    
    def update(self):
        """This is called when the sprite is supposed to update
        itself."""
        self.y += self.velocity
        wpf.SetPosition(self.ellipse, self.x, self.y)
        
        if ((self.y + self.height) >= self.game_canvas.Height):
            #We have hit the bottom! Game over!
            self.notify_function(GAME_OVER, self)
    
class TargetGame(Object):
    """A Quick Target game"""
    
    def __init__(self, game_canvas):
        """Init the Target Game
        @param game_canvas - The canvas for the game.
        """
        #Create a random object
        self.random = _random.Random()
        #Save the game canvas
        self.game_canvas = game_canvas
        #The score
        self.score = 0
        #The list of targets that we have
        self.targets = []
        #Make sure that we have the minimum number of targets
        self.ensure_targets()
        #hook into the keydown event
        self.game_canvas.KeyDown += EventHandler(self.on_key_down)
        #Not done yet
        self.done = False
    
    def on_key_down(self, sender, e):
        """Check to see if they hit escape"""

        if (e.Key == 8):
            self.game_over()
    
    def game_over(self):
        """Called when the game should end"""
        self.game_over_text = TextBlock()
        self.game_over_text.FontSize = 50
        self.game_over_text.Text = "GAME OVER"
        self.game_canvas.Children.Add(self.game_over_text)
        wpf.SetPosition(self.game_over_text
            , 100
            , 100)
        #We are done
        self.done = True
            
    def ensure_targets(self):
        #Make sure that we have enough targets
        while (len(self.targets) < NUM_TARGETS):
            self.targets.append(self.create_target())
            
    def create_target(self):
        #Create a new target and return it
        
        #Init to random size and position
        x = int(self.random.random()*400)
        width = int(self.random.random()*30) + 20
        height = int(self.random.random()*30) + 20
        y = 0 - height
        """Init the velocity to a random number based off of the 
        score so that more targets are hit, the game gets harder."""
        velocity = int(self.random.random()*(int(self.score / 15)+1))
        #The minimum velocity is 1
        if (velocity<=0):
            velocity = 1
    
        return TargetSprite(self.on_target_event
                , self.game_canvas, x, y,width, height
                , velocity)
                
    def on_target_event(self, event, target_sprite):
        """Called when an event is sent from the target
        sprite
        @param event - number - What has happened?
        @param target_sprite -TargetSprite - The sprite that
        has sent this event"""
        
        if (self.done==True):
            #We are already done don't bother
            return
        
        if (event == GAME_OVER):
            #The game is over!
            self.game_over()
        elif (event == TARGET_HIT):
            """A target has been hit
            Remove the hit target from the list and from
            the canvass"""
            self.targets.remove(target_sprite)
            self.game_canvas.Children.Remove(target_sprite.ellipse)
            #Update the score and the score text
            self.score += 1
            Score.Text = "Targets Hit: %d" % (self.score)
            #Now make sure that we have enough targets
            self.ensure_targets()
            
    def run(self):
        """Start the game."""
        #initialize the elements
        self.done = False
        self.score = 0
        #Our storyboard timer
        self.gameLoop = wpf.Storyboard()
        #Set the name property for the 1.1 refresh
        self.gameLoop.SetValue[System.String](self.gameLoop.NameProperty, "GameLoop")
        #Add to the canvas
        self.game_canvas.Resources.Add(self.gameLoop)
        #Add the completed event handler
        self.gameLoop.Completed += EventHandler(self.on_game_timer)
        #Start the game loop
        self.gameLoop.Begin()
        
    def on_game_timer(self, sender, e):
        """This is the main game loop that we are going to be
        using."""

        #Update the sprites
        for sprite in self.targets:
            sprite.update()
        #If we are not done, start the timer again    
        if (not self.done):
            self.gameLoop.Begin()
            
def on_canvas_loaded(sender, e):
    target_game = TargetGame(root_canvas)
    target_game.run()

All in all it’s pretty simple to create something like this using Silverlight and python. Hopefully this tutorial provides enough information so that all of you can create your own game or application, if you do drop me a line I’d love to check it out.

As always if you have any questions, comments, or spot a problem with the tutorial, add a comment below.

selsine

del.icio.us del.icio.us

29 Responses to “Creating a game using python and Silverlight 1.1”

  1. francois
    Says:

    Hi,

    Thanks for your tutorial which is exactly what I was searching for but unfortunately I have a little problem.

    I’m on Vista and I’ve installed Silverlight from the link you gave. This download “Silverlight.1.1.AlphaRefresh” version on my PC.

    After installation and browser reboot (an even PC reboot to be sure) I can’t “read” you’re example:
    http://www.learningpython.com/silverpy/index.htm
    (It ask to install Silverlight which is already installed).

    I’m sure Silverlight works because when I try the gallery:
    http://silverlight.net/themes/silverlight/community/gallerydetail.aspx
    1.0 RC samples work
    1.1 Alpha Refresh sample work
    1.0 Beta samples work
    1.1 Alpha Mix samples *doesn’t work* (asking for silverlight)

    So I’m note sure what’s going on. Maybe there is a new version 1.1 called “Refresh” and examples done with the previous 1.1 doesn’t work anymore.

    I know 1.1 is alpha but If you have any idea of what I should do to make your example works it would be great! :) (thanks for your tutorial!)

    francois

  2. francois
    Says:

    EDIT: Forgot to mention that I tried with both IE7 and Firefox with the same results.

  3. francois
    Says:

    Hello? For information:
    http://weblogs.asp.net/mschwarz/archive/2007/07/31/upgrading-your-project-to-silverlight-alpha-1-1-refresh.aspx

  4. selsine

    selsine
    Says:

    All right francois, sorry it took me so long to get back to you but I finally figured out what the problem is and I think that everything should be working now. Give it another chance and let me know what happens.

  5. yuval t3h computergeek
    Says:

    Hi,

    I really like your website. I’ve created something similar, http://my-python-blog.freehostia.com/, but it will take a more formal approach. So anyway, I have a couple tutorial requests. Can you post a tutorial explaining how to make exe, dmg, bin/deb/rpm files? And can you create a tutorial about porting your pyMan game to Jython?
    Thanks,
    Yuval

  6. JesĂşs
    Says:

    Thanks selsine, i will wait for the next tutorial for linux’s users :P

  7. selsine

    selsine
    Says:

    Yuval! That’s very cool! It’s great to see more and more people learning python. Keep up the good work.

    Jesus – Yeah, I’m looking into that, hopefully there will be something soon!

  8. Yuval
    Says:

    incase you’re interested, forums and chat are up

  9. Yuval
    Says:

    what digg, reddit ect plugins are you using?

  10. francois
    Says:

    Thanks selsine, your example works great now! :)

    Unfortunately I can’t follow the tutorial. When I download the “Refresh” 1.1 SDK (the only one available now) I can’t find the files you mentioned (DLRConsole.xaml, wpf.py,etc).

    Maybe I’ve missed something obvious but it seems to me they’ve changed many things in the “Refresh” SDK. If this is the case could you update the tutorial or tell me what I’m missing.

    Thanks! :)

  11. selsine

    selsine
    Says:

    Hi francois,

    Looks like they removed some of the samples, I’ll have to rework the tutorial, for now you can download the DLR sample from here:

    http://silverlight.net/themes/silverlight/community/gallerydetail.aspx?cat=4

  12. francois
    Says:

    Thanks Selsine for the link!

    I followed your instructions with the DLRSample and the tutorial but I’m stuck here:

    “”” Now if you load index.html into Internet Explorer you should see the following:”””

    I have the following error:

    “””
    Error code: 2007
    ErrorType: Parser Error
    Messages: Unknown element:canvas.
    Xam File: SilverPy.xaml
    Line: 5 Position:1
    “””
    So it looks like it loads SilverPy.xaml but don’t know what to do with the canvas tag??

    This is my SilverPy.xaml

    “””

    “””

    any idea?

    Thanks for your help :)

    francois

  13. francois
    Says:

    Oopos the silverPy.xaml paste don’t appear in my post above.

    It is in fact just the copy of the box content below “This is our XAML file, it’s used to create our “GUI”. The first step is to create the Canvas element:”

    Is there a way to show tags in a post reply here?

    Thanks

    francois

  14. selsine

    selsine
    Says:

    Hi Francois,

    Try wrapping the xml in [ code ] [ /code ] (without the spaces) that way I can take a look at it and see if there is anything wrong with it. Have you added your handler to your .py file?

  15. francois
    Says:

    Here I am again :)

    To pass the above error I changed “canvas” to “Canvas”

    Then I had another error and to pass this one I’ve deleted the space between x and :Code in
    x :Code Source=”Silver.py” Type=”text/python”

    But now, on the same line, I have:
    Error Code:2024
    Message: Invalid attribute value text/python for property %1

    So I tried to change the Type to Type=”text/ironpython” but that doesn’t work either.

    I’m stuck :(

    Help …

  16. francois
    Says:

    This was my first SilverPy.xaml (a copy/paste from the tutorial box):

    ::HLIGHT_BLOCK_1::

    and this is my last attempt:

    ::HLIGHT_BLOCK_2::

  17. selsine

    selsine
    Says:

    Hmm what is the contents of your python file?

    This is what I am using for my xaml:

    <Canvas x:Name=”root_canvas” Width=”500″ Height=”300″
    xmlns=”http://schemas.microsoft.com/client/2007″
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml”
    Background=”Purple”
    >
    <x:Code Source=”Silver.py” Type=”text/python” />
    <Canvas x:Name=”game_canvas”
    Loaded=”on_canvas_loaded”
    Width=”500″ Height=”300″/>
    <TextBlock Name=”Score” Text=”Targets Hit: 0″ FontSize=”10″ Canvas.Left=”400″ Canvas.Top=”305″/>
    </Canvas>

  18. francois
    Says:

    Ok I’m not sure that worked so I sent to you a mail directly.

  19. francois
    Says:

    Thanks Selsine for your feedback

    Like I saw in your mail I’ve changed textblock to TextBlock (also I didn’t point to the good Python file which didn’t help, silly me…).

    Thanks !! :)

    Python and Silverlight seem to have a bright future :)

  20. Yuval
    Says:

    I got my own domain name! You’ll have to update your blogroll

  21. Aki Iskandar
    Says:

    Hello –

    I enjoyed your article, and am excited about IronPython and Silverlight. Keep up the good work.

    The real reason I am writing though is to save your visitors extreme frustration. I clicked on the Python Web Hosting link (at the top of your site’s page: Creating a game using python and Silverlight 1.1), and was taken to http://www.micfo.com. I’ve signed up with these people about 2 weeks ago, and have experienced a great deal of pain.

    Their service doesn’t work. Their systems (hosting and accounting) are terrible. They advertise a 30-day money back guarantee, yet I find myself spending valuable time trying to get them to refund my money (they claim that the transaction is not going through because of PayPal and an invalid invoice number). Well, I never used my PayPal account (used MasterCard), and the invoice number I gave them was what they had given to me.

    When I signed up, it took 3 days to get my account set up – which ended up not working.

    They run a joke of an operation. NEVER, in my 20 years of business have I been so annoyed or played with.

    To add insult to injury, I am being spammed by their virtual server (which was supposed to be cancelled because it is missing all kinds of modules) at the rate of about 150 emails per day!

    I have all sorts of emails from me to them, and their replies to back all of this up.

    Please consider removing this link. It’s hurting you – for recommending them as an ISP. They are a joke – and a HUGE waste of time.

    Regards,
    Aki Iskandar
    aki.net@gmail.com

  22. Vince
    Says:

    Hey there,

    This is Vince from SocialRank.

    We’re launching a new Web 2.0 site dedicated to cycling and we have started indexing your blog posts as part of our content filter.

    I’d like to send you an invite to a beta preview. Can you get back to me with your email address.

    Mine is vince@SocialRank.com

    Thanks
    Vince

  23. Vince
    Says:

    oops, sorry for the typo over there, It’s python instead of cycling

  24. selsine

    selsine
    Says:

    Hi Yuval,

    Congrats on the new domain! Keep up the good work!

  25. Someone
    Says:

    well I stole your silver game to see if it could run on the page/server I use, and well it didn’t. Took me ages to find out that you link to the SilverLight.js file by a name silverlight.js. Not all systems ignores case in filenames it seems. :D,

  26. selsine

    selsine
    Says:

    Hey Someone,

    Thanks for the catch!

  27. B&Y
    Says:

    This is great!!!

    I can do some neat stuff now knowing I can use Python as a scriptiong language makes stuff alot easier!

  28. george naing
    Says:

    Python and Silverlight!
    A wonderful combo.
    thanks.

  29. Code to unlock Samsung phones
    Says:

    Thank you…

    [...]Might you be interested in swapping links?[...]…

Leave a Reply

 

Popular Posts