Candy Crush Saga Type 倒计时生命系统 jQuery & Phonegap

Posted

技术标签:

【中文标题】Candy Crush Saga Type 倒计时生命系统 jQuery & Phonegap【英文标题】:Candy Crush Saga Type countdown life system jQuery & Phonegap 【发布时间】:2014-04-08 22:54:40 【问题描述】:

我正在开发一个应用程序,我对实现 Candy Crush Saga Type 倒计时生命系统的方法很感兴趣。 我的应用程序是在 phonegap 中开发的(所以 html、css jquery 和 jquery mobile),直到现在我还没有弄清楚如何使用外部文件,因为我认为这个算法需要它。 因此,我希望拥有 5 条生命,并且当用户失败或退出 lvl 并在 10 分钟后重新生成时,它们中的每一条都会消失。如果应用程序关闭,如何保持计数器处于活动状态? 或者日期减法算法...

如果有人对 Phonegap 有了解,我将非常感激他能帮助我使用 jsfiddle,我将在我的应用程序中进一步实施。

我也不知道该用什么:localstorage vs DB

我将提供 50 的赏金给可以帮助我解决此问题的 jsfiddle 示例的人。

谢谢!

【问题讨论】:

怀疑将“生命”存储在可操作的本地存储上是个好主意。尤其是当您考虑在人们之间进行在线排行榜/竞争时-大多数游戏恰好是关于..我建议您做一个小型服务器后端(NodeJS会很好),这将挽救并恢复生命播放器。每当有人开始关卡时,从服务器加载关卡数据,这样人们每次开始关卡时都会失去生命。对于重新生成,保存一个时间戳,如果在任何请求上给出最后生命 > 10 分钟前,则相应地添加 1-5 以表示从那以后经过的时间。 @user1610743 好吧,游戏不在线.. 就像糖果迷一样,当我开始一个 lvl 时,游戏中就会有生命,如果我失去生命,如果我通过了 lvl,我就会失去生命到达下一个生活保持不变。我也不确定要使用什么:localstorage vs DB?带有时间戳的部分很好,但是如果我失去了总共 5 条生命中的 3 条,而我在玩第二条时,第三条必须重新生成,如果我不松开,第四条和第五条必须重新生成。如果我也丢失了第二个丢失了...我是 jquery 的新手,phonegap 并且我迷路了。如果你有更多的知识,你可以发布一个 jsfiddle 例子吗? 【参考方案1】:

编辑:对不起,这是一些基于 php 的伪代码 - 但你不需要疯狂的算法或任何东西

我不编写手机应用程序,但我知道你想做什么,而且你想得太苦了。当应用程序关闭时,您不需要运行计数器。您可以保存游戏结束时的时间戳,并在下次打开应用时引用它。

start_game();

if($lives > 0) //run game
    if($death === true)
        $lives = $lives - 1;
        $timer_value = date(Y-m-d h:i:s);
        end_game($timer_value); //save starting time locally in "end_game" function
    

 else 
    //buy more lives

现在假设用户关闭它并打开它。您可以参考当前时间与保存的时间。此后每 10 分钟,增加一条生命。

$old_time = strtotime($timer_value); //635393400
$cur_time = strtotime(date(Y-m-d h:i:s)); //635394600

if( $cur_time - $old time > 600 )  $lives = $lives + 1; 
if( $cur_time - $old time > 1200 )  $lives = $lives + 2; 
if( $cur_time - $old time > 1800 )  $lives = $lives + 3; 
if( $cur_time - $old time > 2400 )  $lives = $lives + 4; 
if( $cur_time - $old time > 3000 )  $lives = $lives + 5; 
if( $lives > 5 )  $lives = 5; 

这是一些糟糕的代码,哈哈,但你明白了这个想法。您不需要在后台运行计时器(您不能真正关闭应用程序,而不进行某种在线服务器检查,这基本上是同一件事,但将所有个人生活记录托管在云中而不是在手机上。

【讨论】:

但是例如,如果我目前正在玩 4'ts 并且游戏还没有结束,那么 5 livee 也应该重新生成。所以如果我不关闭应用程序,他们应该重新生成 alos。重生应该从我失去生命的那一刻开始。关于如果你告诉我的,例如,如果我失去了 t 条生命并且当前时间是 1200,那么将增加 3 条生命,因为如果 > 600,它也会出现在第一个生命中;这不是我想要的情况。还有一个问题,存储呢?我应该使用哪个?本地存储还是数据库?所以实际上整个人生经历应该和糖果迷一样。【参考方案2】:

在这段代码中,我使用localStorage,因为它们在所有平台和网络上都可用。 使用本地存储,您将获得更好的跨平台兼容性:

WebStorage (localStorage & sessionStorage) IndexedDB SQL-Storage

Localstorage 是数组,但每个元素中只能有字符串(使用 JSON 我们可以存储任何东西,不是递归的)。网络大约为 5MB。我想这对于移动应用程序来说是无限的。当用户关闭浏览器时,SessionStorage 被删除,我不确定它在移动设备上会如何做。

只是一个小的日期验证器......

Date.prototype.isValid = function(first_argument) 
    if ( Object.prototype.toString.call(this) !== "[object Date]" )
        return false;
    return !isNaN(this.getTime());

从localStorage检索变量中的主要var声明

var timeout = null;
var maxlife = 5;
if (undefined === localStorage.life) 
    localStorage.life = maxlife;

if (undefined === localStorage.date||localStorage.date=="") 
    localStorage.date = "";
    var date = null;
else
    var date = new Date(Number(localStorage.date));
    if(!date.isValid())
        date = null;
    

var timeoutTime = 5 * 60000;
var life = Number(localStorage.life);

失去生命,如果还没有,请设置日期。也设置一个超时并减去生命(并将其写入本地存储)。

function loseLife() 
    if (null === date) 
        date = new Date();
        localStorage.date = date.getTime();
        timeout = setTimeout(function()addLife(), timeoutTime);
    
    life--;
    localStorage.life = life;
    lives.innerHTML = life;
    console.log(life);

添加生命,设置日期新日期或完全重置日期。如果需要,设置超时,并添加生命(并将其写入本地存储)。

function addLife() 
    life++;
    localStorage.life = life;
    if (life < maxlife) 
        date = new Date();
    localStorage.date = date.getTime();
        timeout = setTimeout(function()addLife(), timeoutTime);
     else 
        date = null;
    localStorage.date = "";
    
    lives.innerHTML = life;

在这里,您可能需要更改模糊(窗口不可见)和焦点(窗口再次可见)的挂钩。模糊只是清除超时,所以它不会打扰我们。

window.addEventListener('blur', function () 
    clearTimeout(timeout);
);

这个函数检查它可以从现在和我们失去生命的日期的差异中减去我们获得生命所需的时间。

function tillNow()
    if (life < maxlife&&date!=null) 
        var d = new Date();
        var diff = d - date;
        while (diff - timeoutTime > 0) 
            diff = diff - timeoutTime;
            if (life < maxlife) 
                life++;
                console.log("add");
            else
                date = null;
                localStorage.date = "";
                break;
            
        
        localStorage.life = life;
        if (life < maxlife) 
            date = new Date((new Date()).getTime()-diff);
            localStorage.date = date.getTime();
            timeout = setTimeout(function()addLife(), timeoutTime-diff);
        
    
    lives.innerHTML = life;

焦点只需调用tillNow()

window.addEventListener('focus', function () 
    tillNow();
);

Onload 的作用与焦点相同,但最初用一个值填充 div...

window.onload=function()
    var lives = document.getElementById("lives");
    lives.innerHTML = life;
    tillNow();

Demo 抱歉不能做 codepen 的 jsFiddle,因为他们不喜欢本地存储。 (演示使用 15 秒作为计时器来获得新的生活;)我很不耐烦)

【讨论】:

嘿伙计!我试图在我的应用程序中实现脚本,因为我担心它不能 100% 正确工作。当我关闭应用程序时,生命的再生不再起作用。此外,如果我最小化应用程序并返回它,有时它会增加不必要的生命,即使 15 se 还没有结束……我在设备中实现了整个脚本准备好了……可以吗?你能帮我一点忙吗?这是我当前使用您的脚本的应用程序...dl.dropboxusercontent.com/u/89068397/android.rar 我记得对代码做一些修改,如果你复制demo中的js,你肯定会拥有最新版本,我可能忘记在这里镜像,请告诉我,如果您将 JS 从 Web 复制到您的应用程序,它是否有效。我没有安卓,现在不在家 它仍然无法与最新版本一起使用。我今天一整天都做了一些测试,以确定问题出在哪里,但这很奇怪。因此,如果我进入应用程序一切正常(它们应该重新生成)如果我删除生命直到 0 并且我关闭应用程序并重新输入它,数字仍然是 0。如果我再次按下按钮它是 -1 并且没有任何东西再生.在这一刻,如果我最小化应用程序并重新输入它,则生命被设置为好像最初的“计数器”正在工作,但如果再次按下按钮,它们仍然不会重新生成。我必须最小化和最大化几次才能工作 我在手机和涟漪模拟器上进行了测试,效果几乎相同。我也注意到你的演示中的那些错误,但我不知道是什么原因造成的。我能发现的是,有时本地存储(以及界面中)的生命周期和日期在我单击按钮之前不会更新。当我这样做时,它们有时会开始再生,有时不会。这很奇怪。当您在家时,请查看我的代码。也许我没有包含您正确提供的功能。而且你也可以在没有android的rippe上测试它。 我可能会找到它...在 || 的地方有 &&什么wac导致重生所有生命。它位于代码的第 145 行。我找不到任何其他错误,但如果你找到了,请告诉我。【参考方案3】:

我会使用类似于 Xhynk 建议的逻辑。我会使用像 milisecondsUntilYouGainALife 这样的变量,当你失去第一个生命时,设置这个变量 = 1000ms*60sec*10min = 600000。然后在主循环中的第一行(左右)记录当前时间。下次它到达循环时,还要记录时间并从毫秒UntilYouGainALife 中减去差值。如果

伪代码:

function game()
    ...
    while(mainLoop)
         oldTime = curTime
         curTime = GetTime() //I Forget the exact code to get the miliseconds
         deltaTime = curTime - oldTime
         if(deltaTime > milisectionsUntilYouGainALife)
            if(lives < MAX_LIVES)
                lives++
                milisecondsUntilYouGainALife - deltaTime
             
          

    

function AppClosing()
    curTime = GetTime()
 
function LoseALife() 
    milisecondsUntilYouGainALife += 600000

我可能缺少一些东西,但这应该会让你走上正轨!

【讨论】:

以上是关于Candy Crush Saga Type 倒计时生命系统 jQuery & Phonegap的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode 723. Candy Crush

LeetCode 723. Candy Crush

[LeetCode] Candy Crush 糖果粉碎

[LeetCode] 723. Candy Crush 糖果粉碎

消消乐candy crush类三消游戏程序逻辑分析

使用 Cocos2d-x + Marmalade 制作类似 Candy Crush 的地图