charging Timer doesn't quite work? - actionscript-3

I'm writing a game where I want the character to jump after holding the spacebar to charge their jump up for a bit and then the charge will get added into the jump afterwards.
However, the code that I currently have going only works around 50% of the time, and will almost indefinitely not work if the player is holding a directional movement button down at the same time.
function greenTimerHandler(e:TimerEvent){
if(spacePressed&&downBumping){
charge += 3;
if(charge >= 50){
charge = 50;
}
} else if(!spacePressed&& downBumping) {
greenSlimeJump(charge);
greenSlimeTimer.stop();
}
}
//And the jump function
function greenSlimeJump(greenCharge){
ySpeed = greenCharge * -1.5
slimeAmt -= Math.floor(greenCharge * 0.25);
charge = 0;
}
the downBumping is just a boolean collision value based on a hitTestPoint for the bottom of the player...
Is there any way that I can make it so that it actually runs the jump function more than it currently does? It will even keep the charge value for the next time it tries to jump and the slimeAmt value is never subtracted because the code just seems to completely skip the green jump function altogether.
Heres the downBumping code:
if(back.collisions.hitTestPoint(player.x + downBumpPoint.x, player.y +
downBumpPoint.y, true)){
downBumping = true;
} else {
downBumping = false;
}
and heres the timer/ space pressed:
if(e.keyCode == 32 && slimeAction){
spacePressed = true;
if(slimeType == 1 && downBumping){
greenSlimeTimer.start();
}
}

Related

AS3 AI barrier detection and movement

I'm using flash CC for school and i am making a top down RPG which i am making using action script 3.
the problem that i am having is multi layered; i need the AI i made to detect the set boundaries, and i need them to change direction when they hit these boundaries. at the moment i have used trace functions to find out when the AI is hitting the boundaries, so i know that that is working. however then it doesn't run the code after that. the map at the moment is a maze so the barriers are a movie clip that have rectangles going over the walls within the maze. it works for the player that the user controls so why won't it work here? below is the code for the AI movement:
switch (guyFacing) { // which way the AI has turned (left, right, up, down) (this is randomly generated below
case 0:
OverworldMC.guyMC.gotoAndStop("walk back frame");
OverworldMC.guyMC.y -= guySpeed;
break;
case 1:
OverworldMC.guyMC.gotoAndStop("walk front frame");
OverworldMC.guyMC.y += guySpeed;
break;
case 2:
OverworldMC.guyMC.gotoAndStop("walk left frame");
OverworldMC.guyMC.x -= guySpeed;
break;
case 3:
OverworldMC.guyMC.gotoAndStop("walk right frame");
OverworldMC.guyMC.x += guySpeed;
break;
}
guyTimer++; //duration that the AI is moving around the screen
} else {
guyWalkDur = Math.random() * 75;
guyFacing = Math.floor(Math.random() * 4);
guyTimer = 0;
}
}
if (OverworldMC.collisionMC.hitTestPoint(OverworldMC.guyMC.x + GleftBumpPoint.x, OverworldMC.guyMC.y + GleftBumpPoint.y, true)) {
trace("GleftBumping");
GleftBumping = true;
} else {
GleftBumping = false;
}
if (OverworldMC.collisionMC.hitTestPoint(OverworldMC.guyMC.x + GrightBumpPoint.x, OverworldMC.guyMC.y + GrightBumpPoint.y, true)) {
trace("GrightBumping");
GrightBumping = true;
} else {
GrightBumping = false;
}
if (OverworldMC.collisionMC.hitTestPoint(OverworldMC.guyMC.x + GupBumpPoint.x, OverworldMC.guyMC.y + GupBumpPoint.y, true)) {
trace("GupBumping");
GupBumping = true;
} else {
GupBumping = false;
}
if (OverworldMC.collisionMC.hitTestPoint(OverworldMC.guyMC.x + GdownBumpPoint.x, OverworldMC.guyMC.y + GdownBumpPoint.y, true)) {
trace("GdownBumping");
GdownBumping = true;
} else {
GdownBumping = false;
}
if (GleftBumping) {
OverworldMC.guyMC.gotoAndStop("walk right frame");
OverworldMC.guyMC.x -= guySpeed;
trace("hitting is true");
}
if (GrightBumping) {
OverworldMC.guyMC.gotoAndStop("walk left frame");
OverworldMC.guyMC.x += guySpeed;
}
if (GupBumping) {
OverworldMC.guyMC.gotoAndStop("walk front frame");
OverworldMC.guyMC.y -= guySpeed;
}
if (GdownBumping) {
OverworldMC.guyMC.gotoAndStop("walk back frame");
OverworldMC.guyMC.y += guySpeed;
}
The aim of this code is to randomly generate an action (which it does), detect when it is hitting the barrier and then act according to how it is interacting with the barrier only i am having some trouble with the last part. Any and all help is appreciated.
Regards.

What do these statements mean and what happens when I change their values

Still learning AS3. I would love to know more about these 2 simple statements.
My educated guess is movement or gravity on the x/y co-ords?
var dx:Number = x;
var dy:Number = x;
Much appreciation!
So the code makes the character if jumping, move up at a gradually slower rate until it hits the ground again, where isJumping becomes false again. Each time the character jumps the isJumping is made true again and the cycle repeats (jumpPower is what controls how high). There is also gravity, which is also controlling how fast the jump falls.. however! I would like to point out a major flaw in this code..
jumpPower should not be controlling how fast he falls, gravity should. When jumpPower reaches zero, it then begins to fall into the negatives untill the character reaches the ground. This means that gravity + jumpPower will both be speeding the character to the ground.
I don't know if you meant to do this, but I would recommend having only gravity being the thing sending your character to the ground. A better way to code this would to give the character a velocity, which you apply to its x and y cords each enter frame.
Something like this..
velocityY += gravity;
MainChar.y += velocityY;
This way, when the character jumps, you only need to call this once:
velocityY += jumpPower;
...
Your code with velocity...
var dx:Number = x; // Not sure what these are
var dy:Number = x; // Not sure what these are
var velocityX:Number = 0;
var velocityY:Number = 0;
function doJump(evt:MouseEvent):void {
if(!isJumping) {
jumpPower = -30;
velocityY += jumpPower;
isJumping = true;
}
}
function update(evt:Event):void {
if(MainChar.y + gravity < ground) {
velocityY += gravity
MainChar.y += velocityY;
} else {
velocityY = 0;
MainChar.y = ground;
isJumping = false;
}
}
....
Final note. How come your MainChar is a static class?
I suppose the point is, not much can be answered about this question as I don't expect we have all of the code here.
On one hand you don't need to use these 2 variables dx and dy. On the contrary you forgot to declare the variables used in the code: gravity, jumpPower, isJumping and ground.
On the other hand it's better to use enterFrame event only when necessary and remove it at the end of the movement (in your function update).
At last you don't need to use your boolean variable isJumping (by actualising the value of your variable jumpPower = 30 at the end of your function update).
So your code should really be more simple:
stage.addEventListener(MouseEvent.MOUSE_DOWN, doJump);
const GRAVITY:int = 3;
var jumpPower:int = 0;
var ground:int = stage.stageHeight - MainChar.height;
function doJump(evt:MouseEvent):void {
addEventListener(Event.ENTER_FRAME, update);
}
function update(evt:Event):void {
MainChar.y -= jumpPower;
jumpPower -= 2;
MainChar.y += GRAVITY;
if(MainChar.y + GRAVITY > ground) {
MainChar.y = ground;
jumpPower = 30;
removeEventListener(Event.ENTER_FRAME, update);
}
}

AS3 Character jumping/falling problems

I am having problems with getting the character to jump/fail when the up arrow is pressed. I'm trying to make it so when the up arrow key is pressed once it will jump a certain height then fall.
Here is my movement code:
public var gravity:int = 2;
public function fireboyMovement(e:KeyboardEvent):void
{
if (e.keyCode == 37) //right
{
fireboy1.x = fireboy1.x -5;
checkBorder()
}
else if (e.keyCode == 39) //left
{
fireboy1.x = fireboy1.x +5;
checkBorder()
}
if (e.keyCode == 38) //up
{
fireboy1.y = fireboy1.y -20;
fireboy1.y += gravity;
checkBorder()
}
Your issue is you need to increment the players position over time (and not all at once).
You can either use a tweening engine (like tweenlite), or roll your own timer or enter frame handler.
Here is an example of the latter:
if (e.keyCode == 38) //up
{
if(!isJumping){
isJumping = true;
velocity = 50; //how much to move every increment, reset every jump to default value
direction = -1; //start by going upwards
this.addEventListener(Event.ENTER_FRAME,jumpLoop);
}
}
var isJumping:Boolean = false;
var friction:Number = .85; //how fast to slow down / speed up - the lower the number the quicker (must be less than 1, and more than 0 to work properly)
var velocity:Number;
var direction:int = -1;
function jumpLoop(){ //this is running every frame while jumping
fireboy1.y += velocity * direction; //take the current velocity, and apply it in the current direction
if(direction < 0){
velocity *= friction; //reduce velocity as player ascends
}else{
velocity *= 1 + (1 - friction); //increase velocity now that player is falling
}
if(velocity < 1) direction = 1; //if player is moving less than 1 pixel now, change direction
if(fireboy1.y > stage.stageHeight - fireboy1.height){ //stage.stageheight being wherever your floor is
fireboy1.y = stage.stageHeight - fireboy1.height; //put player on the floor exactly
//jump is over, stop the jumpLoop
this.removeEventListener(Event.ENTER_FRAME,jumpLoop);
isJumping = false;
}
}

AS3: Swipe Gesture With Velocity

So I would like to add velocity to my swipe gesture. Currently I have it moving 10 px on swipe, but I want it to move with a velocity so the user can toss the object around on the screen. Here's the code I am currently using with the object moving the 10 px.
function onSwipe (e:TransformGestureEvent):void{
player_mc.gotoAndStop(5);
if (e.offsetX == 1) {
//User swiped towards right
player_mc.x += 10;
}
if (e.offsetX == -1) {
//User swiped towards left
player_mc.x -= 10;
}
if (e.offsetY == 1) {
//User swiped towards bottom
player_mc.y += 10;
}
if (e.offsetY == -1) {
//User swiped towards top
player_mc.y -= 10;
}
if(collision(player_mc.cp, level_mc))
{
player_mc.x = player_mc.prevX;
player_mc.y = player_mc.prevY;
}
}
Thanks for the help
Here is a way you can do this: (you'll want to swap the mouse events for touch events if using on mobile)
player_mc.addEventListener(MouseEvent.MOUSE_DOWN,startSwipe);
player_mc.addEventListener(MouseEvent.MOUSE_UP,endSwipe);
var velocity:Point = new Point(); //this stores the current velocity of the object
var previous:Point = new Point(); //this stores the previous frames x/y of the object.
var isDragging:Boolean = false;
var friction:Number = .85; //this how quickly to slow down the object once the mouse is released - smaller the number (must be less than 1) the quicker the object will slow/stop
function startSwipe(e){
isDragging = true;
player_mc.startDrag(false);
this.addEventListener(Event.ENTER_FRAME,enterFrameHandler);
}
function enterFrameHandler(e):void {
if(isDragging){
velocity.x += player_mc.x - previous.x; //we're adding the new velocity to the old one, then dividing in half to average the value - this makes it seem smoother
velocity.y += player_mc.y - previous.y;
velocity.x *= .5; //dividing in half
velocity.y *= .5;
previous.x = player_mc.x;
previous.y = player_mc.y;
}else{
velocity.x *= friction; //gradually slow down the object
velocity.y *= friction;
player_mc.x += velocity.x;
player_mc.y += velocity.y;
if(velocity.x < .05 && velocity.y < .05){ //once it gets slow enough, stop the enter frame handler
this.removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
}
}
trace(velocity);
}
function endSwipe(e){
player_mc.stopDrag();
isDragging = false;
}

Action Script 3.0 timer doesn't stop

I'm trying to make flappy birds in actionscript (just for practicing and fun). This is my first programming language and I'm still new to this.
So the problem starts here, I want to make the bird rotates (as the real flappy bird does) every 2 seconds when no button is pressed. But it turned out that the timer still activates after I pressed spacebar again which I think it is supposed to stop the last timer first before activating the new one.
If I press spacebar 2 times, the timer will activate twice. Without stopping the timer first.
Code :
stage.addEventListener (KeyboardEvent.KEY_DOWN, jump);
function jump(event: KeyboardEvent):void
{
var myTimer4:Timer = new Timer (2000)
if(event.keyCode == 32)
{bird.y=bird.y-40;
bird.rotation=0;
myTimer4.stop();
myTimer4.start();
}
myTimer4.addEventListener(TimerEvent.TIMER, fall);
function fall (e:TimerEvent):void{
bird.rotation=40;
myTimer4.stop();
}
I think the problem might be you are creating a new instance of Timer every time the key is pressed and myTimer4 takes in a new reference. Try removing it outside the function scope like this:
var myTimer4:Timer = new Timer (2000);
function jump(event: KeyboardEvent):void
{
if(event.keyCode == 32)
{bird.y=bird.y-40;
bird.rotation=0;
myTimer4.stop();
myTimer4.start();
}
onClipEvent (load) {
power = 0.3;
yspeed = 0;
xspeed = 0;
friction = 0.95;
gravity = 0.5;
thrust = 3.75;
wind = 0.18;
_root.level1_text.text = 0+collected_coin19;
reverse = new Sound();
reverse.attachSound("hit2");
}
onClipEvent (enterFrame) {
if (Key.isDown(Key.LEFT)) {
xspeed -= power;
}
if (Key.isDown(Key.RIGHT)) {
xspeed += power;
}
if (Key.isDown(1)) {
yspeed -= power*thrust;
}
if (Key.isDown(Key.SPACE)) {
yspeed -= power*thrust;
}
xspeed += wind;
xspeed *= friction;
yspeed += gravity;
_y += yspeed;
_x += xspeed;
Try This one Might Help you