So I'm creating a simple 2d game in the vein of bitrunner, with character moving to the right. And I'm having trouble getting the camera to stick to the character.
I'm very much in the beginning of learning as3 and have never done this kind of thing before. I've looked up for examples of this, but so far I haven't found any simple code that I understood enough to put into my game. And quite a few say it is so simple, that I shouldn't need code to do it...but I do.
I'm better at learning from code I can see, than someone explaining it to me.
//stop/start animations
Player.stop();
rocket_1.play();
//variables
var gravity = 5;
var speedy = 20;
var speedx = 5;
//event listeners
stage.addEventListener(KeyboardEvent.KEY_DOWN,charMove);
stage.addEventListener(KeyboardEvent.KEY_UP, stand);
stage.addEventListener(Event.ENTER_FRAME, grav);
function grav(event:Event): void{
Player.y += gravity;
}
//functions
function charMove(event:KeyboardEvent): void{
switch (event.keyCode){
case Keyboard.RIGHT:
trace("I've been pressed right");
Player.x += speedx;
Player.play();
break;
case Keyboard.SPACE:
trace("space");
Player.y -= speedy;
break;
}
}
function stand(event:KeyboardEvent): void{
Player.gotoAndStop(1);
}
In Flash there is no default Camera,
there is a stage, with a size, width and height,
so if you character move outside the stage, you canĀ“t see it anymore.
so you have to make everything move on x axis, but not your character..
Related
Hey everyone so I've been at this for awhile now and finally decided to ask for some help. So I am creating a game in AS3 where the object rotates in a circular motion from either left to right depending on the users mouse Presses. So I have some variables set up to act as friction. What I AM trying to accomplish is when the object is greater or less than a certain rotation degree I want the object to feel like it being pulled more and more to that side that it is currently at and the only way the object can say come back to its original position is if the use clicks on the mouse enough so their is no more force acting on it and say the speed increases at the same time for difficulty.
Here are the Variables I am currently working with:
//Variables
speed = 0.2;
vx = 0;
friction = 0.93;
maxspeed = 10;
I also have these buttons on stage so the user can click them to change the rotation of the objectlike so:
mainScreen.leftBtn.addEventListener(MouseEvent.CLICK, leftButtonClicked);
mainScreen.rightBtn.addEventListener(MouseEvent.CLICK, rightButtonClicked);
private function leftButtonClicked(e:MouseEvent):void
{
clickLeft = true;
clickRight = false;
}
private function rightButtonClicked(e:MouseEvent):void
{
clickRight = true;
clickLeft = false;
}
and I try to set up the mechanics in my ENTER_FRAME event listener like so:
//RIGHT = CLOCKWISE +, Left = COUNTER CLOCKWISE -
if (clickRight)
{
vx += speed;
moveSlow = true;
moveFast = false;
}else
if (clickLeft)
{
vx -= speed;
moveSlow = true;
moveFast = false;
}else
{
vx *= friction;
}
//IF object is Past 15 Degrees make object go faster MOVE FAST
if (object.rotation > 15)
{
moveFast = true;
moveSlow = false;
trace("MOVE_FAST");
}else
if (object.rotation < - 15)
{
moveFast = true;
moveSlow = false;
}else
{
vx *= friction;
}
object.rotation += vx;
//lumberJack.rotation += speed;
//boundaries of object
if (vx > maxspeed)
vx = maxspeed;
else if (vx < -maxspeed)
vx = -maxspeed;
I know I need to add something in the if object.rotation statement but not to sure what i also know i need to add something in the Mouse clicked event listeners to manipulate either speed or friction so the user can pull away from the force acting on it. I tried several time but still cant seem to figure it out. As of now the object rotates left or right depending on the users input and say the object is moving left and the user presses right the object slowly moves back to the left then returns to normal speed.
Please If anyone can help me figure this out I will greatly appreciate it!
To be honest I am having a little bit of trouble following your question, so this may only be a partial answer. I know, bad me, but I don't have enough stupid internet points to leave a comment, so this is all I can do to help, and I just can't care about the internet point system anymore.
First, for the love of insert deity, clean up all that unnecessary white space.
Here's a potential problem in your code: the rotation property of display objects returns a value between -180 and 180. This means that every 180 degrees, the rotation value changes sign. So you can't use whether the rotation is positive or negative to determine which direction the object is rotating in. That should be stored in a separate variable.
Another thing to consider: if moveSlow and moveFast are never true at the same time, you don't need to have two variables because it's redundant. You don't make use of those variables in your code above, but assuming you wrote this:
if (moveSlow) {
moveALittleBit();
} else if (moveFast) {
moveALot();
}
You could replace it with:
if (moveSlow) {
moveALittleBit();
} else {
moveALot();
}
Not only is that giving yourself unnecessary work, but it's bad because it means you can create "invalid states" (i.e. if you make a mistake and "moveSlow" and "moveFast" are both true at the same time).
Likewise, you shouldn't need separate variables for "clickedLeft" and "clickedRight" if they are both mutually exclusive. If they can both be false at the same time, however, you might be better off with something like:
clickDirection = "left";
clickDirection = "right";
clickDirection = "none";
If you went that route, you'd be better off using string constants instead of hardcoded strings, but I think that's getting too off-topic.
After reading your question many times, it sounds like maybe what you are looking for is momentum. Does this cover what you need?
if (clickRight)
{
vx += speed;
momentum = 0;
} else if (clickLeft)
{
vx -= speed;
momentum = 0;
} else
{
vx *= friction;
}
//IF object is Past 15 Degrees make object go faster MOVE FAST
if (object.degreesRotated > 15)
{
momentum += 1;
}else if (object.degreesRotated < - 15)
{
momentum -= 1;
}else
{
vx *= friction;
}
vx += momentum;
object.rotation += vx;
object.degreesRotated += vx; //remember how much we've rotated
//lumberJack.rotation += speed;
If object is a dynamic type, you can add the "degreesRotated" property whenever you feel like it. Otherwise, you might have to make a new class by extending whatever display type that object is, and add the degreesRotated field to that class
Hey I am still getting some unwanted sound effects still playing in another frame, for example when I click my left mouse button which is also my jump button it will play the jump sound as well as playing the collect coins sound wierdly even though i remove each child from the stage when going to the game over screen.
Now im a bit unfamiliar with the sound channel so if its needed to be used please be kind and explain :)
In Frame 1:
var myMusic1:Sound = new Game_Over_Noise();
var myMusic2:Sound = new Jump_Noise();
var myMusic3:Sound = new Coin_Noise();
var myMusic4:Sound = new Power_Up_Noise();
var myMusic5:Sound = new Theme();
var channel:SoundChannel = myMusic5.play();
In Frame 8, Game Screen:
function doJump(evt:MouseEvent):void
{
if(!isJumping) //If the player is jumping.
{
jumpPower = 30; //Jump power is equal to 30.
isJumping = true; //isJumping variable is also equal to true.
var channel:SoundChannel = myMusic2.play(); //Play sound effect.
}
}
function update(evt:Event):void
{
if(isJumping) //If the player is jumping.
{
MainChar.y -= jumpPower; //Subtract the value of jumpPower from the player's y co-ordinate.
jumpPower -= 2; //Decrease the value of jumppower by 2.
}
if(MainChar.y + gravity < ground) //If the value of the player's Y co-ordinate and gravity is less than ground.
MainChar.y += gravity; //Then add the value of gravity to the player's Y co-ordinates.
else //else
{
MainChar.y = ground; //The players Y co-ordinate is equal to ground.
isJumping = false; //Make isJumping equal to false.
}
}
in Frame 5, Game Over Screen:
SoundMixer.stopAll();
Now this stops the theme music and not the sound effects, now i actually dont mind the theme tune playing all the time but i would like ALL sound effects (game sounds) to only play in the game.
I know my coding isnt the best and efficient but its easily readible to me, I appreciate the help! :D
Looks to me like you need to remove your event listeners (they're active even when something is off-stage).
I have a student who is working on a Tower Defense game in AS3 and has an issue that has stumped me. He is using hitTestObject to change the direction that a movieClip is moving. The movieClip has its own timeline with frames for the different directions that the object is facing and a linked .as file with the code for the behavior of the object.
When he calls gotoAndStop to change the internal frame of the movieClip, the removed event is triggered, but the object stays on the screen and no longer moves.
All of my searches find answers about removing objects, but I have not seen anything about preventing an object from removing itself.
The following code is a loop triggered by an ENTER_FRAME event in the .as class file for the movieClip object:
private function eFrame(event:Event):void
{
if (_root.isPaused == false)
{
//MOVING THE ENEMY
this.x += speed * xDir;
this.y -= speed * yDir;
if (health <= 0)
{
_root.currency += 4;
this.parent.removeChild(this);
}
if (this.x > 770)
{
this.parent.removeChild(this);
_root.health -= 10;
_root.gotHit = true;
}
//checking if touching any invisible markers
for (var i:int=0; i<_root.upHolder.numChildren; i++)
{
//the process is very similar to the main guy's testing with other elements
var upMarker:DisplayObject = _root.upHolder.getChildAt(i);
if (hitTestObject(upMarker))
{
yDir = 1;
xDir = 0;
this.gotoAndStop(3);
}
}
for (i=0; i<_root.downHolder.numChildren; i++)
{
//the process is very similar to the main guy's testing with other elements
var downMarker:DisplayObject = _root.downHolder.getChildAt(i);
if (hitTestObject(downMarker))
{
yDir = -1;
xDir = 0;
this.gotoAndStop(7);
}
}
for (i=0; i<_root.rightHolder.numChildren; i++)
{
//the process is very similar to the main guy's testing with other elements
var rightMarker:DisplayObject = _root.rightHolder.getChildAt(i);
if (hitTestObject(rightMarker))
{
yDir = 0;
xDir = 1;
this.gotoAndStop(6);
}
}
for (i=0; i<_root.leftHolder.numChildren; i++)
{
//the process is very similar to the main guy's testing with other elements
var leftMarker:DisplayObject = _root.leftHolder.getChildAt(i);
if (hitTestObject(leftMarker))
{
yDir = 0;
xDir = -1;
this.gotoAndStop(2);
}
}
}
}
private function remove(event:Event):void
{
trace("remove");
removeEventListener(Event.ENTER_FRAME, eFrame);
_root.enemiesLeft -= 1;
}
}
When the gotoAndStop line executes, the frame of the movieClip changes and then the code jumps directly to a function that is triggered by the REMOVED event.
Does anyone have an idea why the REMOVED event might be triggered by this code?
Thank you for your help.
The REMOVED Event is triggered by anything that is removed from the stage inside the MovieClip or Sprite that is containing it, if I'm not mistaken. And especially with MovieClips that have animation, things get removed and added everytime, for instance if some part of the animation ends on the timeline, or at keyframes.
Event.REMOVED_FROM_STAGE is dispatched only when the container itself is removed from stage. Maybe that's causing your confusion? I can't see from your code example exactly what event type you're listening for.
Where are you adding the remove-listener?
Without more information, I would guess that you are listening to a clip inside an animation, and that it's not there on all frames (or, maybe even more likely - that the instance is being swapped out for another, identical one, by flash pro. This can happen depending on in what order you added keyframes, the alignment of the moon and fluctuations in the ionosphere. It's easiest fixed by simply removing all key-frames and then re-creating them. And then never using flash pro for anything ever again.)
I have a class Catcher which lets you control a movieclip in a game. I'm trying to program the game so it finishes and you can restart. So I need to remove everything and go back to the menu. Should be a simple thing to solve but I can't seem to find out how.
So far I just have ourCatcher.parent.removeChild(ourCatcher); to remove my movieclip from the stage. And an if statement to stop one of the functions which drops things onto the stage. SoundMixer.stopAll(); to stop the music.Then I just have it going to frame 3 which is the gameover screen.
It looks fine but I get constant 1009 errors overflowing in the error console and when I restart the game, it's super slow. It seems the function for movement within Catcher is still running and creating an error because the Catcher was removed from stage and is null now.
I know I need to un-reference everything to do with the Catcher but I can't find out any documentation online to do it in my situation. Everyone seems to have different methods which I've tried and don't work.
The two functions in the Catcher class I'm using to move the character :
public function Catcher(stageRef:Stage)
{
stop();
this.stageRef = stageRef;
key = new KeyObject(stageRef);
addEventListener(Event.ENTER_FRAME, loop, false, 0, true);
}
//movement
public function loop(e:Event):void
{
if (key.isDown(Keyboard.A))
vx -= walkSpeed;
else if (key.isDown(Keyboard.D))
vx += walkSpeed;
else
vx *= friction;
//update position
x += vx;
//speed adjustment
if (vx > maxspeed)
vx = maxspeed;
else if (vx < -maxspeed)
vx = -maxspeed;
//stay inside screen
if (x > stageRef.stageWidth)
{
x = stageRef.stageWidth;
vx = -vx
}
else if (x < 0)
{
x = 0;
vx = -vx;
}
if (key.isDown(Keyboard.A))
{
scaleX = -1;
}
else if (key.isDown(Keyboard.D))
{
scaleX = 1;
}
movement();
// Jumping
jump += gravity;
if (y > stage.stageHeight /1.5)
{
jump = 0;
canJump = true;
}
if (key.isDown(Keyboard.SPACE) && canJump)
{
jump = -10;
canJump = false;
}
y += jump;
}
The other class where I'm removing the things from the stage is called CatchingGame and it has a function which drops objects, I put the game over code there for when playerlives == 0 .
if (playerLives == 0 )
{
stop();
ourCatcher.parent.removeChild(ourCatcher);
SoundMixer.stopAll();
gotoAndStop(3);
}
I've probably made an elementary mistake since this is my first flash game. Any help is greatly appreciated as this is pretty much the last step in finishing my game.
Instead of just removing the child by referencing its parent to remove itself (I had to test to make sure this actually worked). Create a function in same place that you create/instantiate the Catcher that removes first the eventListener ENTER_FRAME, then removes the Catcher.
if (playerLives == 0 ) {
stop();
removeCatcher();
SoundMixer.stopAll();
gotoAndStop(3);
}
// new location in the main code where the catcher is created
function removeCatcher():void {
ourCatcher.cleanUp();
removeChild(ourCatcher);
}
// in the Catcher class
function cleanUp():void {
removeEventListener(Event.ENTER_FRAME, loop);
}
if (ourCatcher.parent) ourCatcher.parent.removeChild(ourCatcher);
else trace("Catcher without a parent still plays! DEBUG THIS!");
Basically, you are most likely losing control flow of your catcher, that is, it seemingly tries to remove itself from the stage twice. After it removes itself first time, its parent becomes null, hence the 1009. And, seeing as you've hit a 2028, the same reason applies, your catcher is no longer a child of anywhere.
I'm new on here and needing a little help. Basically I'm designing a Pac-man like game which it has to be based on Wind in the Willows, so Mole-man it is!!
Anyway, I've done the basics of it, I've made my 2d mole, made him move, made him react to button presses etc. and now trying to get the walls to work, starting with the outer walls.
I made 4 rectangles around the edge, merged them to one shape and called it "outerWalls". I've been using hitTestObject to try and get it to work but with no success.
I did a test to make it work with moleman.xIncrement = -5 which makes him immediately move backwards without touching any walls. I am curious as to if this is because he is inside of the walls and it classes 4 outer walls as a square overall and as he is already inside the theoretical square moves him out? I am unsure. Have some code!!
Actions layer - frame 1:
import flash.events.KeyboardEvent;
var moleman = this.addChild(new Moleman_mc());
moleman.x = 100;
moleman.y = 200;
moleman.width = 24;
moleman.height = 24;
moleman.xIncrement = 5;
moleman.yIncrement = 0;
stage.addEventListener(KeyboardEvent.KEY_DOWN, doKeyDown);
function doKeyDown (e:KeyboardEvent):void
{
switch(e.keyCode)
{
case Keyboard.UP:
moleman.xIncrement = 0;
moleman.yIncrement = -5;
moleman.rotation = -90;
break;
case Keyboard.DOWN:
moleman.xIncrement = 0;
moleman.yIncrement = 5;
moleman.rotation = 90;
break;
case Keyboard.LEFT:
moleman.xIncrement = -5;
moleman.yIncrement = 0;
moleman.rotation = 180;
break;
case Keyboard.RIGHT:
moleman.xIncrement = 5;
moleman.yIncrement = 0;
moleman.rotation = 0;
break;
}
}
Actions layer - frame 2:
import flash.events.Event;
var collectCounter:int = 0;
moleman.x += moleman.xIncrement;
moleman.y += moleman.yIncrement;
if(moleman.hitTestObject(collect))
{
collectCounter ++;
collect.visible = false;
}
moleman.addEventListener(Event.ENTER_FRAME, wallHit);
function wallHit(event:Event):void
{
if(moleman.hitTestObject(outerWalls))
{
moleman.stop();
}
}
Actions layer - frame 3:
gotoAndPlay(2);
In addition, I cannot get the collect (e.g. collectables) to work, the plan would be to make it so each time you collect one "collect" item, that one disappears, you add one to collectCounter but all others stay visible. Currently if you collect one "collect" item, moleman just stops and stays where he is while another moleman appears and continues, not very useful. Any help on this would also be appreciated, not sure where to take it from there.
Any help is much appreciated, I am new at this but hoping it can go well :)
All help is much appreciated.
John.
In your case to detect collision you should use hitTestPoint method instead of hitTestObject. hitTestPoint method has the signature:
public function hitTestPoint(x:Number, y:Number, shapeFlag:Boolean = false):Boolean
so, when shapeFlag is set to true, it is possible to detect collision with the point (your hero) and maze shape (or any other arbitrary shape). This method is very powerful because the intersection with the real shape, not its bounding box is calculated. Modified wallHit method may look like this:
moleman.addEventListener(Event.ENTER_FRAME, wallHit);
function wallHit(event:Event):void
{
if(outerWalls.hitTestPoint(moleman.x, moleman.y, true))
{
// collision
moleman.x += -moleman.xIncrement;
moleman.y += -moleman.yIncrement;
moleman.xIncrement=0;
moleman.yIncrement=0;
}
moleman.x += moleman.xIncrement;
moleman.y += moleman.yIncrement;
if(moleman.hitTestObject(collect))
{
collectCounter ++;
collect.visible = false;
}
}
you may also remove frame 3 and "gotoAndPlay(2);" call because it is better to put the code which controls hero's position into ENTER_FRAME handler either.