add timeout to qtes

This commit is contained in:
Jeremy Penner 2011-06-08 16:42:25 -07:00
parent cf425b27c5
commit 0e0753e1d7
5 changed files with 90 additions and 14 deletions

View file

@ -9,10 +9,12 @@ package
public class EventQte extends Event public class EventQte extends Event
{ {
public static const QTE:String = "qte"; public static const QTE:String = "qte";
public static const QTE_TIMEOUT:String = "qte-timeout";
public static const QTE_CANCEL:String = "qte-cancel";
public var qte:Qte; public var qte:Qte;
public function EventQte(qte:Qte) public function EventQte(type:String, qte:Qte)
{ {
super(QTE); super(type);
this.qte = qte; this.qte = qte;
} }
} }

View file

@ -28,6 +28,7 @@ package
addEventListener(MouseEvent.CLICK, onClick); addEventListener(MouseEvent.CLICK, onClick);
videotube.addEventListener(EventQte.QTE, onQte); videotube.addEventListener(EventQte.QTE, onQte);
videotube.addEventListener(EventQte.QTE_TIMEOUT, onTimeout);
} }
private function cleanup(e:Event):void private function cleanup(e:Event):void
{ {
@ -36,13 +37,27 @@ package
videotube.removeEventListener(EventQte.QTE, onQte); videotube.removeEventListener(EventQte.QTE, onQte);
} }
private function onQte(e:EventQte):void private function onQte(e:EventQte):void
{ {
clearClickarea();
clickarea = new ClickArea(e.qte.rgpoint, 0xffff00, 0.7); clickarea = new ClickArea(e.qte.rgpoint, 0xffff00, 0.7);
addChild(clickarea); addChild(clickarea);
} }
private function onTimeout(e:EventQte):void
{
if (clickarea != null)
{
// fail
}
clearClickarea();
}
private function onClick(mouse:MouseEvent):void private function onClick(mouse:MouseEvent):void
{ {
if (clickarea != null && clickarea.FHit(new Point(mouse.stageX, mouse.stageY))) if (clickarea != null && clickarea.FHit(new Point(mouse.stageX, mouse.stageY)))
clearClickarea();
}
private function clearClickarea():void
{
if (clickarea != null)
{ {
removeChild(clickarea); removeChild(clickarea);
clickarea = null; clickarea = null;

View file

@ -23,6 +23,10 @@ package
return -1; return -1;
return 1; return 1;
} }
public function secTimeout():Number
{
return secTrigger + 1.0;
}
public function ToJson():Object public function ToJson():Object
{ {
var jsonRgpoint:Array = []; var jsonRgpoint:Array = [];

View file

@ -25,6 +25,10 @@ package
} }
return -imin; return -imin;
} }
public static function FInTimespan(sec:Number, secPrev:Number, secNow:Number):Boolean
{
return (sec <= secNow) && (sec > secPrev);
}
public static function alert(...rgo:*):void public static function alert(...rgo:*):void
{ {
ExternalInterface.call("alert", JSON.encode(rgo)); ExternalInterface.call("alert", JSON.encode(rgo));

View file

@ -17,35 +17,86 @@ package
public function pause():void { throw "not implemented"; } public function pause():void { throw "not implemented"; }
public function resume():void { throw "not implemented"; } public function resume():void { throw "not implemented"; }
public function time():Number { throw "not implemented"; } public function time():Number { throw "not implemented"; }
public function seek(sec:Number):void { throw "not implemented"; } protected function seekI(sec:Number):void { throw "not implemented"; }
private var secPrev:Number; private var secPrev:Number;
private var iqte:int; private var iqte:int;
private var iqtePrev:int;
protected var gamedisc:Gamedisc; protected var gamedisc:Gamedisc;
public function Videotube(gamedisc: Gamedisc) public function Videotube(gamedisc: Gamedisc)
{ {
this.gamedisc = gamedisc; this.gamedisc = gamedisc;
secPrev = 0; secPrev = 0;
iqte = 0; iqte = 0;
iqtePrev = 0;
}
public function seek(sec:Number):void
{
seekI(sec);
if (iqtePrev != -1)
{
dispatchEvent(new EventQte(EventQte.QTE_CANCEL, gamedisc.rgqte[iqtePrev]));
iqtePrev = -1;
}
iqte = -1;
}
// returns true if triggered
private function Trigger(iqte:int, ev:String, secNow:Number): Boolean
{
if (iqte >= 0 && iqte < gamedisc.rgqte.length)
{
var qte:Qte = gamedisc.rgqte[iqte];
var secQte:Number;
if (ev == EventQte.QTE)
secQte = qte.secTrigger;
else
secQte = qte.secTimeout();
if (Util.FInTimespan(secQte, secPrev, secNow))
{
dispatchEvent(new EventQte(ev, qte));
return true;
}
}
return false;
} }
protected function tick(e: Event):void protected function tick(e: Event):void
{ {
var secNow:Number = time(); var secNow:Number = time();
if (secNow > secPrev && secPrev >= 0) var fPrevQteProcessed:Boolean = false;
var fQteProcessed:Boolean = false;
if (iqte < 0)
{ {
while(iqte < gamedisc.rgqte.length) iqte = Util.binarySearch(gamedisc.rgqte, secNow, function(qte:Qte, secNow:Number):int {
{ if (qte.secTrigger < secNow)
var qte:Qte = gamedisc.rgqte[iqte]; return -1;
if (qte.secTrigger > secNow) if (qte.secTrigger > secNow)
break; return 1;
if (qte.secTrigger > secPrev) return 0;
dispatchEvent(new EventQte(qte)); });
iqte ++; iqtePrev = iqte;
}
} }
else else
{ {
iqte = 0; // we loop here so that, in the event of being passed bad data, we still do something vaguely sensible.
while (!fPrevQteProcessed && !fQteProcessed)
{
if (Trigger(iqtePrev, EventQte.QTE_TIMEOUT, secNow))
{
fPrevQteProcessed = false;
iqtePrev ++;
}
else
fPrevQteProcessed = true;
if (Trigger(iqte, EventQte.QTE, secNow))
{
fQteProcessed = false;
iqte ++;
}
else
fQteProcessed = true;
}
} }
secPrev = secNow; secPrev = secNow;
} }