Making a teeter totter/ chopping motion in Flash AS3 with away 3D - actionscript-3

I am trying to make a choppping motion based on the accelerometer of my tablet and showing it using away3D box. Essentially what I want to do it every time the user shakes the device on accelerationY the box moves up and then right away moves back down. Think of a knife chopping motion. Right now I have the following code but it seems to cancel itself out and just remain in the same place. Any help would be much appreciated!
protected function onAccUpdate(event:AccelerometerEvent):void{
var threshold:Number = 1.5;
if(event.accelerationY > threshold){
targetY = event.accelerationY *10;
knife.y += targetY;
trace(knife.y);
if (knife.y >0){
knife.y -= targetY;
trace(knife.y);
}

In the execution order of your function, as soon as you set knife.y += targetY; the if (knife.y >0) returns true and sets knife.y back to the original position. Therefore the knife looks like it never moved.
You should use an onEnterFrame update function to ease the knife towards the target position. Then in your onAccUpdate function if the knife needs to move set targetY to the new position. In your update function, as soon as the knife has reached the new position set targetY to 0 and animate the knife back.
Here's an example of onEnterFrame code:
var diff:Number = targetY - knife.y;
knife.y += diff * 0.05; // 0.05 is to ease/smooth the animation
if( Math.abs( diff ) <= 1 ) targetY = 0; // we reached the target position, now go back to 0

Related

collision as3 dectect

hi im trying to make a basic game on adobe flash as3 to help learn collision dection, the aim is to make your way through traffic. the player (box_MC) has to make it to the other side and the other objects are in the way (cycle) which have collision detection. i did the collision detection by going into cycle movieclip and making other smaller cycles which if you hit creates collision.
the collision error lies with if the player moves down onto the cycle it doesnt run the collision
p.s if there is a better way of doing the collision how is it done?
hitTestObject() and hitTestPoint() aren't very good when it comes to collision detection, which is somewhat ironic since, of course, those are the first things most people look at when trying to implement collisions. However, I've found that simple math (like, really simple) combined with an equally simple while() loop is the best way to go about it.
What I do is:
// the stage collision box
var mStageRect:Rectangle = new Rectangle(/*stage collision box properties here*/);
// create a Point object that holds the location of the bottom center of the player
var mPlayerBase:Point = new Point(player.x + (player.width / 2), player.y + player.height);
// call this function every frame through your game loop (onEnterFrame)
private function checkCollision(e:Event):void
{
// while the player's bottom center point is inside of the stage...
while (rectContainsPoint(mStageRect, mPlayerBase))
{
// decrement the player's y
player.y--;
// set gravity to 0
player.gravity = 0;
// set isOnGround to true
player.isOnGround = true;
}
}
// checks if a point is currently positioned within the bounds of a rectangle object using ultra simple math
private function rectContainsPoint(rect:Rectangle, point:Point):Boolean
{
return point.x > rect.x && point.x < rect.x + rect.width && point.y > rect.y && point.y < rect.y + rect.height;
}
This is waaaaaaay more efficient than hitTestObject/Point, imo, and has given me no problems.

ActionScript 3 stage width

Im doing my first flash AS game, so need a little help.
I have only 1 thing on the stage, its ball (layer instance) which has anchor point in the middle. I'm trying to make this ball bounce off walls (i mean screen).
This instance name is called 'kugla1'
Heres my code (its second frame):
if(kugla1.x<=kugla1.width/2 || kugla1.x>=stage.stageWidth-kugla1.width/2)
speedX=-speedX;
if(kugla1.y<=kugla1.height/2 || kugla1.height>=stage.stageHeight-kugla1.height/2)
speedY=-speedY;
kugla1.x+=speedX;
kugla1.y+=speedY;
First frame is:
var speedX:int=5;
var speedY:int=5;
kugla1.x=100;
kugla1.y=100;
And third frame is only:
gotoAndPlay(2);
what am I doing wrong?
Thanks!
Your problem, is likely this line:
if(kugla1.y<=kugla1.height/2 || kugla1.height>=stage.stageHeight-kugla1.height/2)
In the second part (after the ||) you are comparing the height of kugla1 instead of the y position.
Another issue you could run into, is your ball could potentially meet the same condition for longer than one frame, so it would be best to separate your speed from the current direction of movement.
See code comments:
On your first frame, you'll need two additional variables:
var speedX:int=5;
var speedY:int=5;
var curSpeedX:Number = speedX;
var curSpeedY:Number = speedY;
on your second frame:
if(kugla1.x <= kugla1.width/2){
curSpeedX = speedX; //we need the positive value to make it go right
}
if(kugla1.x >= stage.stageWidth - kugla1.width/2){
curSpeedX = -speedX; //we need the negative value to make it go left
}
if(kugla1.y <= kugla1.height/2){
curSpeedY = speedY; //we need the positive value to make it go down
}
if(kugla1.y >= stage.stageHeight - kugla1.height/2){
curSpeedY = -speedY; //we need the negative value to make it go up
}
kugla1.x+= curSpeedX;
kugla1.y+= curSpeedY;

startdrag start point limitations?

I have a slider that controls a movie clip by dragging it through the frames to animate and this works great when dragging from left to right, But i want the slider to start in the middle and drag through the movie clip from a center point being able to go 350 to the right and 350 to the left.
Is this possible?
Heres my code so far and as you can see it drags 350 to the right through dialSpin_mc.
Is there a way to make the slider start at a certain frame and go backwards and forwards?
dialSpin_mc.stop();
slider_mc.knob_mc.buttonMode = true;
slider_mc.knob_mc.addEventListener(MouseEvent.MOUSE_DOWN, onDragKnob);
stage.addEventListener(MouseEvent.MOUSE_UP, onReleaseKnob)
slider_mc.knob_mc.buttonMode = true;
function onDragKnob(myEvent:Event):void
{
slider_mc.knob_mc.startDrag(false, new Rectangle(0,0,350,0));
slider_mc.knob_mc.addEventListener(Event.ENTER_FRAME, onScrubMovie);
}
function onReleaseKnob(myEvent:Event):void
{
slider_mc.knob_mc.stopDrag();
slider_mc.knob_mc.removeEventListener(Event.ENTER_FRAME, onScrubMovie);
}
function onScrubMovie(myEvent:Event):void {
var playHead:int=Math.round((slider_mc.knob_mc.x/350*8)+1);
dialSpin_mc.gotoAndStop(playHead);
}
As discussed in comments this is how you could code the slider functionality without using the startDrag() and stopDrag() functions.
The idea is that when you press the mouse button down over the slider, an ENTER_FRAME listener is created. Every frame the sliders X position will be updated to match the mouseX position, and to make sure it can only travel 175 pixels either way we also check the sliders new position.
After making sure the sliders position is valid, you can use the same code to set the dialSpin_mc frame.
Once the mouse button is released, the enter frame listener is removed.
The sliderOrigin declared at the top of the code will need to be changed to whatever is appropriate for your project (whatever the sliders xposition is when you move it to the middle of the slide area rather than the very left).
var sliderOrigin:int = 150; // The x position the slider is in when in the center of the slide bar
slider_mc.x = sliderOrigin;
slider_mc.addEventListener(MouseEvent.MOUSE_DOWN, mDown);
slider_mc.addEventListener(MouseEvent.MOUSE_UP, mUp);
function mDown(e:MouseEvent):void
{
addEventListener(Event.ENTER_FRAME, UpdateDrag);
}
function mUp(e:MouseEvent):void
{
removeEventListener(Event.ENTER_FRAME, UpdateDrag);
}
function UpdateDrag(e:Event):void
{
slider_mc.x = mouseX;
// Check if the slider is 'out of bounds' and change its position if it is
if(slider_mc.x < sliderOrigin - 175)
slider_mc.x = sliderOrigin - 175;
else if(slider_mc.x > sliderOrigin + 175)
slider_mc.x = sliderOrigin + 175
var playHead:int = Math.round((slider_mc.x/350*8)+1);
dialSpin_mc.gotoAndStop(playHead);
}
Depending on the start position of the slider the range of playHead will change (so if the slider starts at x pos 200 the range would be between 2 and 10, at x pos 400 the range is between 6 and 14 - simple fix by changing the offset from +1 to whatever is necassary).

AS 3 simple ease

How can I move an object and be able to physically see it when it is moving? Not just disappear and appear on a different location like it would be using the following code.
buttonL2_btn.addEventListener(MouseEvent.CLICK, left);
function left(event:Event):void{
box_mc.x =241.5;
}
This is going to move myObject to any location specified, but again I want to be able to see it when moving.
In your example you are just setting it's X position when some button is pressed, when you need to change X into an EnterFrame event, like this:
this.addEventListener(Event.ENTER_FRAME, move);
function move(event:Event):void{
box_mc.x -= 5
}
Your box_mc should move left 5 pixels accordingly with your framerate.
You can use a easing library to that easily. I strongly recommend TweenMax.
Okay I am getting a bit sick of people constantly suggesting some tweening engine. Sure they rock, but it won't help the OP to understand what he is doing.
Kircho to move an object with a really easy tween I suggest the following code in an onEnterFrame event for your object to move:
addEventListener(Event.ENTER_FRAME, onEnterFrame);
var xGoal:Number = 100; //:: The target X destination for your object
var yGoal:Number = 100; //:: The target Y destination for your object
var smothness:Number = 10; //:: Smoothness factor for movement. The lower the value the faster the movement.
function onEnterFrame(e:Event):void
{
box_mc.x += (xGoal - box_mc.x) / smothness;
box_mc.y += (yGoal - box_mc.y) / smothness;
}
Will move/ease your box object to the desired location with a set smoothness.
You can install any of the 437 available tweening engines
or you can add a few lines of code
set up a variable that holds the destination value
var dest:Number = 241.5; // this is what gets updated on mouse click
on enterframe event for box:
function onBoxEnterFrame(e:MouseEvent):void{
if (dest != box_mc.x){
var easeNum:Number = 0.4 // between 0 and 1, the higher the number, the slower the transition
box_mc.x = box_mc.x * easeNum + dest * (1-easeNum);
}
}
you can add a few more lines to snap the position when it is close (less than 0.1 difference) or use a more linear change where you adjust incrementally like box_mc.x += 5; until it matches the dest number

Problem rotating image with MOUSE_MOVE

Hey gang. Stumped on something.
I have a disc I am rotating with the mouse with event.MOUSE_MOVE, like a jog wheel on some audio equipment. Everything almost works as expected, but the problem I am experiencing is that the disc always jumps to the point where the user clicks on the disc. I need the point on the disc that the user clicks on to remain under the mouse while the user spins the disc but I can't seem to come up with the correct math to make it happen. Here's the code i am using:
var xd = (_knob.x - _stageRef.stage.mouseX);
var yd = (_knob.y - _stageRef.stage.mouseY);
var radAngle = Math.atan2(yd, xd);
_knob.rotation = int(radAngle * 360/(Math.PI * 2) - 90);
_knob is a vector circle wrapped in a movieclip, with the circle centered on the movieclip's reg point. _stageRef represents the main stage.
Any help would be awesome. I've scoured the interweb and can't come up with anything.
Thx!
You are setting _knob rotation to the angle between _knob and mouse cursor. So if rotation was 0, and angle 45, rotation becomes 45, therefore it jumps. What you need is measure changes in this angle, not setting it instantly:
var _mouseAngle:Number;
function getMouseAngle():Number
{
var xd = (_knob.x - _stageRef.stage.mouseX);
var yd = (_knob.y - _stageRef.stage.mouseY);
return Math.atan2(yd, xd);
}
function onMouseDown(event:MouseEvent):void
{
_mouseAngle = getMouseAngle();
}
function onMouseMove(event:MouseEvent):void
{
var newAngle:Number = getMouseAngle();
_knob.rotation += (newAngle - _mouseAngle) * 180.0 / Math.PI; //EDIT: forgot to convert into degrees
_mouseAngle = newAngle;
}
(Code not tested)