你如何让游戏随着时间的推移补充其生命?

时间:2014-04-08 18:00:04

标签: android actionscript-3 flash

我正在使用Action Script3 Flash pro cc。我试图在我的游戏中编写代码,以便随着时间的推移补充玩家的生命。但我没有成功。例如,在“Candy Crush”中,它被称为“生命”。你最多可以有5条生命。一旦你开始了一个关卡,它将从5个生命中夺走1点生命。然后生命标签旁边的计时器从20分钟开始倒计时到0,一旦达到0,它就会给你一次生命,这样你就可以再次开始一个关卡。我尝试这样做:Frame LifeListener在生命数低于5时从20分钟倒计时到0,一旦达到5,停止倒数。听起来很简单,很简单。但是如果玩家在计时器倒计时退出游戏怎么办?假设玩家在下午3:10离开游戏,剩下3个生命,剩下10分钟让生活充实。并且玩家在下午3:30再次开始游戏。然后玩家将有4条生命和10分钟的生命补充。我试图通过使用日期类来完成此任务。但是每当我退出游戏并重新开始游戏时,剩下的时间就会搞乱。

1 个答案:

答案 0 :(得分:2)

基本上你需要跟踪你上次获得自由生命的时间,然后只是将当前时间与最后一次进行比较,看看有多少生命可以给予。

您需要在某处存储lastFreeLifeTS时间戳,因此您有2个选项:

  • 本地 - SharedObject或XML文件,具体取决于您是否在网上,或者使用AIR作为移动应用。正如@DodgerThud指出的那样,通过查找文件并修改值或更改系统时间,这很容易作弊。虽然Candy Crush做到了这一点,但你必须决定这对你来说是否是一个非常重要的问题
  • 在线 - 理想情况下,您可以将此时间戳存储在服务器上,在这种情况下,最好将此逻辑移到那里,因此服务器决定何时获得免费直播(通过告诉客户端,或者客户端可以在认为它应该有服务器时轮询服务器

获取时间戳非常简单:

this.lastFreeLifeTS = ( new Date() ).time;

当你要么a)给予新的自由生命,或者b)在你最大的时候使用生命(那时你希望你的下一个自由生命在那个时间点的最大时间到来),请打电话给你。

然后你需要处理2个问题:

  • 玩家应该在游戏中获得生命
  • 当玩家在X时间后回来时

第一个很简单 - 只需要一个倒计时器(注意:你不需要每帧一次 - 这比你需要的更高保真度。每隔一秒左右就是你需要的)。当你的时间到了,给予生命:

var currTime:Number = ( new Date() ).time;
var diff:Number = ( currTime - this.lastFreeLifeTime );
var lifeTime:Number = 1000 * 60 * 20; // give a life every 20 minutes
if( diff > lifeTime )
{
    giveFreeLife();
    this.lastFreeLifeTime += lifeTime;
}

如果您知道什么时候开始新生活,您几乎可以用getTimer()替换它,这意味着您无需继续创建新的Date个对象时间。

// starting off
var lifeTime:Number = 1000 * 60 * 20; // 20 minutes
var msUntilNextLife:Number = ( ( new Date() ).time - this.lastFreeLifeTime ) + lifeTime;
this.nextFreeLifeTime = getTimer() + msUntilNextLife;

...

// check if we need to give a new life
if( getTimer() > this.nextFreeLifeTime )
{
    giveFreeLife();
    this.lastFreeLifeTime += lifeTime;
    this.nextFreeLifeTime += lifeTime;
}

对于第二个,你只需要在开始游戏时检查时间戳,并给予必要的免费生命,然后你回到上面的第一种逻辑。

// load our SharedObject/XML and set our lastFreeLifeTime
...

// check how much time has passed and give any lives necessary
var currTime:Number = ( new Date() ).time;
var diff:Number = currTime - this.lastFreeLifeTime;
var lifeTime:Number = 1000 * 60 * 20; // 20 minutes
var numLives:int = int( diff / lifeTime );
if( numLives > 5 )
    numLives = 5; // only give a maximum number of lives
if( numLives > 0 )
{
    giveFreeLives( numLives );

    // update our lastFreeLifeTime only if we didn't give the max number of lives
    // (as otherwise we don't need it)
    // NOTE: because we're adding (lifeTime * numLives), it handles the time between
    // lives nicely. E.g. If we get a life every 20m and we come back after 30m, then
    // our lastFreeLifeTime will be (20 * i), meaning a 10m difference between the 
    // current time, meaning we only have to wait 10m to get our next one
    if( numLives < 5 )
        this.lastFreeLifeTime += lifeTime * numLives;
}

更新 - 从互联网上获取时间

从网络获取时间戳的最简单方法是自己控制源码;即你拥有你要求时间戳的服务器/网页。

一个简单的解决方案是将以下php代码托管在某个文件中:

<?php
    echo round( microtime( true ) * 1000 );
?>

所有这一切都是打印页面的当前时间戳。您应该可以使用URLLoader

来阅读时间
// NOTE: add all the other listeners, like IOErrorEvent, and SecurityErrorEvent
var urlLoader:URLLoader = new URLLoader( new URLRequest( "http://myserver.com/timestamp.php" ) );
urlLoader.addEventListener( Event.COMPLETE, onGetTime );

function onGetTime( e:Event ):void
{
    // remove our event listener so we can clean up
    var urlLoader:URLLoader = ( e.target as URLLoader );
    urlLoader.removeEventListener( Event.COMPLETE, onGetTime );

    // the data is the timestamp returned by php, as a string, so convert it
    var timestamp:Number = Number( urlLoader.data );
    if ( isNaN( timestamp ) ) 
    {
        trace( "Couldn't get the timestamp from the server! Returned details: " + urlLoader.data );
        timestamp = ( new Date() ).time; // fallback to client
    }

    // do something with the time
}

这种方法的问题

  • 这很慢;每当您需要知道当前时间时,您就会发出Web请求。由于延迟,您获得的时间不会是实际的当前时间。对于大多数情况,这不是问题,但
  • 您需要互联网连接;如果用户关闭他们,这将无法正常工作
  • 您可能遇到安全问题,需要托管一个crossdomain.xml(可能)
  • 这很麻烦;它比简单的(new Date()).time更尴尬;你现在需要在某处托管这个文件;如果您的游戏成功,您的服务器可能会很快受到攻击,具体取决于您拥有多少玩家以及您有多少次呼叫

由您决定是否值得。如果您的游戏已经有服务器组件,那么这通常不是问题。我建议你先让它在客户端工作,必要时再回来(即你有很多玩家作弊)