Apsaradb for redis is used as the ranking data storage in casual games.

Source: Internet
Author: User
Tags autoload

Apsaradb for redis is used as the ranking data storage in casual games.
1. Ranking requirements

I have made a website http://www.cgame360.com/, dedicated to a few simple html5game. Now I have two requirements: I want to score the top 10 users in a game, and I want to rank some users, plus the first and fourth employees. If the name is missing, the cocos2d js input box will not be added if it is a problem. What database is better to store? I want to find the data as quickly as possible. I have worked on a relational database like mysql. I feel it will be slow to use it here. A large amount of data will be very slow, because it will process all the data during sorting. The second requirement is that using SQL statements can be very painful. I did not expect an efficient implementation method. For the first 10 users, you can create a table to store the first 10 users. It is mainly stuck in the second requirement. I Googled and found that nosql is more suitable for today's needs. Nosql is famous for Hadoop and MongoDB. However, I found a database redis that is more suitable for this requirement.
2. Ordered Set in redis
2.1insert a data entry into an ordered set of redis
There is no time to start from installing redis. I remember it seems that the Mac system is relatively easy to use, and windows does not seem very easy to use redis. It is very easy to insert a data entry into an ordered set of redis: ZADD key score memeber specific example: ZADD game1 89 tom so that there is a piece of data in game1, Tom's score is 89
2.2 redis obtains the list of elements ranked in a certain range.
ZRANGE key start stop [withscores] ZREVRANGE key start stop [withscores]
For example, ZRANGE game1 0-1 withscores to obtain all records in game1, sorted in ascending order.-1 indicates the meaning of the last element. So what command should we use to get the first 10 records? Very simple: ZRANGE game1-10-1 withscores-10 indicates the meaning of a number of 10. Below is the output of my mac machine execution:

127.0.0.1:6379> zrange g_1 -10 -1 withscores 1) "tom5" 2) "506" 3) "tom6" 4) "507" 5) "hug" 6) "600" 7) "tom" 8) "5000" 9) "tom8"10) "5088"11) "tom9"12) "5089"13) "tom10"14) "5090"15) "tom11"16) "5091"17) "tom12"18) "5092"19) "tom13"20) "5093"

Zrevrange indicates the reverse direction, which is output from large to small.

2.3 redis gets an element ranking
ZRANK key member ZREVRANK key memeber example: zrank game1 tom
2.4 redis gets an element score
ZSCORE key member example: zscore game1 tom
3. Use redis in PHP
The redis commands mentioned above are enough for us to use. Next we will use redis, java, php, and other server languages to form a service. I chose PHP here. I feel that users can submit a post with http scores and get the ranking scores using php get. There are two methods for using redis in php: predis and phpredis. The former is completely php, and the latter is php extension written in C language. The latter provides better performance, but it is troublesome to install php extensions. Predis is very simple, that is, some PHP files can work by throwing them into the website directory. Predis is used here.
3.1 insert a data record
<?phprequire './predis/autoload.php';$redis = new Predis\Client(    array(        'scheme'=>'tcp',        'host'=>'127.0.0.1',        'port'=>6379, ));//header("content-type:text/html;charset=utf-8");if(trim($_POST['game_id']) == '' || trim($_POST['user_name']) == ''  || trim($_POST['score']) == ''){    echo 'need more information!';    exit;}else{    // echo 'OK';    // echo $_POST['game_id'];    // echo $_POST['user_name'];    // echo $_POST['score'];    $game_id = "g_" . $_POST['game_id'];    $name = $_POST['user_name'];    $score = $_POST['score'];    if($score > 0){       $beforeScore = $redis->zscore($game_id, $name);       if($score > $beforeScore){         $itemScore = array($name => $score);         $redis->zadd($game_id, $itemScore);       }    }    }

Here, I simply determined whether his current score is higher than the previous score. If his score is higher than the previous score, I inserted a piece of data. Very simple.
3.2 get the first 10 player scores
<?phprequire './predis/autoload.php';$redis = new Predis\Client(    array(        'scheme'=>'tcp',        'host'=>'127.0.0.1',        'port'=>6379, ));if(trim($_GET['game_id']) == ''){    echo 'need game_id';}else{$game_id = "g_" . $_GET['game_id'];    $board_score = $redis->zrange($game_id, -10, -1, 'withscores');    //print_r($board_score);    echo json_encode($board_score);    //echo $board_score;}

It looks very simple here. Finally, I used json_encode to convert the array in php to json. This facilitates processing.
3.3 get my ranking
<?phprequire './predis/autoload.php';$redis = new Predis\Client(    array(        'scheme'=>'tcp',        'host'=>'127.0.0.1',        'port'=>6379, ));if(trim($_GET['game_id']) == '' || trim($_GET['user_name']) == ''){    echo 'need game_id and name';}else{$game_id = "g_" . $_GET['game_id'];    $user_name = $_GET['user_name'];    $userCurrentRange = $redis->zrevrank($game_id, $user_name);      //echo 'current range:' . $userCurrentRange;    $result = array();    if(true){        $halfCount = 4;         $leftRank = $userCurrentRange - $halfCount;        $rightRank = $userCurrentRange + $halfCount;        if($leftRank < 0){          $leftRank  = 0;        }        $board_score = $redis->zrevrange($game_id, $leftRank, $rightRank, 'withscores');        $index = 0;        foreach($board_score as $name => $score){           if($name == $user_name){               break;           }else{               $index = $index + 1;           }       }        $firstRank = $userCurrentRange - $index + 1;        foreach($board_score as $name => $score){           $eachItem = array();           $eachItem['name'] = $name;           $eachItem['score'] = $score;           $eachItem['rank'] = $firstRank;           $result[] = $eachItem;           $firstRank = $firstRank + 1;        }        echo json_encode($result);     }else{        echo json_encode($result);    }     }

This is a little more complicated. I first get the ranking of this player, so that I can get the ranking range of the four players before and after him. Then I can use zrevrange. Note that if left is a negative number, it means other things, so avoid negative numbers. Finally, I added the ranking information to the php array and returned it in json again.
4.0 talk about http in cocos2d js
Php can now return json data. Let's talk about how to use http in cocos2d js to display top 10 player information. The code is provided here, which is also relatively simple. It is important to handle the returned data in JSON. parse. Use post to insert data, and get the ranking information with get. I have not added the anti-cheating feature.
getJsonFromUrl:function(){        var xhr = cc.loader.getXMLHttpRequest();        var args = "?game_id=" + gameId;        xhr.open("GET", rankBoardURL + args, true);        xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");        xhr.onreadystatechange = function () {            if (xhr.readyState == 4 && (xhr.status >= 200 && xhr.status <= 207)) {                var response = xhr.responseText;                cc.log("res:" + response);                cc.log("send success");                var obj = JSON.parse(response);                this.initContent(obj);            }        }.bind(this);        xhr.send();    },    initContent:function(jsonValue){        var size = cc.director.getWinSize();        var fontDefBlueStroke = new cc.FontDefinition();        fontDefBlueStroke.fontName = "Arial";        fontDefBlueStroke.fontSize = 50;        fontDefBlueStroke.textAlign = cc.TEXT_ALIGNMENT_LEFT;        var jsonLength = 0;        for(var name in jsonValue){            jsonLength++;        }        cc.log("jsonlength:" + jsonLength);        var nameMargin = 50;        var nameStartPositionY = 800 - nameMargin * jsonLength;        var lastRank = jsonLength;       for(var name in jsonValue){          cc.log(name);          cc.log(jsonValue[name]);          this.rankLabel = new cc.LabelTTF(lastRank + ':', fontDefBlueStroke);          this.addChild(this.rankLabel);          this.rankLabel.x = 100;          this.rankLabel.y = nameStartPositionY;          this.rankLabel.setAnchorPoint(cc.p(0, 0.5));          this.nameLabel = new cc.LabelTTF(name, fontDefBlueStroke);          this.addChild(this.nameLabel);          this.nameLabel.x = size.width * 0.5 - 100;          this.nameLabel.y = nameStartPositionY;          this.nameLabel.setAnchorPoint(cc.p(0, 0.5));          this.scoreLabel = new cc.LabelTTF(parseFloat(jsonValue[name]).toFixed(2), fontDefBlueStroke);          this.addChild(this.scoreLabel);          this.scoreLabel.x = size.width * 0.5;          this.scoreLabel.y = nameStartPositionY;          this.scoreLabel.setAnchorPoint(cc.p(0, 0.5));          nameStartPositionY = nameStartPositionY + nameMargin;          lastRank = lastRank - 1;       }    }


Finally, let's play this html5 game that uses the technology mentioned above, developed with cocos2d js. Http://www.cgame360.com/halloweengame/

I have packaged the entire ranking PHP service into a file and click the link below to download it. Predis is included. If you have a mac or linux system, install php, redis, and so on, unzip the package to the root directory of the website. I am also using redis for the first time. Please comment out in my comments. Thank you. Http://www.waitingfy.com /? Attachment_id = 1421



Http://www.waitingfy.com/archives/1420


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.