Actionscript 3 object collision to prevent character overlapping - actionscript-3

Me and my friend are trying to make an rpg-style game where you see your character from above but we've run into some trouble with object collision. Might be worth mentioning we're doing this in an object oriented AS3 project in flash CS6.
I'm sorry if this has been asked a million times but we've been looking for solutions all day and what we've found so far has either been stuff that's a bit too advanced for us like box2d/nape or just plain collision detection which we know already.
The problem we have is that we want a convenient way to detect collision and prevent the main character from overlapping with objects in the scene, without having it freeze up or get stuck. So far we've scrapped all attempts at solving the issue but here's the rest of the code in case that helps you understand where we're at(sorry if it's difficult to read). Any kind of suggestions or referral to relevant tutorials is appreciated.
The main class
package {
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.Event;
public class Engine extends MovieClip
{
private var hero:Hero;
private var box1:Box1;
public function Engine()
{
box1 = new Box1();
stage.addChild(box1);
box1.x = stage.stageWidth / 4;
box1.y = stage.stageHeight / 2;
hero = new Hero(stage, box1);
stage.addChild(hero);
hero.x = stage.stageWidth / 2;
hero.y = stage.stageHeight / 2;
}
}
}
The character class
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
public class Hero extends MovieClip
{
private var box1:Box1;
private var stageRef:Stage;
private var vy:Number = 0;
private var vx:Number = 0;
private var limit:Number = 30;
private var rad:Number;
private var bounce:Number = 0.125;
private var _max:Number = 8;
public function Hero(stageRef:Stage, box1:Box1)
{
//box variable was used in previous experiments with hit tests
this.box1 = box1;
this.stageRef = stageRef;
Input.initialize(stageRef);
stageRef.addEventListener(Event.ENTER_FRAME, moveHero);
}
private function moveHero(e:Event):void
{
if (Input.kd("W","UP"))
{
vy = vy < 1 - _max ? _max * -1:vy - 1;
}
if (Input.kd("S","DOWN"))
{
vy = vy > _max - 1 ? _max:vy + 1;
}
else if (!Input.kd("W", "UP", "S", "DOWN"))
{
if (vy > 1)
{
vy = vy < 1 ? 0:vy - 1;
}
else
{
vy = vy > -1 ? 0:vy + 1;
}
}
if (Input.kd("A","LEFT"))
{
vx = vx < 1 - _max ? _max * -1:vx - 1;
}
if (Input.kd("D","RIGHT"))
{
vx = vx > _max - 1 ? _max:vx + 1;
}
else if (!Input.kd("A", "LEFT", "D", "RIGHT"))
{
if (vx > 1)
{
vx = vx < 1 ? 0:vx - 1;
}
else
{
vx = vx > -1 ? 0:vx + 1;
}
}
if (x < limit)
{
x = limit;
vx *= - bounce;
}
if (x > stage.stageWidth - limit)
{
x = stage.stageWidth - limit;
vx *= - bounce;
}
if (y < limit)
{
y = limit;
vy *= - bounce;
}
if (y > stage.stageHeight - limit)
{
y = stage.stageHeight - limit;
vy *= - bounce;
}
x += vx;
y += vy;
rad = (Math.atan2(stage.mouseY - y,stage.mouseX - x)) * 180 / Math.PI;
this.rotation = rad;
}
}
}

A simple way to do collision detection is:
1) Attempt to move the object X to its new position
2) For each other object in the game Y, compute if Y and X overlap (will use different algorithms for rectangle in circle, rectangle in rectangle, circle in circle, etc)
3) If they do overlap, go back to step 1 but attempt to move it half as far. ALTERNATIVELY: If the object you collided with was round, alter the angle of movement to go tangential to it while making it smaller according to how much you rotated it by (the cosine of the angle change, so 0x for 90 degree changes, (sqrt2/2)x for 45 degree changes and 1x for 0 degree changes, makes sense in my head.)
4) If your move was successful, keep it. If the movement length is growing incredibly small and is still being rejected, assume you are at rest and give up.
More complex algorithms would eject you away from the center of what you collided with, so you'll curve around curved objects by walking into them and so on, but then you have to be careful that the ejection doesn't collide you with a third object Z, and it can get tricky. (Have you considered using a physics library? They're coded for a good reason - physics is hard to get right.)

Related

How can I code an object to spawn onto the stage in the Actions panel?

I am trying to introduce a new ball into my pong game, sort of like a power up. I am writing all of my code in the Actions panel in the first frame. The new ball should appear on the stage and start moving around randomly like the original ball. Although I am using a code snippet and not .as file. So all of my code is in the Actions panel(Accessed by pressing f9).
I would also like my dynamic text box to merge with the stage colour so that you can't see the white background.
I can't show you what the fla looks like because I have less than 10 reputation, but the dynamic text box will not merge into the background and instead has a white surrounding. This hides the ball when the ball goes up.
import flash.events.Event;
import flash.ui.Mouse;
//hide mouse
Mouse.hide();
init(); //initialises everything
var bSpeedX:int = -3.5;
var bSpeedY:int = -2.5;
// assign a maximum speed to the AI
var compPaddleSpeed:int = 3.5;
var pScore:int = 0;
var cScore:int = 0;
// Updates the score
function scoreUpdate():void {
playerScore.text = ("Player Score: " + pScore);
computerScore.text = ("AI Score: " + cScore);
}
function init():void //tells flash not to return values
{
stage.addEventListener(Event.ENTER_FRAME, loop);
}
/*we want the ySpeed to be larger if there
is a greater difference between the y
positions of the ball and paddle, so I started with
(gameBallY-padY). To convert this difference
into a number between -1 and 1, I divided
this number by 25, which
is half the height of the paddle. Finally, I wanted
the ySpeed to be more powerful than
just -1 to 1, and after a bit of trial and error
I decided to times by 5 at the end
to change the total magnitude of the new ySpeed.*/
//defying the laws of Physics
function calculategameBallAngle(padY:Number, gameBallY:Number):Number
{
var ySpeed:Number = 5 * ((gameBallY-padY) / 25 );
return ySpeed;
}
//main loop
function loop(e:Event):void
{
//makes the paddle track the mouse
playerPaddle.y = mouseY;
//paddle AI
if(compPaddle.y < gameBall.y - 10){
compPaddle.y += compPaddleSpeed;//make it go up
} else if(compPaddle.y > gameBall.y + 10){
compPaddle.y -= compPaddleSpeed;//make it go down
}
//Collisions
if( playerPaddle.hitTestObject(gameBall) == true ){
if(bSpeedX < 0){
bSpeedX *= -1;
bSpeedY = calculategameBallAngle(playerPaddle.y, gameBall.y);
}
} else if(compPaddle.hitTestObject(gameBall) == true ){
if(bSpeedX > 0){
bSpeedX *= -1;
bSpeedY = calculategameBallAngle(compPaddle.y, gameBall.y);
}
}
//makes the gameBall move
gameBall.x += bSpeedX; //each frame, we add the bSpeedX to the ball's x position.
gameBall.y += bSpeedY; //same for the bSpeedY to the ball's y postion.
// checks to see if the ball misses the paddle
if(gameBall.x <= gameBall.width/2){
gameBall.x = gameBall.width/2;
bSpeedX *= -1;
cScore ++;
scoreUpdate();
//keeps the ball within the stage
} else if(gameBall.x >= stage.stageWidth-gameBall.width/2){
gameBall.x = stage.stageWidth-gameBall.width/2;
bSpeedX *= -1;
pScore ++;
scoreUpdate();
}
if(gameBall.y <= gameBall.height/2){
gameBall.y = gameBall.height/2;
bSpeedY *= -1;
}
else if(gameBall.y >= stage.stageHeight-gameBall.height/2){
gameBall.y = stage.stageHeight-gameBall.height/2;
bSpeedY *= -1;
}
//-------------------------------------------------------
//keeps the player paddle within the stage
//check if paddle is above top of the screen
if(playerPaddle.y - playerPaddle.height/2 < 0){
playerPaddle.y = playerPaddle.height/2;
} else if(playerPaddle.y + playerPaddle.hieght/2 > stage.stageHeight){
playerPaddle.y = stage.stageHeight - playerPaddle.height/2;
//check if paddle is below bottom of the screen
} else if(playerPaddle.y + playerPaddle.height/2 > stage.stageHeight){
playerPaddle.y = stage.stageHeight - playerPaddle.height/2;
}
}
If you only want your ball to be replaced with new one which has diffrent grphics and/or speed you can for example export your ball class to action script:
Library>RMB on your symbol>Properties>ActionScript Linkage>Export for ActionScript
Type your class name under Class: field like "MyBallClass" and hit OK.
Now you can construct this ball in your code and replace old one like this:
var newBall:MyBallClass = new MyBallClass();
addChild(newBall);
newBall.x = gameBall.x; newBall.y = gameBall.y;
gameBall = newBall;
Additionally you can define new variable like var speedModifier:Number = 1; to use with:
gameBall.x += bSpeedX * speedModifier;
gameBall.y += bSpeedY * speedModifier;
And change that also when you change the ball.
If You want to have multiple balls at same time You really should consider build this in OOP. For simplest example in addition to previous one
You can create MyBallClass.as file and write in it something like:
package
{
import flash.display.Sprite;
import flash.geom.Point;
public class MyBallClass extends Sprite
{
public var speedFactor:Number;
public var speed:Point = new Point(-3.5, -2.5);
public function MyBallClass(x:Number, y:Number, speedFactor:Number = 1)
{
this.x = x; this.y = y;
this.speed = speed;
}
}
}
Now you can create container for all the balls in yor game.
var balls:Vector<MyBallClass> = Vector<MyBallClass>([]);
and run your physics for all of them in a loop.
Generally main code would look something like this:
var balls:Vector.<MyBallClass> = Vector.<MyBallClass>([]);
addBall(...)//place first ball.
function loop(e:Event):void {
processBalls();
if(wantToAddNewSuperSpeedBall) addBall(x,y,3);
...
}
function processBalls() {
for (var i:int = 0; i < balls.length; i++) {
detecCollision(balls[i]);
moveBall(balls[i]);
//any code that process a single ball...
}
}
function addBall(x:Number, y:Number, speedFactor:Number = 1) {
var newBall:MyBallClass = new MyBallClass(x,y, speedFactor);
addChild(newBall);
balls.push(newBall);
}
function moveBall(ball:MyBallClass) {
ball.x += ball.speed.x * ball.speedFactor;
ball.y += ball.speed.y * ball.speedFactor;
}
So you should modify all functions which affect ball behavior to work with ball passed as argument, not only one specific instance and then use them for all balls.
There are more to cover in this topic and this isn't maybe the best approach but I've tried to make it easy to understend. There a lot of guides for OOP so you can get better idea about what is going on if you read them.
I hope that helped you somehow.

AS3 Constrain Object while Zooming/Panning with GestureEvent / MouseEvent

What I want to do is to keep my MovieClip (which is bigger than the viewport) from having its borders visible. Just like many apps do, e.g. Clash of Clans.
This way if you zoom in and zoom out or pan you will never see the stage under it.
If I was only to pan and not zoom it would be easy because I just had to calculate if my MC rectangle is within my stage and if yes i would just:
mc.x = 0 + mc.width / 2;
//or
mc.x = stage.StageWidth - (mc.width/2);
//or .... The same for y
Now the big problem is when I also zoom! And every time I come up with some code it doesn't work well. There are many examples for zooming via GestureEvent on the web but none of them keeps the MC constrained so you don't see the stage under it.
Can someone please provide an example for me. Lets say the stage is 480x720 and the mc is 1080x720!
You gotta pan and zoom while always covering the stage and the scale of mc will remain within 1-1.5.
Here is my current code:
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_PAN, onPan);
stage.addEventListener(MouseEvent.CLICK, gotoBox);
var isInBox: Boolean = false;
table.x = 203.1;
table.y = 360;
table.scaleX = 1;
table.scaleY = 1;
var mouseTimer: Timer;
function onPan(event: TransformGestureEvent): void
{
if (!isInBox)
{
if (event.phase == GesturePhase.BEGIN)
{
stage.removeEventListener(MouseEvent.CLICK, gotoBox);
trace("noClick");
}
table.x += event.offsetX;
table.y += event.offsetY;
if (table.x > (table.width / 2))
{
table.x = table.width / 2;
}
if (table.x < stage.stageWidth - (table.width / 2))
{
table.x = stage.stageWidth - (table.width / 2)
}
if (table.y > (table.height / 2))
{
table.y = table.height / 2;
}
if (table.y < stage.stageHeight - (table.height / 2))
{
table.y = stage.stageHeight - (table.height / 2)
}
if (event.phase == GesturePhase.END)
{
if (mouseTimer !== null)
{
if (mouseTimer.running)
{
mouseTimer.stop();
mouseTimer.removeEventListener(TimerEvent.TIMER, enableClick);
}
}
mouseTimer = new Timer(250);
mouseTimer.addEventListener(TimerEvent.TIMER, enableClick);
mouseTimer.start();
trace("start");
}
}
}
function enableClick(e: TimerEvent)
{
mouseTimer.stop();
trace("stop");
mouseTimer.removeEventListener(TimerEvent.TIMER, enableClick);
stage.addEventListener(MouseEvent.CLICK, gotoBox);
trace("nowClick");
}
function gotoBox(e: MouseEvent)
{
// here it goes to another frame
}
I cannot add the zooming function because its a total disaster; I used something similar to the function onZoom in this link FlashAndMath
Because I needed to zoom in on a point and out from it, and that is the main issue as I have to move my mc around to make that point in the center WHILE I GOTTA MOVE IT TO MAKE MY WHOLE MC IN A CERTAIN BOUNDARY TO COVER THE STAGE! These too movements act against each other. If this last part is not clear ask me to explain more please:)
After having the right answer from LDMS I updated this question to avoid chat-discussions:)
All you need to do, is whenever you move or scale the object, check to make sure it's not going out of bounds.
So if you made a function called forceBounds, just call it anytime you scale or change the x/y:
function forceBounds():void {
//figure out the bounds to constrain to
//the x, should be the farthest left it can go without the edge being seen on the right. To get this value just subtract the smaller width (stage) from the larger width (mc) - this should be a negative number
var bounds:Rectangle = (stage.stageWidth - mc.width, stage.stageHeight - mc.height, mc.width - stage.stageWidth, mc.height - stage.stageHeight);
if (mc.x > bounds.x + bounds.width) {
mc.x = bounds.x + bounds.width;
}
else if (mc.x < bounds.x) {
mc.x= bounds.x;
}
if (mc.y > bounds.y + bounds.height) {
mc.y = bounds.y + bounds.height;
}
else if (mc.y < bounds.y) {
mc.y = bounds.y;
}
}
Here is a full example I made in FlashPro: (with an object on the the stage with an instance name of mc that is bigger than the stage bounds.
Zoom code taken from FlashAndMath.com
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.events.TransformGestureEvent;
import fl.motion.MatrixTransformer;
import flash.geom.Rectangle;
import flash.geom.Point;
import flash.events.GesturePhase;
Multitouch.inputMode = MultitouchInputMode.GESTURE;
stage.addEventListener(TransformGestureEvent.GESTURE_PAN, onPan);
stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
forceBounds();
function onPan(e:TransformGestureEvent):void {
trace("PAN");
if(e.phase == GesturePhase.BEGIN){
stage.removeEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
}
//localToGlobal is a helper method that converts a point to global coordinates
var p:Point = DisplayObject(e.target).localToGlobal(new Point(e.offsetX, e.offsetY));
//conversely, global to local does the opposite
p = mc.globalToLocal(p);
mc.x = p.x;
mc.y = p.y;
forceBounds();
if(e.phase == GesturePhase.END){
stage.addEventListener(TransformGestureEvent.GESTURE_ZOOM, onZoom);
}
}
function onZoom(event:TransformGestureEvent):void {
trace("ZOOM");
var container:MovieClip = mc;
var locX:Number=event.localX;
var locY:Number=event.localY;
var stX:Number=event.stageX;
var stY:Number=event.stageY;
var prevScale:Number=container.scaleX;
var mat:Matrix;
var externalPoint=new Point(stX,stY);
var internalPoint=new Point(locX,locY);
container.scaleX *= (event.scaleX + event.scaleY) * .5;
if(event.scaleX > 1 && container.scaleX > 6){
container.scaleX=prevScale;
}
if(event.scaleY > 1 && container.scaleY > 6){
container.scaleX=prevScale;
}
if(event.scaleX < 1 && container.scaleX < 0.8){
container.scaleX=prevScale;
}
if(event.scaleY < 1 && container.scaleY < 0.8){
container.scaleX=prevScale;
}
if(container.scaleX < 1) container.scaleX = 1;
if(container.scaleX > 1.5) container.scaleX = 1.5;
container.scaleY = container.scaleX;
mat=container.transform.matrix.clone();
MatrixTransformer.matchInternalPointWithExternal(mat,internalPoint,externalPoint);
container.transform.matrix=mat;
forceBounds();
}
function forceBounds():void {
//figure out the bounds to constrain to
//the x, should be the farthest left it can go without the edge being seen on the right. To get this value just subtract the smaller width (stage) from the larger width (mc) - this should be a negative number
var bounds:Rectangle = new Rectangle(stage.stageWidth - mc.width, stage.stageHeight - mc.height, mc.width - stage.stageWidth, mc.height - stage.stageHeight);
if (mc.x > bounds.x + bounds.width) {
mc.x = bounds.x + bounds.width;
}
else if (mc.x < bounds.x) {
mc.x= bounds.x;
}
if (mc.y > bounds.y + bounds.height) {
mc.y = bounds.y + bounds.height;
}
else if (mc.y < bounds.y) {
mc.y = bounds.y;
}
}

AS3 Smooth Jumping

I would like to know how to make a smooth jump in my game. Its a 2D game and the code is really simple but I would want to know how to make it better for it to slow down when it gets to the max height and then smooth drop.
This is all I have for jumping:
Player.y -= 50;
Your best bet would be to use a physics engine (Box2d etc). If you don't want the overhead of one though (if the only thing you'd use it for is jumping and not collisions) then you just need to add some friction to your logic.
var friction :Number = .85; //how fast to slow down / speed up - the lower the number the quicker (must be less than 1, and more than 0 to work properly)
var velocity :Number = 50; //how much to move every increment, reset every jump to default value
var direction :int = -1; //reset this to -1 every time the jump starts
function jumpLoop(){ //lets assume this is running every frame while jumping
player.y += velocity * direction; //take the current velocity, and apply it in the current direction
if(direction < 0){
velocity *= friction; //reduce velocity as player ascends
}else{
velocity *= 1 + (1 - friction); //increase velocity now that player is falling
}
if(velocity < 1) direction = 1; //if player is moving less than 1 pixel now, change direction
if(player.y > stage.stageHeight - player.height){ //stage.stageheight being wherever your floor is
player.y = stage.stageHeight - player.height; //put player on the floor exactly
//jump is over, stop the jumpLoop
}
}
Copy/paste the following code... jump() can be replaced by jump2() (without bouncing effect). The jumping will be produced by the space bar:
const FA:Number = .99; // air resistance
const CR_BM:Number = .8; // bouncing coefficient
const µ:Number = .03; // floor friction
const LB:int = stage.stageHeight; // floor (bottom limit)
const G:int = 2.5; // gravity
const R:int = 50;
var ball:MovieClip = new MovieClip();
this.addChild(ball);
var ba:* = ball.graphics;
ba.beginFill(0xFFCC00);
ba.lineStyle(0, 0x666666);
ba.drawCircle(0, 0, R);
ba.endFill();
ball.vx = 2;
ball.vy = -30;
ball.r = R;
ball.x = 100;
ball.y = LB - R;
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
function myKeyDown(e:KeyboardEvent):void {
if (e.keyCode == Keyboard.SPACE) {
ball.vy = -30;
addEventListener(Event.ENTER_FRAME, jump);
}
}
function jump(e:Event):void {
ball.vy = ball.vy + G;
ball.vx *= FA;
ball.vy *= FA;
ball.x += ball.vx;
ball.y += ball.vy;
if (ball.y > LB - ball.r) {
ball.y = LB - ball.r;
ball.vy = -1 * ball.vy * CR_BM;
ball.vx += ball.vx * - µ;
}
}
/*
function jump2(e:Event):void {
ball.vy = ball.vy + G;
ball.vx *= FA;
ball.vy *= FA;
ball.x += ball.vx;
ball.y += ball.vy;
if (ball.y > LB - ball.r) {
ball.y = LB - ball.r;
}
}
*/

AS3 Missile Logic

I want to create a simple missile object, which moves at a set speed and rotates towards a specific target at a given rotation speed. However, I'm having trouble figuring out the math of it. This is my code so far:
private function enterFrame(e:Event):void {
// Rotate the missile towards the target.
var targetAngle:Number = getAngle(target.x, target.y, x, y);
if (targetAngle < 0) {
targetAngle += 360;
}
if (targetAngle - turnSpeed > rotation) {
rotation += turnSpeed;
} else if (targetAngle + turnSpeed < rotation) {
rotation -= turnSpeed;
} else {
rotation = targetAngle;
}
// Set the target point to move to based on angle and speed.
var newX:Number = x + Math.sin(degreesToRadians(rotation)) * speed;
var newY:Number = y + Math.cos(degreesToRadians(rotation)) * speed;
// Move to new location
x = newX;
y = newY;
}
private function getAngle (x1:Number, y1:Number, x2:Number, y2:Number):Number {
var dx:Number = x2 - x1;
var dy:Number = y2 - y1;
return (Math.atan2(dy,dx) * 180) / Math.PI;
}
private function degreesToRadians(degrees:Number):Number {
return degrees * Math.PI / 180;
}
I've been trying to debug it using trace and such, but I can't seem to figure out where the problem is, most likely because there are many problems and I can't tell if I've fixed one because the others are masking it. I suspect that the issue(s) lie somewhere in the rotation calculations, since I'm pretty sure that the movement part is working as it should, but I can't say for sure.
At any rate, whatever I do, the missiles always seem to fly off in random directions, sometimes tracking towards straight up, or straight down, or just looping around after nothing in particular.

Actionscript 3 - Rotate symbol?

I'm working on a tutorial on youtube to learn some action-script 3. I've got my finished product which is basically a symbol that is known as ball and it has an instance called _ball. The finished product from the tutorial is shown here.
Tutorial Video - Youtube
So basically what I want to achieve is the ball to rotate, depending on which way the ball is moving how would I go about achieving this? I'm new to action-script so some code samples would be appreciated or a in depth explanation.
Incase anyone wants a copy of the code - this is it - I've edited it about in some ways but it doesnt effect much.
package
{
import flash.display.MovieClip
import flash.text.TextField
import flash.events.Event
import flash.events.MouseEvent
public class DocumentMain extends MovieClip
{
public const GRAVITY:Number = 2; // Declaring a const variable known as gravity
public const BOUNCE:Number = 0.8;
public const HIT:Number = 15;
public var _bounces:TextField;
public var _highscore:TextField;
public var _ball:Ball;
private var _vx:Number; // Declaring a variable known as _vx
private var _vy:Number; // Declaring a variable knwon as _vy
public function DocumentMain(): void
{
_vx = Math.random(); // Initalising _vx
_vy = Math.random(); // Initalising _vy
_ball.buttonMode = true;
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
private function enterFrameHandler (e:Event):void
{
// Gravitate the Ball
_vy += GRAVITY; // The ball is effected by gravity each frame
// Move The Ball
_ball.x += _vx;
_ball.y += _vy;
// Check Stage Boundaries For Collisions
checkBoundaryCollision();
}
private function mouseDownHandler (e:MouseEvent):void
{
// Hit the ball if it has been clicked
if (e.target == _ball)
{
hit(e.target.mouseX, e.target.mouseY);
}
}
private function checkBoundaryCollision():void
{
var left:Number;
var right:Number;
var bottom:Number;
var top:Number;
left = _ball.x - (_ball.width / 2);
right = _ball.x + (_ball.width / 2);
bottom = _ball.y + (_ball.height / 2);
top = _ball.y - (_ball.height / 2);
if (left < 0 && _vx < 0)
{
_ball.x = (_ball.width / 2)
_vx *= -1;
}
else if (right > stage.stageWidth && _vx > 0)
{
_ball.x = stage.stageWidth - (_ball.width / 2)
_vx *= -1;
}
if (top <= 42.70 && _vy < 0)
{
_ball.y = (_ball.height / 2)
_vy *= -1;
}
else if (bottom > stage.stageHeight && _vy > 0)
{
_ball.y = stage.stageHeight - (_ball.height/2)
_vy *= -BOUNCE;
_vx *= BOUNCE;
if (Number(_bounces.text) > Number(_highscore.text))
{
_highscore.text = _bounces.text;
}
_bounces.text = "0";
}
}
private function hit(hitX:Number, hitY:Number):void
{
// increment bounces
_bounces.text = String(Number(_bounces.text) + 1);
// Adjust vertical velocity
if (_vy > 0)
{
_vy *= -BOUNCE / 2;
}
_vy -= HIT;
//adjust horizontal veloity
if (_vx * hitX > 0)
{
_vx *= -BOUNCE;
}
_vx -= (hitX / _ball.width * HIT);
}
}
}
I can't test this right now, but it should be as simple as updating your enterFrameHandler to rotate the ball on each frame by a base value multiplied by the ball's x velocity:
public const ROTATION:Number = 1;
private function enterFrameHandler (e:Event):void
{
// Gravitate the Ball
_vy += GRAVITY; // The ball is effected by gravity each frame
// Move The Ball
_ball.x += _vx;
_ball.y += _vy;
// Rotate the ball each frame at a speed and direction
// related to the ball's current x velocity. A negative
// x velocity will result in a negative rotation.
_ball.rotation += ROTATION * _vx;
// Check Stage Boundaries For Collisions
checkBoundaryCollision();
}