Build Flappy Bird with jQuery and 100 lines of Javascript

Introduction

Build Flappy Bird with jQuery and 100 lines of Javascript

Play online at Gasp Mobile Games

Background

So Flappy bird became a big news: the developer walked away from $50,000 a day. I downloaded a game and played it – it did look simplistic and silly. I put it aside. Then my friends brough up the same topic and jokingly asked “you can probably build it in a couple of days. $50,000 in a couple of days – not a bad business.” I though I should, but then I was busy at work. Some other things came up, and finally when the Apple started to reject Flappy Bird clones because there were soo many, I thought – “I got to get me some of this. With the right timing and a little bit of luck – those $50,000/day can be mine.”
The version I’m presenting here took me a whooping 2 hours to build and under a 100 lines of my javascript.

For those who don’t know the game – get out of your caves. You tap on the bird to give it some initial up speed. Then it start falling (under gravity). You need to keep it in the air and avoid the obstacles it can run into. To simplify the objective, the bird is only moves up and down, perception of horisontal motion is acheived by scrolling background. This is it – get it done and $50,000 a day is yours.

Assets

The game needs only 5 images : the bird, background grass, background sky, obstacles and instuction tap-to-start.
 
  
As you can see, to save myself some headace I’m skimping out on frame animation by using an animated gif file. This way browser can use it much more efficiently. Also it’s something that prevented me from publishing it on Windows Phone – since browser control there doesn’t support animated GIF files.

The base html is also pretty simple:

        <div id='board' style='position:absolute; left:50px; top:50px; width:478px; 
                height:300px; overflow:hidden;'>
            <div id='score' style='position:absolute; left:400px; top:0px; height:25px; 
                    z-index:5; color:red; font-weight:900'></div>
            <img class="c" id='bird' src="b2.gif" style="z-index:5"/>
            <img id='instr' src='instr.png' class='c' style="left:205px; top:75px; 
                    z-index:100" />
            <div class="bg" id='bGrnd' style="top:-20px; height:320px; 
                    background-image:url(bg1.png) "/>
            <div class="bg" id='fGrnd' style="top:235px; height:85px; z-index:4; 
                    background-image:url(bg2.png) "/>
        </div>

I also include latest jQuery from http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.js

Global variables and Initialization

The game uses following global variables:

bird jQuery object to hold our bird
board jQuery object to hold the board – container object
dimPipe Obstacle dimentions
cPos Current bird position (only Y coordinate can change)
gravity Configurable gravity constant – how fast the bird falls
iniSpeed Configurable initial speed
curSpeed Current vertical bird’s speed
score Current Score
noClr number of obstacles cleared
tmStep Step timer to position a bird and launch obstacles
state Game state : 0 – not started; 1 – in play; 2 – game over

The game is initialized in 2 steps: usual jQuery $.ready and reusable start() that we can call every time the game is restarted:

    $(document).ready(function() {
        board = $('#board').bind('mousedown', onTap);
        bird = $('#bird');
        start();
    });
    function start() {
        state = noClr = score = 0;                    // not started
        cPos = { x: 80, y:100, h:40, w:50 };
        bird.css({left:cPos.x, top:cPos.y, width:cPos.w, height:cPos.h, rotate:0});
        $('.obs').remove();
        $('#instr').show();
    }

As you can see in $.ready we are initializing bird and board global variables, attaching onMouseDown handler to the board and calling start() function.
In the start() function I’m resetting all the variables, removing any obstacles still on the board and showing instructions image prompting to tap/click.

Click/Tap handling

So the game is ready to go. The missing part is what happen when you click on the board. The game at this point starts main timer (BirdStep) (if needed) and sets bird’s initial up speed:

    function onTap() {
        if (state > 1) return;
        if (state == 0) {
            state = 1;
            $('#instr').hide();
            tmStep = window.setInterval(BirdStep, 30);
        }
        curSpeed = iniSpeed;
    }

Thing to consider is that the program uses 3 states –

  • 0 – not running
  • 1 – play mode
  • 2 – die mode – no input is accepted.

So here we are checking – if we are in die mode – just get out. If we are not playing, then go into play mode – change state, hide intro image and start timer. Aside from that we want to give our bird initial up speed. 

The main logic however is done in the BirdStep timer function:

    function BirdStep() {
        // update bird position
        curSpeed += gravity;                                
        cPos.y = Math.max(cPos.y + curSpeed, 0);
        var mh = board.height()-cPos.h, m = -12, lo = 0, actPipe = $('.obs');
        bird.css({top: cPos.y});
        // check if we hit the floor or other obstacles
        if (cPos.y > mh)
            return gameOver();
        for (var i = actPipe.length-1; i >= 0; i--) {
            var s = actPipe[i].style, x = parseInt(s.left), y = parseInt(s.top);
            lo = Math.max(lo, x);
            if (x+dimPipe.width +m < cPos.x || x > cPos.x+cPos.w+m)    continue;
            if (y+dimPipe.height+m < cPos.y || y > cPos.y+cPos.h+m) continue;
            return gameOver();
        }
        // check if can launch more obstacles
        if (actPipe.length > 3 || lo > 300 || Math.random() >= 0.05 * (1+noClr))
            return;
        var og = cPos.h * 2;
        var oh = og + Math.floor(Math.random() * (mh-og+1));
        var obs = $("<img /><img />").addClass('c obs').css({left:480, zIndex:3}).css(dimPipe).attr('src', 'vine.png')
            .appendTo(board).animate({left:-50}, 3000, 'linear', function() { 
                $('#score').text(' Score: ' + (score += 1 + Math.floor(++noClr/10)));
                this.remove();
            });
        obs[0].style.top = oh + 'px';
        obs[1].style.top = (oh - og - dimPipe.height) + "px";
    }

As you can see this function tries to do 3 major things:

Update bird position

Every time the BirdStep timer executed, the current bird speed get’s increased by gravity and added to current bird Y position. Also at this point I’m checking to make sure bird doesn’t fly above ceiling (negative Y).

Hit Testing

Here we are testing if bird didn’t fall too low (Y exceeds board height) or we hitting any obstacles – loop that checks if bird’s position (stored in cPos and reduced by some fudge margin – m = 12px) intersects with any of the obstacles – any objects with class of .obs. If so then the game is lost – we can just get out.

Launch new obstacles

First thing we check if new obstacles can be launched:

  • Less then 4 obstacles already on thescreen
  • Last obstacles travel some distance
  • add some random factor

If conditions are satisfied, we can launch 2 more obstacles, one on top of the other, with the gap of 2 bird sizes between randomly positioned along Y coordinate, right after right edge of the board (left = 480px).
After they are created they are animated to move off the left edge of the screen (left = -50px), at which point the score is increased and obstacles are removed. To do the animation we are using plain and simple jQuery linear animation.

Bells and wistles: parallax scrolling effect

That’s pretty much a game. But so far it looks too plain. To add some umpf lets add parallax scrolling effect. Actually we are adding 2 parallax layers – the sky and the grass. We are also need to add a depth perception – in this implementation – the sky will just move slower then the grass – it should suffice. To create a parallax layer, I will create a very wide div element (16,000px) with background-repeat: repeat-x; and set desired image as a background. The browser will horisontally replicate the image. The only thing I need to do is just to add animation – set left position of the div using very handy jQuery animate:

    function Parallax(elm, tmo) {
        elm.css('left', 0).animate({left:-15360}, {
                duration:tmo*1000, easing:'linear', //step : PrlxStep,
                complete : function() { Parallax(elm, tmo); } 
        });
    }
    function onTap() {
        if (state == 0) {
            ...
            Parallax($('#bGrnd'), 240);
            Parallax($('#fGrnd'), 80);
            ...
        }
    }

As you can see the code is surprisingly simple : the left position of the div is set to 0px and then linearly animated to -15,360px (the largest common denominator less then 16,000 of all the background images width – just so I don’t have to add extra parameter to the function) after which the whole process repeats. The supplied argument is a time to animate – the foreground (grass) supposed to scroll for 80 seconds and background (sky) – 240 sec – 3 times slower.

Bells and wistles: rotation

Aside from parallax, it would be nice to rotate the bird – tilt it up when it flies up, and down when it falls. Also when the game is over, to show bird roll over. To do that i created simple jquery css hook. Please check jQuery documentation on detail about CSS Hooks.

    $.cssNumber.rotate = true;
    $.cssHooks.rotate = {
        set : function(el, v) {
                if (typeof v === 'string') 
                v = (v.indexOf("rad") != -1) ? parseInt(v) * 180 / Math.PI : parseInt(v);
            v = (~~v);
            if (v == ($.data(el, 'rotate') || 0)) return;
            el.style["MozTransform"] = el.style["MozTransform"] = el.style["-webkit-transform"]
                = el.style["transform"] = " rotate(" + (v % 360) + "deg)"; 
            $.data(el, 'rotate', v);
        },
        get : function(el, computed) {
            return $.data(el, 'rotate') || 0;
        }
    };

As you can see over here we are storing current rotation value in $.data("rotate") and setting element’s browser specific CSS attributes to set current rotation.
To use newly acquired capability let’s change our BirdStep function to rotate a bird with the angle of 5 times the speed. If bird flies up and speed negative, the bird tilts up, if bird is falling and speed is positive, the bird tilts down. On top of that we want to limit the tilt between -20 and 90 degrees – completely arbitrary:

        function BirdStep() {
            ...
            var ang = curSpeed * 5;
            bird.css({top: cPos.y, rotate:(ang < -20) ? -20 : (ang > 90) ? 90 : ang});
            ...
        }

Also we can introduce a nice animation when the bird dies – it will fall to the ground and rotate 540 degrees for one second and then wait for another half a second :

        function gameOver() {
            state = 2;
            $(":animated").stop();
            if (tmStep) tmStep = window.clearInterval(tmStep);
            bird.animate({ top:board.height()-cPos.h, rotate:540}, 1000)
                .animate({ top:board.height()-cPos.h}, 500, function() {
                    $('#score').text(' Score: ' + score);
                    start();
                });
        }

Beside that as you can see we are setting our game state to the ‘die’ mode so we don’t check for any clicks while we are showing the animation, stop all the animations (think parallax scrolling and moving obstacles), stop the birtd timer. After that we can play ‘die sequence’ and once done move back to the start screen.

Points of Interest

Just as I mentioned in the begining this was an initial version of the game that took me 2 hours to put together. Added a PhoneGap, threw onto the Galaxy and got completely bummed out: while working just fine on the slowest laptop, it would completely choke even on the best smart phone, so I had to spend next 2 days trying to improve performance – caching jQuery obstacles objects, accounting for time between timer executions not being as requested, … Even with all those improvements, depending on the model of your smartphone performance may be somewhat disappointing – check it for yourself at:

As far as $50,000/day – that didn’t quite materialize – in a last 3 month on the market I made a cool $20 off that game – or about $1/hr for the time I spend. Once again I attribute my success to the perfect timing and a little bit of luck. Good thing I already had Google developer account (one time $25), Apple Developer account ($99/year), Microsoft Store ($99/year) and Web Publishing ($49/year) – otherwise it could of been really expensive excersize. But since I already paid for those – it’s a $20 I didn’t have before – the glass is half full!

 

LINK: http://www.codeproject.com/Articles/778727/Build-Flappy-Bird-with-jQuery-and-lines-of-Javascr

Advertisements

Sử dụng ASP.NET MVC5 trong Visual Studio 2013

Khi bạn cài đặt Visual Studio thì mặc định đã có MVC 5 rồi

Khi cần tạo 1 project sử dụng MVC 5 trong Visual Studio 2013 bạn làm theo các bước sau

1. @Start Page –> New Project > Templates > Visual C# > Web > ASP.NET Web Application > PressOK > Select MVC > Press OK

– Lưu ý: Không chọn thư mục con Visual C# > Web > Visual Studio 2012

How to Enable / Disable Multiple RDP Sessions in Windows 2008 or 2008 R2

How to Enable/Disable Multiple RDP Sessions in Windows 2008 or 2008 R2
By default, Windows 2008/2008R2 servers allow two simultaneous Remote Desktop sessions. You may choose to disable multiple RDP sessions if desired. If only one session is available and you take over another person’s live session, you may choose to enable multiple RDP sessions. This article describes the process for disabling and enabling multiple sessions.

Disable Multiple RDP Sessions

  1. Log into the server using Remote Desktop.
    • In Windows 2008 R2
      • Click Start > Administrative Tools > Remote Desktop Services > Remote Desktop Session Host Configuration.
    • In Windows 2008
      • Click Start > Administrative Tools > Terminal Services >Terminal Services Configuration.
  2. Double click Restrict Each User to a Single Session.
  3. Check Restrict each user to a single session.

Enable Multiple RDP Sessions

  1. Log into the server using Remote Desktop.
    • In Windows 2008 R2
      • Click Start > Administrative Tools > Remote Desktop Services > Remote Desktop Session Host Configuration.
    • In Windows 2008
      • Click Start > Administrative Tools > Terminal Services >Terminal Services Configuration.
  2. Double click Restrict Each User to a Single Session.
  3. Uncheck Restrict each user to a single session.
  4. Click OK.

LINK: https://support.powerdnn.com/kb/a419/how-to-enable-disable-multiple-rdp-sessions-windows.aspx

PushSharp – Push Notifications to all Platforms

http://forums.xamarin.com/discussion/16/pushsharp-push-notifications-to-all-platforms (PushSharp – Push Notifications to all Platforms)
https://github.com/Redth/PushSharp (Source code + Ví dụ)
http://stackoverflow.com/questions/22350118/sending-messages-to-iphone-pushsharp-or-signalr (Phân tích trường hợp nào dùng SignalR, trường hợp nào dùng PushSharp)
– SignalR là một cách tốt để gửi thông tin thời gian thực tới một web client, về cơ bản server đẩy thông tin tới client và gọi code phía client (javascritp) ở thời gian thực.
– PushSharp là một cách tốt để đẩy thông báo tới các ứng dụng navtive cho mobile (không phải ứng dụng web), trong iOS nó sử dụng cơ sở hạ tầng của Apple, điều đó có nghĩa là
thông báo sẽ được hiển thị như một thông báo trong iPhone/iPad và không chỉ ở bên trong trình duyệt.
-> Nếu cần 1 ứng dụng native (gốc) trong iOS bạn nên dùng PushSharp, nếu cần một ứng dụng web chạy trong trình duyệt, bạn nên sử dụng SignalR
https://github.com/Redth/PushSharp/wiki/How-to-Configure-&-Send-Apple-Push-Notifications-using-PushSharp

Viber choose Couchbase for 3rd DB architecture

Được đánh giá là tăng tốc độ và giảm phần cứng.

Function-A Calling Another Function-B After A Returns

Introduction

Let’s say there are two functions, Foo1 and Foo2Foo2 needs to be called after Foo1, and only Foo1 can call Foo2:

A realistic scenario might be when Foo1 is invoked using a web service. Foo1 is called and needs to return as quickly as possible so that the calling client doesn’t hang. This means both Foo1 and Foo2 must be asynchronous functions, and that Foo2 must run after Foo1 has returned.

For Foo1 to be able to call Foo2 after Foo1 returns can be done in multiple ways. One way might be to have external queue into which tasks can be inserted so that they can be run when a certain state is set by a separate thread. This is good for scalable enterprise architecture, but seems a bit of an overkill when all we want to do is to call Foo2—afterFoo1.

Another way is using the timer object. A third way is using the relatively new ‘async’ method modifier.

The “async” function modifier was introduced in Visual Studio 2012/2013.

Before talking more about the async modifier, here is a complete listing of the code that is also attached to this tip. It’s a console application:

using System;

namespace MyCSasync
{
    using System.Threading;
    using System.Threading.Tasks;

    class MyClass
    {
        public static string[] Strings = new string[3];
        public static int Count = 0;

        private async Task Foo2()
        {
            await Task.Yield();

            Strings[Count++] = "Foo2 called at " + DateTime.Now.Ticks;
        }

        public async Task Foo1()
        {
            Strings[Count++] = "Foo1 at " + DateTime.Now.Ticks;

            // Call Foo2 asynchronously AND after this function returns.
            Foo2();

            Strings[Count++] = "End of Foo1 at " + DateTime.Now.Ticks;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            MyClass myclass = new MyClass();

            myclass.Foo1();

            while (MyClass.Count != 3) Thread.Sleep(1);
            foreach (string msg in MyClass.Strings)
            {
                Console.WriteLine(msg);
            }
        }
    }
}

While Foo1() is called asynchronously from the Main function, it could be called from a web service method which needs to return back to a client as quickly as possible so the client doesn’t seem to hang. Foo2() is a privatefunction that will need to be called after Foo1 completes.

Foo2 is partially executed so that Foo1 can return. This partial execution is just

    await Task.Yield()

This allows Foo2 to temporarily exit so that Foo1 can finish. The “Yield” method, as described by Microsoft, “creates an awaitable task that asynchronously yields back to the current context when awaited.” That’s exactly what we would like to do. There are other ways to do this. Using a delay. The problem with that approach is the behavior of the code may change depending on how fast your computer is. This is easy to test. If you use Task.Delay(1), which is 1 millisecond, it is more than enough to make the code above seem to be behaving the same. If you change the Delayparameter to a TimeSpan object with 1 tick, you may see that the code no longer works as expected.

When you run the code above (ctrl-F5), you should see something similar to:

Foo2 is called after Foo1. Note the tick difference, about 20,000. On my machine, that’s about 3200th of a second. So a delay of 1 second would seem to work, but certainly not 1 tick. As an exercise, change the code “await Task.Yield()” to “await Task.Delay(1)” and you’ll likely see that Foo2 is called after Foo1. Now change it to “await Task.Delay(TimeSpan.FromTicks(1))“. You will see that Foo2 is called before “End of Foo1“. This is because Foo2‘s await took less time than Foo1 could return.

LINK: http://www.codeproject.com/Tips/768633/Function-A-Calling-Another-Function-B-After-A-Retu

Link tham khảo ASP.NET MVC

1. SmartStore.NET – Free ASP.NET MVC Ecommerce Shopping Cart Solution
http://smartstore.codeplex.com/
2. Design and Develop a website using ASP.NET MVC 4, EF, Knockoutjs and Bootstrap
http://ddmvc4.codeplex.com/wikipage/history
3. EFMVC – ASP.NET MVC 4, Entity Framework 5 Code First and Windows Azure
http://efmvc.codeplex.com/
4. MVC 5 Forum
http://themvcforum.codeplex.com/
5. JQuery DataTables ASP.NET MVC
http://datatablesmvc.codeplex.com/
6. jQuery Grid for ASP.NET MVC
http://jqmvcgrid.codeplex.com/
7. MVCwCMS – ASP.NET MVC CMS
http://mvcwcms.codeplex.com/
8. Voting Control using MVC5 and Razor
http://www.codeproject.com/Articles/772887/Voting-Control-using-MVC-and-Razor