I recently used Telerik Platform (http://www.telerik.com/platform) to build my first mobile game (Wah! http://www.ampzone.com/projects/wah). It was a bit of an experiment as I didn't know how well a game built with HTML, CSS and JS would work out on a mobile device. While I feel I have plenty of room for improvement, overall I think the test proved a success. I'm just going to write about one issue I had while attempting to improve the performance of the animations in my game. I had read that it was more efficient to use CSS animation rather than using JavaScript timers and jQuery Animations. Therefore, I decided I would use them wherever I could.
CSS animations felt like they naturally suited my need to remove certain objects (toys and broccoli) from the screen after a set amount of time. I wanted to have the objects flash in and out a few times before disappearing completely. This was relatively straight forward to achieve with the following:
body:not(.pause) .toy{
animation: ease-in;
animation-name: blinkOut, blinkIn, blinkOut, blinkIn, removeItem;
animation-delay: 8s, 8.4s, 8.8s, 9.2s, 9.6s;
animation-fill-mode: forwards;
-webkit-animation: ease-in;
-webkit-animation-name: blinkOut, blinkIn, blinkOut, blinkIn, removeItem;
-webkit-animation-delay: 8s, 8.4s, 8.8s, 9.2s, 9.6s;
-webkit-animation-fill-mode: forwards;
}
And the animations I had simply changed the background position so that my sprites would display a faded out version of the object. Here is the code:
@keyframes blinkOut {
to {
background-position:0 0;
}
}
@-webkit-keyframes blinkOut {
to {
background-position:0 0;
}
}
@keyframes blinkIn {
to {
background-position:0 -45px;
}
}
@-webkit-keyframes blinkIn {
to {
background-position:0 -45px;
}
}
@keyframes removeItem {
to {
overflow:hidden;
width:0;
height:0;
visibility: hidden;
}
}
@-webkit-keyframes removeItem {
to {
overflow:hidden;
width:0;
height:0;
visibility: hidden;
}
}
I then had a JS function which was being called every second to act as a garbage collector. It would check if there were elements which were removed from display and, if so, remove the html for that element.
cleanUpItems:function(){
var items = $( ".toy:hidden, .broccoli:hidden, .toast:hidden" );
for (var i=0; i < items.length; i++) {
var item =$(items[i]);
if(item.height()==0){
if(Draggable.get(item)!=null){
//removes item as a draggable element
Draggable.get(item).kill();
}
item.remove();
}
}
var sweets = $( ".sweet:hidden" );
for (var i=0; i < sweets.length; i++) {
$(sweets[i]).parent().remove();
}
}
This seemed to work well, until I started testing on actual mobile devices instead of in the emulator. Issues varied slightly across devices, either it wouldn't flash or it became virtually impossible to interact with the element. I tried a few different options to fix this, but in the end I decided it was best to move back to JavaScript in this instance. I selected to use the GreenSock Animation Platform (GSAP https://greensock.com/gsap) as it has good reviews for performance compared to jQuery. It also easily fitted into my project technology stack and ended up becoming a valuable addition.
Here is the simple method I called whenever an object (toy in this case) was created.
animateToy:function(toy){
var toyDisplayTime = 10;
TweenLite.to(toy, 0, { delay:(toyDisplayTime-2), backgroundPosition:'0 -45px' });
TweenLite.to(toy, 0, { delay:(toyDisplayTime-1.6), backgroundPosition:'0 0' });
TweenLite.to(toy, 0, { delay:(toyDisplayTime-1.2), backgroundPosition:'0 -45px' });
TweenLite.to(toy, 0, { delay:(toyDisplayTime-0.8), backgroundPosition:'0 0' });
TweenLite.to(toy, 0, { delay:(toyDisplayTime-0.4), overflow:'hidden',height:0,width:0,visibility: 'hidden' });
}
CSS animations are the best option in many cases and for most websites they work incredibly smoothly, but unfortunately, this was a more unique situation that they just weren't compatible with. Although I'm sure it won't be long.