ActionScript 3.0 Slider doesn't continue when sliding to start - actionscript-3

I made a slider to search trough my actionscript video.
Maybe you'll understand better if you can see what i'm working on:
http://www.stevevo.sin.khk.be/Website%202SDesign/ -> this is the link of the testserver where the website i'm building is running on. You'll see the huge banner in the center, rollover it an you'll see a slider and a pause/start button.
The slider works great exept for 1 little thing. When you drag the slider to the utter left actionScript 3.0 will start the movie again (i asume), now drag to the right without interuptions and the slider won't move to the right as he should (all in one drag).
Why ain't it possible to first slide to the start and then continue sliding?
MY CODE:
very simple. You start dragging, the rectangle is the dragRestriction. The Movie stops. isDragging = true.
SearchBarSlider.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void
{
var rect:Rectangle = new Rectangle(SearchBar.x + 3,
SearchBar.y,
SearchBar.width - 10,
0);
SearchBarSlider.startDrag(false, rect);
stop();
isDraging = true;
}
Again easy peasy. Drag stops. Movie starts to play again. isdragging = false;
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void
{
SearchBarSlider.stopDrag();
play();
isDraging = false;
}
When the mouse moves when dragging the x-position of the slider will be converted to the right amount of frames. In between the 3 parts other lengths aply.
stage.addEventListener(MouseEvent.MOUSE_MOVE, fl_Drag);
function fl_Drag(event:MouseEvent):void
{
if(isDraging == true) {
if(SearchBarSlider.x - (SearchBar.x + 3) < 20){
gotoAndStop(Math.round(((SearchBarSlider.x - (SearchBar.x + 3)) / 20) * 320));
} else if(SearchBarSlider.x - SearchBar.x + 3 >= 20 && SearchBarSlider.x - SearchBar.x + 3 < 40){
gotoAndStop(Math.round(((SearchBarSlider.x - (SearchBar.x + 3) - 20) / 20) * 365) + 365);
} else {
gotoAndStop(Math.round(((SearchBarSlider.x - (SearchBar.x + 3) - 40) / 20) * 465) + 685);
}
}
}
This event accurs at every frame when not dragging. But instead of converting the x-position of the slider to frames this will convert frames to x-positon of the slider.
stage.addEventListener(Event.ENTER_FRAME, fl_frameEvent);
function fl_frameEvent(e:Event):void
{
if(isDraging == false) {
if(currentFrame < 365){
SearchBarSlider.x = SearchBar.x + 3 + Math.round((currentFrame / 365) * 20);
} else if(currentFrame >= 365 && currentFrame < 685){
SearchBarSlider.x = SearchBar.x + 23 + Math.round(((currentFrame - 365) / 320) * 20);
} else {
SearchBarSlider.x = SearchBar.x + 43 + Math.round(((currentFrame - 685) / 465) * 20);
}
}
}

Does the second function really not occur when dragging? Do you remove it, or is it running at the same time? I think your enter_frame function and your mouse_move function are fighting each other. in your drag function add this:
stage.removeEventListener(Event.ENTER_FRAME, fl_frameEvent);
and in your drop function add this:
stage.addEventListener(Event.ENTER_FRAME, fl_frameEvent);
Another workaround, I noticed if you zoom way way in on the slider, if you come 99.9% of the way left, but don't quite line it up, it works as expected, so you could just adjust your draggable rectangle to leave just a tiny space on the left side.
SearchBar.x + 4

I actually fixed my own problem here's the solution.
stage.addEventListener(MouseEvent.MOUSE_MOVE, fl_Drag);
function fl_Drag(event:MouseEvent):void
{
if(isDraging == true) {
if(SearchBarSlider.x - (SearchBar.x + 3) < 1){
} else if(SearchBarSlider.x - (SearchBar.x + 3) < 20){
gotoAndStop(Math.round(((SearchBarSlider.x - (SearchBar.x + 3)) / 20) * 320));
} else if(SearchBarSlider.x - SearchBar.x + 3 >= 20 && SearchBarSlider.x - SearchBar.x + 3 < 40){
gotoAndStop(Math.round(((SearchBarSlider.x - (SearchBar.x + 3) - 20) / 20) * 365) + 365);
} else {
gotoAndStop(Math.round(((SearchBarSlider.x - (SearchBar.x + 3) - 40) / 20) * 465) + 685);
}
}
}
The problem was that when the gotoAndStop event accured at frame 1 the whole program restarted because at frame 1 the actions layer reinitiates the code. So the drag that was busy got ended. With the new piece of code the searchbar won't execute gotoAndStop(1);

Related

Object still moving even when the number of move is 0

I have an object called player and a virtual joystick controller called joystick and it contains its knob called knob and I've placed the joystick and the knob in a different movieclip.
I use a script to move the player as the amount of movement of the knob.
Here's the code :
function enterFrame(e:Event): void {
if (moving) {
// I move the knob as the touch point moves
// and the player as the knob moves
} else {
// I'm trying to slow down the knob movement to get back to its default position
// and slow down the player movement until it stopped
if (knob.x - joystick.x > 0) {
knob.x -= (knob.x - joystick.x)*.5;
player.x -= -(knob.x - joystick.x)*.9;
}
if (knob.x - joystick.x < 0) {
knob.x += -((knob.x - joystick.x)*.5);
player.x += (knob.x - joystick.x)*.9;
}
if (knob.y - joystick.y > 0) {
knob.y -= (knob.y - joystick.y)*.5;
player.y -= -((knob.y - joystick.y)*.9);
}
if (knob.y - joystick.y < 0) {
knob.y += -((knob.y - joystick.y)*.5);
player.y += (knob.y - joystick.y)*.9;
}
// Then I use trace to trace the player x position
trace(player.x);
}
}
And what I got is when I move the knob to left position and touch_end it, the slow down works but the player keep moving left by .01. But when I move the knob to another directions and touch_end it, the slow down works well until the player stopped.
Why could that happens?
Is there a way I can fix this?
This looks like a floating-point precision effect. If you start with knob.x at 1 and joystick.x at 0.5, you'll get:
knob.x joystick.x knob-joystick knob-joystick/2
1 0.5 0.5 0.25
0.75 0.5 0.25 0.125
0.625 0.5 0.125 0.0625
0.5625 0.5 0.0625 0.03125
0.53125 0.5 0.03125 0.015625
0.515625 0.5 0.015625 0.0078125
It's clearly trending towards zero, but there's a small remaining positive value when you calculate knob.x-joystick.x.
Note: Since your if statement that changes knob.x is in an EnterFrame listener, any joystick changes in response to user input will take longer than this to occur.
Instead of checking that your difference is > 0, check that it's greater than some small guard value, e.g.
if (knob.x - joystick.x > 0.01) {
knob.x -= (knob.x - joystick.x)*.5;
player.x -= -(knob.x - joystick.x)*.9;
}
//etc.
You might also add some guard code at the end of your listener:
if (knob.x > 0 && knob.x < 0.01) {
knob.x = 0;
}
//etc.
Well, after working around it, finally I did it!
I use Math.floor "trick" to force the -0.0249999999999828 (the last position when moving to left which make the player keep moving left even when I'm not control it anymore) to be change to 0.
Here's the code :
function enterFrame(e:Event): void {
.... // bla bla bla
} else {
if (knob.x > joystick.x) {
knob.x -= (knob.x - joystick.x)*.5;
player.x -= -((knob.x - joystick.x)*.9);
}
if (knob.x < joystick.x) {
knob.x += -(Math.floor((knob.x - joystick.x)*.5));
player.x += Math.floor((knob.x - joystick.x)*.9);
}
if (knob.y > joystick.y) {
knob.y -= (knob.y - joystick.y)*.5;
player.y -= -((knob.y - joystick.y)*.9);
}
if (knob.y < joystick.y) {
knob.y += -(Math.floor((knob.y - joystick.y)*.5));
player.y += Math.floor((knob.y - joystick.y)*.9);
}
}
}
I changed the if (knob.x - joystick.x > 0) (and all of kind of this) to if (knob.x > joystick.x) I think it's more efficient to detect where the knob is (right, left, up, down).
Or maybe you guys can find another way more efficient and more exact? It would help me

Problems with a simple physics system in AS3

Well, first of all, I'm a student, so I really beg to you to be patient in the answer. I'm not a english speaker too, by the way.
Everything begins because I'll attend a Game Jam and I already started to write (or trying to write) a simple "physics" code, who I really was thinking would be easy.
I was working with classes and using hitTestObject for colision detection.
Actually I was having issues since the begin, but I was constantly trying to fix it. At this time the code really sucks and I'm already thinking in another way to do it. But something puzzles me.
Here's a part of the the code who I'd already written (It probably seems very newbie). Most part of the code is bullshit, just take a look in the last "else if".
Note: this is the "block" class, and the "obj" it's the Movie Clip of the player.
public function checkObj(obj:MovieClip):void
{
if (this.hitTestObject (obj))
{
if (this.y < obj.y)
{
if (this.x - this.width/2 <= obj.x+obj.width/2 && this.x + this.width/2 >= obj.x-obj.width/2)
{
downCol = true;
}
}
else if (this.y + this.height/2 > obj.y-obj.height/2)
{
if (this.x - this.width/2+2 <= obj.x+obj.width/2 && this.x + this.width/2-2 >= obj.x-obj.width/2)
{
upCol = true;
onBox = true;
}
}
if (this.x - this.width/2 >= obj.x+obj.width/2-2)
{
if (this.y - this.height/2<= obj.y+obj.height/2&& this.y + this.height/2>= obj.y-obj.height/2)
{
leftCol = true;
}
}
else if (this.x + this.width/2 <= obj.x-obj.width/2-2)
{
if (this.y + 5>= obj.y-obj.height/2 && this.y - 5<= obj.y+obj.height/2)
{
trace ("Collided on right");
rightCol = true;
}
}
}
}
For some reason, this way it doesn't work. It never returns me the message.
But if I do a little change:
public function checkObj(obj:MovieClip):void
{
if (this.x + this.width/2 <= obj.x-obj.width/2-2)
{
objOnRight = true;
}
if (this.hitTestObject (obj))
{
//...
else if (objOnRight == true)
{
if (this.y + 5>= obj.y-obj.height/2 && this.y - 5<= obj.y+obj.height/2)
{
rightCol = true;
trace ("Collided on right");
}
}
}
}
It works. Just because I checked the X axis of "obj " before testing the collision. I know this code it's bad at all, but if someone could help me to understand that error and maybe guide me to a more efficient solution I'll really appreciate it! Thank you.
Try this for the last else if
else if (this.x + this.width / 2 <= obj.x + obj.width / 2 - 2) {
if (this.y + 5 >= obj.y - obj.height / 2 && this.y - 5 <= obj.y + obj.height / 2) {
trace("Collided on right");
rightCol = true;
}
}
just change the "-" to "+" .
Ok, forget it. I wrote a brand new code, without hitTest, and it works like a charm. I think the Math.abs solved the problem with negative numbers.
Thanks for your help, kare81.
Here's the code:
public function checkObj(obj:MovieClip,place:int):void
{
if (obj.x + obj.width / 2 > this.x - width / 2 && obj.x < this.x - width / 2 + 7 && Math.abs (obj.y - y) < height / 2)
{
obj.x = this.x - width / 2 - obj.width / 2;
}
if (obj.x - obj.width / 2 < this.x +width / 2 && obj.x > this.x + width / 2 - 7 && Math.abs (obj.y - y) < height / 2)
{
obj.x = this.x +width / 2 + obj.width / 2;
}
if (Math.abs (obj.x- this.x) < width / 2 + obj.width / 2 && obj.y<y-height/2 && obj.onFloor > y-height/2 && obj.onBlock != place)
{
obj.onFloor = y - height / 2;
obj.onBlock = place;
}
if (Math.abs (obj.x - this.x) >= width / 2 + obj.width / 2 && obj.onBlock == place)
{
obj.onFloor = 450;
}
if (obj.y - obj.height / 2 < y + height /2 && obj.y > y && Math.abs (obj.x - this.x) < width / 2 + obj.width / 2)
{
obj.y = y + height / 2 + obj.height / 2;
}
}

ActionScript 3.0 - Variable sharing, across two movieclips. COMPLEX

I have a really interesting problem, associated with the animation of my main character in the development of my mobile game.
I have one movieclip, of my players arm/attackArm, attached to a moving animation of his body [on frame 1 of HERO]
I also have another movieclip of an arm/attackArm, attached to his jumping and falling movieclips [on frame 2 + 3 of HERO]
I need cross-communication between the two, through a variable or variables of THROWframe / CurrentThrowFrame. To be able to fix a certain bug.
The bug is that, when i throw the spear, and jump (mid throw animation) he continues where he left off in the throwing animation. HOWEVER,,,
When I jump, then throw [regardless of if hes on Frame 2 or 3, falling or proceeding upward, because both share the same ARM] ;;; upon hitting the ground, his throw animation resets back to frame 0, regardless if he was in mid throw whilst in the air.
Can anyone help? This is very specific, I Know.
Any and all Help welcome.
Here is a smidgen of code.
// PLAYER : SHOOT (OVERALL)
public function playerShoot(m:MouseEvent):void
{
//Running Shoot
///////////////
if (JungleBob.player.currentFrame == 1 && JungleBob.player.runBody.runBody2.playerWeaponArm.currentFrame == 1)
{
var angle_in_radF1:Number = Math.atan2(mouseY - (JungleBob.player.y + JungleBob.player.runBody.runBody2.playerWeaponArm.y - (36)), mouseX - (JungleBob.player.x + JungleBob.player.runBody.runBody2.playerWeaponArm.x + (32)));
var heroBullet_mcF1:MovieClip = new projectile_spear();
Heros_Bullets_Array.push(heroBullet_mcF1);
heroBullet_mcF1.x = (JungleBob.player.x + (JungleBob.player.runBody.runBody2.playerWeaponArm.x) + (32));
heroBullet_mcF1.y = (JungleBob.player.y + (JungleBob.player.runBody.runBody2.playerWeaponArm.y) - (36));
heroBullet_mcF1.rotation = angle_in_radF1 * 180/Math.PI;
JungleBob.player.runBody.runBody2.playerWeaponArm.rotation = angle_in_radF1 * 180/Math.PI + (10);
addChild(heroBullet_mcF1);
JungleBob.mainClass.randomThrowSoundTraffic();
JungleBob.player.runBody.runBody2.playerWeaponArm.gotoAndPlay(2);
(new Tween(JungleBob.Vcamera,'x',Strong.easeOut,630,625,0.5,true));
}
//Jumping and Falling Shoot
///////////////////////////
if (JungleBob.player.currentFrame >= 2 && JungleBob.player.playerWeaponArm.currentFrame == 1)
{
var angle_in_rad:Number = Math.atan2(mouseY - (JungleBob.player.y + JungleBob.player.playerWeaponArm.y - (36)), mouseX - (JungleBob.player.x + JungleBob.player.playerWeaponArm.x + (32)));
var heroBullet_mc:MovieClip = new projectile_spear();
Heros_Bullets_Array.push(heroBullet_mc);
heroBullet_mc.x = (JungleBob.player.x + (JungleBob.player.playerWeaponArm.x) + (32));
heroBullet_mc.y = (JungleBob.player.y + (JungleBob.player.playerWeaponArm.y) - (36));
heroBullet_mc.rotation = angle_in_rad * 180/Math.PI;
JungleBob.player.playerWeaponArm.rotation = angle_in_rad * 180/Math.PI + (10);
addChild(heroBullet_mc);
JungleBob.mainClass.randomThrowSoundTraffic();
JungleBob.player.playerWeaponArm.gotoAndPlay(2);
(new Tween(JungleBob.Vcamera,'x',Strong.easeOut,630,625,0.5,true));
}
}
// PLAYER : SHOOT (LISTENERS)
//
//Other Throw Frame Listener
public function otherListener(e:Event):void
{
if ((hero_mc.canJump == true) && ThrowFrame == 0)
{
stage.addEventListener(Event.ENTER_FRAME, throwFrameListener);
}
}
//Throw Frame Listener
public function throwFrameListener (e:Event):void
{
if (JungleBob.player.currentFrame == 1)
{
ThrowFrame = JungleBob.player.runBody.runBody2.playerWeaponArm.currentFrame;
}
if ( (JungleBob.player.currentFrame >= 2) && (ThrowFrame >= 2) && (hero_mc.yVelocity <= 0) )
{
JungleBob.player.playerWeaponArm.gotoAndPlay(ThrowFrame);
stage.removeEventListener(Event.ENTER_FRAME, throwFrameListener);
}
}
BEST OF LUCK
&&
THANKS IN ADVANCE

Breakout with Flash: I need help to improve my Brick n Ball collision

I've been stuck on this problem for a very long time now, I've searched around alot and tried stuff, but nothing works. Some explanations are just very hard for me to understand as Im pretty new to programming overall and got alot to learn.
I have two problems
1: The ball wont collide with the bricks sometimes when the speed is too fast.
2: The ball is capable of hitting 2 bricks.
Both problems is related to the fact that 60 fps isnt enough for my type of collision detection to work properly.
I just need someone to explain in a simple way as possible what I need to do to make a collision detection that will prevent this from happen.
Here's my current collision code:
private function checkCollision(): void {
grdx = Math.floor((ball.x) / 28);
grdy = Math.floor((ball.y) / 14);
ngrdx = Math.floor((ball.x + dx) / 28);
ngrdy = Math.floor((ball.y + dy) / 14);
var flipX: Boolean = false;
var flipY: Boolean = false;
if ((grdy <= level.length - 1) &&
(ngrdy <= level.length - 1) &&
(grdy >= 0 && ngrdy >= 0)) {
if (testBlock(grdx, ngrdy)) {
flipY = true;
paddleFlag = 1;
}
if (testBlock(ngrdx, grdy)) {
flipX = true;
paddleFlag = 1;
}
if (testBlock(ngrdx, ngrdy)) {
flipX = true;
flipY = true;
paddleFlag = 1;
}
dx *= flipX ? -1 : 1;
dy *= flipY ? -1 : 1;
}
}
private function testBlock(xPos: int, yPos: int): Boolean {
if (level[yPos][xPos] > 0 && level[yPos][xPos] != 13) {
trace("hit on X,Y");
level[yPos][xPos] = 0;
breakBlock("Block_" + yPos + "_" + xPos);
trace("Block: " + totalBreaks + " / " + totalBlocks);
return true;
}
return false;
}
private function breakBlock(blockName: String): void {
if (this.getChildByName(blockName)) {
this.removeChild(this.getChildByName(blockName));
totalBreaks++;
}
}
Thank you and sorry for my bad english, its not my motherlanguage.
One solution is to move the ball in smaller iterations, multiple times in a given frame.
For example, and I am giving this solution assuming that you are moving the ball based on the time elapsed from the last frame.
Suppose that 30 milliseconds have elapsed since the last frame update. In that case you would update the movement/collision twice in that frame using 15 millisecond as your time elapsed.
The higher resolution of collision you want, the more iterations you would do.
Here's an example :
// class declarations
var lastFrame:Number;
var iterationsPerFrame:int;
function startGame():void
{
// lets specify 3 updates per frame
iterationsPerFrame = 3;
// save initial time
lastFrame = getTimer();
// create your listener
addEventListener(Event.ENTER_FRAME, update);
}
function update(e:Event):void
{
var currentFrame:Number = getTimer();
var deltaTime:Number = (currentFrame - lastFrame)/1000;
var iterationDelta:Number = deltaTime/iterationsPerFrame;
for (var index:int = 0;index < iterationsPerFrame;index++)
{
// I'm assuming dx,dy are the velocity of the ball, in pixels per second
ball.x += dx * iterationDelta;
ball.y += dy * iterationDelta;
// check collision
}
// set lastFrame to the currentFrame time, preparing for next frame
lastFrame = currentFrame;
// after this, your frame is going to render
}
You could work out how far the ball travels each frame (A) based on its speed, how far the ball is from the paddle (B) and if A > B manually trigger a collision that frame.
You're essentially checking every bricks X and Y coordinate to the balls X and Y coordinate, so if the bricks are stored in an array this becomes: Sqrt( Sqrd(p2.x - p1.x) + Sqrd(p2.y - p1.y))
for(var i=0; i<brickArray.length; i++)
{
var distance:Number = Math.sqrt((brickArray[i].x - ball.x) * (brickArray[i].x - ball.x) +
(brickArray[i].y - ball.y) * (brickArray[i].y - ball.y));
}
This is a very good tutorial on high speed collison detection:
http://www.newgrounds.com/bbs/topic/1072673

Mouse move panning

I'm trying to scroll a series of thumbnails horizontally based on the mouseX position. I can get it to scroll but it's very choppy and for some reason it's not reading my start and end numbers so it will stop scrolling. Can anyone point me in the right direction? Thanks.
var thumbBounds:Object = new Object();
thumbBounds = thumbContainer.getBounds(this);
thumbContainer.addEventListener(MouseEvent.MOUSE_OVER, setScrolling);
private function setScrolling(me:MouseEvent):void
{
thumbContainer.removeEventListener(MouseEvent.MOUSE_OVER, setScrolling);
stage.addEventListener(Event.ENTER_FRAME, scrollThumbs);
}
private function scrollThumbs(e:Event):void
{
if(mouseX <= thumbBounds.x || mouseX > thumbBounds.width ||
mouseX < thumbBounds.y || mouseX > thumbBounds.height)
{
thumbContainer.addEventListener(MouseEvent.MOUSE_OVER, setScrolling);
stage.removeEventListener(Event.ENTER_FRAME, scrollThumbs);
}
if(thumbContainer.x >= 0)
{
thumbContainer.x = 0;
}
if(thumbContainer.x <= -842)
{
thumbContainer.x = -842;
}
var xdist:Number = new Number();
xdist = mouseX - 382;
thumbContainer.x += Math.round(-xdist / 10);
}
One error I see immediately is:
if(mouseX <= thumbBounds.x || mouseX > thumbBounds.width ||
mouseX < thumbBounds.y || mouseX > thumbBounds.height)
Shouldn't you be checking the mouseY agains the thumbBounds.y and thumbBounds.height?
As for the choppyness, that could be related to the framerate of the movie, the size and the number of the images. It also depends on the magnitude of your xdist value. I'd try and use interpolation (tweening) some how. Calculate the end destination of the container and animate it towards there using Tweener or TweenLite.
e.g.
TweenLite.to(thumbContainer.x, 0.5, { x: thumbContainer.x + Math.round(-xdist / 10) });
This will cause the movement between the thumbcontainer current position and the new position will happen smoothly over half a second (instead of immediately).