My game lags when I press button - actionscript-3

I have an app that I'm developing for iOS and Android using AS3. I'm currently having several performance issues with this project. This is my very first app and game. So any type of feedback or insight is greatly appreciated. My game is a dirt bike wheelie game. It allows the user to press a button (gasPress) to wheelie upward and another button (brake) to wheelie downward. Once the "gasPress" button is pressed, a boolean "holdGas" is set to true. In my "gameLoop" (Enter_Frame event), the bike is rotated upward, IF "holdGas" is equal to true. The code for pressing the brake is the same, except it rotates the bike donward. I have buildings that slide across the screen, creating the illusion that the bike is moving. The building movie clips are cached as bitmap. I use two instances of the same building movie clip. Once the first clip slides off the stage, it's placed behind the other. In a recycling kind of mechanism lol. The problem I'm having with this is, when i press the "gasPress" button, it lags before wheelie/rotating upward. When it lags, the buildings moving in the background skips. It happens every time. So if you keep tapping the gasPress, (which is part of the gameplay) the objects on the screen keep jumping. It makes the game unplayable. I've tested the buttons by completely removing the code to move the bike upward/downward and the game still skips. I've noticed more of a skip or lag when the gas is pressed and the bike rotates upward. I currently have the frame rate set to 32, it did the same at 24.
public function TheGame() {
//Connect to tapjoy's ad network
//tjClass = new TapJoyClass();
//stage.scaleMode = StageScaleMode.NO_SCALE;
//stage.align = StageAlign.TOP_LEFT;
//Give game focus so the keyboard keys will work on computer
stage.focus = this;
globalStage = this.stage;
//Checks if ScoreData and Bike data shared object has been created, if not it creates
scoreInfo = SharedObject.getLocal ( "ScoreData" );
bikeInfo = SharedObject.getLocal ( "BikeData" );
//scoreInfo.clear ();
//bikeInfo.clear ();
mostSprocketsCollected = scoreInfo.data.mostSprocketsCollected;
//Handling background
background1 = new Background;
background2 = new Background;
addChild ( background1 );
addChild ( background2 );
background1.cacheAsBitmap = true;
background2.cacheAsBitmap = true;
background1.mouseChildren = false;
background1.mouseEnabled = false;
background2.mouseChildren = false;
background2.mouseEnabled = false;
background1.x = background1.width;
background2.x = background1.x + background2.width;
//Handling buildings
building1 = new Buildings;
building2 = new Buildings;
addChild ( building1 );
addChild ( building2 );
building1.cacheAsBitmap = true;
building2.cacheAsBitmap = true;
building1.mouseChildren = false;
building1.mouseEnabled = false;
building2.mouseChildren = false;
building2.mouseEnabled = false;
building1.x = building1.width;
building2.x = building1.x + building2.width;
//Choose which bike will be used
if( bikeInfo.data.EquippedBike == undefined ){
//Start off with original bike
whichBike = "OriginalDirtBike";
bikeInfo.data.BikeColor = "OriginalDirtBike";
}else{
whichBike = bikeInfo.data.EquippedBike;
}
if( whichBike == "Banshee" ){
//Add far wheels first
wheelClip2 = new Banshee_Far_WheelClip;
addChild ( wheelClip2 );
//wheelClip2. = 208.30;
wheelClip2.y = 350;
//Add Banshee
bitmapBike = new Banshee_Bitmap ();
bitmapBike.gotoAndStop ( bikeInfo.data.BikeColor );
addChild ( bitmapBike );
bitmapBike.y = 399.80;
bitmapBike.x = 0;
//Add frontWheels
wheelClip = new Banshee_WheelClip ();
wheelClip.backTire.frontFace.gotoAndStop ( bikeInfo.data.BikeColor );
wheelClip.frontTire.frontFace.gotoAndStop ( bikeInfo.data.BikeColor );
addChild ( wheelClip );
wheelClip.x = 187.70;
wheelClip.y = 399;
}else if( whichBike == "SupermotoDRZ400" ){
//Add Wheels
wheelClip = new WheelClip ();
wheelClip.backTire.gotoAndStop ( bikeInfo.data.BikeColor );
wheelClip.frontTire.gotoAndStop ( bikeInfo.data.BikeColor );
addChild ( wheelClip );
wheelClip.x = 0;
wheelClip.y = 409.45;
//Add bike
bitmapBike = new SuperMoto_Bitmap ();
bitmapBike.gotoAndStop ( bikeInfo.data.BikeColor );
addChild ( bitmapBike );
bitmapBike.y = 399.80;
}else if( whichBike == "OriginalDirtBike" ){
//Add wheels
wheelClip = new OriginalBike_WheelClip ();
wheelClip.backTire.gotoAndStop ( bikeInfo.data.BikeColor );
wheelClip.frontTire.gotoAndStop ( bikeInfo.data.BikeColor );
addChild ( wheelClip );
wheelClip.x = 0;
wheelClip.y = 405;
//Add Bike
bitmapBike = new OriginalBike_Bitmap ();
addChild ( bitmapBike );
bitmapBike.gotoAndStop ( bikeInfo.data.BikeColor );
bitmapBike.y = 399.80;
//Add rider
//rider = new Rider_Original_bitmap ();
//addChild ( rider );
//rider.y = 353.1
}
//bitmapBike.mouseChildren = false;
//bitmapBike.mouseEnabled = false;
//bitmapBike.cacheAsBitmapMatrix = bitmapBike.transform.concatenatedMatrix;
//bitmapBike.cacheAsBitmap = true;
//
trace ( "bitmap bike : " + getSize ( bitmapBike) );
//rider.cacheAsBitmapMatrix = rider.transform.concatenatedMatrix;
//rider.cacheAsBitmap = true;
rider.mouseChildren = false;
rider.mouseEnabled = false;
gasPress.addEventListener ( MouseEvent.MOUSE_DOWN, hitGas );
gasPress.addEventListener ( MouseEvent.MOUSE_UP, releaseGas );
brake.addEventListener ( MouseEvent.MOUSE_DOWN, hitBrake );
brake.addEventListener ( MouseEvent.MOUSE_UP, releaseBrake );
stage.addEventListener ( KeyboardEvent.KEY_DOWN, useKeyboard);
stage.addEventListener ( KeyboardEvent.KEY_UP, stopUseKeyboard);
addEventListener ( Event.ADDED_TO_STAGE, init );
ScoreBoardFormat = new TextFormat ();
ScoreBoardFormat.bold = true;
sprocketVector = new Vector.< MovieClip > ();
sprocketPool = new SprocketPool( Sprocket, pool_SprocketAmount );
stage.addEventListener ( Event.RESIZE, resizeObjects );
stage.dispatchEvent( new Event( Event.RESIZE ) );
if( Accelerometer.isSupported ){
//on mobile device
}else{
//on desktop
gravity = 15; // low values for phone
dy = 60; // low values for phone
backgroundDx = -160;
buildingDx = -300;
dx = 300; // speed and direction
}
//start bike off in a wheelie
bitmapBike.rotation = -45;
rider.rotation = -45;
wheelClip.x = -15;
rider.x = bitmapBike.x;
//Add the first sprocket
addSprocket();
}
//Following Functions are Gas and Brake related
public function hitGas (e:MouseEvent){
e.stopImmediatePropagation();
holdGas = true;
pressedBrake = "no";
}
public function hitBrake (e:MouseEvent){
e.stopImmediatePropagation();
pressedBrake = "yes";
}
public function releaseGas (e:MouseEvent){
e.stopImmediatePropagation();
holdGas = false;
}
public function releaseBrake (e:MouseEvent){
e.stopImmediatePropagation();
pressedBrake = "no";
}
//Game Loop
public function gameLoop ( e:Event ):void{
e.stopImmediatePropagation();
var timePassed:int = getTimer()-lastTime;
lastTime += timePassed;
if ( whichBike == "SupermotoDRZ400" ){
//Keep wheels in position with the bike
wheelClip.rotation = bitmapBike.rotation;
wheelClip.x = bitmapBike.x;
//make tires spin
wheelClip.frontTire.rotation += 75*timePassed/1000;
wheelClip.backTire.rotation += 75*timePassed/1000;
rider.rotation = bitmapBike.rotation - 1;
rider.x = bitmapBike.x + 25;
}else if ( whichBike == "OriginalDirtBike" ){
//Keep wheels in position with the bike
wheelClip.rotation = bitmapBike.rotation - 1.5;
wheelClip.rotation = bitmapBike.rotation;
wheelClip.x = bitmapBike.x + 16.5;
//make tires spin
wheelClip.frontTire.rotation += 75*timePassed/1000;
wheelClip.backTire.rotation += 75*timePassed/1000;
//rider
rider.x = bitmapBike.x;
rider.rotation = bitmapBike.rotation;
}else if ( whichBike == "Banshee" ){
rider.rotation = bitmapBike.rotation;
rider.x = bitmapBike.x;
//First wheels
wheelClip.x = bitmapBike.x;
wheelClip.rotation = bitmapBike.rotation;
wheelClip.frontTire.frontFace.rotation += 75*timePassed/1000;
wheelClip.frontTire.backFace.rotation += 75*timePassed/1000;
wheelClip.backTire.frontFace.rotation += 75*timePassed/1000;
wheelClip.backTire.backFace.rotation += 75*timePassed/1000;
//second wheels
wheelClip2.x = bitmapBike.x;
wheelClip2.rotation = bitmapBike.rotation;
wheelClip2.farBackTire.frontFace.rotation += 75*timePassed/1000;
wheelClip2.farFrontTire.frontFace.rotation += 75*timePassed/1000;
wheelClip2.farFrontTire.backFace.rotation += 75*timePassed/1000;
}
if( popUp != null ){
this.setChildIndex ( popUp, this.numChildren - 2 );
}
this.setChildIndex ( rider, this.numChildren - 1 );
//Stores the bikes current rotation point
var currRotation = bitmapBike.rotation;
//make shadow follow bike
var bikeX:int = bitmapBike.x;
newShadow.x = bikeX + 150; //109.8;
//ANITMATING THE DRIVER!!!!
if( currRotation <= -11 ){ //This should occur at a lower
rider.gotoAndPlay ( "sitDown" );
sitDown = true;
newShadow.gotoAndStop ( "fullShadow" );
}
if( currRotation <= -15 ){
newShadow.gotoAndStop( "three4thShadow" );
leanBack = true;
}
//just change shadow with this one
if( currRotation <= -25 ){
newShadow.gotoAndStop ( "midShadow" );
}
if( currRotation <= -30 ){
rider.gotoAndPlay ( "LeanBack" );
leanBack = true;
newShadow.gotoAndStop ( "smallShadow" );
}
if( currRotation <= -34 ){ //Highest
rider.gotoAndPlay ( "LeanBack2" );
leanBack = true;
newShadow.gotoAndStop ( "smallestShadow" );
}
if( currRotation <= -35 ){ //Highest
rider.gotoAndPlay ( "LeanBack2" );
leanBack = true;
newShadow.gotoAndStop ( "allTheWayBack" );
}
//if player holds or hit the brake
if( pressedBrake == "yes" ) { //for some reason the opposite is working right now
var currBikePosition:int;
currBikePosition = bitmapBike.rotation;
bitmapBike.rotation += 2;
currBikePosition = 0;
}
//gravity pulling bike down
bitmapBike.rotation += gravity*timePassed/1000;
bitmapBike.rotation += gravity*timePassed/1000;
//if player holding gas, do wheeliez
if( holdGas == true ){
//Make bike wheelie
bitmapBike.rotation -= dy*timePassed/1000;
rider.rotation -= dy*timePassed/1000;
}
//Move Bike to center, then move buildings
if( bitmapBike.x <=187 ){
//move bike
bitmapBike.x += dx*timePassed/1000;
}else{
//move buildings and background
building1.x += buildingDx*timePassed/1000;
building2.x += buildingDx*timePassed/1000;
//buildings
if( building1.x <= -25 ){
building1.x = building2.x + building1.width;
}else if( building2.x <= -25 ){
building2.x = building1.x + building2.width;
}
background1.x += backgroundDx*timePassed/1000;
background2.x += backgroundDx*timePassed/1000;
//background
if( background1.x <=0 ){
background1.x = background2.x + background1.width;
}else if ( background2.x <=0 ){
background2.x = background1.x + background2.width;
}
}

How are you handling the masking of "background image"? How big is the image?
Most likely the drop is due to you having to redraw EVERYTHING when your bike moves since it can no longer reuse the old values of the cached bitmap. And since your background is HUGE this causes the performance drop you notice.
As a start, you should probably define a scrollRect on the "gigantic moving background" instead of just drawing the entire background. This causes only the part of image being shown to be sent to GPU. Such as bg.scrollRect = new Rectangle(offsetX,offsetY, 1280, 1024);
read http://gskinner.com/blog/archives/2006/11/understanding_d.html for a short introduction to scrollRect.
CacheAsBitmap might not be doing what you want it to do, if you are changing the look of a displayobject over each frame, you would actually loose performance since you first have to draw the items, then put them into a bitmap, and then draw that bitmap. Then on the next frame, you would end up redoing the exact same thing (since the old cached bitmap is no longer valid). cacheAsBitmap is very useful for when you have complex vector shapes that remain the same for an amount of frames.
For a more comprehensive optimization guideline, read the following two massive pdf-files:
http://help.adobe.com/en_US/as3/mobile/flashplatform_optimizing_content.pdf
http://help.adobe.com/en_US/as3/dev/as3_devguide.pdf

in Publish setting set your Hardware acceleration to GPU, that will lean off the processor

Related

HitTestObject distance bug between two object

I have a car game which is drive reverse.The game over when enemy and car hit each other.I have problem with collision.
Car and enemy hit when they get close each other,but they have still big space in there.
Please check this image.
https://s8.postimg.cc/p85w0wm2t/image.gif
I use this code.
if(dubageri1.hitTestObject(carMC)){
dubageri1.gotoAndPlay(2);
geribas.gericarpti = true;
stage.removeEventListener(Event.ENTER_FRAME,engeller1geri1lev1)
}
Also I tried something like this.But this time collision has late.
var nDistX:Number = Math.abs ( carMC.x - dubageri1.x );
var nDistY:Number = Math.abs ( carMC.y - dubageri1.y );
var nDistance:Number = Math.sqrt ( nDistX * nDistX + nDistY * nDistY );
var sDistx:Number = Math.abs ( carMC.x - dubageri1.x );
var sDisty:Number = Math.abs ( carMC.y - dubageri1.y );
var nsistance:Number = Math.sqrt ( sDistx * sDistx + sDisty * sDisty );
collect.text=String(nDistance);
if ( nDistance < 120 )
{
trace("aha");
dubageri1.gotoAndPlay(2);
stage.removeEventListener(Event.ENTER_FRAME,dsaa);
}
Note:My objects was made as vector.
Does anybody tell me what im doing wrong ?
UPDATE
var aPoint:Point = new Point();
aPoint = carMC.localToGlobal(aPoint);
var bPoint:Point = new Point();
bPoint = dubageri1.localToGlobal(bPoint);
stage.addEventListener(Event.ENTER_FRAME,ilkcikis);
function ilkcikis(event:Event) {
bPoint = root.globalToLocal(bPoint);
var zHit:Boolean = carMC.hitTestPoint(bPoint.x, bPoint.y, true);
textbaba.text = zHit? "! HIT !": "NO HIT";
carMC.x=mouseX;
carMC.y=mouseY;
}

as3 error: ReferenceError: Error #1069: Property keyCode not found on flash.display.Shape and there is no default value

I am following a tutorial on building a rhythm game in as3 here, and I am very new to the language. On running the swf, I get the following error in the output:
ReferenceError: Error #1069: Property keyCode not found on flash.display.Shape and there is no default value.
at source_fla::MainTimeline/makeLvl()[source_fla.MainTimeline::frame10:116]
I have tried some previous solutions posted to the same error, but I have not been able to resolve the issue.
Here is the source code:
stop();
stage.focus = stage;
//VARIABLES
//sTime is the current frame that is being played
//Once it reaches sTempo, then it will be reset
//and a note will be created
var sTime:int = 0;
//sTempo is how many frames it takes before
//a note is created. Because it's 12, and
//the frame rate is 24, it will take a half of a second
//for a note to be made
var sTempo:Number = 12;
//sNote is the current arrow of the level that is created
//0 makes no arrow
//1 makes a left arrow
//2 makes an up arrow
//3 makes a down arrow
//4 makes a right arrow
var sArrow:int = 0;
//arrowSpeed is how fast the arrow moves up the screen
var arrowSpeed:Number = 10;
//gameIsOver is whether the game's over
var gameIsOver:Boolean = false;
//the score variable
var score:int = 0;
//either perfect, great, nice, or good
var scoreString:String = '';
var combo:int = 0;
var mcHealth:Number = 0;
//Booleans checking if the arrows are touching the receptor
var touchLeft:Boolean = false;
var touchUp:Boolean = false;
var touchDown:Boolean = false;
var touchRight:Boolean = false;
function beginCode():void{
addEventListener(Event.ENTER_FRAME, makeLvl);
//make the level array longer
lvlArrayAll[lvlCurrent].push(0,0,0,0,0);
}
function makeLvl(e:Event):void{
//code here will create the level
if(sTime < sTempo){
//if the required time hasn't reached the limit
//then update the time
sTime ++;
} else {
//if the time has reached the limit
//then reset the time
sTime = 0;
//if an actual arrow can be made
if(lvlArrayAll[lvlCurrent][sArrow] != 0){
var currentArrow:MovieClip; //this will hold the current arrow
if(lvlArrayAll[lvlCurrent][sArrow] == 1){
//place a left note onto the stage
currentArrow = new arrowLeft();
//set the _x value of the note so that it is in the
//right place to touch the receptor
currentArrow.x = 105 ;
//set the note's y coordinate off of the stage
//so that the user can't see it when it appears
currentArrow.y = 0;
//setting the key that needs to be pressed
currentArrow.keyCode = 68;
addChild(currentArrow);//add it to stage
} else if(lvlArrayAll[lvlCurrent][sArrow] == 2){
//place an up note onto the stage
currentArrow = new arrowUp();
currentArrow.x = 230;
currentArrow.y = 0;
currentArrow.keyCode = 70;
addChild(currentArrow);
} else if(lvlArrayAll[lvlCurrent][sArrow] == 3){
//place a down note onto the stage
currentArrow = new arrowDown();
currentArrow.x = 355;
currentArrow.y = 0;
currentArrow.keyCode = 74;
addChild(currentArrow);
} else if(lvlArrayAll[lvlCurrent][sArrow] == 4){
//place a right note onto the stage
currentArrow = new arrowRight();
currentArrow.x = 480;
currentArrow.y = 0;
currentArrow.keyCode = 75;
addChild(currentArrow);
}
}
//get the next arrow if it the song isn't finished
if(sArrow < lvlArrayAll[lvlCurrent].length){
sArrow ++;
} else {
//if the song is finished, then reset the game
gotoAndStop('win');
gameIsOver = true;
//then remove this enter_frame listener
removeEventListener(Event.ENTER_FRAME, makeLvl);
}
}
//checking if mcReceptor is touching any arrows
//first we reset the variables we got last time just in case they aren't true anymore
touchLeft = false;
touchUp = false;
touchDown = false;
touchRight = false;
//this for loop will be used for the hit testing
for(var i:int = 0;i<numChildren;i++){
var target:Object = getChildAt(i);
if(target.keyCode != null && target.hitTestObject(mcReceptor)){//if the object is an arrow and the receptor is touching it
if(target.keyCode == 68){//if left arrow
touchLeft = true;
} else if(target.keyCode == 70){//if up arrow
touchUp = true;
} else if(target.keyCode == 74){//if down arrow
touchDown = true;
} else if(target.keyCode == 75){//if right arrow
touchRight = true;
}
}
}
//changing the score text
mcTxt.txtScore.text = 'Score: '+score;
mcTxt.txtCombo.text = 'Combo: '+combo;
mcTxt.txtScoreString.text = scoreString;
}
//this function will change the health depending on how much health change
//it needs, positive or negative
function changeHealth(healthDiff:Number):void{
healthDiff = 100;//only changes in percentages
//checking if the health is already at it's full
//or will be full after this hit
if(mcHealth + healthDiff >= 100){
mcHealth = 100;
} else if(mcHealth + healthDiff <= 0){
//checking if the health will be equal or below 0
gotoAndStop('lose');
gameIsOver = true;
removeEventListener(Event.ENTER_FRAME, makeLvl);
} else {
//if there are no problems
mcHealth += healthDiff;
}
}
stage.addEventListener(KeyboardEvent.KEY_DOWN, checkKeys);
function checkKeys(event:KeyboardEvent):void{
//if the left key is down and no left arrows are touching the receptor
if(event.keyCode == 68 && !touchLeft){
changeHealth(-10);//make the health go down
combo = 0;
scoreString = 'Bad';
} else if(event.keyCode == 70 && !touchUp){//and so on
changeHealth(-10);
combo = 0;
scoreString = 'Bad';
} else if(event.keyCode == 74 && !touchDown){
changeHealth(-10);
combo = 0;
scoreString = 'Bad';
} else if(event.keyCode == 75 && !touchRight){
changeHealth(-10);
combo = 0;
scoreString = 'Bad';
}
}
beginCode();
Can someone tell me why this error is occurring? Thank you.
While iterating numChildren, it's necessary to check the object is an arrow or not.
Maybe you can distinguish it by having keyCode property or not.
Try to use Object.hasOwnProperty(property name) method.
if (target.hasOwnProperty("keyCode")){
// access target.keyCode here.
}
Or this might works too.
if (target is arrowLeft || target is arrowUp || target is arrowDown || target is arrowRight){
// the target should be arrow class
// access target.keyCode here.
}
//this for loop will be used for the hit testing
for(var i:int = 0;i<numChildren;i++){
var target:Object = getChildAt(i);
if (target.hasOwnProperty("keyCode")){ // If the object is an arrow, that object should has keyCode property.
if(target.keyCode != null && target.hitTestObject(mcReceptor)){//if the object is an arrow and the receptor is touching it
if(target.keyCode == 68){//if left arrow
touchLeft = true;
} else if(target.keyCode == 70){//if up arrow
touchUp = true;
} else if(target.keyCode == 74){//if down arrow
touchDown = true;
} else if(target.keyCode == 75){//if right arrow
touchRight = true;
}
}
}
}

Why can't I reset this game? I tried resetting variables etc

I have this flash game coded with AS3. It works on the first round. When you die, the program will loop it back to the game frame in which a couple or errors occur. One. the dead characters from last round still remain still. Two. The speed doubles everytime. Why????
I create a resetEverything() function to reset all variables, remove Event Listeners and a clear.graphics()
Why doesn't anything work?
Here is my code..
stop();
var leftBorder:verticalwall = new verticalwall(); // defining a variable to hold the left wall
addChild(leftBorder); // adding the left wall to the stage
var rightBorder:verticalwall = new verticalwall(); // defining a variable to hold the left wall
rightBorder.x = 790; // pushing the right wall to the edge of the stage
addChild(rightBorder); // adding the right wall to the stage
var topBorder:horizontalwall = new horizontalwall(); // defining a variable to hold the left wall
addChild(topBorder); // adding the top wall to the stage
var bottomBorder:horizontalwall = new horizontalwall(); // defining a variable to hold the bottom wall
bottomBorder.y = 790; // pushing the bottom wall to the base of the stage
addChild(bottomBorder); // adding the bottom wall to the stage
var P1positions:Array = new Array(); //defining a new variable to hold the poistions of Player 1
var P2positions:Array = new Array(); //defining a new variable to hold the poistions of Player 2
graphics.beginFill( 0x000000 ); // defining a colour for the background
graphics.drawRect( 0, 0, 800, 800); // drawing a rectangle for background
graphics.endFill(); // ending the background creating process
stage.addEventListener(Event.ENTER_FRAME, checkPlayersSpeed);
function checkPlayersSpeed(event:Event)
{
if(P1speed == 0 || P2speed == 0){
P1speed = 0;
P2speed = 0;
gotoAndStop(1, "Conclusion");
}
}
//Player 1
var player1col = "0xFF0000";
var Player1:Shape = new Shape(); //defining a variable for Player 1
Player1.graphics.lineStyle(10,0xffff00); //defining the colour of the style
Player1.graphics.beginFill(0xffff00); //begin filling the shape
Player1.graphics.drawRoundRect(0,0,3,3,360);
Player1.graphics.drawCircle(Player1.x, Player1.x, 2.4) //draw a circle
Player1.graphics.endFill(); //finish the filling process
addChild(Player1); //add player 1 to stage
Player1.x = 250;
Player1.y = 250;
var P1leftPressed:Boolean = false; //boolean to check whether the left key for Player 1 was pressed
var P1rightPressed:Boolean = false; //boolean to check whether the right key for Player 1 was pressed
var P1speed = 3.5; //variable to store the speed of which player 1 moves
var P1Dir = 45; //variable containing the direction in which player 1 moves
var P1position, P2position;
Player1.addEventListener(Event.ENTER_FRAME, P1fl_MoveInP1DirectionOfKey); //adding a listener to the player
stage.addEventListener(KeyboardEvent.KEY_DOWN, P1fl_SetKeyPressed); //listener for a key to be pressed
stage.addEventListener(KeyboardEvent.KEY_UP, P1fl_UnsetKeyPressed); // listener for a key to be released
function P1fl_MoveInP1DirectionOfKey(event:Event) //Moves the player depedning on what key was pressed
{
if(Player1.hitTestObject(leftBorder) || Player1.hitTestObject(rightBorder) || Player1.hitTestObject(topBorder) || Player1.hitTestObject(bottomBorder)){ //checking to see whether Player 1 has hit the wall
P1speed = 0; //stopping Player 1 from moving
Player1.removeEventListener(Event.ENTER_FRAME, P1fl_MoveInP1DirectionOfKey); //adding a listener to the player
stage.removeEventListener(KeyboardEvent.KEY_DOWN, P1fl_SetKeyPressed); //listener for a key to be pressed
stage.removeEventListener(KeyboardEvent.KEY_UP, P1fl_UnsetKeyPressed); // listener for a key to be released
}
if (P1leftPressed)
{
P1Dir -= 0.1; //changes the direction to make Player 1 rotate
}
if (P1rightPressed)
{
P1Dir += 0.1; //changes the direction to make Player 1 rotate
}
P1position = [Player1.x, Player1.y]; //defining a variable for Player 1's constant positions
P1positions.push(P1position); //pushes every position of Player 1 to the array
for (var i = 0; i < P1positions.length - 10; i++) { //a loop that opperates for as long as the array is receiving positions
var P1x = P1positions[i][0]; //saving x positions into array with a unique identifier
var P1y = P1positions[i][1]; //saving y positions into array with a unique identifier
if (distanceBetween(P1x, P1y, Player1.x, Player1.y) < 15) { //checking distance between Player 1 and its trail
P1speed = 0;
}
}
Player1.x += P1speed * Math.cos(P1Dir); //this makes player 1 move forard
Player1.y += P1speed * Math.sin(P1Dir); //this makes player 2 move forward
var P1trail:Shape = new Shape; //defining a variable for player 1's trail
graphics.lineStyle(8, player1col); //setting the format for the trail
graphics.drawCircle(Player1.x, Player1.y, 1.4); //drawing the circles within the trail
addChild(P1trail); //adding the circles to the stage
}
function P1fl_SetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.LEFT:
{
P1leftPressed = true; //tells the computer that left has been pressed
break;
}
case Keyboard.RIGHT:
{
P1rightPressed = true; //tells the computer that right has been pressed
break;
}
}
}
function P1fl_UnsetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.LEFT:
{
P1leftPressed = false; //tells the computer that left has been released
break;
}
case Keyboard.RIGHT:
{
P1rightPressed = false; //tells the computer that left has been released
break;
}
}
}
function distanceBetween (x1:Number, y1:Number, x2:Number, y2:Number) { // creating a function
// return d = Math.sqrt(x2 - x1)^2 +(y2 - y1)^2);
var diffX = x2 - x1; // creating variable to tidy up the pythagoras line below
var diffY = y2 - y1; // creating variable to tidy up the pythagoras line below
return Math.sqrt(diffX * diffX + diffY * diffY); // using pythagras theorem
}
// Player 2
var player2col = "0x0066CC";
var Player2:Shape = new Shape(); //defining a variable for Player 1
Player2.graphics.lineStyle(10,0xffff00); //defining the colour of the style
Player2.graphics.beginFill(0xffff00); //begin filling the shape
Player2.graphics.drawRoundRect(0,0,3,3,360);
Player2.graphics.drawCircle(Player2.x, Player2.x, 2.4) //draw a circle
Player2.graphics.endFill(); //finish the filling process
addChild(Player2); //add player 1 to stage
Player2.x = 500;
Player2.y = 500;
var P2leftPressed:Boolean = false;
var P2rightPressed:Boolean = false;
var P2speed = 3.5;
var P2Dir = 180;
Player2.addEventListener(Event.ENTER_FRAME, P2fl_MoveInP1DirectionOfKey);
stage.addEventListener(KeyboardEvent.KEY_DOWN, P2fl_SetKeyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, P2fl_UnsetKeyPressed);
function P2fl_MoveInP1DirectionOfKey(event:Event)
{
if(Player2.hitTestObject(leftBorder) || Player2.hitTestObject(rightBorder) || Player2.hitTestObject(topBorder) || Player2.hitTestObject(bottomBorder)){
P2speed = 0;
Player2.removeEventListener(Event.ENTER_FRAME, P2fl_MoveInP1DirectionOfKey);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, P2fl_SetKeyPressed);
stage.removeEventListener(KeyboardEvent.KEY_UP, P2fl_UnsetKeyPressed);
}
if (P2leftPressed)
{
P2Dir -= 0.1;
}
if (P2rightPressed)
{
P2Dir += 0.1;
}
P2position = [Player2.x, Player2.y];
//trace(P2position);
P1positions.push(P2position);
for (var a = 0; a < P1positions.length - 10; a++) {
var P2x = P1positions[a][0];
var P2y = P1positions[a][1];
if (distanceBetween(P2x, P2y, Player2.x, Player2.y) < 15) {
P2speed = 0;
}
}
Player2.x += P2speed * Math.cos(P2Dir);
Player2.y += P2speed * Math.sin(P2Dir);
var P2trail:Shape = new Shape;
graphics.lineStyle(8, player2col);
graphics.drawCircle(Player2.x, Player2.y, 1.4);
addChild(P2trail);
}
function P2fl_SetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case event.keyCode = 90:
{
P2leftPressed = true;
break;
}
case event.keyCode = 67:
{
P2rightPressed = true;
break;
}
}
}
function P2fl_UnsetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case event.keyCode=90:
{
P2leftPressed = false;
break;
}
case event.keyCode=67:
{
P2rightPressed = false;
break;
}
}
}
Please help!

Drag panning with zoom on mouseclick location AS3

So, another post on here REALLY helped me prior from this link!
It got me to zoom in neatly, but what I'm really looking for in my panning is a mouse drag (I will be working with a touch screen, so dragging to move is important) No need to use Touch classes, I have done dragging events with Mouse classes before and find it easier to me.
My problem here is that my neat zoom is linked to this MOUSE_MOVE panning, and I want to know a clean way to change my panning to a drag event, and still not have my panning go past my image constraints.
bg_mc- is my background image to move and zoom.
My code:
import com.greensock.*;
bg_mc.doubleClickEnabled = true;
//Variables
var percX:Number;
var percY:Number;
var destX:Number;
var destY:Number;
//Image panned and masked
this.mask = mask_mc;
stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
function mousemove(e:MouseEvent) {
if (mask_mc.hitTestPoint(stage.mouseX,stage.mouseY,false)) {
if (bg_mc.width>mask_mc.width) {//Avoids Scrolling if image is under mask area width
percX = mask_mc.mouseX/mask_mc.width;
}
if (bg_mc.height>mask_mc.height) {
//Avoids Scrolling if image is under mask area height
percY = mask_mc.mouseY/mask_mc.height;
}
destX = -(bg_mc.width-mask_mc.width)*percX;
destY = -(bg_mc.height-mask_mc.height)*percY;
TweenMax.to(bg_mc,.5,{x:destX,y:destY});
}
}
//Add listeners for the imgLoader movie clip.
bg_mc.doubleClickEnabled = true;
bg_mc.addEventListener(MouseEvent.DOUBLE_CLICK, increaseSize);
bg_mc.addEventListener(MouseEvent.CLICK, decreaseSize);
function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number,
bounds:Rectangle = null, onComplete:Function = null):TweenLite {
// scaling will be done relatively
var relScaleX:Number = scaleAmount / objectToScale.scaleX;
var relScaleY:Number = scaleAmount / objectToScale.scaleY;
// map vector to centre point within parent scope
var scalePoint:Point = objectToScale.localToGlobal( new
Point(objectToScale.mouseX, objectToScale.mouseY));
scalePoint = objectToScale.parent.globalToLocal( scalePoint );
// current registered postion AB
var AB:Point = new Point( objectToScale.x, objectToScale.y );
// CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
var CB:Point = AB.subtract( scalePoint );
CB.x *= relScaleX;
CB.y *= relScaleY;
// recaulate AB, objectToScale will be the adjusted position for the clip
AB = scalePoint.add( CB );
// set actual properties
if(bounds){
var limits:Rectangle = new Rectangle(
bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
(objectToScale.width * relScaleX) - bounds.width,
(objectToScale.height * relScaleY) - bounds.height
);
if(AB.x < limits.x) AB.x = limits.x;
if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
if(AB.y < limits.y) AB.y = limits.y;
if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;
}
return TweenLite.to(objectToScale,1,{onComplete: onComplete,
scaleX: scaleAmount, scaleY: scaleAmount, x: AB.x, y: AB.y});
}
function increaseSize(event:MouseEvent):void{
stopMouseMove();
scaleAroundMouse(bg_mc, 4, null, resumeMouseMove);
}
function decreaseSize(event:MouseEvent):void{
stopMouseMove();
scaleAroundMouse(bg_mc, 1, null, resumeMouseMove);
}
function stopMouseMove():void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE,mousemove);
}
function resumeMouseMove():void {
stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
}
Any help I can get would be great!
On a mousedown or whatever listener you want to start dragging, use the MovieClip.StartDrag() function to allow dragging, and the StopDrag() to stop it.
While you could use the built in startDrag (or startTouchDrag) and stopDrag methods, it will not play nice with your zoom in/out function.
bg_mc.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown); //add the listener to the bg directly
function mouseDown(e:MouseEvent) {
// if (mask_mc.hitTestPoint(stage.mouseX,stage.mouseY,false)) { //this isn't needed if you add the listener directly to bg_mc
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUp);
bg_mc.startDrag(false, getBoundsRect()); //see the code below for the getBoundsRect() function
}
function mouseUp(e:MouseEvent):void {
bg_mc.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP,mouseUp);
}
You'd be better served to have a custom drag function, like below:
import com.greensock.*;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.geom.Point;
bg_mc.doubleClickEnabled = true;
//Variables
var percX:Number;
var percY:Number;
var destX:Number;
var destY:Number;
//Image panned and masked
bg_mc.mask = mask_mc;
//this function generates a bounds rectangle that would keep bg_mc edges from going outside of mask_mc area
function getBoundsRect():Rectangle {
return new Rectangle((mask_mc.x + mask_mc.width) - bg_mc.width, (mask_mc.y + mask_mc.height) - bg_mc.height, bg_mc.width - mask_mc.width, bg_mc.height - mask_mc.height);
}
var isZoomed:Boolean = false; //a var to keep track of whether your zoomed in or out
var isDragging:Boolean = false; //a var to keep track of whether the bg is being dragged
var tmpMousePoint:Point = new Point(); //this stores the mouse coordinates on the mouse down, to compare later on the mouse up to see if the mouse moved
var decay:Number = .27; //make this lower for slower drag, make it 1 to turn off a smooth drag all together
var tmpMouseMoved:Boolean = false; //to keep track on mouse up whether the action was a drag or a click
var mouseMoveSensitivity:Number = 15; //how far does mouse need to move before you cancel the click event
var offset:Point = new Point(); //the offset of the initial mouse click relative to bg_mc's 0,0
bg_mc.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
bg_mc.addEventListener(MouseEvent.CLICK,mouseClick, false, 99999); //listen with a higher priority than any other click listeners on bg_mc - this way if it's a drag, you can cancel the click event
function mouseDown(e:Event):void {
//reset these to default
isDragging = true;
tmpMouseMoved = false;
tmpMousePoint.x = mouseX; //capture the current mouse to check later if it moved (so you know the user intended to drag not click)
tmpMousePoint.y = mouseY;
offset.x = bg_mc.mouseX;
offset.y = bg_mc.mouseY;
bg_mc.addEventListener(Event.ENTER_FRAME,bgEnterFrame); //listen every frame until the mouse is released
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
function bgEnterFrame(e:Event):void {
bg_mc.x += decay * (mouseX - offset.x - bg_mc.x);
bg_mc.y += decay * (mouseY - offset.y - bg_mc.y);
var bounds:Rectangle = getBoundsRect();
switch(true){
case (bg_mc.x < bounds.x):
bg_mc.x = bounds.x;
break;
case (bg_mc.x > bounds.x + bounds.width):
bg_mc.x = bounds.x + bounds.width;
}
switch(true){
case (bg_mc.y < bounds.y):
bg_mc.y = bounds.y;
break;
case (bg_mc.y > bounds.y + bounds.height):
bg_mc.y = bounds.y + bounds.height;
}
if(Math.abs(tmpMousePoint.x - mouseX) > mouseMoveSensitivity || Math.abs(tmpMousePoint.y - mouseY) > mouseMoveSensitivity){
tmpMouseMoved = true;
}
}
function mouseUp(e:Event):void {
isDragging = false;
//remove listeners
bg_mc.removeEventListener(Event.ENTER_FRAME,bgEnterFrame);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
function mouseClick(e:MouseEvent):void {
trace("CLICK cap");
if(tmpMouseMoved){
trace("Kill");
e.stopImmediatePropagation(); //cancel the mouse event
}
}
//Add listeners for the imgLoader movie clip.
bg_mc.doubleClickEnabled = true;
bg_mc.addEventListener(MouseEvent.DOUBLE_CLICK, increaseSize);
bg_mc.addEventListener(MouseEvent.CLICK, decreaseSize,false,0,true);
function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number,
bounds:Rectangle = null, onComplete:Function = null):TweenLite {
// scaling will be done relatively
var relScaleX:Number = scaleAmount / objectToScale.scaleX;
var relScaleY:Number = scaleAmount / objectToScale.scaleY;
// map vector to centre point within parent scope
var scalePoint:Point = objectToScale.localToGlobal( new
Point(objectToScale.mouseX, objectToScale.mouseY));
scalePoint = objectToScale.parent.globalToLocal( scalePoint );
// current registered postion AB
var AB:Point = new Point( objectToScale.x, objectToScale.y );
// CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
var CB:Point = AB.subtract( scalePoint );
CB.x *= relScaleX;
CB.y *= relScaleY;
// recaulate AB, objectToScale will be the adjusted position for the clip
AB = scalePoint.add( CB );
// set actual properties
if(bounds){
var limits:Rectangle = new Rectangle(
bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
(objectToScale.width * relScaleX) - bounds.width,
(objectToScale.height * relScaleY) - bounds.height
);
if(AB.x < limits.x) AB.x = limits.x;
if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
if(AB.y < limits.y) AB.y = limits.y;
if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;
}
TweenLite.killTweensOf(objectToScale); //need to add this so the click/double click don't compete with each other
return TweenLite.to(objectToScale,1,{onComplete: onComplete,
scaleX: scaleAmount, scaleY: scaleAmount, x: AB.x, y: AB.y});
}
function increaseSize(event:MouseEvent):void{
if(isZoomed){
scaleAroundMouse(bg_mc, 4, getBoundsRect());
isZoomed = false;
}
}
function decreaseSize(event:MouseEvent):void{
if(!isZoomed){
scaleAroundMouse(bg_mc, 1, getBoundsRect());
isZoomed = true;
}
}

Sprite (x,y) defaulting to (0,0) in AS3

When executing the code:
var cont:Sprite = new Sprite();
var a:Vector.<int > = Vector.<int > ([1,2]);
var b:Vector.<Number > = Vector.<Number > ([0,0,40,40]);
cont.graphics.lineStyle(5, 0x442299);
cont.graphics.drawPath(a, b);
addChild( cont );
cont.x = 100;
cont.y = 100;
trace("X coordinate of purple line: ", cont.x);
I get the output "X coordinate of purple line: 100"
However, when I test this code and draw a line from (100, 100) to (140, 140) with the mouse:
var line:Sprite = new Sprite();
stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler);
var startX:int = -1;
var startY:int = -1;
function mouseDownHandler(event:MouseEvent):void
{
startX = mouseX;
startY = mouseY;
}
function mouseUpHandler(event:MouseEvent):void
{
swype(Vector.<int> ([1,2]), Vector.<Number> ([startX,startY,mouseX,mouseY]));
}
function swype(commands:Vector.<int>, coords:Vector.<Number>):void
{
var container:Sprite = new Sprite();
container.graphics.lineStyle(5, 0x0066CC);
container.graphics.drawPath(commands, coords);
addChild( container );
container.x = 100;
container.y = 100;
trace("X coordinate of blue line: ", container.x);
}
I get the output: "X coordinate of blue line: 0"
Why is it that when I am getting the coordinates from the mouse's position on the screen and adding them to the vector, the Sprite container's x and y coordinates default to 0,0?
Not sure what you are wanting to do but you may need to use the localToGlobal methods if you keep moving that _container around ;)
This has to do with the context of where you get the property of the mouseX and mouseY.
You have to think more about the display stack and how that relates to what the properties of mouseX and Y will give you.
Have a try of this and shoot me any questions if you cannot understand why it works.
package
{
import flash.display.Sprite;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
public class Testing extends Sprite
{
private var startX:Number;
private var startY:Number;
private var _container:Sprite = new Sprite ();
public function Testing ()
{
stage.quality = StageQuality.BEST;
stage.align = "TL";
stage.scaleMode = StageScaleMode.NO_SCALE;
// if you comment this it will stuff up the first swype
_container.x = _container.y = 100;
var cont:Sprite = new Sprite ();
var a:Vector.<int> = Vector.<int> ( [1, 2] );
var b:Vector.<Number> = Vector.<Number> ( [0, 0, 40, 40] );
cont.graphics.lineStyle ( 5 , 0x442299 );
cont.graphics.drawPath ( a , b );
addChild ( cont );
cont.x = 100;
cont.y = 100;
trace ( "X coordinate of purple line: " , cont.x );
var line:Sprite = new Sprite ();
addChild ( _container );
stage.addEventListener ( MouseEvent.MOUSE_DOWN , mouseDownHandler );
stage.addEventListener ( MouseEvent.MOUSE_UP , mouseUpHandler );
var startX:int = - 1;
var startY:int = - 1;
}
function mouseDownHandler ( event:MouseEvent ):void
{
startX = _container.mouseX;
startY = _container.mouseY;
}
function mouseUpHandler ( event:MouseEvent ):void
{
swype ( Vector.<int> ( [1, 2] ) , Vector.<Number> ( [startX, startY, _container.mouseX, _container.mouseY] ) );
}
function swype ( commands:Vector.<int> , coords:Vector.<Number> ):void
{
_container.graphics.lineStyle ( 5 , 0x0066CC );
_container.graphics.drawPath ( commands , coords );
//this moves it after the property was collected for the initial swype which you don't want
_container.x = 100;
_container.y = 100;
trace ( "X coordinate of blue line: " , _container.x );
}
}
}