I am at a lost, which is not surprising for a beginner to encounter. Im attempting to execute a smooth and seamless keyboard direction command. Issue occurs when keys are held which creates a delay and fragmented like movement. code is below and please be gentle im new at this =)
var dx:Number = 0;
paddle.addEventListener(Event.ENTER_FRAME, motion);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyPressed);
function motion (event:Event):void{
paddle.x = dx
}
function keyPressed(event:KeyboardEvent):void{
if(event.keyCode == Keyboard.LEFT){
dx -= 20;
}
if(event.keyCode == Keyboard.RIGHT){
dx += 20;
}
}
You basically keep track of when the key is pressed on KEY_DOWN and reset it on KEY_UP. Then, in your ENTER_FRAME, you check if the key is pressed, and move your paddle.
Something like this:
var isLeftPressed:Boolean = false;
var isRightPressed:Boolean = false;
stage.addEventListener( KeyboardEvent.KEY_DOWN, this._onKeyDown );
stage.addEventListener( KeyboardEvent.KEY_UP, this._onKeyUp );
paddle.addEventListener( Event.ENTER_FRAME, this._onEnterFrame );
// called when a key is pressed
function _onKeyDown( e:KeyboardEvent ):void
{
if( e.keyCode == Keyboard.LEFT )
isLeftPressed = true;
if( e.keyCode == Keyboard.RIGHT )
isRightPressed = true;
}
// called when a key is released
function _onKeyUp( e:KeyboardEvent ):void
{
if( e.keyCode == Keyboard.LEFT )
isLeftPressed = false;
if( e.keyCode == Keyboard.RIGHT )
isRightPressed = false;
}
// called every frame
function _onEnterFrame( e:Event ):void
{
// get our direction based on what key is pressed, and move our paddle
var dirX:int = ( isLeftPressed ) ? -1 : ( isRightPressed ) ? 1 : 0;
paddle.x += 20 * dirX;
}
This can easily be generalised for any key (keep a Vector.<Boolean> using the keyCode as an index) - Check out the PushButtonEngine KeyboardManager for the general gist: https://github.com/PushButtonLabs/PushButtonEngine/blob/PBE2/src/com/pblabs/input/KeyboardManager.as
You should move the object when you have a key pressed by the user until KeyboardEvent.KEY_UP event is dispatched to know when the user releases the key. Here is an example of what you are looking for:
Moving Movieclips using Keys with Acstionscript 3
I wish that it helps you. Good luck!
Related
I have written a code to move a MovieClip on pressing space bar. So if someone presses space bar ..it activates a boolean variable from false to true and if its true the object moves ..but its not working. can some one please help. Thank you
var rope = MovieClip(this.root).boat_mc.rope_mc.fishyrope_mc.hitbox_mc;
var ropeMove:Boolean = false;
stage.addEventListener(Event.ENTER_FRAME, ropeCode);
stage.addEventListener(KeyboardEvent.KEY_UP, onSpacebarUp);
function onSpacebarUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.SPACE)
ropeMove = !ropeMove; // toggles ropeMove (i.e. if it's true, sets it to false, and vice versa)
}
function ropeCode(e:Event):void
{
// move the rope
if( ropeMove )
{
rope.y += xSpeed;
// stop moving if we've gone too far
if( rope.y > 600.0 )
{
rope.y = 600.0;
ropeMove = false;
}
}
}
This should work
var ropemove:Boolean = true;
var xSpeed = 5;
var once:Boolean=false;
stage.addEventListener(Event.ENTER_FRAME,ropeCode);
stage.addEventListener(KeyboardEvent.KEY_UP,onSpacebarUp);
function onSpacebarUp(e:KeyboardEvent):void
{
if (e.keyCode == 32)
{
if (ropemove==true)
{
if(once==false)
{
ropemove = false;
once=true
}
}
if(ropemove==false)
{
ropemove==true
}
}
if (rope.x >= stage.stageWidth )
{
ropemove = false;
}
trace(ropemove)
}
function ropeCode(e:Event):void
{
if (ropemove == true)
{
rope.x += xSpeed;
}
}
Two problems I can spot in your code:
1.) Everything is inside your Event.ENTER_FRAME event handler. This means every frame, that code is going to be run: including where you're adding a keyboard event listener. After 1 second, (assuming you are running at 30 fps) onSpacebarUp() will fire 30 times when you press space, and keeps increasing. Probably not a good idea, pretty sure you only want to add this once.
2.) The part where the boolean value will cause your movieclip to move is in a method: dropRope(). But this is not called anywhere, so it is actually not doing anything. Also may not need the event argument (the e:event) part, as you're not using it nor is it being called from an event.
BennettLiam's code should do something closer to what you want, I'm just adding this answer as an explanation for why your code isn't working. In their answer, they've fixed the above problems I mentioned: moved the event listener code for the keyboard outside of the event frame handler loop so it is only added once, and changed the enter frame event handler to call dropRope() o every frame, so that it is doing something.
var rope = MovieClip(this.root).boat_mc.rope_mc.fishyrope_mc.hitbox_mc;
var ropeMove:Boolean = false;
stage.addEventListener(Event.ENTER_FRAME, ropeCode);
stage.addEventListener(KeyboardEvent.KEY_UP, onSpacebarUp);
function onSpacebarUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.SPACE)
ropeMove = !ropeMove; // toggles ropeMove (i.e. if it's true, sets it to false, and vice versa)
}
function ropeCode(e:Event):void
{
// move the rope
if( ropeMove )
{
rope.y += xSpeed;
// stop moving if we've gone too far
if( rope.y > 600.0 )
{
rope.y = 600.0;
ropeMove = false;
}
}
}
I could not find topic like this and that is why I am posting this question. I have a side scrolling game with the character set up in positions with frame labels- animation states to stand, jump, run, kneel and fire. She is also made to fire bullets with separate class file. The problem is that right now she is firing bullets in all of the animation states. The question is how do I make this character fire the bullets only on the frame label fire. The frame label fire consists of 2 frames and I want the launching of the bullet to happen on the second frame. Which means that the keyboard space will be pressed for a second or two before it goes to this frame and then it will fire (like in real life).
I tried to connect the animation state to the bullets somehow and tried to put the condition in these lines of code somehow:
if(e.keyCode == Keyboard.SPACE){
if (Animation state "Fire (2)")
fireBullet();
}
But it did not work, it doesn't know what I am talking about. The class file for the bullet is separate and I don't think is relevant to the problem.
The rest of the timeline code is like this:
var bulletList:Array = new Array();
if(e.keyCode == Keyboard.SPACE){
fireBullet();
}
}
function fireBullet():void
{
var playerDirection:String;
if(player.scaleX < 0){
playerDirection = "left";
} else if(player.scaleX > 0){
playerDirection = "right";
}
var bullet:Bullet = new Bullet(player.x - scrollX, player.y - scrollY,
playerDirection xSpeed);
back.addChild(bullet);
Thank you. I hope that my question is clear.
There is addFrameScript, AS3's mystery function that can be useful in this situation. And that would look something like this:
playerAnimation.addFrameScript( insertFrameNumber, fireBullet );
addFrameScript runs the method passed as a parameter when the MovieClip reaches a certain frame.
I believe how you would want to use this in your current code:
player.addFrameScript( 5, fireBullet );
Then in your KEY_UP handler:
function keyUpHandler(e:KeyboardEvent):void{
if(e.keyCode == Keyboard.SPACE){
spacePressed = false;
player.gotoAndPlay("fire");
}
if(e.keyCode == Keyboard.LEFT){
leftPressed = false;
}
else if(e.keyCode == Keyboard.RIGHT){
rightPressed = false;
}
else if(e.keyCode == Keyboard.UP){
upPressed = false;
}
else if(e.keyCode == Keyboard.DOWN){
downPressed = false;
}
}
hi guys thank you so much for trying to help
Ok so the question is this. I am trying to move a movieclip automatically with
movieClip.x += xspeed ;
ofcourse this works but the point is i want this to be triggered with keyboard press ..problem is i couldn't a keyboard event which works as a mouse click..it works as long as space bar is pressed but if i release it ..it stops working..i want it to be like onclick it should start moving automatically.
Any ideas? thanks
hi thanks so much for your reply and sorry for the delay. Your code gave me an idea but I tried to write it without classes . It doesnt throw up any errors however it doesnt work either . I must be doing something stupid , please have a look and let me know . //rope coding
var ropey = MovieClip(this.root).boat_mc.rope_mc.fishyrope_mc.hitbox_mc.y ;
trace(ropey);
var ropemove:Boolean;
stage.addEventListener(Event.ENTER_FRAME,ropeCode);
function ropeCode(e:Event):void
{
//detect keyboard spacebar click
stage.addEventListener(KeyboardEvent.KEY_UP,onSpacebarUp);
function onSpacebarUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.SPACE)
{
ropemove = true;
} else if(ropey > 600 ) {
ropemove = false;
}
}
//drop rope if variable = true
function dropRope(e:Event):void
{
if(ropemove = true) {
MovieClip(this.root).boat_mc.rope_mc.y += xSpeed;
} else if (ropemove = false) {
MovieClip(this.root).boat_mc.rope_mc.y -= xSpeed;
}
}
}
MyObj extends MovieClip (or Sprite). Basically alls that's happening is you should just toggle a variable when you get the KEY_UP (not KEY_DOWN, as that will repeat if the key is held down). Then, every frame, check this variable, and if's it's good, move
Something like:
private var m_shouldMove:Boolean = false;
// constructor
public function MyObj()
{
// add our listener for when we're added to the stage as we'll be adding events on it
this.addEventListener( Event.ADDED_TO_STAGE, this._onAddedToStage );
}
private function _onAddedToStage( e:Event ):void
{
// NOTE: the keyboard listener goes onto the stage
// you'll also need to remove the events when your object is removed (e.g. REMOVED_FROM_STAGE)
this.removeEventListener( Event.ADDED_TO_STAGE, this._onAddedToStage );
this.addEventListener( Event.ENTER_FRAME, this._onEnterFrame );
this.stage.addEventListener( KeyboardEvent.KEY_UP, this._onKeyUp );
}
private function _onEnterFrame( e:Event ):void
{
// every frame, if we should move, do so
if( this.m_shouldMove )
this.x += this.speed;
}
private function _onKeyUp( e:KeyboardEvent ):void
{
if( e.keyCode == Keyboard.SPACE )
this.m_shouldMove = !this.m_shouldMove; // toggle our var
}
Update
I've reworked your code sample, so it should work now:
var rope = MovieClip(this.root).boat_mc.rope_mc.fishyrope_mc.hitbox_mc;
var ropeMove:Boolean = false;
stage.addEventListener(Event.ENTER_FRAME, ropeCode);
stage.addEventListener(KeyboardEvent.KEY_UP, onSpacebarUp);
function onSpacebarUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.SPACE)
ropeMove = !ropeMove; // toggles ropeMove (i.e. if it's true, sets it to false, and vice versa)
}
function ropeCode(e:Event):void
{
// move the rope
if( ropeMove )
{
rope.y += xSpeed;
// stop moving if we've gone too far
if( rope.y > 600.0 )
{
rope.y = 600.0;
ropeMove = false;
}
}
}
What I changed:
Held your rope as a variable to make it easier to access
Removed ropey as it's not needed (for your > 600.0 check, you need to recalculate it anyway
The keyboard event is now added with the enter frame event (you were adding a new keyboard event every frame
The keyboard event listener just toggles the ropeMove var (there's no point checking for > 600.0 here as it means you only check when any other key is pressed)
The enter frame event simply moves the rope y
In the enter frame event, if our y is too big, we stop moving
What the code is doing:
We set up our vars - rope and ropeMove - ropeMove is used to know if we can move the rope or not
We add our event listeners - one for the keybard event, to catch the spacebar key, and one enter frame event, so we can move our rope if necessary
In the keyboard event, if our key is the spacebar, we toggle our ropeMove variable
In the enter frame event, if ropeMove is true, we move our rope
If our rope.y is greater than 600, we clamp it to 600, and set ropeMove to false so we stop moving
Update 2
With the addition of a variable ropeDir, the rope will now continuously move up and down (assuming ropeMove is true)
var rope = MovieClip(this.root).boat_mc.rope_mc.fishyrope_mc.hitbox_mc;
var ropeMove:Boolean = false;
var ropeDir:int = 1;
stage.addEventListener(Event.ENTER_FRAME, ropeCode);
stage.addEventListener(KeyboardEvent.KEY_UP, onSpacebarUp);
function onSpacebarUp(e:KeyboardEvent):void
{
if (e.keyCode == Keyboard.SPACE)
ropeMove = !ropeMove; // toggles ropeMove (i.e. if it's true, sets it to false, and vice versa)
}
function ropeCode(e:Event):void
{
// move the rope
if( ropeMove )
{
rope.y += xSpeed * ropeDir;
// stop moving if we've gone too far
if( rope.y > 600.0 && ropeDir == 1 )
ropeDir = -1;
else if( rope.y < 0.0 && ropeDir == -1 )
ropeDir = 1;
}
}
addEventListener(KeyboardEvent.KEY_DOWN, moveStarter);
function moveStarter():void
{
addEventListener(Event.ENTER_FRAME, startMove);
}
I'm very new to coding and am having trouble finishing the last little bit of a mini game type project for school.
So this is a draft of what the program looks like so far: http://aaronmillard.com/dir/wp-content/uploads/2013/08/Google-Doodle_Roomba.swf
Now what I want the program to do is "vacuum" up the google when the roomba drives over it. The easiest way to achieve this (I think) is to have an exact replica of the carpet layer without the google logo beneath the carpet layer with the google logo. So I would need to code something like "when the object(roomba) passes over object(carpetwithgooglelogo) make object(carpetwithgooglelogo) have 0 opacity." I just can't figure out how to say that in code.
The code as of right now look like this:
// Assign 4 booleans for the 4 arrow keys
var keyUp = false;
var keyDown = false;
var keyLeft = false;
var keyRight = false;
// Add the keyboard event (KEY_DOWN) on the stage
stage.addEventListener(KeyboardEvent.KEY_DOWN, pressKey);
function pressKey(pEvent)
{
// If an arrow key is down, switch the value to true to the assigned variable
if (pEvent.keyCode == 38)
{
keyUp = true;
}
else if (pEvent.keyCode == 40)
{
keyDown = true;
}
else if (pEvent.keyCode == 37)
{
keyLeft = true;
}
else if (pEvent.keyCode == 39)
{
keyRight = true;
}
}
// Add the keyboard event (KEY_UP) on the stage
stage.addEventListener(KeyboardEvent.KEY_UP, releaseKey);
function releaseKey(pEvent)
{
// If the arrow key is up, switch the value to false to the assigned variable
if (pEvent.keyCode == 38)
{
keyUp = false;
}
else if (pEvent.keyCode == 40)
{
keyDown = false;
}
else if (pEvent.keyCode == 37)
{
keyLeft = false;
}
else if (pEvent.keyCode == 39)
{
keyRight = false;
}
}
// Set the velocity of the object
var speed = 4;
// And the rotation speed
var rotationSpeed = 6;
// Add an enter frame event on the moving object
myCircle.addEventListener(Event.ENTER_FRAME, circleEnterFrame);
function circleEnterFrame(pEvent)
{
// Set the default velocity to 0 if no key is pressed
var velocity = 0;
if (keyUp)
{
// If the key up is pressed set the new velocity to the speed value
velocity = speed;
}
if (keyDown)
{
// If the key down is pressed set the new velocity to the half speed value
velocity = -speed/2;
}
if (keyLeft)
{
// rotate the object
pEvent.currentTarget.rotation -= rotationSpeed;
}
if (keyRight)
{
// rotate the object
pEvent.currentTarget.rotation += rotationSpeed;
}
// Convert the degreeAngle to the radian angle
var angleRadian = pEvent.currentTarget.rotation / 180 * Math.PI;
// Move the object with the radian angle and the object speed
pEvent.currentTarget.x += Math.cos(angleRadian) * velocity;
pEvent.currentTarget.y += Math.sin(angleRadian) * velocity;
}
Any help would be very much appreciated! Thanks!
The easiest way is to do something like this:
if( roomba.hitTestObject(google)){
google.alpha = 0;
}
You'll have to check this on every frame using an ENTER_FRAME event.
If this is confusing tell me in the comments and I will clarify with more code.
I have a vertical shooter game I'm working on. I need to find a way to make random objects(enemies) drop down from the top. At the moment I've got 1 enemy that drops down randomly from the top which is working. here is the code I'm using.
Main code
// Full Screen Command
fscommand("fullscreen","true");
stop();
//center player on screen
mcMain.x = 880,45;
mcMain.y = 940,40;
//these booleans will check which keys are down
var leftDown:Boolean = false;
var upDown:Boolean = false;
var rightDown:Boolean = false;
var downDown:Boolean = false;
//how fast the character will be able to go
var mainSpeed:int = 25;
//how much time before allowed to shoot again
var cTime:int = 0;
//the time it has to reach in order to be allowed to shoot (in frames)
var cLimit:int = 12;
//whether or not the user is allowed to shoot
var shootAllow:Boolean = true;
//how much time before another enemy is made
var enemyTime:int = 0;
//how much time needed to make an enemy
//it should be more than the shooting rate
//or else killing all of the enemies would
//be impossible :O
var enemyLimit:int = 16;
//the player's score
var score:int = 0;
//this movieclip will hold all of the bullets
var bulletContainer:MovieClip = new MovieClip();
addChild(bulletContainer);
//whether or not the game is over
var gameOver:Boolean = false;
//adding a listener to mcMain that will move the character
mcMain.addEventListener(Event.ENTER_FRAME, moveChar);
function moveChar(event:Event):void{
//checking if the key booleans are true then moving
//the character based on the keys
if(leftDown){
mcMain.x -= mainSpeed;
}
if(upDown){
mcMain.y -= mainSpeed;
}
if(rightDown){
mcMain.x += mainSpeed;
}
if(downDown){
mcMain.y += mainSpeed;
}
//keeping the main character within bounds
if(mcMain.x <= 0){
mcMain.x += mainSpeed;
}
if(mcMain.y <= 0){
mcMain.y += mainSpeed;
}
if(mcMain.x >= stage.stageWidth - mcMain.width){
mcMain.x -= mainSpeed;
}
if(mcMain.y >= stage.stageHeight - mcMain.height){
mcMain.y -= mainSpeed;
}
//Incrementing the cTime
//checking if cTime has reached the limit yet
if(cTime < cLimit){
cTime ++;
} else {
//if it has, then allow the user to shoot
shootAllow = true;
//and reset cTime
cTime = 0;
}
//adding enemies to stage
if(enemyTime < enemyLimit){
//if time hasn't reached the limit, then just increment
enemyTime ++;
} else {
//defining a variable which will hold the new enemy
var newEnemy = new Enemy();
//making the enemy offstage when it is created
newEnemy.y = -1 * newEnemy.height;
//making the enemy's x coordinates random
//the "int" function will act the same as Math.floor but a bit faster
newEnemy.x = int(Math.random()*(stage.stageWidth - newEnemy.width));
//then add the enemy to stage
addChild(newEnemy);
//and reset the enemyTime
enemyTime = 0;
}
//updating the score text
txtScore.text = 'SCORE: '+score;
}
//this listener will listen for down keystrokes
stage.addEventListener(KeyboardEvent.KEY_DOWN, checkKeysDown);
function checkKeysDown(event:KeyboardEvent):void{
//making the booleans true based on the keycode
//WASD Keys or arrow keys
if(event.keyCode == 37 || event.keyCode == 65){
leftDown = true;
}
if(event.keyCode == 39 || event.keyCode == 68){
rightDown = true;
}
//checking if the space bar is pressed and shooting is allowed
if(event.keyCode == 32 && shootAllow){
//making it so the user can't shoot for a bit
shootAllow = false;
//declaring a variable to be a new Bullet
var newBullet:Bullet = new Bullet();
//changing the bullet's coordinates
newBullet.x = mcMain.x + mcMain.width/2 - newBullet.width/2;
newBullet.y = mcMain.y;
//then we add the bullet to stage
bulletContainer.addChild(newBullet);
mcMain.gotoAndPlay(1);
}
}
//this listener will listen for keys being released
stage.addEventListener(KeyboardEvent.KEY_UP, checkKeysUp);
function checkKeysUp(event:KeyboardEvent):void{
//making the booleans false based on the keycode
if(event.keyCode == 37 || event.keyCode == 65){
leftDown = false;
}
if(event.keyCode == 39 || event.keyCode == 68){
rightDown = false;
}
}
enemy class
package{
//we have to import certain display objects and events
import flash.display.MovieClip;
import flash.events.*;
//this just means that Enemy will act like a MovieClip
public class Enemy extends MovieClip{
//VARIABLES
//this will act as the root of the document
//so we can easily reference it within the class
private var _root:Object;
//how quickly the enemy will move
private var speed:int = 5;
//this function will run every time the Bullet is added
//to the stage
public function Enemy(){
//adding events to this class
//functions that will run only when the MC is added
addEventListener(Event.ADDED, beginClass);
//functions that will run on enter frame
addEventListener(Event.ENTER_FRAME, eFrame);
}
private function beginClass(event:Event):void{
_root = MovieClip(root);
}
private function eFrame(event:Event):void{
//moving the bullet up screen
y += speed;
//making the bullet be removed if it goes off stage
if(this.y > stage.stageHeight){
removeEventListener(Event.ENTER_FRAME, eFrame);
_root.removeChild(this);
}
//checking if it is touching any bullets
//we will have to run a for loop because there will be multiple bullets
for(var i:int = 0;i<_root.bulletContainer.numChildren;i++){
//numChildren is just the amount of movieclips within
//the bulletContainer.
//we define a variable that will be the bullet that we are currently
//hit testing.
var bulletTarget:MovieClip = _root.bulletContainer.getChildAt(i);
//now we hit test
if(hitTestObject(bulletTarget)){
//remove this from the stage if it touches a bullet
removeEventListener(Event.ENTER_FRAME, eFrame);
_root.removeChild(this);
//also remove the bullet and its listeners
_root.bulletContainer.removeChild(bulletTarget);
bulletTarget.removeListeners();
//up the score
_root.score += 5;
}
}
//hit testing with the user
if(hitTestObject(_root.deadLine)){
//losing the game
_root.gameOver = true;
_root.gotoAndStop('lose');
}
//checking if game is over
if(_root.gameOver){
removeEventListener(Event.ENTER_FRAME, eFrame);
this.parent.removeChild(this);
}
}
}
}
I'm using the tutorial from here : http://www.flashgametuts.com/tutorials/as3/how-to-make-a-vertical-shooter-in-as3-part-1/
any help is much appriciated.
I used to make games in flash and I used this condition to constantly add Enemies in my game.
if (Math.floor(Math.random() * 90) == 5){
under this condition you can use your code do add 1 enemy randomly
I think you shold get a timer class conected to your main code.
get a global counter.
int count=0;
int timeElapsedToNewEnemy = int((Math.random()*10+1)*10);
//get u a number from 10 to 100
get ur timer
var time:Timer=new Timer(100,0);// each 1/10 seconds
time.start();
time.addEventListener(TimerEvent.TIMER, countTime);
get ur function for timer
function countTime(e:TimerEvent):void
{//increment ur timer
count++;
if (cont == timeElapsedToNewEnemy)
{
cont=0;//restar ur counter..
//createUrNewEnemyHere
//get a new timeElapsedToEnemy
timeElapsedToNewEnemy = int((Math.random()*10+1)*10);
}
}
now u can easily adjust it to create random enemys each random x time.
let me know if its work for u
Thanks guys, but i found a solution.
var newEnemy = new (getDefinitionByName("Enemy"+Math.floor(Math.random()*4)));
and then created different movieclips of the enemy as enemy