MOUSE_DOWN trigger every frame, ActionScript 3
as I am new to as3, I want to implement a MachineGun, that fires while has ammo, and the trigger is pulled, In my case, th开发者_Go百科e MouseEvent.MOUSE_DOWN
.
The problem is that this event fires only once.
The closest I get is to this is MouseEvent.MOUSE_MOVE
, but it fails my purpose when the mouse position is sustained
EDIT:
I need the updated mouse cursor every frame
When your MouseEvent.MOUSE_DOWN
event handler you can create an event listener that listens for the Event.ENTER_FRAME
event to be dispatched. Using the Event.ENTER_FRAME
event handler you can repeatedly call a method that handles shooting the bullet. The following is an example I modeled after an example at http://www.benoitfreslon.com/actionscript-throw-bullets-to-mouse-direction:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(width="500", height="500", frameRate="24", backgroundColor="0xFFFFFF")]
public class Main extends Sprite
{
private var _gun:Gun;
private var _interval:int;
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}// end function
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
_gun = new Gun();
_gun.x = stage.stageWidth / 2 - _gun.width / 2;
_gun.y = stage.stageHeight / 2 - _gun.height / 2;
addChild(_gun);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onStageMouseDown);
}// end function
private function onStageMouseDown(e:MouseEvent):void
{
stage.addEventListener(Event.ENTER_FRAME, onStageEnterFrame);
stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
}// end function
private function onStageEnterFrame(e:Event):void
{
shootBullet();
}// end function
private function shootBullet():void
{
if (_interval > 5)
{
var bullet:Bullet = new Bullet();
bullet.addEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
bullet.x = _gun.x;
bullet.y = _gun.y;
bullet.angleRadian = Math.atan2(stage.mouseY - _gun.y, stage.mouseX - _gun.x);
bullet.addEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
addChild(bullet);
_interval = 0; // reset
}// end if
_interval++;
}// end function
private function onBulletEnterFrame(e:Event):void
{
var bullet:Bullet = Bullet(e.target);
bullet.x += Math.cos(bullet.angleRadian) * bullet.SPEED;
bullet.y += Math.sin(bullet.angleRadian) * bullet.SPEED;
if ( bullet.x < 0 || bullet.x > 500 || bullet.y < 0 || bullet.y > 500)
{
removeChild(bullet);
bullet.removeEventListener(Event.ENTER_FRAME, onBulletEnterFrame);
}// end if
}// end function
private function onStageMouseUp(e:MouseEvent):void
{
stage.removeEventListener(Event.ENTER_FRAME, onStageEnterFrame);
stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
_interval = 0;
}// end function
}// end class
}// end package
import flash.display.Sprite;
internal class Gun extends Sprite
{
public function Gun()
{
graphics.beginFill(0x000000);
graphics.drawCircle(0, 0, 10);
graphics.endFill();
}// end function
}// end class
internal class Bullet extends Sprite
{
public var angleRadian:Number;
public const SPEED:Number = 10;
public function Bullet()
{
graphics.lineStyle(1, 0x000000);
graphics.drawCircle(0, 0, 10);
graphics.endFill();
}// end function
}// end class
The point of interest is in the onStageEnterFrame()
method. There's an if
statement that checks whether the _interval
property's value is greater than 5, if so, a new bullet is created and shot otherwise the _interval
property's value is incremented. The purpose of the _interval
property is to space out the bullets being shot.
[UPDATE]
Here is an image of the example flash application running:
The mouse button is being held down in the top right corner hence the bullets being shot in that direction.
On receiving a MouseEvent.MOUSE_DOWN event, run a while loop making the machine gun fire. The loop breaks on receiving a MouseEvent.MOUSE_UP event. Something like this
private function handleMouseDown( event:Event ):void
{
this.addEventListener( MouseEvent.MOUSE_UP , handleMouseUp );
startFiring();
}
private function handleMouseUp( event:Event ):void
{
this.removeEventListener( MouseEvent.MOUSE_UP , handleMouseUp );
this.addEventListener( MouseEvent.MOUSE_DOWN , handleMouseDown);
stopFiring();
}
EDIT: For clarification, the stop and start firing functions are functions that run a loop to keep the machine gun firing animation going however that may be.
add firing action to ENTER_FRAME event when mouse is pressed and remove when mouse is up
this.addEventListener( MouseEvent.MOUSE_DOWN, this.handler_down );
this.addEventListener( MouseEvent.MOUSE_UP, this.handler_up );
private function handler_down(event:Event):void {
super.addEventListener( Event.ENTER_FRAME, this.handler_frame );
}
private function handler_up(event:Event):void {
super.removeEventListener( Event.ENTER_FRAME, this.handler_frame );
}
private function handler_frame(event:Event):void {
this.fire();
}
I have to do this regularly, and instead of using an enter_frame listener, I opt for a Timer() and TimerEvent.Timer listener. That way I have more control over how often the repeat is fired without accounting for frame rate and what not.
private var fireRepeat:Timer;
private function triggerDown(e:MouseEvent):void {
if (!this.fireRepeat) { // create the repeater
this.fireRepeat = new Timer(500, 0);
this.fireRepeat.addEventListener(TimerEvent.TIMER, this.fire);
}
fire(); // fire the first bullet
this.fireRepeat.reset(); // reset the repeater
this.fireRepeat.start(); // start the repeater
}
private function triggerUp(e:MouseEvent):void {
if (this.fireRepeat) { this.fireRepeat.stop(); }
}
public function fire(e:* = null):void {
trace('fire!');
}
精彩评论