AS3 What causes lag with side scrollers? - actionscript-3

I've been programming a side scroller based on a tutorial found in a book. My friend did the same, and his is working perfectly.
I've only really changed a few variable names around (I've also done animations differently) but for some reason, when my character is moving, there is a large amount of lag.
HOwever the lag is only present when there are 'walls' on the stage. When I scroll past them, the lag goes away, then returns.
Walls and Floors both use the same code (they are both assigned as 'floorObjects' variables) and use the same collision code, however I cannot figure out why there is lag involved.
From where the character starts (about 60x) if the character goes left, there is a HUGE amount of lag. If I go right, there isn't too much lag, until the screen starts to scroll.
The lag from going left I believe may have something to do with the program being preventing from scrolling off the map etc. But I can't figure out why there is lag when trying to move right.
I've listed the Scroll code, and the main loop, if need be I can upload the collisions code, and any help would be greatly appreciated.
Scroll code;
public function scrollGame()
{
var stagePosition:Number = gameLevel.x + player.mc.x;
var rightEdge:Number = stage.stageWidth - edgeDistance;
var leftEdge:Number = edgeDistance;
//Scroll the GameLevel to the Left if player moves right
if(stagePosition > rightEdge)
{
gameLevel.x -= (stagePosition - rightEdge);
//Prevent the game scrolling off the stage
if (gameLevel.x < -(gameLevel.width-stage.stageWidth))
gameLevel.x = -(gameLevel.width-stage.stageWidth);
}
//Scroll the GameLevel to the right if player moves left
if(stagePosition < leftEdge)
{
gameLevel.x += (leftEdge - stagePosition);
//Prevent the game scrolling off the stage
if(gameLevel.x > 0)
gameLevel.x = 0;
}
}
Main Loop:
public function gameLoop(e:Event)
{
//Get Time Difference
if(lastTime == 0) lastTime = getTimer();
var timeDiff:int = getTimer() - lastTime;
lastTime += timeDiff;
//Game Cycle tasks
//Only perform if in play mode
if(gameMode == "play")
{
moveCharacter(player, timeDiff);
moveEnemies(timeDiff);
checkCollisions();
scrollGame();
}
}
UPDATE:
So I "profiled" it, most of the time is being spent either in the MoveCharacter() function, using the gotoAndStop() command. So I removed that, and it made no difference, still lagging. I then removed the enemies also, still lagging. But turning quality down to low has somehow fixed it (though at a poor quality now ) Any ideas as to what is causing the lag and how to fix it?

this is from the flash university book isn't it?
The code is fine.
I know what will lag your flash game.
This is a guess though, and I do get this error some times.
Make sure your images are optimized!
If they're imported from photo shop or illustratro then flash will have to deal with those complicate vector points.
Use .png for transparent images, bitmaps don't hurt either.

Related

AS3 Swap depths in Flash IDE without destroying movieclips

I have two movieclips, one is on top, one is on bottom. The top one is set to the second frame. I move it to the z axis bottom on the next frame, and for the remaining frames it plays all frames like it has been reset without any code (like I didn't tell it gotoAndStop(2)).
Image example: http://i.imgur.com/mQ8f5uT.gif (hard to tell by the frame rate, but the dark green box starts playing as if I didn't set it's frame once I move it below)
I know it doesn't have that issue when I code the depth swapping with setChildIndex, but the animations are lost.
If you're wondering, it's a simplified issue of a larger moving character sprite animation that I would like to swap depths of movie clips in the animation without resetting the movie clips underneath the depth change. So I'm not really looking for a work around per se, unless there's a well design solution and not a band aid "hack."
I think I didn't understand your question fully. A MovieClip will keep playing or keep being stopped no matter what you do with it, even if it was removed from the scene. I made a simple example which shows that MovieClip state is not affected by depth change.
The working SWF is here to test: http://zdg.ru/tmp/updown.swf
And the code is:
import flash.events.MouseEvent;
var is_playing:Boolean = true;
btn_toggle.addEventListener(MouseEvent.CLICK, doToggle);
btn_updown.addEventListener(MouseEvent.CLICK, doUpdown);
function doToggle(evt:MouseEvent) {
if (is_playing) mv_test.stop(); else mv_test.play();
is_playing = !is_playing;
}
function doUpdown(evt:MouseEvent) {
var tmp:int = getChildIndex(mv_block);
setChildIndex(mv_block, getChildIndex(mv_test));
setChildIndex(mv_test, tmp);
}

What is this, and why is it happening?

So I have been working on my final project for the semester for my Computer Systems class, and we have been tasked to make a game using Flash and ActionScript 3.0. I've pretty much completed everything but I have come across an extremely strange occurrence of Flash CS6 being silly. I am moving a MovieClip up and down depending on a selected index, however, the image leaves 'residue of it's footprints' behind and also moves. I have tried hard to look for an answer as to why this is happening, but I don't know what it's called, or how to appropriately explain it - I'm coming from an area where one must program graphics, not just simply, drag and drop.
Below are pictures as to what I've come across, but first the code I'm using:
function updateThemeScreen():void {
button_selection.y += (selectedPositions[selectedTheme] - button_selection.y) / 2;
}
function attemptThemeChange(mxP:Number, myP:Number):void {
if(objectContains(theme_darkness, mxP, myP)) {
selectedTheme = 0;
} else if(objectContains(theme_halloween, mxP, myP)) {
selectedTheme = 1;
}
}
As you can see in the final image, it has copied half of itself and left it at the last button, which is strange, and shouldn't happen...
Link to the SWF zipped up with the required AS3 classes: Dude, RUN
So it seems that I have magically fixed this problem by hiding the buttons and showing them all in one frame. I don't know what this problem is or why it does it, but to fix it, you just need to hide and show the affected components - yes, in one frame:
function hideShow(object:MovieClip):void {
object.visible = false;
object.visible = true;
}

Collision Detection - How to?

I am currently working on a flash game and am rather new to AS 3 or flash. Need some advice in how to implement one of the core elements of my game.
The idea is 2 player competitive snake style game, only the players do not try to kill each other, but try to reach their opponents spawnpoint.
1 of the key parts of the game would be a grid which is created over the stage where either player may use to "Create walls" by passing through points on the grid. I have no idea how to implement this. Currently I have the basics down where there are 2 players with a starting spot, and if either one reaches the other's starting zone, they score a point.
I need some advice in how to go about implementing this feature:
Each point in the grid will start off in a certain state, and when a player passes through that point, it will be "activated". Then the player may move through any adjacent points to the "activated" point, which will generate a wall between both active points, and thats how they will create mazes to protect their starting area.
Should I generate each point individually or create a grid with a simple function:
//function to create grids on the map
public function createGrid()
{
var rows:int = 6;
var cols:int = 11;
for (var py:int = 0; py < rows; py++) {
for (var px:int = 0; px < cols; px++) {
this.grid = new griDot(player1,player2, this);
grid.x = 50 + grid.width + 100 * px +10;
grid.y = 50 + grid.height +100 * py + 10;
this.addChild(grid);
}
}
}
and they are detected with this function(don't laugh i'm pretty noob):
public function checkDotCollision(player)
{
if(player1.hitTestObject(grid) == true)
{
trace("player dot collision detected");
}
if(player2.hitTestObject(grid) == true)
{
trace("player dot collision detected");
}
}
currently only the left most bottom square of the grid is detecting the player. Any help / advice on how to implement this feature would be greatly appreciated.
I'm not going to provide you with code, just with an idea.
In your Player class (if you don't have one, you can get away with the dynamic properties of a movieclip but it's not very clean), add a lastTouchedGriDot of type griDot.
In checkDotCollision, check for each tile. You can't do this at the moment; looks like you'll have to maintain a collection for griDots somewhere. So alter createGrid() to store the created objects in a collection of sorts. Then we can check for each tile. So do so. If you've found a hit, do the following:
If there is no last touched grid point, set the last touched grid point to the one you're touching now.
If the grid point that was last touched is the same as the one you're touching now, do nothing.
If the grid point that was last touched is different than the one you're touching now, check if it's adjacent. If so, build a wall. If not, set the last touched grid point to the one you're touching now.
This should provide you with a solid start. You'll have to add wall collisions and checking if there already IS a wall yourself.

Smooth/Accurate Kinect movement in AS3 game

For a project I need to make a flashgame with the Kinect for Xbox.
Using the AS3NUI library to get acces to most of the Kinect functions worked well for me.
It's a pong game where you have to move your paddle vertically through hand movement.
I've tried a few ways of moving the paddle, but none of them is really accurate. And if they are more accurate, they aren't smooth at all anymore.
My first methode was setting the paddle.y to the value of the hand.y.
_paddleLeft.y = (userLeft.leftHand.position.y);
Of course the result was terrible.
This was my next try:
_paddleLeft.y = (userLeft.leftHand.position.rgbRelative.y * stage.stageHeight*2);
This was pretty accurate, but not smooth at all, and sometimes it was very hard to reach the top of the stage, or the bottom.
At last, I tried something else. I saved the hands last Y position, and checked if the new position was higher or lower, and on that I moved the paddle up or down.
currYLeft = userLeft.leftHand.position.rgb.y;
currYRight = userRight.rightHand.position.rgb.y;
if (currYLeft > prevYLeft + 10){
isDown1 = true;
isUp1 = false;
}else if( currYLeft < prevYLeft - 10){
isDown1 = false;
isUp1 = true;
}
prevYLeft = userLeft.leftHand.position.rgb.y;
prevYRight = userRight.rightHand.position.rgb.y;
In another enterframehandler, I make them move up or down.
This is the most smooth way I achieved, but it isn't very accurate anymore. There is some kind of delay wich you don't have with the first two ways.
I would like to know if it is possible to make the movement smooth AND accurate at the same time? And how this is possible.
If you already have an accurate solution, May be you can try putting some easing in it for the smoothness. You might wanna try using this instead in the enterFrame loop
_paddleLeft.y +=
((userLeft.leftHand.position.rgbRelative.y * stage.stageHeight*2)
-_paddleLeft.y)*0.3;
0.3 can be altered to other numbers between 0 and 1, depending on the easing speed you want...That's my best guess, hope this helps ^^

AS3 - can't scrub through FLV using netstream.seek() after FLV finishes loading

I'm trying to play an FLV using the Netstream class - standard stuff, really using nothing more complex than things you can find in the help files. I've created a control panel with a bar you can use to click and drag and scrub through the video.
Exporting to Flash Player 9, it's working fine and I can scrub through the video, but only while the FLV is still loading. As soon as it hits 100% the scrubbing (using Netstream.seek()) becomes incredibly unresponsive, almost to the point of crashing the player.
I've killed all ENTER_FRAMES, removed all unnecessary listeners and nullified everything I can think of but something massively resource-intensive seems to be kicking in as soon as the load finishes.
Has anyone ever seen this? I've never come across this and can't find anything similar across assorted forums.
Code below but I don't think the mouse-move drag actions are the problem! Fine in the Flash CS4 IDE, broken in the browser.
Thanks for any help you might be able to provide,
Gareth
// Drag
private function dragVideo(e:MouseEvent):void {
// Match the x position of the dragger to the x position of the mouse
videoControls.progressBar.dragger.x = videoControls.progressBar.barInner.mouseX;
// If this results in the dragger moving outside the dragging area, constrain it
if (videoControls.progressBar.dragger.x < videoProgressRectangle.left) {
videoControls.progressBar.dragger.x = videoProgressRectangle.left;
} else if (videoControls.progressBar.dragger.x > videoProgressRectangle.right) {
videoControls.progressBar.dragger.x = videoProgressRectangle.right;
}
// As the dragger moves, work out its position as a percentage of the total distance it CAN move
// That distance is the width of the black inner bar but you must also accomodate the centred registration point of the dragger
// So knock off half the dragger's width from it's current position (which gives the left edge of the inner bar)
// Then knock off the dragger's width minus the 2px overhang of the white progress bar border, from the total draggable distance
videoSeekPercentageMouse = (videoControls.progressBar.dragger.x - (videoControls.progressBar.dragger.width / 2)) / (videoControls.progressBar.barInner.width - (videoControls.progressBar.dragger.width - 2));
// Now use that percentage to seek the video to the equivalent percentage of its total time
if (videoSeekPercentageMouse <= 0) {
videoNetStream.seek(0);
} else if (videoSeekPercentageMouse >= 1) {
// Because video metaData says the length is xyz while the real length is xyz + 0.015,
// seek to slightly before the end
videoNetStream.seek(videoDuration - 0.016);
} else {
videoNetStream.seek(videoDuration * videoSeekPercentageMouse);
}
// Show the video's current progress
videoControls.progressBar.barProgress.scaleX = videoSeekPercentageMouse;
// After the mouse moves update the display
e.updateAfterEvent();
}
Got it!
You should try this..
Pause the streaming "before" seeking..
Seek()
And then resume the streaming!