EventListener for key combinations in AS3? - actionscript-3

im tryin to figure out condition AND for "shortcut" for quitting standalone app from flash. I would like to push 2 keys and combination of these two keys "C+M" should quit my app.
Heres my code but its still not working. I tryed to make shure that app allow me to push multiple buttons at the same time and after that I created the function for quitting.
Any answers be great.
var keyPressedC:Boolean;
var keyPressedM:Boolean;
addEventListener(KeyboardEvent.KEY_DOWN, check_key_down,false,0,true);
addEventListener(KeyboardEvent.KEY_UP, check_key_up,false,0,true);
addEventListener(Event.ENTER_FRAME, check_keys,false,0,true);
function check_keys(event:Event):void
{
if(keyPressedC)
trace("pushed C")
if(keyPressedM)
trace("pushed M")
}
function check_key_down(event:KeyboardEvent):void
{
if(event.keyCode == 67)
keyPressedC = true;
if(event.keyCode == 77)
keyPressedM = true;
}
function check_key_up(event:KeyboardEvent):void
{
if(event.keyCode == 67)
keyPressedC = false;
if(event.keyCode == 77)
keyPressedM = false;
}
import flash.system.fscommand;
stage.addEventListener(KeyboardEvent.KEY_DOWN, enterKeyHandlercm);
function enterKeyHandlercm(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.C && event.keyCode == Keyboard.M)
{
fscommand("quit");
}
}
Edited, still not working:
var keyPressedC:Boolean;
var keyPressedM:Boolean;
addEventListener(KeyboardEvent.KEY_DOWN, check_key_down,false,0,true);
addEventListener(KeyboardEvent.KEY_UP, check_key_up,false,0,true);
addEventListener(Event.ENTER_FRAME, check_keys,false,0,true);
function check_keys(event:Event):void
{
if(keyPressedC)
trace("pushed C")
if(keyPressedM)
trace("pushed M")
}
function check_key_down(event:KeyboardEvent):void
{
if(event.keyCode == 67)
keyPressedC = true;
if(event.keyCode == 77)
keyPressedM = true;
}
function check_key_up(event:KeyboardEvent):void
{
if(event.keyCode == 67)
keyPressedC = false;
if(event.keyCode == 77)
keyPressedM = false;
}
import flash.system.fscommand;
stage.addEventListener(KeyboardEvent.KEY_DOWN, enterKeyHandlercm);
function enterKeyHandlercm(event:KeyboardEvent):void
{
if (keyPressedM == true && keyPressedC == true)
{
fscommand("quit");
}
}

In your enterKeyHandlercm block, your logic should be evaluating the keypressed value, not the keyCode value.
function enterKeyHandlercm(event:KeyboardEvent):void
{
if (keyPressedM == true && keyPressedC == true)
{
fscommand("quit");
}
}
With this code, a different MC is added for each of your 5 key possibilities (c up, c down , m up, m down, c+m down).
package {
import flash.display.*;
import flash.events.*;
import flash.system.fscommand;
import flash.system.System; //add this if you try System.exit(0);
public class FlashTest extends MovieClip
{
public function FlashTest()
{
var keyPressedC:Boolean;
var keyPressedM:Boolean;
// need to add eventListener to stage
// default values work fine.
stage.addEventListener(KeyboardEvent.KEY_DOWN, check_key_down);
stage.addEventListener(KeyboardEvent.KEY_UP, check_key_up);
stage.addEventListener(Event.ENTER_FRAME, check_keys);
function check_key_down(event:KeyboardEvent):void
{
if(event.keyCode == 67)
{
keyPressedC = true;
newBall(-100);
}
if(event.keyCode == 77)
{
keyPressedM = true;
newBall();
}
}
function check_key_up(event:KeyboardEvent):void
{
if(event.keyCode == 67)
{
keyPressedC = false;
newBall(-50);
}
if(event.keyCode == 77)
{
keyPressedM = false;
newBall(50);
}
}
function enterKeyHandlercm(event:KeyboardEvent):void
{
if (keyPressedM == true && keyPressedC == true)
{
newBall(100);
fscommand("quit");
// or try System.exit(0);
}
}
function newBall(x:Number=0):void
{
var ball:Sprite = new Sprite();
ball.graphics.lineStyle();
ball.graphics.beginFill(0x000000);
ball.graphics.drawCircle(0,0,20);
ball.graphics.endFill();
addChild(ball);
ball.x = stage.stageWidth/2+x;
ball.y = stage.stageHeight/2;
}
}
}
}
Please forgive my verbosity, but this way we aren't missing anything. The reason I added the ball constructor was because I only have my laptop with me so I had to use an online IDE and I don't know how to find an output window or run a debugger and it doesn't take system commands. But what I can confirm with the ball method is that when "c" and "m" are pressed together, a unique MC is instantiated. This means our code now causes flash to register a unique event when both keys are simultaneously pressed.

Related

Why does flash output a TypeError: Error #2007: Parameter child must be non-null. at flash.display::DisplayObjectContainer/addChild()

This is my code that I have so far
package {
import flash.display.MovieClip;
import flash.events.*;
public class Main extends MovieClip {
var leftpressed:Boolean = false;
var rightpressed:Boolean = false;
public function Main()
{
//constructor code
Spaceship.addEventListener(Event.ENTER_FRAME, moveToKey);
stage.addEventListener(KeyboardEvent.KEY_DOWN, setKeyPress);
stage.addEventListener(KeyboardEvent.KEY_UP, setKeyUnpress);
stage.addEventListener(KeyboardEvent.KEY_DOWN, FlyBullet);
}
function moveToKey (event:Event)
{
if (leftpressed && (Spaceship.x>0))
{
Spaceship.x = -5;
}
if (rightpressed && (Spaceship.x<550))
{
Spaceship.x = +5;
}
}
function setKeyPress(e:KeyboardEvent):void
{
if (e.keyCode == 37)
{
leftpressed = true;
}
if (e.keyCode == 39)
{
rightpressed = true;
}
}
function setKeyUnpress(e:KeyboardEvent): void
{
if (e.keyCode == 37)
{
leftpressed = false;
}
if (e.keyCode == 39)
{
rightpressed = false;
}
}
function FlyBullet (e:KeyboardEvent):void
{
if (e.keyCode == 32)
var bulletshot:Bullet = new Bullet();
addChild(bulletshot);
bulletshot.x = Spaceship.x;
bulletshot.y = Spaceship.y
}
}
}
With the biggest issue with the final FlyBullet function that outputs an the error listed as
TypeError: Error #2007: Parameter child must be non-null.
at flash.display::DisplayObjectContainer/addChild()
at Main/FlyBullet()
This is your problem:
if (e.keyCode == 32)
var bulletshot:Bullet = new Bullet();
addChild(bulletshot);
bulletshot.x = Spaceship.x;
bulletshot.y = Spaceship.y
There are no curly brackets so the if condition only applies to the first line where bulletshot is assigned. In other words, if you press any key other than SPACE it will skip the assignment of bulletshot but still try to addChild(bulletshot), but since bulletshot was not assigned a value it is null and you get errors.
I think you meant this:
if (e.keyCode == Keyboard.SPACE) {
var bulletshot:Bullet = new Bullet();
addChild(bulletshot);
bulletshot.x = Spaceship.x;
bulletshot.y = Spaceship.y
}
PS: Your code is poorly indented in a lot of places. It helps to have correctly indented code. An auto-formatter could help you here.
It is generally considered bad practice to omit brackets in multiline if statements, this is an example why. Whenever e.keyCode != 32 the addChild line will try to run.
Solution would be:
///...in the Main function//
stage.addEventListener(KeyboardEvent.KEY_DOWN, flyBullet);
///...
function flyBullet (e:KeyboardEvent):void
{
if (e.keyCode == 32)
{
var bulletshot:Bullet = new Bullet();
addChild(bulletshot);
bulletshot.x = Spaceship.x;
bulletshot.y = Spaceship.y;
}
}
Some unrelated as3 code quality tips, to avoid possible errors later:
I'm guessing Spaceship isn't a static class, so i suggest using lowercase first letters for variable/function names, and uppercase for classes, but this is just good practice and does not affect your codes correctness.
It is also good practice to define the accessibility of your functions, i.e public, private, internal, protected. If you omit it the default is internal.
And only skip brackets after conditionals when necessary.

Actionscript 3.0: Cannot get key input

guys. I created a little game. Nothing actually happening thought, because im not getting my keyboard input. I spend some time trying to create my own taht didnt work. Then I copy/pasted code from official actionscript 3.0 reference page, but tweaked it for my game (but I didnt touch anything related to keyboard stuff). Also the only thing my game returns in cosnole is false
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
stop();
var left = false;
var right = false;
var speed = 0.3;
player.addEventListener(KeyboardEvent.KEY_DOWN, keydF);
player.addEventListener(KeyboardEvent.KEY_UP, keyuF);
player.addEventListener(Event.ENTER_FRAME, updF);
function keydF(event:KeyboardEvent):void {
trace("test0");
if(event.keyCode == Keyboard.D) {
trace("test1");
left = true;
}
if(event.keyCode == Keyboard.A) {
right = true;
}
}
function keyuF(event:KeyboardEvent):void {
trace("test2");
if(event.keyCode == Keyboard.D) {
left = false;
}
if(event.keyCode == Keyboard.A) {
right = false;
}
}
function updF(e:Event):void {
if(left) {
level.x -= speed;
}
if(right) {
level.x += speed;
}
trace(left + ""); //always false :\
}
If you want to get the key input to your app, you should add the listeners to the stage :)

Flash CS4/AS3: trying to make part of a movieclip loop only while keyboard button is pressed

I'm working on a project in which a character walks forwards or backwards across the screen or shoots a rifle depending on whether the user presses one of the following keyboard keys: forward arrow (key 39), back arrow (key 37) or spacebar (key 32).
My problem is that when the user presses and holds the forward arrow key, the character's movieclip plays one instance of the walking forward animation, and then moves forward. I want the walking forward animation to play throughout the entire time the character is moving.
Here is my code:
import fl.transitions.Tween;
import fl.transitions.easing.*;
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveCharacter);
stage.addEventListener(KeyboardEvent.KEY_UP, stopCharacter);
var muzzlePosition:Number = new Number();
var bullet:Bullet = new Bullet();
function moveCharacter(e:KeyboardEvent):void {
switch (e.keyCode) {
case 39 :
if (sprite_Cicada.x<stage.stageWidth-150) {
sprite_Cicada.gotoAndPlay("walk-fwd");
sprite_Cicada.x+=5;
} else {
sprite_Cicada.x+=0;
sprite_Cicada.gotoAndPlay("push");
}
break;
case 37 :
if (sprite_Cicada.x>225) {
sprite_Cicada.x-=3;
sprite_Cicada.gotoAndPlay("walk-bkwds");
} else {
sprite_Cicada.x-=0;
sprite_Cicada.gotoAndPlay("standing");
}
break;
case 32 :
muzzlePosition=sprite_Cicada.x+sprite_Cicada.AK47.x+28;
addChild(bullet);
bullet.gotoAndStop("lead");
bullet.x=muzzlePosition;
bullet.y=328;
sprite_Cicada.gotoAndPlay("fireAK");
var shootBullet:Tween=new Tween(bullet,"x",None.easeOut,muzzlePosition,stage.stageWidth*2,.5,true);
if (bullet.x>stage.stageWidth+50) {
removeChild(bullet);
}
break;
}
}
function stopCharacter(e:KeyboardEvent):void {
sprite_Cicada.gotoAndPlay("standing");
}
Perhaps you can do
stage.addEventListener(KeyboardEvent.KEY_DOWN, keydown );
stage.addEventListener(KeyboardEvent.KEY_UP, keyup);
addEventListener(Event.ENTER_FRAME, movePerson);
function keydown(e:KeyboardEvent) {
if (e.keyCode == Keyboard.LEFT || e.keyCode == Keyboard.RIGHT) { per_mc.gotoAndStop(2) }
if (e.keyCode == Keyboard.LEFT) {leftkeyStatus = true; rightkeyStatus = false;}
if (e.keyCode == Keyboard.RIGHT) {leftkeyStatus = false; rightkeyStatus = true;}
}
function keyup(e:KeyboardEvent) {
if (e.keyCode == Keyboard.LEFT || e.keyCode == Keyboard.RIGHT) { per_mc.gotoAndStop(1) }
if (e.keyCode == (Keyboard.LEFT)) {leftkeyStatus = false;}
if (e.keyCode == (Keyboard.RIGHT)) {rightkeyStatus = false;}
}
function movePerson(e:Event) {
if (rightkeyStatus) {
sprite_Cicada.x-=3;
}
}

AS3 error 1061 trying to get collision

" Player.as, Line 59 1061: Call to a possibly undefined method hitTestObject through a reference with static type Class."
I am new to flash and am trying to make a game, specifically I am trying to make it so the player class in a game can collide with things, I am using a square at the bottom of his feet (not yet referenced in the code) and a MovieClip called collisionTest
package
{
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
import KeyObject;
public class Player extends MovieClip
{
public var stageRef:Stage;
public var key:KeyObject;
//add these four variables:
public var leftPressed:Boolean = false; //keeps track of whether the left arrow key is pressed
public var rightPressed:Boolean = false; //same, but for right key pressed
public var upPressed:Boolean = false; //...up key pressed
public var downPressed:Boolean = false; //...down key pressed
private var gravity:Number = 2;
private var runSpeed:Number = 5;
private var touchingGround:Boolean = false;
public var vPressed:Boolean = false;
public function Player(stageRef:Stage, X:int, Y:int):void
{
this.stageRef = stageRef;
this.x = X;
this.y = Y;
key = new KeyObject(stageRef);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
public function loop(e:Event):void
{
checkKeypresses(); //call "checkKeypresses()" every frame
checkCollisions();
if(leftPressed)
{
x -= runSpeed;
}else if(rightPressed)
{
x += runSpeed;
}
if(upPressed)
{
y -= runSpeed;
}else if(downPressed)
{
y += runSpeed;
}
}
public function checkCollisions():void
{
**(this is line 59)** if(Player.hitTestObject(Player.collisionTest)){
touchingGround = true;
trace("gounded");
}
}
public function checkKeypresses():void
{
// I used http://www.dakmm.com/?p=272 as a reference to get the keyCode numbers for each key
if(key.isDown(37) || key.isDown(65)){ // if left arrow or A is pressed
leftPressed = true;
//trace("left pressed");
} else {
leftPressed = false;
}
if(key.isDown(38) || key.isDown(87)){ // if up arrow or W is pressed
upPressed = true;
//trace("up pressed");
} else {
upPressed = false;
}
if(key.isDown(39) || key.isDown(68)){ //if right arrow or D is pressed
rightPressed = true;
//trace("right pressed");
} else {
rightPressed = false;
}
if(key.isDown(40) || key.isDown(83)){ //if down arrow or S is pressed
downPressed = true;
//trace("down pressed");
} else {
downPressed = false;
}
}
}
}
Function hitTestObject isn't a static function, so you should call it from an object instance, same to the collisionTest.
So it should be
this.hitTestObject(collisionTest);//set collisionTest in the Player class

removeEventListener not working

function Drag(event:MouseEvent):void {
if ((event.target.parent == InventoryMenu) && (event.target is item)) {
var picked:item = item(event.target);
stage.addEventListener(MouseEvent.MOUSE_UP, Drop);
InventoryArrowDown.addEventListener(MouseEvent.MOUSE_OVER, InventoryNav("down"));
InventoryArrowUp.addEventListener(MouseEvent.MOUSE_OVER, InventoryNav("up"));
function Drop(event:MouseEvent):void {
if ((event.target.parent == InventoryMenu) && (event.target is item)) {
var dropped:item = item(event.target);
if ((event.target is item) && (event.target.parent == InventoryMenu)) {
if (picked.itemdata("workswith") == dropped.name) {
var itemname:item = item(FetchResult(picked, dropped));
itemname.addChild(itemname.itemdata("filename"));
InventoryMenu.removeChild(picked);
InventoryMenu.removeChild(dropped);
InventoryMenu.addChild(itemname);
InventoryUpdate();
} else if (picked.name != dropped.name) {
trace("No son compatibles");
}
stage.removeEventListener(MouseEvent.MOUSE_UP, Drop);
InventoryArrowDown.removeEventListener(MouseEvent.MOUSE_OVER, InventoryNav("down"));
InventoryArrowUp.removeEventListener(MouseEvent.MOUSE_OVER, InventoryNav("up"));
}
}
}
}
}
For some reason the removeEventListener on InventoryArrowDown and InventoryArrowUp isn't working. I'm fairly sure the route is correct as it's a direct copy paste from the addEventListener and it uses no variables.
Any clue what's wrong?
Hard to help you without seeing the code of InventoryNav but maybe the issue is that you should remove the event listeners before your tests.
Also, you should write two different handlers instead of using one and passing an argument like you do.
Here is a modified version of your code that might help:
private function drag(event:MouseEvent):void {
if ((event.target.parent == inventoryMenu) && (event.target is Item)) {
var picked:Item = Item(event.target);
stage.addEventListener(MouseEvent.MOUSE_UP, drop);
inventoryArrowDown.addEventListener(MouseEvent.MOUSE_OVER, inventoryNavDown);
inventoryArrowUp.addEventListener(MouseEvent.MOUSE_OVER, inventoryNavUp);
}
}
private function drop(event:MouseEvent):void {
stage.removeEventListener(MouseEvent.MOUSE_UP, drop);
inventoryArrowDown.removeEventListener(MouseEvent.MOUSE_OVER, inventoryNavDown);
inventoryArrowUp.removeEventListener(MouseEvent.MOUSE_OVER, inventoryNavUp);
if ((event.target.parent == inventoryMenu) && (event.target is Item)) {
var dropped:Item = Item(event.target);
if ((event.target is Item) && (event.target.parent == inventoryMenu)) {
if (picked.itemdata("workswith") == dropped.name) {
var itemname:Item = Item(fetchResult(picked, dropped));
itemname.addChild(itemname.itemdata("filename"));
inventoryMenu.removeChild(picked);
inventoryMenu.removeChild(dropped);
inventoryMenu.addChild(itemname);
inventoryUpdate();
} else if (picked.name != dropped.name) {
trace("No compatible sons");
}
}
}
}