I'm making a top-down RPG style game, very much a throwback to zelda. This is my code for the movement controls based on keyboard controls. The movement itself is pretty solid, no stutter-key syndrome, all animations are triggered correctly.
However, when the attack button (SPACE in this case) is pressed it triggers the appropriate frame but when the key is released the corresponding frame is still visible, until another direction key is pressed. So, when you attack it looks like he keeps his sword extended until another movement is made, and so on. This should only happen when the key is held down not when simply pressed. This is not the expected result. The result I'm looking for is an attack that triggers every time the key is pressed, creating the normal buttondown=attacking, buttonup = not attacking.
The attacks and movement now are based on a variable moving:int = 4; That way I can switch the attack position to the corresponding movement direction.
Any ideas on how to correct this issue?
import flash.events.Event;
import flash.events.KeyboardEvent;
character.stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress);// when key is pressed
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyRelease);//when key is released
stage.addEventListener(Event.ENTER_FRAME, MainLoop);
var moving:int = 4;
var movingDown:Boolean = false;
var movingUp:Boolean = false;
var movingRight:Boolean = false;
var movingLeft:Boolean = false;
function onKeyPress(e:KeyboardEvent):void
{
switch (e.keyCode)
{
case Keyboard.DOWN : movingDown = true; moving = 1; break;
case Keyboard.UP : movingUp = true; moving = 2; break;
case Keyboard.RIGHT : movingRight = true; moving = 3; break;
case Keyboard.LEFT : movingLeft = true; moving = 4; break;
case Keyboard.SPACE : handleAttack(); break;
}
}
function onKeyRelease(e:KeyboardEvent):void
{
switch (e.keyCode)
{
case Keyboard.DOWN: character.gotoAndStop(1); movingDown=false; moving = 1; break;
case Keyboard.UP: character.gotoAndStop(3);movingUp=false; moving = 2; break;
case Keyboard.LEFT: character.gotoAndStop(5);movingLeft=false; moving = 3; break;
case Keyboard.RIGHT: character.gotoAndStop(7);movingRight=false; moving = 4; break;
case Keyboard.SPACE: handleAttack(); break;
}
}
function handleAttack():void
{
switch (moving)
{
case 1: character.gotoAndStop(9); movingDown = false; break; //down
case 2: character.gotoAndStop(10); movingUp = false; break; //up
case 3: character.gotoAndStop(11); movingLeft = false; break; //left attacks
case 4: character.gotoAndStop(12); movingRight = false; break; //right
}
}
function MainLoop(e:Event):void
{
switch (true)
{
case movingDown: character.gotoAndStop(2); character.y+=4.5; break;
case movingUp: character.gotoAndStop(4); character.y-=4.5; break;
case movingLeft: character.gotoAndStop(6); character.x-=4.5; break;
case movingRight: character.gotoAndStop(8); character.x+=4.5; break;
}
}
I am kinda new myself but i think it's because both onKeyPress() and onKeyRelease() point to the same function handleAttack() and as such point to the same frame even when you release. Try making two seperate attack functions for each one.
e.g
attackPressed() for onKeyPress()
function attackPressed():void
{
switch (moving)
{
case 1: character.gotoAndStop(9); movingDown = false; break;
case 2: character.gotoAndStop(10); movingUp = false; break;
case 3: character.gotoAndStop(11); movingLeft = false; break;
case 4: character.gotoAndStop(12); movingRight = false; break;
}
}
and attackRelease() for onKeyRelease()
function attackRelease():void
{
switch (moving)
{
case 1:character.gotoAndStop(1); movingDown = false; break;
case 2:character.gotoAndStop(3); movingUp = false; break;
case 3: character.gotoAndStop(5); movingLeft = false; break;
case 4: character.gotoAndStop(7); movingRight = false; break;
}
}
Hope this helps.
Related
I'm having trouble making my figure move diagonally with the arrowkeys. I can make it so that it moves up, down, left and right but I'm unsure how to make it read that two buttons are pressed down at once and therefore it should move in a certain way. This it the code I have for the keypresses so far. Any tips are appreciated!
function keyPressHandler(event:KeyboardEvent):void
{
switch( event.keyCode )
{
case Keyboard.UP:
up = true;
beetle_mc.rotation = 0;
beetle_mc.y -=speed;
up_mc.gotoAndStop(2);
break;
case Keyboard.DOWN:
down = true;
beetle_mc.rotation = 180;
beetle_mc.y +=speed;
down_mc.gotoAndStop(2);
break;
case Keyboard.LEFT:
left = true;
beetle_mc.rotation = 270;
beetle_mc.x -=speed;
left_mc.gotoAndStop(2);
break;
case Keyboard.RIGHT:
right = true;
beetle_mc.rotation = 90;
beetle_mc.x +=speed;
right_mc.gotoAndStop(2);
break;
I'm using flash CS4 to have an animated character moving within the stage boundaries. There are no code errors when generating the SWF file and the character is moving fine when I test the movie in Flash. Once I publish the file, the character is completely unresponsive to the arrow keys. I have no clue as what the issue might be and some help would be greatly appreciated. Here's the code of the movie :
stop();
var upPressed:Boolean = false;
var downPressed:Boolean = false;
var leftPressed:Boolean = false;
var rightPressed:Boolean = false;
var isWalking:Boolean = false;
var mySpeed:Number = 3;
my_Sprite.addEventListener(Event.ENTER_FRAME, moveSprite);
stage.addEventListener(KeyboardEvent.KEY_DOWN, setKeyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, unsetKeyPressed);
function moveSprite(event:Event):void {
if(upPressed && my_Sprite.y >= 40){
my_Sprite.y -= mySpeed;
}
if(downPressed && my_Sprite.y <= 440){
my_Sprite.y += mySpeed;
}
if(leftPressed && my_Sprite.x >= 20){
my_Sprite.x -= mySpeed;
}
if(rightPressed && my_Sprite.x <= 600){
my_Sprite.x += mySpeed;
}
}
function setKeyPressed(event:KeyboardEvent):void {
switch(event.keyCode){
case Keyboard.UP: {
upPressed = true;
if (!isWalking) {
my_Sprite.gotoAndPlay("Up");
isWalking = true;
}
break;
}
case Keyboard.DOWN: {
downPressed = true;
if (!isWalking) {
my_Sprite.gotoAndPlay("Down");
isWalking = true;
}
break;
}
case Keyboard.LEFT: {
leftPressed = true;
if (!isWalking) {
my_Sprite.gotoAndPlay("Left");
isWalking = true;
}
break;
}
case Keyboard.RIGHT: {
rightPressed = true;
if (!isWalking) {
my_Sprite.gotoAndPlay("Right");
isWalking = true;
}
break;
}
}
}
function unsetKeyPressed(event:KeyboardEvent):void {
switch(event.keyCode) {
case Keyboard.UP: {
upPressed = false;
my_Sprite.gotoAndStop("Up");
isWalking = false;
break;
}
case Keyboard.DOWN: {
downPressed = false;
my_Sprite.gotoAndStop("Down");
isWalking = false;
break;
}
case Keyboard.LEFT: {
leftPressed = false;
my_Sprite.gotoAndStop("Left");
isWalking = false;
break;
}
case Keyboard.RIGHT: {
rightPressed = false;
my_Sprite.gotoAndStop("Right");
isWalking = false;
break;
}
}
}
You may need to add some JavaScript to your HTML to set the focus on the Flash object:
<body onLoad="window.document.movieID.focus();">
Make sure you change movieID to whatever you actually set as your ID.
you can force the focus by doing
this.stage.focus = myTextField; // assuming this is added to the display hierarchy
I'm trying to setup keyboard control for my game and ran into an interesting obstacle: When the player presses a key to move in a specific direction a delay in the physical movement occurs similar to the delay that happens when editing text.
For instance, When you hold down the "a" key (just as an example, of course it could be any key) and there is a second delay before the cursor will then register "aaaaaaa". The same problem is happening here, so when a direction key is pressed the frame animations begin before the physical movement starts. Which results in an animation that looks like the character is running in place and then finally starts moving after about a 1 or 2 seconds.
Any thoughts, ideas, or advice on a fix would be much appreciated. Thanks in advance, all.
import flash.events.Event;
import flash.events.KeyboardEvent;
character.stop();
stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyPress);
stage.addEventListener(KeyboardEvent.KEY_UP, onKeyRelease);
stage.addEventListener(Event.ENTER_FRAME, onEnterThisFrame);
var moving:int = 4;
var animate:Boolean = false;
function onKeyPress(e:KeyboardEvent):void
{
switch(e.keyCode)
{
case 37: moving = 1; character.gotoAndStop(6); character.x-=5; break; //left
case 38: moving = 2; character.gotoAndStop(4); character.y-=5; break; //up
case 39: moving = 3; character.gotoAndStop(8); character.x+=5; break; //right
case 40: moving = 4; character.gotoAndStop(2); character.y+=5; break; //down
case 32: handleAttack();
}
animate = false;
}
function onKeyRelease(e:KeyboardEvent):void
{
switch(moving)
{
case 1: character.gotoAndStop(6); break; //left
case 2: character.gotoAndStop(4); break; //up
case 3: character.gotoAndStop(8); break; //right
case 4: character.gotoAndStop(2); break; //down
}
animate = true;
}
function handleAttack():void
{
switch (moving)
{
case 1: character.gotoAndStop(11); break; //left
case 2: character.gotoAndStop(10); break; //up
case 3: character.gotoAndStop(12); break; //right
case 4: character.gotoAndStop(9); break; //down
}
}
function onEnterThisFrame(e:Event):void
{
if (animate == true)
{
switch (moving)
{
case 1: if(character.currentFrame == 6) character.gotoAndStop(5); break;
case 2: if(character.currentFrame == 4) character.gotoAndStop(3); break;
case 3: if(character.currentFrame == 8) character.gotoAndStop(7); break;
case 4: if(character.currentFrame == 2) character.gotoAndStop(1); break;
}
}
}
Have bools for each direction and change your onKeyPress and onKeyRelease to set these, then check them and move your character in your onEnterThisFrame function.
There a strange bug on my program compilation...
For my program scenario, it's just a MovieClip names "perso" who move with keyboard's arrows.
Flash says me that "clavierUp" and "animation" property access can't be find.
I really don't understand...
var perso:Perso = new Perso();
stage.addEventListener(KeyboardEvent.KEY_DOWN, clavierDown);
stage.addEventListener(KeyboardEvent.KEY_UP, clavierUp);
stage.addEventListener(Event.ENTER_FRAME, animation);
function clavierDown(e)
{
switch(e.keyCode)
{
case Keyboard.LEFT:
perso.speedX = -speedHero;
break;
case Keyboard.RIGHT:
perso.speedX = speedHero;
break;
case Keyboard.UP:
perso.speedY = -speedHero;
break;
case Keyboard.DOWN:
perso.speedY = speedHero;
break;
}
function clavierUp(e)
{
switch(e.keyCode)
{
case Keyboard.LEFT:
perso.speedX = 0;
perso.scaleX = -1;
break;
case Keyboard.RIGHT:
perso.speedX = 0;
perso.scaleX = 1;
break;
case Keyboard.UP:
perso.speedY = 0;
break;
case Keyboard.DOWN:
perso.speedY = 0;
break;
}
}
function animation(e)
{
animeHero();
}
Thank you !
Sorry, i just missed a rightbrace at the end of "clavierDown" function...
I am struggling a bit with my switch statement (I've never used switch before). I have a hit test for when my object reaches the top or bottom of the stage. When this happens, I want to switch states (the game in question is a simple platformer that allows the player to switch the gravity when they hit a new surface. Below is my current code:
{
...
if(player.hitTestObject(bottom)) {
//Switch state to normal
}
if(player.hitTestObject(top)) {
//Switch state to inverted
}
}
switch (myGrav){
case "NORMAL":
trace("Normal")
player.gotoAndPlay(1);
oktoJump = false;
player.y = 376.5;
case "INVERTED":
trace("Inverted")
player.gotoAndPlay(8);
oktoJump = false;
player.y = 12;
}
Thanks!
Cases within your switch statement are missing a break; therefore, code will continue to execute through the switch statement.
This should be:
var myGrav:String = "NORMAL";
if (player.hitTestObject(bottom))
myGrav = "NORMAL";
if (player.hitTestObject(top))
myGrav = "INVERTED";
switch (myGrav)
{
case "NORMAL":
trace("Normal")
player.gotoAndPlay(1);
oktoJump = false;
player.y = 376.5;
break;
case "INVERTED":
trace("Inverted")
player.gotoAndPlay(8);
oktoJump = false;
player.y = 12;
break;
}
I prefer less variables when I can get away with it.
switch (true){
case (player.hitTestObject(bottom)):
trace("Normal")
player.gotoAndPlay(1);
oktoJump = false;
player.y = 376.5;
break;
case (player.hitTestObject(top)):
trace("Inverted")
player.gotoAndPlay(8);
oktoJump = false;
player.y = 12;
break;
}