我正在使用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分钟的生命补充。我试图通过使用日期类来完成此任务。但是每当我退出游戏并重新开始游戏时,剩下的时间就会搞乱。
答案 0 :(得分:2)
基本上你需要跟踪你上次获得自由生命的时间,然后只是将当前时间与最后一次进行比较,看看有多少生命可以给予。
您需要在某处存储lastFreeLifeTS
时间戳,因此您有2个选项:
SharedObject
或XML文件,具体取决于您是否在网上,或者使用AIR作为移动应用。正如@DodgerThud指出的那样,通过查找文件并修改值或更改系统时间,这很容易作弊。虽然Candy Crush做到了这一点,但你必须决定这对你来说是否是一个非常重要的问题获取时间戳非常简单:
this.lastFreeLifeTS = ( new Date() ).time;
当你要么a)给予新的自由生命,或者b)在你最大的时候使用生命(那时你希望你的下一个自由生命在那个时间点的最大时间到来),请打电话给你。
然后你需要处理2个问题:
第一个很简单 - 只需要一个倒计时器(注意:你不需要每帧一次 - 这比你需要的更高保真度。每隔一秒左右就是你需要的)。当你的时间到了,给予生命:
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
}
这种方法的问题
(new Date()).time
更尴尬;你现在需要在某处托管这个文件;如果您的游戏成功,您的服务器可能会很快受到攻击,具体取决于您拥有多少玩家以及您有多少次呼叫由您决定是否值得。如果您的游戏已经有服务器组件,那么这通常不是问题。我建议你先让它在客户端工作,必要时再回来(即你有很多玩家作弊)