MouseEvent Not Happening On Click AS3 - actionscript-3

This looks all fine to me, but I have a simple star shape on the screen and when that star shape has been clicked it should remove the image from the screen. Can't see why its not working hoping one of you can, would be much appreciated
public class TouchRemove extends Sprite
{
private var _color:uint;
private var _radius:int;
private var star:Sprite;
public function mouseClick(event:MouseEvent): void {
star.visible = false;
}
public function TouchRemove(c:uint = 0xffff00, r:int = 100)
{
_color = c;
_radius = r;
star = new Sprite();
createStar();
addChild(star);
star.x = 250;
star.addEventListener(MouseEvent.CLICK, mouseClick);
}
private function createStar():void
{
star.graphics.lineStyle(9,_color);
star.graphics.moveTo(_radius, 0);
var angleIncrement = Math.PI / 5;
var ninety:Number = Math.PI * 3;
for (var i:int = 0; i <= 10; i++)
{
var radius:Number = (i % 2 > 0 ? _radius : _radius * .5);
var px:Number = Math.cos(ninety + angleIncrement * i) * radius;
var py:Number = Math.sin(ninety + angleIncrement * i) * radius;
if (i == 0) star.graphics.moveTo(px, py);
star.graphics.lineTo(px, py);
}
}
}
}

Your code looks correct.
Try this:
- Add listener to the parent
- Add star manually and add listener at it through the code
This will help locate the error.

Related

Flash as3 Var movieClip duplicates

Having multiple movieclips being able to move around on a grid, once dragging it, it seems to duplicate and the 'original' remains in place.
What causes it to duplicate in my code?
import flash.display.MovieClip
[SWF(width = 1300, height = 1000)]
var tileSize: int = 100;
var cols: int = stage.stageWidth / tileSize;
var rows: int = stage.stageHeight / tileSize;
var grid: Sprite = Sprite(addChild(new Sprite()));
grid.graphics.lineStyle(0, 0x000000, 0);
var i: int = 0;
for (i = 1; i < cols; i++) {
var posX: Number = i * tileSize
grid.graphics.moveTo(posX, 0);
grid.graphics.lineTo(posX, stage.stageHeight);
}
for (i = 1; i < rows; i++) {
var posY: Number = i * tileSize
grid.graphics.moveTo(0, posY);
grid.graphics.lineTo(stage.stageWidth, posY);
var ball: the_ball = new the_ball();
addChild(ball);
ball.x = tileSize * 5;
ball.y = tileSize * 5;
ball.buttonMode = true;
ball.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
function onDown(evt: MouseEvent): void {
addEventListener(Event.ENTER_FRAME, onRunSnapping);
}
function onRunSnapping(evt: Event): void {
ball.x = Math.round(mouseX / tileSize) * tileSize;
ball.y = Math.round(mouseY / tileSize) * tileSize;
}
stage.addEventListener(MouseEvent.MOUSE_UP, onUp);
function onUp(evt: MouseEvent): void {
removeEventListener(Event.ENTER_FRAME, onRunSnapping);
}
}
It's not duplicating, there are just many movieclips stacked on top of each other.
You add a new ball for each row you add on the exact same position.
I dont know how you want the balls to be distributed, but try to replace
ball.y = tileSize * 5; with ball.y = posY; to see what im talking about.

How to change MovieClip transparency based on mouse position?

So, I'm trying to make a grid of rectangles each get more transparent the closer the mouse is to it.
Using some basic maths, I thought I had got it, but instead it seems I got a weird graphic bug(maybe?) shown here:
The middle of the rings is where the mouse is.
Part of code that deals with transparency:
private function update(e:Event = null):void
{
for (var i:int = 0; i < buttons.length; i++) {
lightFact = getDistance(buttons[i])
lightBrightness = lightPower - (lightFact * 10)
buttons[i].alpha = lightBrightness
}
}
getDistance is just getting distance from the block to the mouse.
Each rectangle is a movie clip, if that matters.
If you are trying to do this:
Then I think your problem is basically that your alpha value is ranging from 0 to about 3000 or something like that. That's going to cause strange effects. The value needs to range smoothly from 0 to 1 (so it needs to be a floating point number as in Number).
Here is the code which generated the image above which I wrote for you that will get you started in the right direction:
package
{
import flash.display.*;
import flash.events.*;
public class lightFactTest extends MovieClip
{
private var boxesArray: Array = new Array();
private var xDist: Number = 0;
private var yDist: Number = 0;
private var d: Number = 0;
private var size_Glow : Number = 0;
private var size_Radius : Number = 0;
public function lightFactTest(): void
{
// creates a background for rectangles array.
var BG_box: Sprite = new Sprite();
BG_box.graphics.lineStyle();
BG_box.graphics.beginFill(0x080839);
BG_box.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
BG_box.graphics.endFill();
addChild(BG_box);
//# creates a grid of sprites (rectangles).
for (var i:int = 0; i < (stage.stageWidth / 10); i++)
{
for (var j:int = 0; j < (stage.stageHeight / 10); j++)
{
var box: Sprite = new Sprite();
box.graphics.lineStyle();
box.graphics.beginFill(0xFFFFFF);
box.graphics.drawRect(0, 0, 10, 10);
box.graphics.endFill();
addChild(box);
box.x += i*10; //+ 50;
box.y += j*10; //+ 50;
boxesArray.push(box);
}
}
addEventListener(Event.ENTER_FRAME, lightCalc);
}
private function lightCalc(e: Event): void
{
size_Glow = 3.5;
size_Radius = 0.64;
//# iterates through the array calculating each distance and then alpha.
for (var i:int = 0; i < boxesArray.length; i++)
{
xDist = Math.abs(stage.mouseX - boxesArray[i].x);
yDist = Math.abs(stage.mouseY - boxesArray[i].y);
//var d: Number = Math.pow(xDist * xDist + yDist * yDist, 0.5);
d = Math.sqrt(xDist * xDist + yDist * yDist) / (size_Radius / 5);
//# This is the code that you really need to focus on...
boxesArray[i].alpha = Math.min(1 / d * 10, 1 ) * (Math.PI / 0.5 - Math.min(size_Radius, 0) ) * size_Glow;
}
}
}
}
Hope that helps!

Flash AS3:Constructor functions must be instance method

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")

Collision detection and clipping issues in AS3

I've recently started putting together a little physics simulation from scratch, something I've never tried before, and I've run into an issue regarding the interaction between the collision of the objects I have on stage, and what I think is my constant gravity. I'm not sure if 200 lines of code is too large for here, but this is what I have.
package {
import flash.events.*;
import flash.display.*;
import flash.geom.Rectangle;
[SWF (width="1500", height="1000", frameRate="24")]
public class ElasticityV2 extends MovieClip{
/* Gravity is 9.8 m/s2, which for flash, since it's being applied every frame, needs to be
divided out by the frame rate as to not have super fast acceleration. GravMulti is to balance
out gravity's speed, as it seemed a little slow after the framerate division. Resistance is acting
like friction for now, and slows down the objects in the air and on the ground at the same rate.
Elasticity is how bouncy each object is and how the force it recieves is applied*/
public var gravMulti:Number = 5;
public var gravity:Number = gravMulti *(9.8/stage.frameRate);
public var resistance:Number = 0.98;
public var elasticity:Number = 0.8;
public var floor:Number = stage.stageHeight - 100;
public var objectList:Array = new Array();
public var shadowList:Array = new Array();
public var yVelocityList:Array = new Array();
public var xVelocityList:Array = new Array();
public var massList:Array = new Array();
public var frictionList:Array = new Array();
public var lastXList:Array = new Array();
public var lastYList:Array = new Array();
public var elasticityList:Array = new Array();
public var dragList:Array = new Array();
public var spawnNum:int = 20;
public var bounding:Rectangle = new Rectangle(0,0,stage.stageWidth - 100,stage.stageHeight);
public var distantBackground:Background = new Background();
public var starLight:Light = new Light();
public function ElasticityV2() {
addChild(starLight);
starLight.x = stage.stageWidth/2;
starLight.y = -400;
starLight.addEventListener(MouseEvent.MOUSE_DOWN, onLightDrag);
starLight.addEventListener(MouseEvent.MOUSE_UP, onLightDrag);
starLight.addEventListener(MouseEvent.MOUSE_OUT, onLightDrag);
for(var s:int=0;s<spawnNum;s++){
var ballShadow:Shadow = new Shadow();
addChild(ballShadow);
setChildIndex(ballShadow,0);
ballShadow.y = floor - (ballShadow.height/2);
ballShadow.x = 100;
shadowList.push(ballShadow);
var ball:ElasticBall = new ElasticBall();
var dragging:Boolean = false;
addChild(ball);
ball.y = 100;
ball.x = s * 200;
objectList.push(ball);
yVelocityList.push(randomMe(20,-20));
xVelocityList.push(randomMe(40,-40));
massList.push(randomMe(20,5));
frictionList.push(randomMe(0.6,0.01));
objectList[s].width = objectList[s].height = massList[s] * 10;
elasticityList.push(elasticity);
dragList.push(dragging);
ball.addEventListener(MouseEvent.MOUSE_DOWN, onDrag);
ball.addEventListener(MouseEvent.MOUSE_UP, onDrag);
ball.addEventListener(MouseEvent.MOUSE_OUT, onDrag);
}
addChild(distantBackground);
distantBackground.y = stage.stageHeight - distantBackground.height;
distantBackground.width = stage.stageWidth;
setChildIndex(distantBackground,0);
addEventListener(Event.ENTER_FRAME, onGameLoop);
}
public function onGameLoop(e:Event):void{
//checkCollision();
for(var i:int=0;i<objectList.length;i++){
updatePhysics(i);
updateShadows(i,starLight);
}
}
public function updatePhysics(objRef:int):void{
if(lastXList[objRef] != undefined){
if(lastXList[objRef] != objectList[objRef].x){
xVelocityList[objRef] = objectList[objRef].x - lastXList[objRef];
}
}
if(lastYList[objRef]!= undefined){
if(lastYList[objRef] != objectList[objRef].y){
yVelocityList[objRef] = 4*(objectList[objRef].y - lastYList[objRef])/stage.frameRate;
}
}
if(objectList[objRef].y>= floor - objectList[objRef].height){
yVelocityList[objRef] = -(yVelocityList[objRef] * elasticityList[objRef]);
objectList[objRef].y = floor - objectList[objRef].height;
}
if(objectList[objRef].y<= 0){
yVelocityList[objRef] = -(yVelocityList[objRef] * elasticityList[objRef]);
objectList[objRef].y = 0;
}
if(objectList[objRef].x > (stage.stageWidth - objectList[objRef].width)){
xVelocityList[objRef]=-xVelocityList[objRef];
objectList[objRef].x = stage.stageWidth - objectList[objRef].width;
}
if (objectList[objRef].x <0){
xVelocityList[objRef]=-xVelocityList[objRef];
objectList[objRef].x = 0;
}
if(!dragList[objRef]){
yVelocityList[objRef]+=gravity;
objectList[objRef].y += yVelocityList[objRef];
xVelocityList[objRef]= (xVelocityList[objRef] * resistance);
if(-0.5<xVelocityList[objRef] && xVelocityList[objRef]<0.5){
xVelocityList[objRef] = 0;
}
objectList[objRef].x += xVelocityList[objRef];
}
lastXList[objRef] = objectList[objRef].x;
lastYList[objRef] = objectList[objRef].y;
if(xVelocityList[objRef] == 0){
xVelocityList[objRef]=randomMe(90,-90);
yVelocityList[objRef]=randomMe(90,-90);
}
}
public function onDrag(e:Event):void{
if(e.type == "mouseDown"){
setChildIndex(DisplayObjectContainer(e.target),numChildren - 1)
e.target.startDrag(false,bounding);
//xVelocityList[objRef] = yVelocityList[objRef] = 0;
//dragging = true;
}else{
e.target.stopDrag();
//dragging = false;
}
}
public function onLightDrag(e:Event):void{
if(e.type == "mouseDown"){
e.target.startDrag(false,bounding);
}else{
e.target.stopDrag();
}
}
public function updateShadows(objRef:int, lightSource:MovieClip):void{
//-----Cut for convenience------
}
public function checkCollision():void{
for(var v:int=0;v<objectList.length;v++){
var ball1 = objectList[v];
for(var w:int=v+1;w<objectList.length;w++){
var ball2 = objectList[w];
if((ball1.x + getRadius(ball1) + getRadius(ball2) > ball2.x) && (ball1.x < ball2.x + getRadius(ball1) + getRadius(ball2)) && (ball1.y + getRadius(ball1) + getRadius(ball2) > ball2.y) && (ball1.y < ball2.y + getRadius(ball1) + getRadius(ball2))){
var dx:Number = ball2.x - ball1.x;
var dy:Number = ball2.y - ball1.y;
var dist:Number = Math.sqrt((dx * dx) + (dy * dy));
if(dist < getRadius(ball1)+getRadius(ball2)){
var newX1:Number;
var newY1:Number;
var newX2:Number;
var newY2:Number;
trace("Magnitude 1 is : " + (Math.sqrt((xVelocityList[v] * xVelocityList[v]) + (yVelocityList[v] * yVelocityList[v]))));
trace("Magnitude 2 is : " + (Math.sqrt((xVelocityList[w] * xVelocityList[w]) + (yVelocityList[w] * yVelocityList[w]))));
newX1 = ((massList[v] * xVelocityList[v])+(massList[w] * xVelocityList[w]))/(massList[v] + massList[w]) * 2 - xVelocityList[v];
newY1 = ((massList[v] * yVelocityList[v])+(massList[w] * yVelocityList[w]))/(massList[v] + massList[w]) * 2 - yVelocityList[v];
newX2 = ((massList[v] * xVelocityList[v])+(massList[w] * xVelocityList[w]))/(massList[v] + massList[w]) * 2 - xVelocityList[w];
newY2 = ((massList[v] * yVelocityList[v])+(massList[w] * yVelocityList[w]))/(massList[v] + massList[w]) * 2 - yVelocityList[w];
xVelocityList[v] = newX1;
yVelocityList[v] = newY1;
xVelocityList[w] = newX2;
yVelocityList[w] = newY2;
ball1.x += newX1;
ball1.y += newY1;
ball2.x += newX2;
ball2.y += newY2;
}
}
}
}
}
public function randomMe(high:Number, low:Number = 0):Number{
return Math.random() * (high - low) + low;
}
public function getRadius(obj:MovieClip):Number{
return obj.width/2;
}
public function centerX(obj:MovieClip):Number{
return obj.x + getRadius(obj);
}
public function centerY(obj:MovieClip):Number{
return obj.y + getRadius(obj);
}
}
}
It's a very simple system to check for collision, just comparing the radius of the objects, and midair collisions seem fine, but if one ball lands on top of another that has no x or y velocity, it just sinks into it. Any ideas as to why?
I expect your balls behave like this: When one ball lands on top of the other, that's actually lying on the ground, the other ball gets pushed down into the ground, then you react at it within updatePhysics() by placing it into the position where it originated, thus, those balls become one within another. One of the suggestions that could remedy this will be to hold last collided object for each of the balls for one cycle of physics, say like this:
if(dist < getRadius(ball1)+getRadius(ball2)){
// process collision
ball1.lastCollided=ball2;
ball2.lastCollided=ball1;
}
Then, when you update your coordinates in updatePhysics(), check if lastCollided is null, if not, update that ball's coordinates and speed the same way, essentially simulating another collision. After checking for all the events within update physics cycle, assign null to lastCollided of all balls.

Shoot multiple bullets in a 360 degree spread?

I want this sort of effect:
http://i.imgur.com/xGi46.png
So wherever I click, it makes a bomb type effecting using the bullets.
Here's my code so far. Right now it only creates bullets in the direction of the mouse.
Sorry if the code is messy.
shotDex = new Timer(timerDelay2);
shotDex.addEventListener(TimerEvent.TIMER, shot);
stage.addEventListener(MouseEvent.MOUSE_DOWN, shootBullet);
stage.addEventListener(MouseEvent.MOUSE_UP, dontShoot);
public var angleRadian = Math.atan2(mouseY + 42.75,mouseX + 331.7);
public var angleDegree = angleRadian * 180 / Math.PI;
public var speed1:int = 10;
public var shotDex:Timer;
public var timerDelay2:int = (250);
public function shot(tEvt:TimerEvent)
{
var _bullet2:bullet2 = new bullet2;
_bullet2.x = 300;
_bullet2.y = 300;
_bullet2.angleRadian = Math.atan2(mouseY + 42.75,mouseX + 331.7);
_bullet2.addEventListener(Event.ENTER_FRAME, bulletEnterFrame);
stage.addChild(_bullet2);
}
public function shootBullet(evt:MouseEvent)
{
var _bullet2:bullet2 = new bullet2;
_bullet2.x = 300;
_bullet2.y = 300;
_bullet2.angleRadian = Math.atan2(mouseY + 42.75,mouseX + 331.7);
stage.addChild(_bullet2);
_bullet2.addEventListener(Event.ENTER_FRAME, bulletEnterFrame);
shotDex.start();
}
public function bulletEnterFrame(evt:Event)
{
var _bullet2 = evt.currentTarget;
_bullet2.x += Math.cos(_bullet2.angleRadian) * speed1;
_bullet2.y += Math.sin(_bullet2.angleRadian) * speed1;
_bullet2.rotation = _bullet2.angleRadian * 180 / Math.PI;
if (_bullet2.x < 0 || _bullet2.x > 600 || _bullet2.y < 0 || _bullet2.y > 600)
{
stage.removeChild(_bullet2);
_bullet2.removeEventListener(Event.ENTER_FRAME, bulletEnterFrame);
}
}
public function dontShoot(evt:MouseEvent)
{
shotDex.stop();
}
You need to provide a different angle for each bullet, with values evenly spaced between 0 radians and 2 * Math.PI radians:
public function shootBulletCircle(evt:MouseEvent) {
var shots:Number = 12; // Number of shots in the circle
for (var i=0; i<shots; i++) {
var _bullet2:bullet2 = new bullet2;
_bullet2.x = 300;
_bullet2.y = 300;
_bullet2.angleRadian = (i/shots)*(2*Math.PI);
stage.addChild(_bullet2);
_bullet2.addEventListener(Event.ENTER_FRAME, bulletEnterFrame);
}
}
As an optional side note: DisplayObject (which is probably a superclass of your Bullets) has a rotation property, which is used automatically when drawing, but it expects that value in degrees. You could try calculating degrees, storing that as the bullet's rotation value, and get rid of angleRadian entirely.