<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DZone Snippets: animation code</title>
    <link>http://snippets.dzone.com/posts</link>
    <pubDate>Fri, 10 Oct 2008 23:06:23 GMT</pubDate>
    <description>DZone Snippets: animation code</description>
    <item>
      <title>Animate with shoes</title>
      <link>http://snippets.dzone.com/posts/show/5934</link>
      <description>Source: &lt;a href="http://shoooes.net/tutorial/"&gt;Shoes &#8226; The Tutorial Walkthrough&lt;/a&gt; [shoooes.net]&lt;br /&gt;The shoes logo will appear to move diagonally from the top left towards the bottom right and the follow the same path back up.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;Shoes.app do&lt;br /&gt;  @shoes = image "http://shoooes.net/shoes.png",&lt;br /&gt;    :top =&gt; 10, :left =&gt; 10&lt;br /&gt;  offset = 1&lt;br /&gt;  bounced = false&lt;br /&gt;  animate(50) do |i|&lt;br /&gt;    if not bounced then&lt;br /&gt;      offset += 1 &lt;br /&gt;    else&lt;br /&gt;      offset -= 1&lt;br /&gt;    end&lt;br /&gt;&lt;br /&gt;    @shoes.top =  offset * 2&lt;br /&gt;    @shoes.left = offset * 3 &lt;br /&gt;&lt;br /&gt;    if offset &gt; 100 and not bounced then &lt;br /&gt;       bounced = true&lt;br /&gt;    elsif offset &lt; 0 and bounced then&lt;br /&gt;       bounced = false&lt;br /&gt;    end&lt;br /&gt;  end&lt;br /&gt;end&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 17 Aug 2008 16:44:05 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5934</guid>
      <author>jrobertson (James Robertson)</author>
    </item>
    <item>
      <title>Create special effects animation with RMagick</title>
      <link>http://snippets.dzone.com/posts/show/5846</link>
      <description>The following code creates an animated gif which displays the text 'Ruby rocks!' with different effects including a drop shadow and blur.&lt;br /&gt;&lt;br /&gt;Source: &lt;a href="http://www.simplesystems.org/RMagick/doc/comtasks.html"&gt;RMagick 1.15.0: Common Tasks&lt;/a&gt; [simplesystems.org]&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;#!/home/software/ruby-1.8.5/bin/ruby -w&lt;br /&gt;require 'RMagick'&lt;br /&gt;&lt;br /&gt;# Add a drop shadow to a text string. This example&lt;br /&gt;# uses a 3-image animation to show each step of the&lt;br /&gt;# process&lt;br /&gt;&lt;br /&gt;Rows = 60&lt;br /&gt;Cols = 250&lt;br /&gt;Text = 'Ruby rocks!'&lt;br /&gt;&lt;br /&gt;# This imagelist will contain the animation frames&lt;br /&gt;anim = Magick::ImageList.new&lt;br /&gt;&lt;br /&gt;ex = Magick::Image.new(Cols, Rows)&lt;br /&gt;&lt;br /&gt;# Create a Draw object to draw the text with. Most of the text&lt;br /&gt;# attributes are shared between the shadow and the foreground.&lt;br /&gt;&lt;br /&gt;text = Magick::Draw.new&lt;br /&gt;text.gravity = Magick::CenterGravity&lt;br /&gt;text.pointsize = 36&lt;br /&gt;text.font_weight = Magick::BoldWeight&lt;br /&gt;text.font_style = Magick::ItalicStyle&lt;br /&gt;text.stroke = 'transparent'&lt;br /&gt;&lt;br /&gt;# Draw the shadow text first. The color is a very light gray.&lt;br /&gt;# Position the text to the right and down.&lt;br /&gt;text.annotate(ex, 0,0,2,2, Text) {&lt;br /&gt;    self.fill = 'gray60'&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;# Save the first frame of the animation.&lt;br /&gt;anim &lt;&lt; ex.copy&lt;br /&gt;&lt;br /&gt;# Blur the shadow. Save a copy of the image as the 2nd frame.&lt;br /&gt;ex = ex.blur_image(0,3)&lt;br /&gt;anim &lt;&lt; ex.copy&lt;br /&gt;&lt;br /&gt;# Add the foreground text in solid black. Position it&lt;br /&gt;# to the left and up from the shadow text.&lt;br /&gt;text.annotate(ex, 0,0,-1,-1, Text) {&lt;br /&gt;    self.fill = 'maroon'&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;# Save yet another copy of the image as the 3rd frame.&lt;br /&gt;anim &lt;&lt; ex.copy&lt;br /&gt;&lt;br /&gt;# Set the delay between frames to 1 second.&lt;br /&gt;anim.delay = 100&lt;br /&gt;&lt;br /&gt;# Set the delay after the last frame to 3 seconds.&lt;br /&gt;anim.cur_image.delay = 300&lt;br /&gt;&lt;br /&gt;# Iterate forever.&lt;br /&gt;anim.iterations = 0&lt;br /&gt;&lt;br /&gt;#anim.animate&lt;br /&gt;anim.write('drop_shadow.gif')&lt;br /&gt;exit&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Wed, 30 Jul 2008 16:35:31 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5846</guid>
      <author>jrobertson (James Robertson)</author>
    </item>
    <item>
      <title>Create an animated gif using ImageMagick</title>
      <link>http://snippets.dzone.com/posts/show/5845</link>
      <description>The program convert which is included with ImageMagick can produce animated gifs&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;convert -delay 9 -loop 0 t*.png animated.gif&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;This code simply delays the animation at the end for a few seconds.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;convert -delay 9 -loop 0 t*.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png t32.png animated2.gif&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Note that JPG files are best when the image contains lots of imagery i.e. (gradients, raster scan, special image effects). </description>
      <pubDate>Wed, 30 Jul 2008 15:45:19 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5845</guid>
      <author>jrobertson (James Robertson)</author>
    </item>
    <item>
      <title>Convert an animation into a video with ffmpeg</title>
      <link>http://snippets.dzone.com/posts/show/5842</link>
      <description>source: &lt;a href="http://www.nuxified.org/article/create_video_animations_with_inkscape_imagemagick_and_ffmpeg"&gt;Create video animations with Inkscape, ImageMagick and FFmpeg | Nuxified GNU/Linux Help Forums&lt;/a&gt; [nuxified.org]&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;ffmpeg -r 12 -i nuxified%05d.png -y -an nuxified.avi&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;PNG preserves the information in vector graphics while still keeping the file size low.  I tried the above script with JPG and the AVI file size was 54.9KB, I tried the same thing with PNG and the AVI file size was only 22.5KB.&lt;br /&gt;&lt;br /&gt;References:&lt;br /&gt; - &lt;a href="http://www.pymolwiki.org/index.php/Making_Movies#Mencoder.2FMplayer"&gt;Making Movies - PyMolWiki&lt;/a&gt; [pymolwiki.org]&lt;br /&gt; - &lt;a href="http://lists.mplayerhq.hu/pipermail/mencoder-users/2005-December/002413.html"&gt;[MEncoder-users] Trouble when making a movie from *.png files&lt;/a&gt; [mplayerhq.hu]&lt;br /&gt; - &lt;a href="http://en.wikipedia.org/wiki/Ffmpeg"&gt;FFmpeg&lt;/a&gt; [wikipedia.org]&lt;br /&gt; - &lt;a href="http://en.wikipedia.org/wiki/MEncoder"&gt;MEncoder&lt;/a&gt; [wikipedia.org]&lt;br /&gt; - &lt;a href="http://dawes.wordpress.com/2007/12/04/animating-png-files/"&gt;Animating PNG files &#171; The Daily Photon&lt;/a&gt; [wordpress.com]</description>
      <pubDate>Wed, 30 Jul 2008 13:59:59 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5842</guid>
      <author>jrobertson (James Robertson)</author>
    </item>
    <item>
      <title>Animate a shape using SVG</title>
      <link>http://snippets.dzone.com/posts/show/5838</link>
      <description>The animation of a rectangle using SVG was tested using Firefox.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;br /&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" version="1.1"&lt;br /&gt;     onclick="moveRectangle(evt, document.getElementById('r1'));"&gt; &lt;br /&gt;  &lt;title&gt;click to animate the rectangle&lt;/title&gt;&lt;br /&gt;  &lt;br /&gt;  &lt;script type="text/ecmascript"&gt;&lt;br /&gt;    &lt;![CDATA[&lt;br /&gt;             var count = 5;&lt;br /&gt;             var rectangle = '';&lt;br /&gt;             var animation = '';&lt;br /&gt;             &lt;br /&gt;              function moveRectangle (evt, element) {&lt;br /&gt;                rectangle = element;&lt;br /&gt;                rectangle.setAttribute('fill','orange');&lt;br /&gt;                moveIt();&lt;br /&gt;                animation = setInterval("moveIt()",20 );&lt;br /&gt;              }&lt;br /&gt;              &lt;br /&gt;              function moveIt() {&lt;br /&gt;                sLeft = rectangle.getAttribute('x');&lt;br /&gt;                iLeft = parseInt(sLeft) + 5;&lt;br /&gt;                rectangle.setAttribute('x', iLeft);&lt;br /&gt;                if (iLeft &gt; 600) {&lt;br /&gt;                  clearTimeout(animation);&lt;br /&gt;                  rectangle.setAttribute('fill','blue');&lt;br /&gt;                }&lt;br /&gt;              }&lt;br /&gt;              ]]&gt;&lt;br /&gt;  &lt;/script&gt; &lt;br /&gt;  &lt;rect id="r1" x="120" y="20" width="60" height="200"  fill="blue"/&gt;&lt;br /&gt;&lt;br /&gt;&lt;/svg&gt; &lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Tue, 29 Jul 2008 23:05:10 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5838</guid>
      <author>jrobertson (James Robertson)</author>
    </item>
    <item>
      <title>TimeLine //JavaScript Class</title>
      <link>http://snippets.dzone.com/posts/show/5293</link>
      <description>&lt;br /&gt;&lt;br /&gt;&lt;a href="http://jsfromhell.com/classes/timeline"&gt;&lt;br /&gt;Simulates the Adobe Flash timeline. You define the amount of frames, the speed in fps (frames per second) and, at each frame passage an event is called, useful for animations.&lt;br /&gt;&lt;br /&gt;[UPDATED CODE AND HELP CAN BE FOUND HERE]&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;//+ Jonas Raoni Soares Silva&lt;br /&gt;//@ http://jsfromhell.com/classes/timeline [v1.0]&lt;br /&gt;&lt;br /&gt;TimeLine = function(fps, f){&lt;br /&gt;	this.fps = fps, this.frames = f;&lt;br /&gt;};&lt;br /&gt;with({o: TimeLine, $: TimeLine.prototype}){&lt;br /&gt;	o.timers = [];&lt;br /&gt;	$.running = !!($.current = +(o.timer = $.time = null));&lt;br /&gt;	o.run = function(){&lt;br /&gt;		var o = this;&lt;br /&gt;		o.timer || (o.timer = setInterval(function(){&lt;br /&gt;			for(var h, d = +(new Date), t = o.timers, i = t.length; i--;){&lt;br /&gt;				(!t[i].running || ((d - t[i].time) / (1e3 / t[i].fps) &gt; t[i].current + 1 &amp;&amp;&lt;br /&gt;				t[i].onframe(++t[i].current), t[i].current &gt;= t[i].frames)) &amp;&amp;&lt;br /&gt;				(h = t.splice(i, 1)[0], h.stop(1));&lt;br /&gt;			}&lt;br /&gt;		}, 1));&lt;br /&gt;	};&lt;br /&gt;	$.start = function(c){&lt;br /&gt;		var o = this, t = TimeLine;&lt;br /&gt;		if(o.running) return;&lt;br /&gt;		o.running = true, o.current = c || 0;&lt;br /&gt;		o.time = new Date, o.onstart &amp;&amp; o.onstart();&lt;br /&gt;		if(!o.onframe || o.frames &lt;= 0 || o.fps &lt;= 0)&lt;br /&gt;			return o.stop(1);&lt;br /&gt;		t.timers.push(this), t.run();&lt;br /&gt;	};&lt;br /&gt;	$.stop = function(){&lt;br /&gt;		var o = this;&lt;br /&gt;		o.running = false;&lt;br /&gt;		if(!TimeLine.timers.length)&lt;br /&gt;			TimeLine.timer = clearInterval(TimeLine.timer), null;&lt;br /&gt;		arguments.length &amp;&amp; o.onstop &amp;&amp; o.onstop();&lt;br /&gt;	};&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Example&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;&lt;div id="box" style="position: absolute; top: 100px; background: #efe; width: 100px; height: 100px"&gt;25 fps&lt;/div&gt;&lt;br /&gt;&lt;div id="box2" style="position: absolute; top: 300px; background: #ff9; width: 100px; height: 100px"&gt;12 fps&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;TimeLine working together with the ease in quad function.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;script type="text/javascript"&gt;&lt;br /&gt;Math.ease = function (t, b, c, d) {&lt;br /&gt;	if ((t /= d / 2) &lt; 1)&lt;br /&gt;		return c / 2 * t * t + b;&lt;br /&gt;	return -c / 2 * (--t * (t - 2) - 1) + b;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;var o = new TimeLine(25, 50), d = document, b = d.getElementById("box");&lt;br /&gt;o.onframe = function(){&lt;br /&gt;	b.style.left = Math.ease(this.current, 0, 400, 30) + "px";&lt;br /&gt;};&lt;br /&gt;o.onstart = function(){&lt;br /&gt;	d.body.appendChild(d.createTextNode("Started"));&lt;br /&gt;};&lt;br /&gt;o.onstop = function(){&lt;br /&gt;	d.body.appendChild(d.createTextNode(" - Finished (" + (((new Date) - this.time)) + " msec)"))&lt;br /&gt;	d.body.appendChild(d.createElement("br"));&lt;br /&gt;	this.start();&lt;br /&gt;};&lt;br /&gt;o.start();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var o2 = new TimeLine(12, 50), b2 = d.getElementById("box2");&lt;br /&gt;o2.onframe = function(){&lt;br /&gt;	b2.style.left = Math.ease(this.current, 0, 400, 30) + "px";&lt;br /&gt;};&lt;br /&gt;o2.onstop = function(){&lt;br /&gt;	this.start();&lt;br /&gt;};&lt;br /&gt;o2.start();&lt;br /&gt;&lt;/script&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Sun, 30 Mar 2008 16:49:21 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/5293</guid>
      <author>jonasraoni (Jonas Raoni Soares Silva)</author>
    </item>
    <item>
      <title>Actionscript _Animate Class</title>
      <link>http://snippets.dzone.com/posts/show/3514</link>
      <description>This is basically a way to set up an animation queue to utilize scripted tweening.  You would have to create external functions which carry forth the animation actions then store the function objects in the _Animate.queue Array in the sequence you wish to play them out.  Ideally, these functions would return a Tween object for the sake of utilizing "onMotionStopped".  Returning False (bool) will simply allow the next function in the queue to fire without checking for the onMotionStopped call.  When you are ready to start the animation sequence, just call launch();&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;import _String;&lt;br /&gt;&lt;br /&gt;dynamic class _Animate {&lt;br /&gt;	var queue:Array;&lt;br /&gt;	&lt;br /&gt;	function _Animate() {&lt;br /&gt;		queue = null;&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	public function caller(qNum){&lt;br /&gt;		var gA = this;&lt;br /&gt;		var callback = queue[qNum].func.apply(this, _String.toArray(queue[qNum].params)); qNum++;&lt;br /&gt;		if (qNum &lt; queue.length &amp;&amp; callback) callback.onMotionStopped = function() { gA.caller(qNum); }&lt;br /&gt;		else if (qNum &lt; queue.length &amp;&amp; !callback) gA.caller(qNum);&lt;br /&gt;	}&lt;br /&gt;	&lt;br /&gt;	public function launch(){ caller(0); }&lt;br /&gt;	&lt;br /&gt;	&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Sample Usage&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;var zoomIn = new _Animate();&lt;br /&gt;&lt;br /&gt;zoomIn.queue = [&lt;br /&gt;	{func:aniSidebar, params:"hide,6"},&lt;br /&gt;	{func:aniMapMidFade, params:"hide,6"}&lt;br /&gt;];&lt;br /&gt;&lt;br /&gt;zoomIn.launch();&lt;br /&gt;&lt;br /&gt;function aniSidebar(action, time){&lt;br /&gt;	var leftBeginX = (action == "hide") ? 0 : 0 - sidebarLeftBg._width;&lt;br /&gt;	var leftEndX = (action == "hide") ? 0 - sidebarLeftBg._width : 0;&lt;br /&gt;	var rightBeginX = (action == "hide") ? Stage.width - sidebarRightBg._width : Stage.width;&lt;br /&gt;	var rightEndX = (action == "hide") ? Stage.width : Stage.width - sidebarRightBg._width;&lt;br /&gt;	var transition = mx.transitions.easing.Regular.easeInOut;&lt;br /&gt;	var leftAni = new mx.transitions.Tween(sidebarLeftBg, "_x", transition, leftBeginX, leftEndX, time);&lt;br /&gt;	var rightAni = new mx.transitions.Tween(sidebarRightBg, "_x", transition, rightBeginX, rightEndX, time);&lt;br /&gt;	return rightAni;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function aniMapMidFade(action, time){&lt;br /&gt;	var begin = (action == "hide") ? 100 : 0;&lt;br /&gt;	var end = (action == "hide") ? 0 : 100;&lt;br /&gt;	var transition = mx.transitions.easing.Regular.easeOut;&lt;br /&gt;	var mapMidAni = new mx.transitions.Tween(mapMid, "_alpha", transition, begin, end, time);&lt;br /&gt;	return mapMidAni;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Tue, 13 Feb 2007 19:47:43 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/3514</guid>
      <author>bgidge (Bryan Gidge)</author>
    </item>
    <item>
      <title>Animacion en allegro</title>
      <link>http://snippets.dzone.com/posts/show/2653</link>
      <description>Codigo que muestra una pequena animacion en Allegro&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;br /&gt;#include &lt;allegro.h&gt;&lt;br /&gt;&lt;br /&gt;void init();&lt;br /&gt;void deinit();&lt;br /&gt;&lt;br /&gt;int piramide(int a, int b, int c){&lt;br /&gt;    line(screen,a+(c/2),b,a,b+c,makecol(0,128,0));    &lt;br /&gt;    line(screen,a,b+c,a+c,b+c,makecol(0,128,0));&lt;br /&gt;    line(screen,a+c,b+c,a+(c/2),b,makecol(0,128,0));    &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;int main() {&lt;br /&gt;	init();&lt;br /&gt;	int a,b,inca,incb;&lt;br /&gt;	a=0,b=0;&lt;br /&gt;	inca=1, incb=1;&lt;br /&gt;	while (!key[KEY_ESC]) {&lt;br /&gt;          clear_to_color(screen,0);&lt;br /&gt;            circlefill(screen,a,b,50,makecol(128,0,128));&lt;br /&gt;            a=a+inca;&lt;br /&gt;            b=b+incb;&lt;br /&gt;            &lt;br /&gt;            if (a==200){&lt;br /&gt;               inca=-1;            &lt;br /&gt;            }&lt;br /&gt;        rest(10);&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	deinit();&lt;br /&gt;	return 0;&lt;br /&gt;}&lt;br /&gt;END_OF_MAIN();&lt;br /&gt;&lt;br /&gt;void init() {&lt;br /&gt;	int depth, res;&lt;br /&gt;	allegro_init();&lt;br /&gt;	depth = desktop_color_depth();&lt;br /&gt;	if (depth == 0) depth = 32;&lt;br /&gt;	set_color_depth(depth);&lt;br /&gt;	res = set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);&lt;br /&gt;	if (res != 0) {&lt;br /&gt;		allegro_message(allegro_error);&lt;br /&gt;		exit(-1);&lt;br /&gt;	}&lt;br /&gt;&lt;br /&gt;	install_timer();&lt;br /&gt;	install_keyboard();&lt;br /&gt;	install_mouse();&lt;br /&gt;	/* add other initializations here */&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;void deinit() {&lt;br /&gt;	clear_keybuf();&lt;br /&gt;	/* add other deinitializations here */&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;</description>
      <pubDate>Fri, 22 Sep 2006 19:57:37 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/2653</guid>
      <author>jcongote (John Edgar Congote Calle)</author>
    </item>
    <item>
      <title>15-square game</title>
      <link>http://snippets.dzone.com/posts/show/414</link>
      <description>py_s60 1.1.3 was released a week ago.&lt;br /&gt;I wonder why there's no more people playing with it.&lt;br /&gt;So, I have created a simple game as an example.&lt;br /&gt;&lt;br /&gt;I don't know what this game is called. It has 4x4 square box&lt;br /&gt;with 15 pieces (1 piece missing). You need to move all the&lt;br /&gt;pieces into sorting order.&lt;br /&gt;&lt;br /&gt;Since the program is so simple, I decided to make the&lt;br /&gt;moving of a piece smoother by moving it bit by bit.&lt;br /&gt;Hope this doesn't make the code to hard to read.&lt;br /&gt;&lt;code&gt;&lt;br /&gt;from appuifw import *&lt;br /&gt;from key_codes import *&lt;br /&gt;import e32, random&lt;br /&gt;&lt;br /&gt;# run and break-loop type of app&lt;br /&gt;sleep = e32.ao_sleep&lt;br /&gt;running = 1&lt;br /&gt;def set_exit():&lt;br /&gt;    global running&lt;br /&gt;    running = 0&lt;br /&gt;app.exit_key_handler= set_exit&lt;br /&gt;&lt;br /&gt;# canvas and typical colors&lt;br /&gt;c = Canvas()&lt;br /&gt;app.body = c&lt;br /&gt;red, green, blue, gray, white = 0xff0000, 0x00ff00, 0x0000ff, 0x777777, 0xffffff&lt;br /&gt;&lt;br /&gt;# randomize number order for pieces&lt;br /&gt;seq = range(1,17)&lt;br /&gt;random.shuffle(seq)&lt;br /&gt;b = [seq[0:4], seq[4:8], seq[8:12], seq[12:16]]&lt;br /&gt;&lt;br /&gt;def piece(i, j, n):&lt;br /&gt;    if n &lt; 10:&lt;br /&gt;        c.text( (12+20*i, 20+20*j), unicode(n))&lt;br /&gt;    else:&lt;br /&gt;        c.text( (7+20*i, 20+20*j), unicode(n))&lt;br /&gt;&lt;br /&gt;def box(i, j, color, fill=None):&lt;br /&gt;    c.rectangle( [5+20*i, 5+20*j, 25+20*i, 25+20*j], color, fill)&lt;br /&gt;&lt;br /&gt;# draw board pieces&lt;br /&gt;for k in range(16):&lt;br /&gt;    j, i = divmod(k, 4)&lt;br /&gt;    piece(i, j, b[j][i])&lt;br /&gt;&lt;br /&gt;y, x = divmod(seq.index(16), 4)&lt;br /&gt;box(x, y, white, white)&lt;br /&gt;moving = 0     # cursor to lock if animating&lt;br /&gt;&lt;br /&gt;# move cursor in dx, dy direction&lt;br /&gt;def move(dx, dy):&lt;br /&gt;    global x,y, moving&lt;br /&gt;    if moving:&lt;br /&gt;        return&lt;br /&gt;    moving = 1&lt;br /&gt;    if 0 &lt;= x-dx &lt; 4 and 0 &lt;= y-dy &lt; 4:&lt;br /&gt;        b[y][x] = b[y-dy][x-dx]&lt;br /&gt;        animate(x-dx, y-dy, dx, dy, b[y][x])&lt;br /&gt;        x -= dx  # the hole move in opposite direction&lt;br /&gt;        y -= dy&lt;br /&gt;    moving = 0&lt;br /&gt;&lt;br /&gt;# moving a piece for x,y to dx, dy direction&lt;br /&gt;def animate(x, y, dx, dy, n):&lt;br /&gt;    if n &lt; 10:&lt;br /&gt;        px = 12&lt;br /&gt;    else:&lt;br /&gt;        px = 7&lt;br /&gt;    for i in range(5):&lt;br /&gt;        c.text( (px+20*x + 4*i*dx, 20+20*y + 4*i*dy), unicode(n))&lt;br /&gt;        sleep(0.05)&lt;br /&gt;        c.text( (px+20*x + 4*i*dx, 20+20*y + 4*i*dy), unicode(n), white)&lt;br /&gt;    c.text( [px+20*(x+dx), 20+20*(y+dy)], unicode(n) )&lt;br /&gt;&lt;br /&gt;# bind arrow keys&lt;br /&gt;c.bind(EKeyRightArrow,lambda:move(1, 0))&lt;br /&gt;c.bind(EKeyLeftArrow,lambda:move(-1, 0))&lt;br /&gt;c.bind(EKeyUpArrow,lambda:move(0, -1))&lt;br /&gt;c.bind(EKeyDownArrow,lambda:move(0, 1))&lt;br /&gt;&lt;br /&gt;# main loop, just wait&lt;br /&gt;while running:&lt;br /&gt;    sleep(0.1)</description>
      <pubDate>Mon, 27 Jun 2005 00:02:53 GMT</pubDate>
      <guid>http://snippets.dzone.com/posts/show/414</guid>
      <author>korakot (Korakot Chaovavanich)</author>
    </item>
  </channel>
</rss>
