I'm trying to make a button draggable and also throw it across the screen. I know that I have to use the mouseDown and mouseUp options for the button, but could someone explain a method for allowing me to drag it and then throw it? In other words, it should keep going after mouseUp.
Thanks in advance for any advice that you can offer -
Chris
Funnily enough, I have an old class for this lying around. Just use the below as a base class for any object you want to be able to throw around:
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
/**
* Use as a base class for objects to be grabbed and thrown with the mouse.
* #author Marty Wallace.
* #version 1.01.
*/
public class BouncingObject extends Sprite
{
// properties
public var yv:Number = 0;
public var xv:Number = 0;
private var _grabbed:Boolean = false;
private var _gy:int = 0;
private var _gx:int = 0;
private var _ox:int = 0;
private var _oy:int = 0;
protected var bounce:Number = 0.3;
protected var weight:Number = 3;
protected var friction:Number = 2;
/**
* Constructor
*/
public function BouncingObject()
{
addEventListener(Event.ADDED_TO_STAGE, _init);
}
/**
* Called on dispatch of Event.ADDED_TO_STAGE
* #param e Event.ADDED_TO_STAGE
*/
private function _init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, _init);
addEventListener(Event.ENTER_FRAME, _handle);
addEventListener(MouseEvent.MOUSE_DOWN, _handleClick);
addEventListener(MouseEvent.MOUSE_UP, _handleRelease);
addEventListener(MouseEvent.MOUSE_OUT, _handleRelease);
}
/**
* Called on dispatch of Event.ENTER_FRAME
* #param e Event.ENTER_FRAME
*/
private function _handle(e:Event):void
{
_ox = x;
_oy = y;
yv += weight;
if(_grabbed)
{
x = parent.mouseX - _gx;
y = parent.mouseY - _gy;
}
else
{
x += xv;
y += yv;
}
if(x < 0)
{
x = 0;
xv = -xv*bounce;
yv -= yv / friction;
}
if(x + width > stage.stageWidth)
{
x = stage.stageWidth - width;
xv = -xv*bounce;
yv -= yv / friction;
}
if(y < 0)
{
y = 0;
yv = -yv*bounce;
xv -= xv / friction;
}
if(y + height > stage.stageHeight)
{
y = stage.stageHeight - height;
yv = -yv*bounce;
xv -= xv / friction;
}
}
/**
* Called on dispatch of MouseEvent.MOUSE_DOWN
* #param e MouseEvent.MOUSE_DOWN
*/
private function _handleClick(e:MouseEvent):void
{
grabbed = true;
parent.addChild(this);
}
/**
* Called on dispatch of MouseEvent.MOUSE_UP
* #param e MouseEvent.MOUSE_UP
*/
private function _handleRelease(e:MouseEvent):void
{
grabbed = false;
}
/**
* Sets grabbed
* #param val Boolean representing value to set grabbed as
*/
protected function set grabbed(bool:Boolean):void
{
_grabbed = bool;
if(_grabbed)
{
_gx = mouseX;
_gy = mouseY;
}
else
{
xv = x - _ox;
yv = y - _oy;
}
}
/**
* Deconstructor - remove event listeners.
*/
public function deconstruct():void
{
removeEventListener(Event.ENTER_FRAME, _handle);
removeEventListener(MouseEvent.MOUSE_DOWN, _handleClick);
removeEventListener(MouseEvent.MOUSE_UP, _handleRelease);
removeEventListener(MouseEvent.MOUSE_OUT, _handleRelease);
}
}
}
Feel free to alter whatever you need, e.g. setting weight to 0 will prevent the object from falling down.
Related
[edit]
I was really stupid, all is working fine now.
So forget about this dummy question!
The rotation of the main clip was a big mistake.
I've changed this by adding a var called _rota with getter and setters.
I had not to rotate the clip but just to place another Sprite in it, so I can place the sub-Sprite in the right direction by using a simple function.
So I avoid all those loops...
My mistake SRY.
I just added a Sprite which have the rotation of the Main Sprite.
Changing the rotation of the main Sprite was the reason of this issue...
So, thank you and forget about this unclear question!!! :)
private function drawLine():void{
if(!clip){
clip = new Sprite();
addChild(clip);
}
var g:Graphics = clip.graphics;
g.clear();
g.lineStyle(1,0xffffff,1);
g.beginFill(0xffffff,1);
g.drawCircle(Math.sin(rota)*this.width/4,Math.cos(rota)*this.height/4,3);
g.endFill();
}
I was changing the rotation property of the clip, so it was usefulness
Now I have a pretty good result.
Solved...
Sorry again...
As you can see the particles are now set in the right direction an I have no more hitTest issues...
Particles are now moving on the direction showed by the white points.
[/edit]
The first thing that pops out at me is you're potentially modifying the position of both x and y properties twice.
If you run the logic once, and store your directionality, then you should be able to update the position of your ball in one go.
Replace your moveBall function with the following...
private var h:int = 1;
private var v:int = 1;
public function moveBall(e:Event):void {
speedx = Math.sin(deg2rad(rotation+90))*speed;
speedy = Math.cos(deg2rad(rotation+90))*speed;
if (x + radius + (speedx * h) > this.loaderInfo.width || (x + (speedx * h) - radius < 0)) {
h *= -1;
}
if (y + radius + (speedy * v) > this.loaderInfo.height || (y + (speedx * v) - radius < 0)) {
v *= -1;
}
this.x += (speedx * h);
this.y += (speedy * v);
}
As I need to set a Sprite in the right direction when the Ball instance change it's "pseudo rotation" (I avoid here the hitTest features)...
I've now two classes...
Do you thing I'm searching in the bright side of code or is it totally unclear? ;)
This is just a test, and I didn't spent time to code since a few years.
So this test is just to revise some basics about trigonometry...
Don't hesitate, to be rude if I'm wrong!
My new class Main :
package com
{
import com.display.Ball;
import flash.display.Graphics;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
[SWF(width = "400", height = "300", frameRate = "60", backgroundColor = "#dddddd")]
public class Main extends MovieClip
{
private var b1:Ball;
private var b2:Ball;
private var b3:Ball;
private var b4:Ball;
private var b5:Ball;
private var testClip:Sprite;
private const ANGLE_TOP_LEFT:int=135;
private const ANGLE_BOTTOM_LEFT:int=-135;
private const ANGLE_TOP_RIGHT:int=45;
private const ANGLE_BOTTOM_RIGHT:int=-45;
public function Main()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
trace("stageSize = " + getStageSize() + ", fps = " + stage.frameRate);
drawlineGuides();
addBalls();
stage.addEventListener(Event.RESIZE,onStageResize);
}
private function addBalls():void{
b1 = new Ball(500/2,250/2,10);
addChild(b1);
b1.color = 0x6666cc;
b1.rota = 135;
b1.drawBall();
b1.move(5);
b2 = new Ball(100,100,10);
addChild(b2);
b2.color = 0xff9900;
b2.rota = -110;
b2.drawBall();
b2.move(4);
b3 = new Ball(50,80,10);
addChild(b3);
b3.color = 0xff0000;
b3.rota = 60;
b3.drawBall();
b3.move(3);
b4 = new Ball(75,20,10);
addChild(b4);
b4.color = 0x00aa00;
b4.rota = 10;
b4.drawBall();
b4.move(4);
b5 = new Ball(125,130,10);
addChild(b5);
b5.color = 0x8457a2;
b5.rota = -45;
b5.drawBall();
b5.move(4);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b1.pauseResume);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b2.pauseResume);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b3.pauseResume);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b4.pauseResume);
stage.addEventListener(MouseEvent.MOUSE_DOWN,b5.pauseResume);
}
private function rotate(e:Event):void{
testClip.rotation = b2.rotation-45;
}
private function getStageSize():Point{
var p:Point= new Point(stage.stageWidth,stage.stageHeight);
return p;
}
private function drawlineGuides():void{
var g:Graphics = this.graphics;
g.clear();
g.lineStyle(1,0x000000,1);
g.moveTo(0,stage.stageHeight/2);
g.lineTo(stage.stageWidth,stage.stageHeight/2);
g.moveTo(stage.stageWidth/2,0);
g.lineTo(stage.stageWidth/2,stage.stageHeight);
}
private function onStageResize(e:Event):void{
drawlineGuides();
}
}
}
And here is my new class Ball :
package com.display
{
/* this import is optionnal
if you want to run this class without the BongSound instance
comment all lines where the var bSound is called
*/
//import com.media.sound.BongSound;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.media.Sound;
public class Ball extends Sprite
{
private var _radius:int;
private var _rotation:Number;
private var _color:int;
private var _g:Graphics;
private var _g2:Graphics;
private var _speed:Number;
private var speedx:Number;
private var speedy:Number;
public var rota:Number;
private var smallCircle:Sprite;
private var rendered:Boolean = false;
public var paused:Boolean = false;
private const ZERO:uint = 0;
//private var bSound:BongSound;
/**
* Ball(posx:Number,posy:Number,radius:uint)<br/>
* this constructor create an instance of a bouncing ball<br/>
* the posx and posy must be included in the range of the defined stageWidth and stageHeight!<br/>
* Otherwise, the ball will be placed in the stage range.
*/
public function Ball(posx:Number,posy:Number,radius:uint)
{
//bSound = new BongSound();
smallCircle = new Sprite();
this.addChild(smallCircle);
this._radius = radius;
this.x = posx;
this.y = posy;
_g = this.graphics;
_g2 = smallCircle.graphics;
}
private function checkStageSize():void{
if(this.x + radius + speedx >= this.stage.stageWidth){
this.x = this.stage.stageWidth - this.width;
}
if(this.y + radius + speedy >= this.stage.stageHeight){
this.y = this.stage.stageHeight - this.height;
}
if(this.x - radius + speedx <= ZERO){
this.x = this.width;
}
if(this.y - radius + speedy <= ZERO){
this.y = this.height;
}
}
public function get speed():Number
{
return _speed;
}
public function set speed(value:Number):void
{
_speed = value;
}
public function get color():int
{
return _color;
}
public function set color(value:int):void
{
_color = value;
}
public function get radius():int
{
return _radius;
}
public function set radius(value:int):void
{
_radius = value;
}
/**
* drawBall()<br/>
* this function draws the main Ball Object
*/
public function drawBall():void
{
_g.clear();
_g.lineStyle(1,0x666666,1);
_g.beginFill(_color,1);
_g.drawCircle(0,0,this._radius);
_g.endFill();
_g.lineStyle(1,0x666666,1);
_g.beginFill(0xffffff,1);
_g.endFill();
}
/**
* drawPoint()<br/>
* this function draws the Point Object wich is placed in the direction/rotation of the main Ball instance.
*/
public function drawPoint():void{
_g2.clear();
_g2.lineStyle(1,0x666666,1);
_g2.beginFill(0xffffff,1);
_g2.drawCircle(ZERO, ZERO, this._radius/2);
smallCircle.x = Math.sin(deg2rad(rota+90))*this.radius/2;
smallCircle.y = Math.cos(deg2rad(rota+90))*this.radius/2;
_g2.endFill();
}
/**
* move(speed:Number):void<br/>
* this function set the speed and makes the Ball move.<br/>
* The displace function is called when an ENTER_FRAME event is triggered.
*/
public function move(speed:Number):void{
this.speed = speed;
this.addEventListener(Event.ENTER_FRAME,displace);
}
/**
* getRota():Number<br/>
* this function returns the rotation of the Ball instance.<br/>
* the rotation is returned in degrees.
*/
public function getRota():Number{
return rad2deg(Math.atan2(speedy,speedx));
}
/**
* pauseResume(e:MouseEvent):void
* Pause or resume movement.
*/
public function pauseResume(e:MouseEvent):void{
switch(paused){
case false:
this.removeEventListener(Event.ENTER_FRAME,displace);
paused = true;
break;
case true:
this.addEventListener(Event.ENTER_FRAME,displace);
paused = false;
break;
}
}
/**
* checkBounds():void<br/>
* <p>
* this function plays a Sound when the Ball instance hit the bounds.<br/>
* the rota variable is updated (even if the rotation of the Ball instance don't change).<br/>
* If the stage is resized, a call to checkStageSize() set the positions x & y in the bounds of the Stage.
* </p>
* #see checkStageSize()
*/
private function checkBounds():void{
if(this.x + radius + speedx >= this.stage.stageWidth){
//bSound.play();
rota = rad2deg(Math.atan2(-speedy,-speedx));
}
if(this.y + radius + speedy >= this.stage.stageHeight){
//bSound.play();
rota = rad2deg(Math.atan2(speedy,speedx));
}
if(this.x - radius + speedx <= ZERO){
//bSound.play();
rota = rad2deg(Math.atan2(-speedy,-speedx));
}
if(this.y - radius + speedy <= ZERO){
//bSound.play();
rota = rad2deg(Math.atan2(speedy,speedx));
}
checkStageSize();
}
/**
* <p>
* displace(e:Event):void
* displace the ball and calls drawPoint to place the sub-Sprite depending of the "rotation" of the Ball instance.</p>
* #see #drawPoint()
* #see #checkBounds()
*/
private function displace(e:Event):void{
checkBounds();
speedx = Math.sin(deg2rad(rota+90))*speed;
speedy = Math.cos(deg2rad(rota+90))*speed;
this.x += speedx;
this.y += speedy;
drawPoint();
}
public function deg2rad(value:Number):Number{
return value/180*Math.PI;
}
public function rad2deg(value:Number):Number{
return value*180/Math.PI;
}
}
}
PrintScreens :
It is now possible to continue the moves even when the Stage is Resized avoiding the issues I had in the past...
In one of the frame of my program I have code for a "player" that is essentially a cannon that follows the character around, specifics aren't important. So I'd like to make this cannon into a class that I can then place as a movieclip, on the stage and have similar cannons serving similar functions. So Basicly I need to make this into a class that somehow interacts with timeline variables?
right now the Player class looks like this
package
{
import flash.display.*;
import flash.events.*;
import flash.ui.*;
public class Player extends MovieClip
{
public function Player() {
}
}
}
Warning code dump you don't have to read all this, this is the player code that I need to make into a class so that I can make more players with different parameters to their not all following the character etc... So how do I do this? this code is interacting with objects on the stage and other variables in the timeline at the moment.
// player settings
var _rotateSpeedMax:Number = 20;
var _gravity:Number = .10;
// projectile gun settings
var _bulletSpeed:Number = 4;
var _maxDistance:Number = 200;
var _reloadSpeed:Number = 250;//milliseconds
var _barrelLength:Number = 20;
var _bulletSpread:Number = 5;
// gun stuff
var _isLoaded:Boolean = true;
var _isFiring:Boolean = false;
var _endX:Number;
var _endY:Number;
var _startX:Number;
var _startY:Number;
var _reloadTimer:Timer;
var _bullets:Array = [];
// array that holds walls
var _solidObjects:Array = [];
// global vars
var _player:MovieClip;
var _dx:Number;
var _dy:Number;
var _pcos:Number;
var _psin:Number;
var _trueRotation:Number;
/**
* Constructor
*/
_solidObjects = [world.wall01,world.wall02,world.wall03,world.wall04];
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpHandler);
//character.addEventListener(Event.ENTER_FRAME, moveDude);
//////////////////////////////////////;
// Player & Weapon Methods
//////////////////////////////////////
/**
* Creates player
* Uses "Player" movieclip linked in library
*/
createPlayer();
function createPlayer():void
{
// attach player movieclip from library
// position player in center
if (character!=null&&_player!=null)
{
_player.x = character.x +5;
_player.y = character.y +5;
}
else if (_player ==null)
{
_player = new Player();
// add to display list
stage.addChild(_player);
}
}
/**
* Fire weapon
*/
function fire():void
{
// check if firing
if (! _isFiring)
{
return;
}
// check if reloaded
if (! _isLoaded)
{
return;
}
// create bullet
createBullet();
// start reload timer
_reloadTimer = new Timer(_reloadSpeed);
_reloadTimer.addEventListener(TimerEvent.TIMER, reloadTimerHandler);
_reloadTimer.start();
// set reload flag to false;
_isLoaded = false;
}
/**
* Creates a bullet movieclip and sets it's properties
*/
function createBullet():void
{
// precalculate the cos & sine
_pcos = Math.cos(_player.rotation * Math.PI / 180);
_psin = Math.sin(_player.rotation * Math.PI / 180);
// start X & Y
// calculate the tip of the barrel
_startX = _player.x - _barrelLength * _pcos;
_startY = _player.y - _barrelLength * _psin;
// end X & Y
// calculate where the bullet needs to go
// aim 50 pixels in front of the gun
_endX = _player.x - 50 * _pcos + Math.random() * _bulletSpread - _bulletSpread * .5;
_endY = _player.y - 50 * _psin + Math.random() * _bulletSpread - _bulletSpread * .5;
// attach bullet from library
var tempBullet:MovieClip = new Bullet();
// calculate velocity
tempBullet.vx = (_endX - _startX) / _bulletSpeed;
tempBullet.vy = (_endY - _startY) / _bulletSpeed;
// set position
tempBullet.x = _startX;
tempBullet.y = _startY;
// save starting location
tempBullet.startX = _startX;
tempBullet.startY = _startY;
// set maximum allowed travel distance
tempBullet.maxDistance = stage.stageHeight;//_maxDistance;
// add bullet to bullets array
_bullets.push(tempBullet);
// add to display list;
stage.addChild(tempBullet);
}
/**
* Updates bullets
*/
function updateBullets():void
{
var i:int;
var tempBullet:MovieClip;
// loop thru _bullets array
for (i = 0; i < _bullets.length; i++)
{
// save a reference to current bullet
tempBullet = _bullets[i];
// check if gravity is enabled
if (gravityCheckbox.selected)
{
// add gravity to Y velocity
tempBullet.vy += _gravity;
}
// update bullet position
tempBullet.x += tempBullet.vx;
tempBullet.y += tempBullet.vy;
// check if bullet went too far
if (getDistance(tempBullet.startX - tempBullet.x, tempBullet.startY - tempBullet.y) > tempBullet.maxDistance + _barrelLength)
{
destroyBullet(tempBullet);
}
// check for collision with walls
if (checkCollisions(tempBullet.x,tempBullet.y))
{
destroyBullet(tempBullet);
}
}
}
/**
* Destroys bullet
* #parambulletTakes bullet movieclip
*/
function destroyBullet(bullet:MovieClip):void
{
var i:int;
var tempBullet:MovieClip;
// loop thru _bullets array
for (i = 0; i < _bullets.length; i++)
{
// save a reference to current bullet
tempBullet = _bullets[i];
// if found bullet in array
if (tempBullet == bullet)
{
// remove from array
_bullets.splice(i, 1);
// remove from display list;
bullet.parent.removeChild(bullet);
// stop loop;
return;
}
}
}
/**
* Reload weapon
*/
function reloadWeapon():void
{
_isLoaded = true;
}
/**
* Checks for collisions between points and objects in _solidObjects
* #returnCollision boolean
*/
function checkCollisions(testX:Number, testY:Number):Boolean
{
var i:int;
var tempWall:MovieClip;
// loop thru _solidObjects array
for (i = 0; i < _solidObjects.length; i++)
{
// save a reference to current object
tempWall = _solidObjects[i];
// do a hit test
if (tempWall.hitTestPoint(testX,testY,true))
{
return true;
// stop loop
break;
}
}
return false;
}
/**
* Calculate player rotation
*/
function updateRotation():void
{
// calculate rotation based on mouse X & Y
_dx = _player.x - stage.mouseX;
_dy = _player.y - stage.mouseY;
// which way to rotate
var rotateTo:Number = getDegrees(getRadians(_dx,_dy));
// keep rotation positive, between 0 and 360 degrees
if (rotateTo > _player.rotation + 180)
{
rotateTo -= 360;
}
if (rotateTo < _player.rotation - 180)
{
rotateTo += 360;
}
// ease rotation
_trueRotation = (rotateTo - _player.rotation) / _rotateSpeedMax;
// update rotation
_player.rotation += _trueRotation;
}
//////////////////////////////////////
// Event Handlers
//////////////////////////////////////
/**
* Enter Frame handler
* #parameventUses Event
*/
function enterFrameHandler(event:Event):void
{
createPlayer();
updateRotation();
updateBullets();
fire();
}
/**
* Mouse Up handler
* #parameUses MouseEvent
*/
function onMouseUpHandler(event:MouseEvent):void
{
_isFiring = false;
}
/**
* Mouse Down handler
* #parameUses MouseEvent
*/
function onMouseDownHandler(event:MouseEvent):void
{
_isFiring = true;
}
/**
* Reload timer
* #parameTakes TimerEvent
*/
function reloadTimerHandler(e:TimerEvent):void
{
// stop timer
e.target.stop();
// clear timer var;
_reloadTimer = null;
reloadWeapon();
}
//////////////////////////////////////
// Utilities
//////////////////////////////////////
/**
* Get distance
* #paramdelta_x
* #paramdelta_y
* #return
*/
function getDistance(delta_x:Number, delta_y:Number):Number
{
return Math.sqrt((delta_x*delta_x)+(delta_y*delta_y));
}
/**
* Get radians
* #paramdelta_x
* #paramdelta_y
* #return
*/
function getRadians(delta_x:Number, delta_y:Number):Number
{
var r:Number = Math.atan2(delta_y,delta_x);
if (delta_y < 0)
{
r += (2 * Math.PI);
}
return r;
}
/**
* Get degrees
* #paramradiansTakes radians
* #returnReturns degrees
*/
function getDegrees(radians:Number):Number
{
return Math.floor(radians/(Math.PI/180));
}
From the class you can access a variable like this: MovieClip(root).variable
I'm importing an external swf into my main project by using the fallowing code:
var FirstLevelLoader:Loader = new Loader();
var FirstLevelFile:URLRequest = new URLRequest("Mainlv.swf");
//load level one
startlevelbttn.addEventListener(MouseEvent.CLICK, LoadFirstLevel);
function LoadFirstLevel(e:Event){
FirstLevelLoader.load(FirstLevelFile);
addChild(FirstLevelLoader);
}
This same type of code works fine when importing other swfs but for Mainlv it doesn't instead it tells me the fallowing error.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at Mainlv/createPlayer()
at Mainlv()
So I suppose the error is in the Mainlv.swf file but I don't see what is wrong and running that file independently produces no errors. Here's the code for the fallowing file.
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class Mainlv extends MovieClip
{
// player settings
private var _moveSpeedMax:Number = 1000;
private var _rotateSpeedMax:Number = 15;
private var _decay:Number = .98;
private var _destinationX:int = 150;
private var _destinationY:int = 150;
// player
private var _player:MovieClip;
// global
private var _isActive:Boolean = false;
private var _dx:Number = 0;
private var _dy:Number = 0;
private var _vx:Number = 0;
private var _vy:Number = 0;
private var _trueRotation:Number = 0;
private var allbullets:Array = new Array();
private var allast:Array = new Array();
private var score:int=0;
/**
* Constructor
*/
public function Mainlv()
{
// create player object
createPlayer();
// add listeners
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_OVER, onMouseUpHandler);
stage.addEventListener(MouseEvent.MOUSE_OVER, onMouseDownHandler);
stage.addEventListener(MouseEvent.CLICK, triggerbullet);
}
private function triggerbullet(event:Event){
var mybullet:Bullet= new Bullet();
stage.addChild(mybullet);
mybullet.x=_player.x;
mybullet.y=_player.y;
mybullet.rotation=_player.rotation;
allbullets.push(mybullet);
}
/**
* Creates player
*/
private function createPlayer():void
{
_player = new Player();
_player.x = stage.stageWidth / 2;
_player.y = stage.stageHeight / 1.15;
stage.addChild(_player);
}
/**
* EnterFrame Handlers
*/
private function enterFrameHandler(event:Event):void
{
updatePosition();
updateRotation();
scorebox.text=String(score);
var t:Number = Math.random();
if(t>0.98) {
addasteroid();
}
for (var a:int = 0;a<allast.length;a++) {
for (var b:int = 0;b<allbullets.length;b++) {
if (allbullets[b].hitTestObject(allast[a])) {
//removeChild(allbullet[b]);
removeChild(allast[a]);
//score
score+=5;
if (score==100) {
dispatchEvent(new Event("next_level"));
}
}
if (allast[a].hitTestObject(_player)) {
//removeChild(allbullet[b]);
trace("hitplayer");
endGame();
}
}
allast[a].y += 3;
}
}//function
/*END GAME*/
private function endGame() {
stage.removeChild(_player);
dispatchEvent(new Event("END_GAME")); // call End_game function to exit external swf
}
/**
* Calculate Rotation
*/
private function updateRotation():void
{
// calculate rotation
_dx = _player.x - _destinationX;
_dy = _player.y - _destinationY;
// which way to rotate
var rotateTo:Number = getDegrees(getRadians(_dx, _dy));
// keep rotation positive, between 0 and 360 degrees
if (rotateTo > _player.rotation + 180) rotateTo -= 360;
if (rotateTo < _player.rotation - 180) rotateTo += 360;
// ease rotation
_trueRotation = (rotateTo - _player.rotation) / _rotateSpeedMax;
// update rotation
_player.rotation += _trueRotation;
}
/**
* Calculate Position
*/
private function updatePosition():void
{
// check if mouse is down
if (_isActive)
{
// update destination
_destinationX = stage.mouseX;
_destinationY = stage.mouseY;
// update velocity
_vx += (_destinationX - _player.x) / _moveSpeedMax;
_vy += (_destinationY - _player.y) / _moveSpeedMax;
}
else
{
// when mouse is not down, update velocity half of normal speed
_vx += (_destinationX - _player.x) / _moveSpeedMax * .25;
_vy += (_destinationY - _player.y) / _moveSpeedMax * .25;
}
// apply decay (drag)
_vx *= _decay;
_vy *= _decay;
// if close to target, slow down turn speed
if (getDistance(_dx, _dy) < 50)
{
_trueRotation *= .5;
}
// update position
_player.x += _vx;
_player.y += _vy;
}
/**
* Mouse DOWN handler
* #param e
*/
private function onMouseDownHandler(e:MouseEvent):void
{
_isActive = true;
}
/**
* Mouse UP handler
* #param e
*/
private function onMouseUpHandler(e:MouseEvent):void
{
_isActive = false;
}
/**
* Get distance
* #param delta_x
* #param delta_y
* #return
*/
public function getDistance(delta_x:Number, delta_y:Number):Number
{
return Math.sqrt((delta_x*delta_x)+(delta_y*delta_y));
}
/**
* Get radians
* #param delta_x
* #param delta_y
* #return
*/
public function getRadians(delta_x:Number, delta_y:Number):Number
{
var r:Number = Math.atan2(delta_y, delta_x);
if (delta_y < 0)
{
r += (2 * Math.PI);
}
return r;
}
/**
* Get degrees
* #param radians
* #return
*/
public function getDegrees(radians:Number):Number
{
return Math.floor(radians/(Math.PI/180));
}
public function addasteroid() {
var newast:asteroid = new asteroid();
newast.x=Math.random()*950;
newast.y=Math.random()*200;
addChild(newast);
allast.push(newast);
}
} //don't code outside of here
}//end
Your problem come from using stage into your class without adding the class instance to the parent stage.
So your code should be like this :
...
public function Mainlv() {
this.addEventListener(Event.ADDED_TO_STAGE, init)
}
private function init(e:Event){
this.removeEventListener(Event.ADDED_TO_STAGE, init);
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(MouseEvent.MOUSE_OVER, onMouseUpHandler);
stage.addEventListener(MouseEvent.MOUSE_OVER, onMouseDownHandler);
stage.addEventListener(MouseEvent.CLICK, triggerbullet);
createPlayer()
}
...
And don't forget to add the Mainlv instance to parent stage :
import Mainlv
var m:Mainlv = new Mainlv()
addChild(m)
I tested this code and it works fine.
Hello guys i have a problem and no idea how to fix it :( Can someone tell me how to do it?
Constructor functions must be instance methods.
So here is my code:
package
{
import com.coreyoneil.collision.CollisionList;
import flash.events.Event;
import flash.display.Sprite;
public class terrain extends Sprite
{
private var wheel:Ball;
private var collisionList:CollisionList;
private var speed:Number;
private const GRAVITY:Number = .75;
private const FRICTION:Number = .98;
private const IMMOVABLE:Number = 10000;
public function terrain():void
{
if(stage == null)
{
addEventListener(Event.ADDED_TO_STAGE, init, false, 0, true);
addEventListener(Event.REMOVED_FROM_STAGE, clean, false, 0, true);
}
else
{
init();
}
}
private function init(e:Event = null):void
{
collisionList = new CollisionList(terrain);
wheel = new wheel(10);
wheel.mass = IMMOVABLE * 2;
addChild(wheel);
collisionList.addItem(wheel);
wheel.x = 30;
wheel.y = 10;
speed = 0;
terrain.graphics.lineStyle(15);
addEventListener(Event.ENTER_FRAME, updateScene);
}
private function updateScene(e:Event):void
{
var collisions:Array = collisionList.checkCollisions();
if(collisions.length)
{
var collision:Object = collisions[0];
var angle:Number = collision.angle;
var overlap:int = collision.overlapping.length;
var sin:Number = Math.sin(angle);
var cos:Number = Math.cos(angle);
var vx0:Number = wheel.vx * cos + wheel.vy * sin;
var vy0:Number = wheel.vy * cos - wheel.vx * sin;
// Unlike the other examples, here I'm choosing to calculate the amount
// of bounce based on the objects' masses, with a default mass of 10000 (IMMOVABLE)
// being used for the drawing the wheel is colliding with. As such, the only
// real variable in play here is the current vector of the wheel.
vx0 = ((wheel.mass - IMMOVABLE) * vx0) / (wheel.mass + IMMOVABLE);
wheel.vx = vx0 * cos - vy0 * sin;
wheel.vy = vy0 * cos + vx0 * sin;
wheel.vx -= cos * overlap /wheel.radius;
wheel.vy -= sin * overlap / wheel.radius;
wheel.vx += speed;
}
trace("down");
wheel.vy += GRAVITY;
wheel.vy *= FRICTION;
wheel.vx *= FRICTION;
wheel.x += wheel.vx;
wheel.y += wheel.vy;
if(wheel.x > stage.stageWidth) wheel.x = stage.stageWidth;
if(wheel.x < 0) wheel.x = 0;
if(wheel.y > stage.stageHeight - (wheel.height >> 1))
{
wheel.y = 10;
wheel.x = 30;
wheel.vx = wheel.vy = 0;
}
}
private function clean(e:Event):void
{
removeEventListener(Event.ENTER_FRAME, updateScene);
}
}
}
There are some comment in the code.. Just ignore it i have used example.
collisionList = new CollisionList(terrain);
terrain.graphics.lineStyle(15);
This is error 1026, also thrown if the constructor is static, private or in your case used as an identifier. Either use this.graphics instead of terrain.graphics or just graphics.etc (remove terrain) and also pass 'this' as parameter for 'CollisionList'.
(Unrelated: Also it's better to name classes starting with a capital "Terrain")
I want to create an object that follows and stops at mouse click. I managed to make it happen with rotation but the problem is that whenever i click on the empty stage, the object will move towards it and it carries on moving. It does not stop at the mouse location. Anyone know how i can do that. Below is my code:
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class Guest extends MovieClip
{
var walkSpeed:Number = 5;
public function Guest()
{
stage.addEventListener(MouseEvent.CLICK, walk);
}
function walk(event:MouseEvent):void
{
var dx = parent.mouseX - x;
var dy = parent.mouseY - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
stage.addEventListener(Event.ENTER_FRAME, loop);
}
function loop(event:Event):void
{
x = x+Math.cos(rotation/180*Math.PI)*walkSpeed;
y = y+Math.sin(rotation/180*Math.PI)*walkSpeed;
stage.removeEventListener(Event.ENTER_FRAME, loop);
}
}
}
Your code is a bit weird, here you will never move towards position for more than one frame since you remove the event listener as soon as loop is done.
Here is some code that fixes the moving and then stopping issue. However I strongly suggests that you do this with some kind of "tweening library" and I will after this show an example of doing that with Caurina Transitions.
function walk(e:MouseEvent):void {
targetX = parent.mouseX; //targetX created as a member variable
targetY = parent.mouseY; //targetY created as a member variable
var dx = parent.mouseX - x;
var dy = parent.mouseY - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
stage.addEventListener(Event.ENTER_FRAME, loop);
}
function loop(e:Event):void {
var newX:Number = x + Math.cos(rotation / 180 * Math.PI) * walkSpeed;
var newY:Number = y + Math.sin(rotation / 180 * Math.PI) * walkSpeed;
var atTarget:Boolean = true;
if (Math.abs(targetX - newX) > walkSpeed) {
x = newX;
atTarget = false;
}
if(Math.abs(targetY - y) > walkSpeed) {
y = newY;
atTarget = false;
}
if (atTarget) {
stage.removeEventListener(Event.ENTER_FRAME, loop);
}
}
Here's the same behaviour with caurina.
package
{
import caurina.transitions.Tweener;
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class TransitionExample extends MovieClip
{
private var targetX:Number;
private var targetY:Number;
var walkSpeed:Number = 5;
public function TransitionExample()
{
trace("ctor()");
stage.addEventListener(MouseEvent.CLICK, walk);
}
private function walk(e:MouseEvent):void {
targetX = parent.mouseX;
targetY = parent.mouseY;
var dx = targetX - x;
var dy = targetY - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
var tweenDone:Function = function():void {
trace("tween is finished");
}
//modify time to be dependant on the "walkspeed" and the distance travelled etc...
Tweener.addTween(this, { x:targetX, y:targetY, time:0.458, transition:"linear", onComplete:tweenDone});
}
}
}