ActionScript: How come i cant draw diagonally? - actionscript-3

So, I'm learning ActionScript on my own with a book ('Foundation AS3.0 with Flash...').
And I'm stuck on an excercise.
I have to make a drawing app with using the arrowkeys and spacebar.
It doesn't work 100%. I can draw up, down, right, left. Even diagonal, only right-up, and left-down.
Do you guys know where my mistake is? I also want to draw left-up and right-down....
Here's my code so far:
package classes{
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.Event;
public class KeyboardDrawing extends Sprite{
private const PIXEL_DISTANCE_TO_DRAW:uint = 2;
private var _canvas:Sprite;
private var _crosshair:Shape;
private var _xDirection:int = 0;
private var _yDirection:int = 0;
private var _isDrawing:Boolean = false;
public function KeyboardDrawing(){
_canvas=new Sprite();
addChild(_canvas);
_crosshair=new Shape();
drawCrosshair();
addChild(_crosshair);
_canvas.graphics.lineStyle(2, 0x000000);
stage.focus=_canvas;
_canvas.addEventListener(KeyboardEvent.KEY_DOWN, onCanvasKeyDown);
_canvas.addEventListener(KeyboardEvent.KEY_UP, onCanvasKeyUp);
_canvas.addEventListener(Event.ENTER_FRAME, onCanvasEnterFrame);
}
private function drawCrosshair():void{
_crosshair.graphics.lineStyle(1, 0x000000);
_crosshair.graphics.moveTo(-5, 0);
_crosshair.graphics.lineTo(6, 0);
_crosshair.graphics.moveTo(0, -5);
_crosshair.graphics.lineTo(0, 6);
}
private function onCanvasKeyDown(event:KeyboardEvent):void{
switch(event.keyCode){
case Keyboard.UP:
_yDirection = -PIXEL_DISTANCE_TO_DRAW;
break;
case Keyboard.DOWN:
_yDirection = PIXEL_DISTANCE_TO_DRAW;
break;
case Keyboard.LEFT:
_xDirection = -PIXEL_DISTANCE_TO_DRAW;
break;
case Keyboard.RIGHT:
_xDirection = PIXEL_DISTANCE_TO_DRAW;
break;
case Keyboard.SPACE:
_isDrawing = true;
break;
}
}
private function onCanvasKeyUp(event:KeyboardEvent):void{
switch(event.keyCode){
case Keyboard.UP:
case Keyboard.DOWN:
_yDirection = 0;
break;
case Keyboard.LEFT:
case Keyboard.RIGHT:
_xDirection = 0;
break;
case Keyboard.SPACE:
_isDrawing = false;
break;
}
}
private function onCanvasEnterFrame(event:Event):void{
_crosshair.x += _xDirection;
_crosshair.y += _yDirection;
if (_isDrawing){
_canvas.graphics.lineTo(_crosshair.x, _crosshair.y);
}else{
_canvas.graphics.moveTo(_crosshair.x, _crosshair.y);
}
}
}
}

It's an issue with the keyboard and certain combinations of keys.
If you change the keys to WASD like so it works fine:
private function onCanvasKeyDown(event:KeyboardEvent):void{
switch(event.keyCode){
case Keyboard.W:
_yDirection = -PIXEL_DISTANCE_TO_DRAW;
break;
case Keyboard.S:
_yDirection = PIXEL_DISTANCE_TO_DRAW;
break;
case Keyboard.A:
_xDirection = -PIXEL_DISTANCE_TO_DRAW;
break;
case Keyboard.D:
_xDirection = PIXEL_DISTANCE_TO_DRAW;
break;
case Keyboard.SPACE:
_isDrawing = true;
break;
}
}
private function onCanvasKeyUp(event:KeyboardEvent):void{
switch(event.keyCode){
case Keyboard.W:
case Keyboard.S:
_yDirection = 0;
break;
case Keyboard.A:
case Keyboard.D:
_xDirection = 0;
break;
case Keyboard.SPACE:
_isDrawing = false;
break;
}
}
Basically it's due to flawed keyboard design that simplifies the wiring at the expense of some key combinations.
I found this article that explains it in full: http://www.microsoft.com/appliedsciences/antighostingexplained.mspx

Related

How do I stop a sprite from jumping in midair? ActionScript 3/Flash Pro CC 2015

I am a beginner Flash/AS3 programmer and I have a very sophisticated problem. How can I prevent a sprite from jumping in midair? I've seen the other question related to "sprite/jump in midair", but I personally cannot figure out how to do that in AS3. Thank you for any response.
Code:
public class DocumentMain extends MovieClip {
private var _vx: Number;
import flash.utils.Timer;
import flash.ui.Keyboard;
import flash.events.Event;
import flash.events.KeyboardEvent;
private var _vy: Number;
public function DocumentMain() {
// constructor code
_vx = 0;
_vy = 0
_startMarker.visible = false;
this.addEventListener("enterFrame", a);
stage.addEventListener("keyDown", b);
stage.addEventListener("keyUp", c);
_windows.addEventListener("enterFrame", handleCollision);
function handleCollision( e:Event ):void
{
{
var collisionWall:Boolean = false;
if (wall.hitTestObject(_windows)) {
collisionWall = true;
}
if (collisionWall) {
while (collisionWall) {
_windows.x += 0.1;
collisionWall = false;
if (wall.hitTestObject(_windows)) {
collisionWall = true;
}
}
_vx = 0;
}
}
}
function a(e:Event):void {
_vy += 2;
_windows.x += _vx;
_windows.y += _vy;
if (_vy > 0) {
if (_windows.y > stage.stageHeight) {
_windows.x = _startMarker.x;
_windows.y = _startMarker.y;
_vy = 0;
}
else {
var collision:Boolean = false;
if (ground.hitTestObject(_windows)) {
collision = true;
}
if (collision) {
while (collision) {
_windows.y -= 0.1;
collision = false;
if (ground.hitTestObject(_windows)) {
collision = true;
}
}
_vy = 0;
}
}
}
}
function b(e:KeyboardEvent):void {
var step:uint = 5
switch (e.keyCode) {
case 37:
_windows.rotationY = -180;
_vx = -7;
break;
case 39:
_windows.rotationY = 0;
_vx = 7;
break;
case 38:
_vy = -20;
break;
}
}
function c(e:KeyboardEvent):void {
switch (e.keyCode) {
case 37:
case 39:
_vx = 0;
}
}
}
}
You need to declare the condition "on the ground" for the player-controlled sprite (I expect from here it's called _windows), and based on that condition, either let the player change vertical speed with up key, or ignore.
You have here a block of code designed to handle ground collision (crude but it does work from what I'm seeing) in your function a(e:Event), this one is the place to set the "on the ground" flag, if there was a collision with ground, set that to true. Since your function first applies "gravity" then checks for collision, it should work properly handling cliffs/slopes together with jumping. So, you declare a Boolean variable in your game class, say "isOnGround", set it to false at first, then check collision with ground, if true, set that var to true. Then, at b() function (a "keyDown" handler) you check whether the var is true, and if yes, jumping is allowed so you happily set your _vy, otherwise you do nothing.
// adding only changed fragments
public class DocumentMain extends MovieClip {
private var _isOnGround:Boolean; // the flag
...
function a(e:Event):void {
...
_isOnGround = false; // reset flag
if (ground.hitTestObject(_windows)) {
collision = true;
_isOnGround = true; // we ARE on ground, rest isn't relevant here
}
...
}
}
function b(e:KeyboardEvent):void {
...
case 38:
if (_isOnGround) { // check here
_vy = -20;
_isOnGround = false; // just in case here
} // otherwise do nothing
break;

Play full Mc in a single key press

First, sorry to ask this silly question (I am new in AS3). I wasted more then 2 weeks on this problem, and am now posting it here.
I am making a hero move with the keyboard. I have three animations.
Standby mode
walk front
walk behind
It's working well so far, but the problem I'm facing in jumping the player is having to hold down the key to jump. I don't want the player to be required to hold the key to perform jumping.
So I want to play the full MovieClip with one key press, and honestly I don't know which function I have to use or how to do it.
Here is the file, and here is my code
import flash.display.Stage;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.display.MovieClip;
import flash.events.Event;
kim.gotoAndStop("kim Stand");
var grav:int = 0;
var floor = 450;
var dPressed:Boolean = false;
var aPressed:Boolean = false;
var jumping:Boolean = false;
stage.addEventListener(KeyboardEvent.KEY_DOWN , keyDownHandaler);
stage.addEventListener(KeyboardEvent.KEY_UP , KeyUpHandaler);
stage.addEventListener(Event.ENTER_FRAME , gameLoop);
function keyDownHandaler(Devent:KeyboardEvent):void
{
if (Devent.keyCode == Keyboard.D)
{
dPressed = true;
}
else if (Devent.keyCode == Keyboard.A)
{
aPressed = true;
}
else if (Devent.keyCode == Keyboard.W && !jumping)
{
jumping = true;
}
}
function KeyUpHandaler (Uevent:KeyboardEvent):void
{
if (Uevent.keyCode == Keyboard.D)
{
dPressed = false;
kim.gotoAndStop("kim Stand");
}
else if(Uevent.keyCode == Keyboard.A)
{
aPressed = false;
kim.gotoAndStop("kim Stand");
}
else if(Uevent.keyCode == Keyboard.W)
{
jumping = false;
kim.gotoAndStop("kim Stand");
}
}
function gameLoop(Levent:Event):void
{
if (dPressed)
{
kim.x += 5;
kim.gotoAndStop("kim Move Right");
}
else if(aPressed)
{
kim.x -= 5;
kim.gotoAndStop("kim Move Left");
}
else if(jumping)
{
kim.gotoAndStop("kim Jump");
kim.y -= 10;
}
gravity();
}
function gravity ():void
{
kim.y += grav;
if (kim.y+kim.height/2 <floor){
grav++;
}
else {
grav = 0;
kim.y = floor - kim.height/2 ;
}
}
You may want to try state based logic. The keyboard events set it, and the actions for updating the character are handled separately in your gameLoop(). The last piece of the puzzle would be to update your state when you recognize you've landed (something that happens not from keyboard interaction, but rather from your gravity function).
import flash.display.Stage;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.display.MovieClip;
import flash.events.Event;
var grav:int = 0;
var floor = 450;
var state:String = "stand";
stage.addEventListener(KeyboardEvent.KEY_DOWN , keyHandler);
stage.addEventListener(KeyboardEvent.KEY_UP , keyHandler);
stage.addEventListener(Event.ENTER_FRAME , gameLoop);
function keyHandler(e:KeyboardEvent):void {
switch (e.keyCode) {
case Keyboard.D:
state = (e.type == "keyDown") ? "right" : "stand";
break;
case Keyboard.A:
state = (e.type == "keyDown") ? "left" : "stand";
break;
case Keyboard.W:
state = (e.type == "keyDown") ? "jumping" : "falling";
break;
}
}
function gameLoop(Levent:Event):void {
switch (state) {
case "stand":
kim.gotoAndStop("kim Stand");
break;
case "right":
kim.x += 5;
kim.gotoAndStop("kim Move Right");
break;
case "left":
kim.x -= 5;
kim.gotoAndStop("kim Move Left");
break;
case "jumping":
kim.y -= 10;
kim.gotoAndStop("kim Jump");
break;
case "falling":
kim.gotoAndStop("kim Jump");
break;
}
gravity();
}
function gravity ():void {
kim.y += grav;
if (kim.y + kim.height/2 < floor) {
grav++;
} else {
grav = 0;
kim.y = floor - kim.height/2;
if (state == "falling") {
state = "stand"
}
}
}

AS3 game development: attack movements not following suit of movement direction

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.

How create border in stage

I need advice, please. I'm working on one project - a simple game. It will be something like "Space Invaders". I just needed to cater to the ship could not leave the area (Stage). Function, is called "RMimoXY" does not work. Could someone please check out what I'm missing in the program?
Thanks in advance for your advice.
import flash.events.KeyboardEvent;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.media.Sound;
import flash.display.Stage;
var let: Boolean = false;
var pozadi: Stage;
var vx:Number = 0;
var vy:Number = 0;
function mezernik(){
var mySound: Sound = new laserFire();
mySound.play();
RMimoXY();
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, klavesnice);
function klavesnice(e: KeyboardEvent){
switch(e.keyCode){
case Keyboard.LEFT: lod.x += -5; break;
case Keyboard.RIGHT: lod.x += 5; break;
case Keyboard.UP: lod.y += -5; break;
case Keyboard.DOWN: lod.y += 5; break;
case Keyboard.SPACE: mezernik(); break;
}
}
function RMimoXY(){
if (lod.x > stage.stageWidth ){
lod.x = 0 - lod.width;
}
else if (lod.x < 0 - lod.width ){
lod.x = stage.stageWidth;
}
if (lod.y > stage.stageHeight ){
lod.y = 0 - lod.height;
}
else if (lod.y < 0 - lod.height ){
lod.y = stage.stageHeight;
}
}
It appears as if you're only calling RMimoXY in your constructor. You should call it every time the ship is moved. So adding it to the end of your keyhandler should work:
function klavesnice(e: KeyboardEvent){
switch(e.keyCode){
case Keyboard.LEFT: lod.x += -5; break;
case Keyboard.RIGHT: lod.x += 5; break;
case Keyboard.UP: lod.y += -5; break;
case Keyboard.DOWN: lod.y += 5; break;
case Keyboard.SPACE: mezernik(); break;
}
RMimoXY();
}

AS 3 : Existing Function doesn't found?

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...