I'm making a simple puzzle-building game. It's working, but I have just spotted an odd in-game behaviour...
When I pick up a piece of the puzzle and move to the left side of the swf, the game runs at a playable frame rate. The farther I move the mouse to the right, the frame rate (or at least update rate) seems to drop.
The only code it's running at that point is a method that checks which piece is carried and moves that piece's x and y coords to match the mouse.
I've already tried using 'updateAfterEvent' with no change.
Has anyone experienced something similar, and if so do you know what the problem is?
Cheers.
I've never heard of or seen an issue like this with flash. The answer is in your code somewhere. Only one thing slows down your frame rate: trying to process too much information between frames, which happens either from moving/altering too many display objects at once, or running too much code between the frames.
If the only change being made to the stage is moving one graphic to follow the mouse, then the problem isn't with trying to render too many graphics.
Are you using the onEnterFrame event or the onMouseMove event to move your puzzle piece?
Is there a function that is being called every frame while moving the piece? (i.e. checking to see if it is in the right spot) If so - maybe that can be changed to only check once when the piece is released.
Sorry I can't help more - i would have to see your code to see if the problem is in there.
Hey there - and thanks for your reply.
I've noticed something even weirder - the direction in which the mouse slows down depends on which piece you pick up. For some pieces the game runs slowest when the piece is dragged to the top right, others to the bottom right.
Anyway.
I've got an event listener attached to the stage, listening for MOUSE_MOVE. This triggers a function which calls a method in the Puzzle class which checks if a piece is carried and if so moves it to match the mouse x and y.
(The ButtonScreen class is just a menu where you choose easy medium or hard difficulty and has a method that returns the difficulty chosen).
Here's the main class...
Code:
package {
import flash.display.MovieClip;
import flash.utils.*;
import flash.events.*;
public class GameHolder3 extends MovieClip {
var menuButtons:ButtonScreen;
var gamePuzzle:Puzzle;
public function GameHolder3():void {
// instantiate difficulty menu
menuButtons = new ButtonScreen();
addChild(menuButtons);
menuButtons.addEventListener(ButtonScreen.DIFFICULTY_CHOSEN, pickedDiff);
function pickedDiff(e:MouseEvent) {
startGame();
// remove menu page
removeChild(menuButtons);
menuButtons = null;
};
function startGame() {
// instantiate new game with 'difficulty' argument from menuButtons
gamePuzzle = new Puzzle(menuButtons.getDifficulty());
stage.addChild(gamePuzzle);
stage.addEventListener(MouseEvent.MOUSE_MOVE, pieceCarried);
};
// if mouse is moving check if piece is carried
function pieceCarried(e:MouseEvent) {
e.updateAfterEvent(); // this made no difference to the slow update problem
gamePuzzle.checkPickUp();
};
};
};
};
and here's the Puzzle class...
Code:
package {
import flash.display.MovieClip;
import flash.events.*;
import flash.geom.Point;
public class Puzzle extends MovieClip {
//trace("game initialising");
public var puzzleSize:int = 400;
var difficultyLevel:int;
var pictureType:int = 1;
var pickedUp:*;
var pieceCarried:Point = null;
var puzzleSolved:Boolean = false;
var puzzlePieces:Array = new Array;
// pieceCorrectPlacement will be an array of Points that is updated with the placed piece's correct coords
var pieceCorrectPlacement:Array = new Array;
var count:int;
var count2:int;
var tempX:Number;
var tempY:Number;
var tempPickX:int;
var tempPickY:int;
var puzzleOffsetX:int = 50;
var puzzleOffsetY:int = 50;
public function Puzzle(difficultyInput:int):void {
difficultyLevel = difficultyInput;
trace("difficulty = "+difficultyInput);
for (count=1;count<=difficultyLevel;count++) {
puzzlePieces[count] = new Array;
pieceCorrectPlacement[count] = new Array;
for (count2=1;count2<=difficultyLevel;count2++) {
puzzlePieces[count][count2] = new Piece(count,count2,difficultyLevel,puzzleSize,pictureType);
pieceCorrectPlacement[count][count2] = null;
// scatterPiece method adds new puzzle piece to scattered pile
puzzlePieces[count][count2].scatterPiece(count, count2, puzzleOffsetX, puzzleOffsetY, puzzleSize, difficultyLevel);
addChild(puzzlePieces[count][count2]);
if (numChildren > 2) {
// randomly arrange new piece in stack of childen on stage
setChildIndex(puzzlePieces[count][count2], Math.floor(Math.random()*numChildren));
};
puzzlePieces[count][count2].addEventListener(MouseEvent.CLICK, pickupPiece);
puzzlePieces[count][count2].setCorrectPlacement(count,count2);
};
};
};
public function pickupPiece(e:MouseEvent):void {
// determine value of space over which mouse is hovering
tempX = Math.floor((mouseX-puzzleOffsetX)/(puzzleSize/difficultyLevel))+1;
tempY = Math.floor((mouseY-puzzleOffsetY)/(puzzleSize/difficultyLevel))+1;
if (tempX < 1 && pieceCarried != null || tempY < 1 && pieceCarried != null || tempX > difficultyLevel && pieceCarried != null || tempY > difficultyLevel && pieceCarried != null) {
if (tempX > difficultyLevel && tempY > 0 && tempY <= difficultyLevel) {
// return piece to pile
puzzlePieces[pieceCarried.x][pieceCarried.y].returnPiece(mouseX, mouseY, puzzleOffsetX, puzzleOffsetY, puzzleSize, difficultyLevel);
pieceCarried = null;
};
} else if (pieceCarried == null) {
e.currentTarget.setCarried(true);
pickedUp = e.currentTarget;
pickedUp.x = mouseX-(puzzleSize/(difficultyLevel*2));
pickedUp.y = mouseY-(puzzleSize/(difficultyLevel*2));
pickedUp.rotation = 0;
trace("pickedUp = "+pickedUp.getCorrectPlacementX()+", "+pickedUp.getCorrectPlacementY());
pieceCarried = new Point(pickedUp.getCorrectPlacementX(), pickedUp.getCorrectPlacementY());
// if picking up from game square set current placement to null
if (tempX <= difficultyLevel) {
pieceCorrectPlacement[pickedUp.getCurrentPlacementX()][pickedUp.getCurrentPlacementY()] = null;
};
addChild(pickedUp);
} else {
// if placement points of current mouse hover coords are empty
if (pieceCorrectPlacement[tempX][tempY] == null) {
// place piece
puzzlePieces[pieceCarried.x][pieceCarried.y].setCurrentPlacement(tempX, tempY, puzzleOffsetX, puzzleOffsetY, puzzleSize, difficultyLevel);
pieceCorrectPlacement[tempX][tempY] = new Point(pieceCarried.x, pieceCarried.y);
pieceCarried = null;
// check if all pieces are in correct place
puzzleSolved = true;
for (count=1;count<=difficultyLevel;count++) {
for (count2=1;count2<=difficultyLevel;count2++) {
if (pieceCorrectPlacement[count][count2] == null) {
puzzleSolved = false;
};
};
};
if (puzzleSolved == true) {
for (count=1;count<=difficultyLevel;count++) {
for (count2=1;count2<=difficultyLevel;count2++) {
if (pieceCorrectPlacement[count][count2].x != count || pieceCorrectPlacement[count][count2].y != count2) {
puzzleSolved = false;
};
};
};
};
if (puzzleSolved == true) {
// code will be added here to progress to next stage of the game
trace("puzzleSolved!");
};
} else {
// swap carried piece for placed piece
tempPickX = pieceCorrectPlacement[tempX][tempY].x;
tempPickY = pieceCorrectPlacement[tempX][tempY].y;
// identify correct placement coords (name) of carried piece from carried piece point and move named piece to hover coords
puzzlePieces[pieceCarried.x][pieceCarried.y].setCurrentPlacement(tempX, tempY, puzzleOffsetX, puzzleOffsetY, puzzleSize, difficultyLevel);
// point pieceCorrectPlacement coords to correct placement coords of placed piece
pieceCorrectPlacement[tempX][tempY] = new Point(pieceCarried.x, pieceCarried.y);
pickedUp = puzzlePieces[tempPickX][tempPickY];
pickedUp.x = mouseX-(puzzleSize/(difficultyLevel*2));
pickedUp.y = mouseY-(puzzleSize/(difficultyLevel*2));
pieceCarried = new Point(tempPickX, tempPickY);
addChild(pickedUp);
};
};
};
// method to update position of carried puzzle piece
public function checkPickUp():void {
if (pieceCarried != null) {
pickedUp.x = mouseX-(puzzleSize/(difficultyLevel*2));
pickedUp.y = mouseY-(puzzleSize/(difficultyLevel*2));
};
};
};
};
It's the very last function above that gets called when the mouse moves. I guess there must be something about the variable 'pickedUp' that makes it run slowly, depending on which piece is picked up - but I have no idea why.
The Piece class basically has a few methods for setting it up and placing it initially and setting and getting its correct placement.
If anyone can be bothered to decipher the above I'd appreciate any tips. I'm new-ish to the concepts of OOP, so I suspect it's not written as elegantly as it might be.
But it's more the mystery of why the mouse slows down in certain positions that I'm trying to get to the bottom off.
Cheers.
Last edited by moosefetcher; 08-27-2009 at 05:24 AM.
I'm not seeing anything here that the flash player would struggle with...
Would it be possible for you to post your swf or put it online and post the site so I (and anyone else) could see exactly what is happening? Not that you aren't explaining it well, sometimes it just helps to see it for yourself.
Moose, I dont get the same behavior that you describe. It works fine (in IE and firefox) on diff. level 1 and 2. There in no decrease in performance ever. In difficulty level 3, with more pieces, the only time i see something that looks like a decreased frame rate is when I am dragging a piece very quickly over the center area of the stage (where you place the pieces), and only when i have filled that area with the pieces. AND it's not that bad at all: totally acceptable imo.
Hopefully more people will test it out for you, but unfortunatlyy (or maybe fortunatly) I am not seeing what you are talking about.