Flash AS3 Snooker Game - actionscript-3

So, I'm absolutely useless at Flash and stupidly thought creating a Snooker game wouldn't be too difficult for a school Assignment. I grossly underestimated.
I'm trying to make the cueBall MovieClip move towards the point where the Mouse clicked on the Stage.
So far I have made the cueBall move to the point where the Mouse clicked, but I need it to keep going (unless obstructed).
I think I need to somehow calculate the angle between the cueBall MovieClip and the Mouse and then tell the MovieClip to start moving in that direction.
Suggestions? It's probably something simple, I bet...
Thanks in advance.
addEventListener(Event.ENTER_FRAME, gameSetup);
var VelocityX;
var VelocityY;
var speed = 1;
var shootCount = 0;
var mouseXPos;
var mouseYPos;
function gameSetup(e:Event) {
removeEventListener(Event.ENTER_FRAME, gameSetup);
addEventListener(Event.ENTER_FRAME, aim);
addEventListener(Event.ENTER_FRAME, shoot);
}
function aim(e:Event) {
cueStick.x = cueBall.x;
cueStick.y = cueBall.y;
cueStick.rotation = (Math.atan2(mouseY-cueStick.y, mouseX-cueStick.x))*(180/Math.PI);
if (mouseX > 25.5 && mouseX < 614.5) {
aimBall.visible = true;
aimBall.x = mouseX;
} else if (mouseX < 25.5) {
aimBall.x = 25.5;
} else if (mouseX > 614.5) {
aimBall.x = 614.5;
}
if (mouseY > 25.5 && mouseY < 294.5) {
aimBall.visible = true;
aimBall.y = mouseY;
} else if (mouseY < 25.5) {
aimBall.y = 25.5;
} else if (mouseY > 294.5) {
aimBall.y = 294.5;
}
if (mouseX > 0 && mouseX < 640 && mouseY > 0 && mouseY < 320) {
Mouse.hide();
} else {
Mouse.show();
}
addEventListener(MouseEvent.MOUSE_DOWN, drawCue);
}
function drawCue(e:MouseEvent) {
removeEventListener(Event.ENTER_FRAME, aim);
addEventListener(MouseEvent.MOUSE_UP, shotAnim);
}
function shotAnim(e:MouseEvent) {
mouseXPos = mouseX;
mouseYPos = mouseY;
cueStick.rotation = (Math.atan2(mouseYPos-cueStick.y, mouseXPos-cueStick.x))*(180/Math.PI);
VelocityX = Math.cos(mouseX-cueBall.x) * speed;
VelocityY = Math.sin(mouseY-cueBall.y) * speed;
cueStick.gotoAndPlay(2);
}
function shoot(e:Event) {
if (shootCount == 1) {
cueBall.x += VelocityX;
cueBall.y += VelocityY;
trace(VelocityX);
trace(VelocityY);
cueStick.visible = false;
} else {
cueStick.visible = true;
}
}

Maybe this example is helpful to you:
http://www.emanueleferonato.com/2008/01/05/complete-flash-pool-game-with-highscores/

If I'm understanding you right, you already have it setup so that when the mouse is clicked, the ball teleports to the mouse's location.
What you want is for the ball to move to the mouse's position over a period of time.
To do this, you will use something called an EnterFrame event. EnterFrame calls a function every frame, which you need to get the ball smoothly rolling to the mouse.
addEventListener(Event.ENTER_FRAME,update);
function update(event:Event) {
// move the ball a little bit toward the mouse
}
Then, you need to determine in what direction the ball needs to roll. You will do this with trigonometric functions. In your OnClick handler, write something like:
VelocityX = Math.cos(mouse.x-ball.x) * SPEED;
VelocityY = Math.sin(mouse.y-ball.y) * SPEED;
Then, each frame, move the ball by that amount.
addEventListener(Event.ENTER_FRAME,update);
function update(event:Event) {
ball.x += VelocityX;
ball.y += VelocityY;
}
Hope that helped!

Related

ActionScript 3, How to get character to jump for longer

I am making a platformer game in Flash (AS3) and the code I have below works. I want my character to jump high enough to allow it time to reach a platform. The only problem with code below is the speed at which it jumps up and down and the height of the jump. Tthe space bar is what triggers the function to run.
Please help as I would much appreciate it! :)
Player.addEventListener(Event.ENTER_FRAME, fl_MoveInDirectionOfKey);
stage.addEventListener(KeyboardEvent.KEY_DOWN, fl_SetKeyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, fl_UnsetKeyPressed);
function fl_MoveInDirectionOfKey(event:Event)
{
if (spacePressed){
var gravity:Number = 9.8;
var jumping:Boolean = false;
var jumpVar:Number = 0;
if(jumping != true)
{
jumpVar = -70;
jumping = true;
}
if(jumping)
{
spacePressed = false;
Player.y += jumpVar;
jumpVar += gravity;
}
Player.addEventListener(Event.ENTER_FRAME, drop);
function drop(event:Event)
{
Player.y -= jumpVar;
jumpVar -= gravity;
if(Player.y > 350){
Player.y = 350;
}
}
Player.removeEventListener(Event.ENTER_FRAME, fl_MoveInDirectionOfKey);
Player.addEventListener(Event.ENTER_FRAME, fl_MoveInDirectionOfKey);
/*var frameNumb:Number = 0;
Player.addEventListener(Event.ENTER_FRAME, jumpup);
spacePressed = false;
function jumpup(event:Event)
{
while(frameNumb < 30){
spacePressed = false;
Player.y -= 1;
frameNumb += 0.5;
}
Player.removeEventListener(Event.ENTER_FRAME, jumpup);
Player.addEventListener(Event.ENTER_FRAME, jumpdown);
function jumpdown(){
while(frameNumb > 0){
spacePressed = false;
Player.y += 1;
frameNumb -= 0.5;
}
}
}*/
}
if (leftPressed)
{
Player.x -= speed;
Player.gotoAndStop("left");
}
if (rightPressed)
{
Player.x += speed;
Player.gotoAndStop("right");
}
}
Thanks
Your use of 9.8 for gravity is meters-per-second-per-second. Since drop() is executed every frame, you're going to get some serious fast-forward gravity, unless the program is doing only 1 FPS. So, assuming you want more fluidity than 1 FPS, consider doing
jumpVar += gravity/fps;
However, to get the exact velocity required to lift you to a height, I think the calculation is...
initialVelocityInMetersPerSecond = Math.sqrt( 2 * gravity * metersToJump )
So instead of jumpVar = -70, you would do something like...
// get posititive distance since we'll use to get a square root
var metersToJump:Number = Player.y - platform.y;
jumpVar = -Math.sqrt( 2 * gravity * metersToJump );
...and then in the ENTER_FRAME handler...
Player.y += jumpVar / fps;
jumpVar += gravity / fps;
From your example it's not the case, but if you place the platform below the Player, it won't work as you can't get the root of a negative number!
In my example code I am not fixing the height of the platform, so how you decide on the target platform is a completely separate matter.

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.

Move and Scale a MovieClip smoothly between multiple points

I have a set-up of 3 horizontal rows with a button aligned to each of them and a character (centered to each row) that I want to move between these rows (think of Little Big Planet). I was able to program it so the character moves between the 3 rows and has a set scale when it does, but I want to see the character actually moving between the points; not just watch it teleport to the location. I've tried everything I can think of: Loops, Boolean on/off, some velocity/distance/difference shenanigans, etc., but I'm having no success getting it to move at a button click and continue moving until it reaches its point. I'm also not sure if it can be set-up to scale incrementally until it reaches a desired end scale size or not. I saw a slightly similar problem asked on a site, but solution they gave uses the Point class and a lot of math, and I have never had success getting my Flash to use Points. Any suggestions would be appreciated.
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class Main_Test_5 extends MovieClip
{
private var cam:MovieClip = new MovieClip();
private var player:Player = new Player();
private var topPosition:uint = 170;
private var centerPosition:uint = 270;
private var bottomPosition:uint = 370;
private var UI:UserInterface = new UserInterface();
private var testBackground:TestBackground = new TestBackground();
public function Main_Test_5():void
{
player.x = 100;
player.y = 370;
cam.addChild(player);
addChild (UI);
// add event listeners
stage.addEventListener(Event.ENTER_FRAME, checkEveryFrame);
UI.topButton.addEventListener(MouseEvent.CLICK, topButtonClick);
UI.centerButton.addEventListener(MouseEvent.CLICK, centerButtonClick);
UI.bottomButton.addEventListener(MouseEvent.CLICK, bottomButtonClick);
addChild (cam);
}
public function checkEveryFrame(event:Event):void
{
cam.x -= player.x - player.x;
cam.y -= player.y - player.y;
}
public function topButtonClick (event:MouseEvent):void
{
trace ("Top Click");
if (player.y > topPosition) // 170, player.y starts at 370
{
player.y -= 100;
}
else if (player.y <= topPosition)
{
player.y = topPosition;
}
if (player.y == topPosition)
{
player.scaleY = 0.8;
player.scaleX = 0.8;
}
else if (player.y != topPosition)
{
player.scaleY = 0.9;
player.scaleX = 0.9;
}
}
public function centerButtonClick (event:MouseEvent):void
{
trace ("Center Click");
if (player.y > centerPosition) // 270
{
player.y -= 100;
}
if (player.y < centerPosition)
{
player.y += 100;
}
if (player.y == centerPosition)
{
player.scaleY = 0.9;
player.scaleX = 0.9;
}
}
public function bottomButtonClick (event:MouseEvent):void
{
trace ("Bottom Click");
if (player.y < bottomPosition) // 370
{
player.y += 100;
}
if (player.y >= bottomPosition)
{
player.y = bottomPosition;
}
if (player.y == bottomPosition)
{
player.scaleY = 1;
player.scaleX = 1;
}
else if (player.y != bottomPosition)
{
player.scaleY = 0.9;
player.scaleX = 0.9;
}
}
}
}
Sounds like you'd like something simple. So I would suggest using a Tweening library. The most prolific of which is Greensocks TweenLite, which is now part of their Animation Platform
Using tweenlite, you would just do the following:
In place of:
player.y += 100;
You would do:
TweenLite.to(player, 1,{y: player.y + 100, ease: Quad.EaseInOut});
This would tween (move gradually over time) your player object from it's current position to the specified y (player.y + 100). It would do it over 1 second and with a nice in and out ease.
You can add more properties to the tween (scaleX/Y, x) anything really.
Do note, there are many Tweening platform alternatives, including one baked into Flash Professional. TweenLite is not free to use if you charge your end users a fee for your application. Be sure to review their license if you use it commercially.

Action Script 3.0 timer doesn't stop

I'm trying to make flappy birds in actionscript (just for practicing and fun). This is my first programming language and I'm still new to this.
So the problem starts here, I want to make the bird rotates (as the real flappy bird does) every 2 seconds when no button is pressed. But it turned out that the timer still activates after I pressed spacebar again which I think it is supposed to stop the last timer first before activating the new one.
If I press spacebar 2 times, the timer will activate twice. Without stopping the timer first.
Code :
stage.addEventListener (KeyboardEvent.KEY_DOWN, jump);
function jump(event: KeyboardEvent):void
{
var myTimer4:Timer = new Timer (2000)
if(event.keyCode == 32)
{bird.y=bird.y-40;
bird.rotation=0;
myTimer4.stop();
myTimer4.start();
}
myTimer4.addEventListener(TimerEvent.TIMER, fall);
function fall (e:TimerEvent):void{
bird.rotation=40;
myTimer4.stop();
}
I think the problem might be you are creating a new instance of Timer every time the key is pressed and myTimer4 takes in a new reference. Try removing it outside the function scope like this:
var myTimer4:Timer = new Timer (2000);
function jump(event: KeyboardEvent):void
{
if(event.keyCode == 32)
{bird.y=bird.y-40;
bird.rotation=0;
myTimer4.stop();
myTimer4.start();
}
onClipEvent (load) {
power = 0.3;
yspeed = 0;
xspeed = 0;
friction = 0.95;
gravity = 0.5;
thrust = 3.75;
wind = 0.18;
_root.level1_text.text = 0+collected_coin19;
reverse = new Sound();
reverse.attachSound("hit2");
}
onClipEvent (enterFrame) {
if (Key.isDown(Key.LEFT)) {
xspeed -= power;
}
if (Key.isDown(Key.RIGHT)) {
xspeed += power;
}
if (Key.isDown(1)) {
yspeed -= power*thrust;
}
if (Key.isDown(Key.SPACE)) {
yspeed -= power*thrust;
}
xspeed += wind;
xspeed *= friction;
yspeed += gravity;
_y += yspeed;
_x += xspeed;
Try This one Might Help you

Make movie clip 'Enemy' follow 'player' instead of walking on set xy axis? Flash, AS3

curious to know if I can somehow make the enemy movie clip in my flash game follow the movie clip the player controls, called 'player' in this instance. At the minute, it's just set to walk -3 on X and 1.5 on Y.
Not really sure if I need to post any code on here, just in case, here is my code inside the Enemy Movie clip.
Thanks in advance!
import flash.events.MouseEvent;
var catxSpeed:Number = -3;
var catySpeed:Number = 1.5;
var myParent:*;
var ground:Number;
var jumping:Boolean = false;
var health:Number;
this.addEventListener(Event.ENTER_FRAME, updatecat);
function updatecat(event:Event):void
{
this.x += catxSpeed;
if(myParent.player.hitTestObject(this))
{
myParent.hit();
}
this.y += catySpeed;
if(jumping == true)
{
catySpeed +=1;
if(this.y >= ground)
{
catxSpeed = -3;
catySpeed = 0;
this.y = ground;
jumping = false;
if(health < 1)
{
shutDown();
}
}
}
}
function activate(passParent:*):void
{
ground = this.y;
this.addEventListener(Event.ENTER_FRAME, updatecat);
this.addEventListener(MouseEvent.MOUSE_DOWN, hit);
myParent = passParent;
health = Math.round(myParent.randomise(2,4));
}
function shutDown():void
{
this.removeEventListener(Event.ENTER_FRAME, updatecat);
this.parent.removeChild(this);
}
function hit(event:MouseEvent):void
{
catxSpeed = 30;
catySpeed = -15;
jumping = true;
myParent.addToScore(1);
health--;
}
if (enemy.x > this.x) this.x += catxSpeed;
else this.x -= catxSpeed;
if (enemy.y > this.y) this.y += catySpeed;
else this.y -= catySpeed;