开几秒停几秒的桌面闹钟秒表定时器器

当前位置: >
> 走在网页游戏开发的路上(五)在游戏开发中计时器/定时器是必须的,而且会在多处用到,如吃药补血每秒回
走在网页游戏开发的路上(五)在游戏开发中计时器/定时器是必须的,而且会在多处用到,如吃药补血每秒回
wangruibing & at
走在网页游戏开发的路上(五)
  在游戏开发中计时器/定时器是必须的,而且会在多处用到,如吃药补血每秒回10点且持续1分钟、玩家从一点到达另一点的过程需要多少时间。下面是定时器在七雄争霸中的几个应用场景,直接上图:
  场景1:建筑升级时间
  场景2:建筑升级时间
  场景3:科技研究时间
  类似的场景还有很多,就不一一列举了。但有一点可以肯定的就是,不可能每个地方都去new一个定时器各自管理,这样会消耗大量CPU和内存,从而导致游戏不流畅,画面卡卡的。所有一般游戏中都只维护一个全局的定时器,这也是本文的主要内容——ActionScript3页游开发中如何设计全局的定时器。
定时器的几种设计
  下面介绍如何设计游戏中全局的定时器,首先我们来看看常用的定时器设计。通常定时器具有以下功能:
启动定时器
停止定时器
定时器定期执行间隔(总共执行多次)或者超时执行(总共执行1次)
有的游戏中还需要暂停定时器、恢复定时器的功能
  关于游戏中的定时器的设计有以下两种争议:
  1)   
每个需要定时器的地方都创建一个,然后问题归结为多个定时器的管理问题;
  2)   
游戏中只有一个定时器,然后问题归结为一个定时器实现多个定时器的效果。
  实际从管理难度以及运行效率上来讲应该选择第2种。
  START_TIMER = O(1)
  STOP_TIMER = O(1)
  PER_TICK_BOOKKEEPING = O(n)
  START_TIMER = O(n)
  STOP_TIMER = O(1)
  PER_TICK_BOOKKEEPING = O(1)
  START_TIMER = O(log(n))
  STOP_TIMER = O(1)
  PER_TICK_BOOKKEEPING = O(1)
  START_TIMER = O(n)
  STOP_TIMER = O(1)
  PER_TICK_BOOKKEEPING = O(1)
  START_TIMER = O(1)
  STOP_TIMER = O(1)
  PER_TICK_BOOKKEEPING = O(1)
  (每个桶中元素有序)
  START_TIMER = 最坏O(n)、平均O(1)
  STOP_TIMER = O(1)
  PER_TICK_BOOKKEEPING = O(1)
  (每个桶中元素无序)
  START_TIMER = O(1)
  STOP_TIMER = O(1)
  PER_TICK_BOOKKEEPING = 最坏O(n)、平均O(1)
  START_TIMER = O(m),m是轮子的数量
  STOP_TIMER = O(1)
  PER_TICK_BOOKKEEPING = O(1)
  上面几种定时器设计可以总结为使用4种数据结构实现:Heap、List、Hash、Wheel。著名的ACE中的定时器按照这4种方式分别都给与了实现,具体的4种定时器都是从ACE_Timer_Queue_T继承,每种定时器用不同的数据结构来实现具体Timer的算法。
  1)ACE_Timer_Heap定时器,根据触发时间建立一个优先级队列(一个最小堆数据结构)来维护所有的定时器,代价就是删除和插入过程为O(logn),代价比较高。
  2)ACE_Timer_List定时器,根据触发时间建立一个有序的双向链表,代价就是插入定时器代价较高。
  3)ACE_Timer_Hash定时器,采用开链的Hash方式每一个桶为一个单链表,在检查所有桶超时的时候会遍历链表所有的元素。为了提高效率这里所用的Hash桶应该足够大,而对于定时器一般是频繁的超时响应定时器,已经插入和删除,响应会采用迭代的方式。所以效率并不是那么高效。
  4)ACE_Timer_Wheel定时器,采用的一种时间轮的方式,具体实现就好象一个轮子上面有很多插槽,每一个插槽下面包括一个有序双向链表,在Ace中把轮子叫做Wheel,插槽叫做Spoke,每一个定时器被Hash到Spoke中,而Spoke也可以理解为timer的分辨率,而Spoke的计算公式为:(触发时间 $>$ 分辨率的位数)&(spoke大小-1)。然后在根据触发时间把定时器插入到每一个Spoke的有序双向链表中,与Ace_timer_Hash的实现类似,只是这里用户可以指定Spoke大小。这里代价就是插入的时候可能最坏为O(n)。
定时器的简单实现
  我所在的Flash网页游戏项目中使用了简单的实现方式,游戏中只有一个定时器,然后问题归结为一个定时器实现多个定时器的效果。定时器使用ActionScript3中的Timer类。
  定时器类(Timer Class)是ActionScript 3.0的内置类,通过AS3的事件分发响应机制实现周期触发。定时器是一个简单却又极为常用的类,系统全面的掌握它是非常必要的。(摘自ActionScript3 帮助文档)
  Timer定时器是精确的,但是定时器的执行结果并非绝对精确。无论是Flash还是Flex,最终的应用程序都是以SWF文件存储。而FlashPlayer在解释SWF文件时,会建立基于帧率的周期循环。每次舞台更新的时间间隔是固定的,脚本中的舞台操作会受到时间轴帧率的制约。
  作为一个多线程的应用程序,FlashPlayer 执行脚本不需要依赖帧率,但是所有的屏幕输出都要借助FlashPlayer的渲染引擎。如果时间轴帧率为10,则运行时舞台每100毫秒播放一帧。当间隔为80毫秒的定时器触发时,SWF应用程序立刻执行该定时器的侦听函数,但是在定时器侦听函数中的任何屏幕操作,都不会及时的反应在舞台上。只有在100毫秒时,FlashPlayer才会更新舞台显示。定时器在160毫秒第二次触发时,SWF应用程序需在200毫秒更新舞台显示。理论上8000毫秒内执行100次定时器,但实际上在帧率为10的SWF应用中,舞台更新只有80次。有可能在舞台刷新间隔内,连续执行两次定时器操作。
  定时器的触发事件间隔可以自由设置,所有的定时器事件都不会错过。屏幕显示虽然不是实时更新,但是由于刷新的速度很快,不会造成显著影响。实际上,任何语言的定时器都要受制于系统时钟,都不是绝对精确的。
  上述原因也是我们采用定时器的简单实现方式的原因之一,下面上代码。
  定时器:
  package
&!--CRLF--&
&!--CRLF--&
  import flash.events.TimerE
&!--CRLF--&
  import flash.utils.T
&!--CRLF--&
  import flash.utils.getT
&!--CRLF--&
&!--CRLF--&
  public class MyTimer
&!--CRLF--&
&!--CRLF--&
  private static var _instance:MyT
&!--CRLF--&
  private var _timer:T
&!--CRLF--&
  private var _timerList:A
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  * 获取单例类MyTimer的实例
&!--CRLF--&
  * 返回值:
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  public static function getInstance():MyTimer
&!--CRLF--&
&!--CRLF--&
  if (_instance == null)
&!--CRLF--&
  _instance = new MyTimer();
&!--CRLF--&
&!--CRLF--&
  return _
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  * 构造函数,用于防止单例类生成多个实例
&!--CRLF--&
&!--CRLF--&
  public function MyTimer()
&!--CRLF--&
&!--CRLF--&
  if (_instance != null)
&!--CRLF--&
  trace("单例类,请不要实例化");
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  * 注册计时器,首先检查id是否存在,如果不存在,就将定时器插入数组_timerList中;否则啥都不做
&!--CRLF--&
  * 参数:
&!--CRLF--&
id - 唯一标识一个定时器
&!--CRLF--&
interval - 刷新间隔,单位为秒(s)
&!--CRLF--&
repeatCount - 重复次数
&!--CRLF--&
callback - 回调函数,每隔interval就执行一次
&!--CRLF--&
...args - 回调函数参数 ///注意,参数实际并没有用到,有待改进
&!--CRLF--&
  * 返回值:空
&!--CRLF--&
&!--CRLF--&
  public function registerTimer(id:String, interval:int, repeatCount:int, callback:Function, ...args):void
&!--CRLF--&
&!--CRLF--&
  if (_timerList == null)
&!--CRLF--&
  _timerList = new Array();
&!--CRLF--&
&!--CRLF--&
  if ( check(id) == -1 )
&!--CRLF--&
&!--CRLF--&
  _timerList.push( { id:id, interval:interval, repeatCount:repeatCount, callback:callback, args:args, tempInterval:0 } );
&!--CRLF--&
  startTimer();
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  trace(id + "已经存在!!!");
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  * 注销计时器,首先检查id是否存在,如果存在,从数组_timerList中删除定时器
&!--CRLF--&
  * 参数:
&!--CRLF--&
id - 唯一标识一个定时器
&!--CRLF--&
  * 返回值:空
&!--CRLF--&
&!--CRLF--&
  public function removeTimer(id:String):void
&!--CRLF--&
&!--CRLF--&
  var index:int = check(id);
&!--CRLF--&
  if (index != -1)
&!--CRLF--&
&!--CRLF--&
  _timerList.splice(index, 1);
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  * 检查指定id的Object是否在_timerList数组中,
&!--CRLF--&
  * 如果存在返回在_timerList数组中的索引;否则返回-1
&!--CRLF--&
  * 参数:
&!--CRLF--&
id - String,唯一标识一个定时器
&!--CRLF--&
  * 返回值:
&!--CRLF--&
-1 or 指定Object的索引
&!--CRLF--&
&!--CRLF--&
  private function check(id:String):int
&!--CRLF--&
&!--CRLF--&
  var len:int = _timerList.
&!--CRLF--&
&!--CRLF--&
  for (var index:int = 0; index & index++)
&!--CRLF--&
&!--CRLF--&
  if (_timerList[index]["id"] == id)
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  return -1;
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  * 启动计时器
&!--CRLF--&
  * 如果_timer为空,生成一个定时器Timer,事件发生间隔1000ms(1s);
&!--CRLF--&
  * 监听TimerEvent.TIMER,处理函数为timerHandler
&!--CRLF--&
&!--CRLF--&
  private function startTimer():void
&!--CRLF--&
&!--CRLF--&
  if (_timer == null)
&!--CRLF--&
  _timer = new Timer(1000);
&!--CRLF--&
  if (!_timer.running)
&!--CRLF--&
&!--CRLF--&
  _timer.addEventListener(TimerEvent.TIMER, timerHandler);
&!--CRLF--&
  _timer.start();
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  * 停止计时器
&!--CRLF--&
  * 当_timerList数组为空时,即没有用户注册定时器,停止_timer
&!--CRLF--&
&!--CRLF--&
  private function stopTimer():void
&!--CRLF--&
&!--CRLF--&
  _timer.stop();
&!--CRLF--&
  _timer.removeEventListener(TimerEvent.TIMER, timerHandler);
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  * 运行计时器
&!--CRLF--&
  * 如果_timerList数组为空,调用stopTimer()停止计时器;
&!--CRLF--&
  * 否则判断_timerList数组中的定时器间隔是否达到,
&!--CRLF--&
如果达到,就调用回调函数;
&!--CRLF--&
否则啥都不做
&!--CRLF--&
&!--CRLF--&
  public function runTimer():void
&!--CRLF--&
&!--CRLF--&
  var timerComplete:Array = new Array();
&!--CRLF--&
  var len:int = _timerList.
&!--CRLF--&
  if (len == 0)
&!--CRLF--&
&!--CRLF--&
  stopTimer();
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  for (var i:int = 0; i & i++)
&!--CRLF--&
&!--CRLF--&
  //运行MyTimer管理的所有计时器
&!--CRLF--&
&!--CRLF--&
  _timerList[i]["tempInterval"] += 1;
&!--CRLF--&
  //判断是否已经经过interval间隔
&!--CRLF--&
  if (_timerList[i]["tempInterval"] == _timerList[i]["interval"])
&!--CRLF--&
&!--CRLF--&
  //如果callback不空,执行callback函数
&!--CRLF--&
  if (_timerList[i]["callback"] != null)
&!--CRLF--&
&!--CRLF--&
  _timerList[i]["callback"](_timerList[i]["args"]);
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  _timerList[i]["tempInterval"] = 0;
&!--CRLF--&
&!--CRLF--&
  //判断初始repeatCount是否=0,如果注册时为0,即无限次数
&!--CRLF--&
  //否则每执行一次,就-1;然后判断repeatCount是否=0,如果=0就注销计时器
&!--CRLF--&
  if (_timerList[i]["repeatCount"] != 0)
&!--CRLF--&
&!--CRLF--&
  _timerList[i]["repeatCount"] -= 1;
&!--CRLF--&
  if (_timerList[i]["repeatCount"] == 0)
&!--CRLF--&
&!--CRLF--&
  trace("执行完成......");
&!--CRLF--&
  timerComplete.push(_timerList[i]["id"]);
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  //注销所有已完成的计时器
&!--CRLF--&
  len = timerComplete.
&!--CRLF--&
  if (len != 0)
&!--CRLF--&
&!--CRLF--&
  trace("注销所有已经完成的计时器...");
&!--CRLF--&
  for ( i = 0; i & i++)
&!--CRLF--&
&!--CRLF--&
  removeTimer(timerComplete.pop());
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  * timerHandler是_timer的TimerEvent.TIMER事件处理函数
&!--CRLF--&
  * 其中调用runTimer(),管理所有注册的计时器
&!--CRLF--&
&!--CRLF--&
  private function timerHandler(evt:TimerEvent):void
&!--CRLF--&
&!--CRLF--&
  runTimer();
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  测试代码:
  package
&!--CRLF--&
&!--CRLF--&
  import flash.display.S
&!--CRLF--&
  import flash.events.E
&!--CRLF--&
  import flash.utils.T
&!--CRLF--&
  import flash.events.TimerE
&!--CRLF--&
&!--CRLF--&
  public class Main extends Sprite
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  public function Main():void
&!--CRLF--&
&!--CRLF--&
  if (stage) init();
&!--CRLF--&
  else addEventListener(Event.ADDED_TO_STAGE, init);
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  private function init(e:Event = null):void
&!--CRLF--&
&!--CRLF--&
  removeEventListener(Event.ADDED_TO_STAGE, init);
&!--CRLF--&
  // entry point
&!--CRLF--&
&!--CRLF--&
  var timer:MyTimer = MyTimer.getInstance();
&!--CRLF--&
  timer.registerTimer("1", 1, 15, tick);
&!--CRLF--&
&!--CRLF--&
  var timer1:MyTimer = MyTimer.getInstance();
&!--CRLF--&
  timer1.registerTimer("2", 5, 0, tick1);
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  private function tick(...args):void
&!--CRLF--&
&!--CRLF--&
  trace("tick(1s)");
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  private function tick1(...args):void
&!--CRLF--&
&!--CRLF--&
  trace("tick(5s)");
&!--CRLF--&
&!--CRLF--&
private function complete(evt:TimerEvent):void
&!--CRLF--&
&!--CRLF--&
  trace("complete...");
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
&!--CRLF--&
  1. Hashed and Hierarchical Timing Wheels: Ef cient Data Structures for Implementing a Timer Facility
  2. ActionScript3帮助文档
  3. 一个高效的定时器分析及设计
本问题标题:
本问题地址:
温馨提示:本问题已经关闭,不能解答。
暂无合适的专家
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&&&湘教QS2-164&&增值电信业务经营许可证湘B2-1, 采用12MHz的晶振,定时ms,用定时器方式0时的初值应为多少?(请给出计算过程)急,混经验者误入!记得要给出过程哦_百度作业帮
拍照搜题,秒出答案
1, 采用12MHz的晶振,定时ms,用定时器方式0时的初值应为多少?(请给出计算过程)急,混经验者误入!记得要给出过程哦
1, 采用12MHz的晶振,定时ms,用定时器方式0时的初值应为多少?(请给出计算过程)急,混经验者误入!记得要给出过程哦
机器周期 T = 12/Fosc = 12/(12x10^6) = 1μ s1ms对应的机器周期数 = 1000μ s/1μ s =1000方式0,是13位计数器,计数预装值 X =2^13 - 1000D =7192D =1C18H若使用定时/计数器T1,则初始化程序如下:||||||||||
||||||||||
查看: 7575|回复: 34
电脑CPU风扇转几秒钟就停了,开不了机
阅读权限25
在线时间 小时
注册家电维修技术论坛,与同行畅聊维修技术,享更多技术论坛功能。
才可以下载或查看,没有帐号?
电脑CPU风扇转几秒钟就停了,开不了机,没有报警声
阅读权限20
在线时间 小时
拔掉内存,冲插上试试
阅读权限25
在线时间 小时
拔掉试过了,还是一样
阅读权限101
在线时间 小时
将内存拔下,用橡皮擦擦金手指,将硬盘拔下,将记忆电池取下,短接一下电池座正负极放一下电,都重新复原试一下!
祝你成功!
阅读权限25
在线时间 小时
都试过了,还换了内存试过,硬盘显卡声卡都去掉了,
阅读权限30
在线时间 小时
你开机时如果键盘指示灯闪一下那么内存应该没有问题,应该是显卡问题;
阅读权限25
在线时间 小时
键盘鼠标一点反应都没有,显卡已经拔掉了
阅读权限60
在线时间 小时
你换个风扇试试,有时风扇不良也会造成好多故障。
阅读权限40
在线时间 小时
瑞雪兆丰年 发表于
你换个风扇试试,有时风扇不良也会造成好多故障。
就算风扇坏了开机用段时间也没问题的&&估计是主板大限到了 取下CPU除灰后装好再试下看.
阅读权限25
在线时间 小时
本帖最后由 zhangyue 于
23:04 编辑
换电源试试,如果不行可能主板挂了
( 鄂ICP备号-1 )&&
Powered by Discuz! X3.2
Comsenz Inc.
CopyRight ©
电子邮箱:
QQ:8794149
官方网址:
服务条款•隐私声明•
Wuhan Qiji Technology Co., Ltd.
武汉奇迹科技有限公司今天白白跟大家分享一下cocos2dx中定时器的使用方法。
首先,什么是定时器呢?或许你有时候会想让某个函数不断的去执行,或许只是执行一次,获取你想让他每隔几秒执行一次,ok,这些都可以统统交给定时器来解决。
cocos2dx中有三种定时器:schedule,scheduleUpdate,scheduleOnce。了解其功能便会发现定时器真是太方便了,废话不多说,我们逐一学习一下。
1、scheduleUpdate
加入当前节点后,程序会每帧都会自动执行一次默认的Update函数。(注:一定是Update函数哦,若想调用其他自己命名的函数则使用schedule)
看例子,走起。
首先在HelloWord类的头文件中声明Update函数:
void Update(float dt);
//注意参数类型
然后在HelloWorld类源文件中实现函数Update:
void HelloWorld::Update(float dt)
CCLOG(&baibai&);
现在我们可以调用了,在需要他不断执行的地方加入调用的代码就ok:
this-&scheduleUpdate();
//this是当前节点,如layer,所以可以省略啦。
运行之后你将会看到不断有baibai被打印出来
2、scheduleUpdate
可以没隔几秒执行某个自定义的函数,来看代码:
首先还是在HelloWorld中声明所要执行的函数:
void Move(float dt);
然后在源文件实现:
void HelloWorld::Move(float dt)
CCLOG(&baibai&);
现在去执行他,注意参数哦
scheduleOnce(schedule_selector(HelloWorld::Move), 1.0f); //每隔1.0f执行一次,省略参数则表示每帧都要执行
运行之后,baibai每隔1.0f才会被打印一次。
3、scheduleOnce
功能:在几秒之后执行,并且只执行一次。
我们就执行上面所写过的Move函数吧:
scheduleOnce(schedule_selector(HelloWorld::Move), 1.0f); //在1.0f之后执行,并且只执行一次。
运行一下,baibai只是被打印了一次就完了。。。
ok,定时器的调用已经讲完,大家不妨自己写一些函数体验一下。
但是怎么让定时器停止呢?
1、停止执行自己定义函数的定时器:
this-&unschedule(schedule_selector(HelloWorld::Move));
2、停止默认定时器:
this-&unscheduleUpdate();
3、停止所有定时器:
this-&unscheduleAllSelectors();
好啦,定时器是不是很有趣呢?大家试着使用一下吧。
&此文从网络中自动搜索生成,不代表本网站赞成被搜索网站的内容或立场
&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& 17:23:06
软件世界网- &2014 蜀ICP备号 三峰网旗下网站怎么用多线程技术,可以让某个定时器处于最高的优先级?
[问题点数:40分,结帖人u]
怎么用多线程技术,可以让某个定时器处于最高的优先级?
[问题点数:40分,结帖人u]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
相关帖子推荐:
2009年7月 总版技术专家分月排行榜第二2009年3月 总版技术专家分月排行榜第二2009年1月 总版技术专家分月排行榜第二2005年7月 总版技术专家分月排行榜第二2005年5月 总版技术专家分月排行榜第二2005年3月 总版技术专家分月排行榜第二
2015年2月论坛优秀版主
匿名用户不能发表回复!|
每天回帖即可获得10分可用分!小技巧:
你还可以输入10000个字符
(Ctrl+Enter)
请遵守CSDN,不得违反国家法律法规。
转载文章请注明出自“CSDN(www.csdn.net)”。如是商业用途请联系原作者。

我要回帖

更多关于 android 停止定时器 的文章

 

随机推荐