How do I make a bullet fire? - actionscript-3

I don't know what to do next.
Right now when I click, it adds the bullet and rotates it to the correct angle, but I don't know how to make it fire. I want to have the bullet shoot to where the mouse is pointing. Thanks!
PS: Sorry if the code is messy.
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.events.KeyboardEvent;
import flash.utils.Timer;
import flash.text.Font;
import flash.events.MouseEvent;
import flash.text.TextDisplayMode;
import flash.text.TextExtent;
import flash.text.TextField;
import flash.text.TextFormat;
import fl.motion.easing.Back;
import flash.display.DisplayObject;
public class GameEnter extends MovieClip
{
public var _bullet:bullet;
public function GameEnter()
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, shootBullet);
stage.addEventListener(MouseEvent.MOUSE_UP, removeBullet);
}
public function init()
{
_bullet = new bullet();
addChild(_bullet);
_bullet.x = stage.stageWidth / 2;
_bullet.y = stage.stageHeight / 2;
addEventListener(Event.ENTER_FRAME, onEnter);
}
public function onEnter(event:Event)
{
var dx:Number = mouseX - _bullet.x;
var dy:Number = mouseY - _bullet.y;
var angle:Number = Math.atan2(dy,dx) * 180 / Math.PI;
_bullet.rotation = angle;
}
public function shootBullet(event:MouseEvent)
{
init();
}
public function removeBullet(event:MouseEvent)
{
removeChild(_bullet);
}
}
}

To move an object in a direction based on rotation, you'll need cos and sin.
Math.cos() and Math.sin() only accept radians, so you'll need to convert rotation to radians like you have for Math.atan2() in your example.
Sample:
// Note: Utilising the property 'angle' from your code.
_bullet.x += Math.cos(angle);
_bullet.y += Math.sin(angle);
And then obviously multiply these values by a value that will represent how fast you want the bullet to go, eg:
var velocity:Number = 10.5;
_bullet.x += Math.cos(angle) * velocity;
_bullet.y += Math.sin(angle) * velocity;

Related

AS3 lineTo method alternative

This is more of a logical question than just looking for code, although it might be needed.
So i'm creating a drawing application and the first thing to do is use the lineTo method to draw a line -- that's all fine. But I learned this is not what I want, it does draw fine etc. but I want a tool that wouldn't "draw a line". I want a tool that doesn't lay the line down as you let go of click, but it lays down right when you click.
Now I don't really have a clue how to create this; can someone explain how one would code such a thing? This would sort of be an alternative to lineTo -- sorry if this sounds confusing, it's hard to word.
Here are two examples:
Drawing application that draws like a pen
Drawing application that draws lines / arrows
Pen Drawing (SWF Example)
This draws lines as curve to match the input device, persisting the line as it's drawn:
Code:
package
{
import flash.display.Graphics;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.MouseEvent;
import flash.geom.Point;
[SWF(percentWidth = 100, percentHeight = 100, backgroundColor = 0xefefef, frameRate = 30)]
public class DrawingExample extends Sprite
{
//------------------------------
// model
//------------------------------
protected var lastPoint:Point;
//------------------------------
// lifecycle
//------------------------------
public function DrawingExample()
{
super();
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
beginDrawing();
}
protected function beginDrawing():void
{
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
protected function mouseDownHandler(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
// mark mouse down location
lastPoint = new Point(mouseX, mouseY);
// listen for movement or up/out
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
stage.addEventListener(MouseEvent.MOUSE_OUT, mouseUpHandler);
}
protected function mouseMoveHandler(event:MouseEvent):void
{
var g:Graphics = graphics;
g.lineStyle(1, 0x0000ff);
// draw line segment
g.moveTo(lastPoint.x, lastPoint.y);
g.lineTo(mouseX, mouseY);
// mark end of line segment
lastPoint = new Point(mouseX, mouseY);
}
protected function mouseUpHandler(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
stage.removeEventListener(MouseEvent.MOUSE_OUT, mouseUpHandler);
beginDrawing();
}
}
}
Line Drawing (SWF Example)
Although tuned for arrow heads, the concept is the same for lines. When the input device is down, a line / arrow is staged but not persisted until the input device is up. Once drawn, the line persists.
Code:
package
{
import flash.display.CapsStyle;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.LineScaleMode;
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(percentWidth = 100, percentHeight = 100, backgroundColor = 0xefefef, frameRate = 30)]
public class Arrows extends Sprite
{
public var arrows:Vector.<Sprite> = new Vector.<Sprite>();
public var canvas:Sprite;
public var lineColor:uint = Math.random() * 0xffffff;
public var lineWeight:Number = 5;
private var startPoint:Point;
public function Arrows()
{
super();
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
protected function addedToStageHandler(event:Event):void
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
addCanvas();
}
protected function addCanvas():void
{
canvas = new Sprite();
addChild(canvas);
lineColor = Math.random() * 0xffffff;
// give alpha for interaction
var g:Graphics = canvas.graphics;
g.beginFill(0x0, 0.0);
g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
g.endFill();
// listen for mouse down
canvas.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
protected function mouseDownHandler(event:MouseEvent):void
{
canvas.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
// mark start point
startPoint = new Point(event.localX, event.localY);
// start rendering
canvas.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
// listen for mouse up / out to end arrow
canvas.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
canvas.addEventListener(MouseEvent.MOUSE_OUT, mouseUpHandler);
}
protected function enterFrameHandler(event:Event):void
{
var angle:Number = polarAngle(new Point(mouseX, mouseY), new Point(startPoint.x, startPoint.y));
// draw line
var g:Graphics = canvas.graphics;
g.clear();
// give alpha for interaction
g.beginFill(0x0, 0.0);
g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
g.endFill();
g.lineStyle(lineWeight, lineColor, 1, true, LineScaleMode.NORMAL, CapsStyle.SQUARE, JointStyle.MITER);
g.moveTo(startPoint.x, startPoint.y);
g.lineTo(mouseX, mouseY);
// draw arrow head
g.moveTo(mouseX - (20 * Math.cos((angle - 45) * Math.PI / 180)),
mouseY - (20 * Math.sin((angle - 45) * Math.PI / 180)));
g.lineTo(mouseX + (5 * Math.cos((angle) * Math.PI / 180)),
mouseY + (5 * Math.sin((angle) * Math.PI / 180)));
g.lineTo(mouseX - (20 * Math.cos((angle + 45) * Math.PI / 180)),
mouseY - (20 * Math.sin((angle + 45) * Math.PI / 180)));
}
protected function polarAngle(point:Point, center:Point=null):Number
{
if (!center)
center = new Point(0, 0);
return Math.atan2(point.y - center.y, point.x - center.x) * 180 / Math.PI;
}
protected function mouseUpHandler(event:MouseEvent):void
{
canvas.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
canvas.removeEventListener(MouseEvent.MOUSE_OUT, mouseUpHandler);
// stop rendering
canvas.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
// push canvas to arrows collection
arrows.push(canvas);
// add a fresh canvas
addCanvas();
}
}
}

as3 hitTestPoint detecting alpha

I am trying to make maze where the user draws with mouse and if they hit the wall it erases the line they just drew. I have a png file with alpha that creates the walls of the maze.
I need the user to draw on the alpha but when they hit a non alpha it will trigger an action and erase the line.
Here is the line I am having issues with:
if (myshape.hitTestPoint(theBall.x,theBall.y, true))
Here is the full code:
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.LineScaleMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.*;
public class MazeClass extends Sprite
{
//Are we drawing or not?
private var drawing:Boolean;
public var myshape:Shape;
public var alreadyDrawn:Shape;
public var theBall:Ball = new Ball();
//alreadyDrawn = new Shape();
public function MazeClass()
{
if (stage)
{
myshape = new Shape();
myshape.graphics.lineStyle(12,0x000000);
addChild(myshape);
drawing = false;//to start with
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, draw);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
//stage.addEventListener(Event.ENTER_FRAME, checkIt);
addChild(theBall);
}
}
public function startDrawing(event:MouseEvent):void
{
myshape.graphics.moveTo( mouseX, mouseY);
drawing = true;
}
public function draw(event:MouseEvent)
{
if (drawing)
{
//checkIt();
myshape.graphics.lineTo(mouseX,mouseY);
if (myshape.hitTestPoint(theBall.x,theBall.y, true))
{
trace("Hit A WALL!");
myshape.graphics.clear();
myshape.graphics.lineStyle(12, 0xFFFFFF);
myshape.graphics.moveTo(mouseX,mouseY);
}
}
}
public function stopDrawing(event:MouseEvent)
{
drawing = false;
}
}
}
Another option is to test the colour of the map bitmapdata pixel that corresponds to the "player's position" (the end of the drawn line, in this case):
var testPixel:uint = _myBitmapData.getPixel(xPosition, yPosition);
Or you can use .getPixel32 which includes alpha in the returned uint.
I FOUND A WORKING SOLUTION:
I found a working solution thanks to fsbmain. Thank you. I am posting my full code in hopes that this can help someone else.
In the end I had to use another movieClip rather than the mouse, but this worked for me. Now instead of drawing anywhere in the maze they have to drag a little character named Beau thru the maze. This works better for me.
It would be nice to know how to also detect if the mouse or the actual line I am drawing hit the wall as well. Maybe someone can make a suggestion. Nevertheless, thanks for helping me get this far.
The short and essential code to make my movieClip detect the alpha can be found here. It really is very short compared to other complicated options I found. Here is the link: http://www.mikechambers.com/blog/2009/06/24/using-bitmapdata-hittest-for-collision-detection/
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.JointStyle;
import flash.display.LineScaleMode;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.*;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;
import flash.events.TouchEvent;
import flash.ui.Multitouch;
import flash.ui.MultitouchInputMode;
import flash.desktop.NativeApplication;
import flash.system.Capabilities;
import flash.display.*;
import flash.geom.*;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Matrix;
public class MazeClass extends Sprite
{
//Are we drawing or not?
private var drawing:Boolean;
public var myshape:Shape;
public var alreadyDrawn:Shape;
public var theMap:*;
public var swiper:Swiper = new Swiper();
public var Beau:littleBeau = new littleBeau();
//alreadyDrawn = new Shape();
public var currentGalleryItem:Number = 1;
public var totalGalleryItems:Number = 4;
public var redClipBmpData:BitmapData;
public var blueClipBmpData:BitmapData;
public var redRect:Rectangle;
public var blueRect:Rectangle;
public function MazeClass()
{
if (stage)
{
theMap = new MapOne();
myshape = new Shape();
myshape.graphics.lineStyle(33,0x0aa6df);
addChild(myshape);
drawing = false;//to start with
stage.addEventListener(MouseEvent.MOUSE_DOWN, startDrawing);
stage.addEventListener(MouseEvent.MOUSE_MOVE, draw);
stage.addEventListener(MouseEvent.MOUSE_UP, stopDrawing);
//stage.addEventListener(Event.ENTER_FRAME, checkIt);
stage.addEventListener(KeyboardEvent.KEY_UP, fl_OptionsMenuHandler);
Multitouch.inputMode = MultitouchInputMode.GESTURE;
addChild(theMap);
//theMap.height = stage.stageHeight - 200;
theMap.theStart.alpha = 0;
theMap.theFinish.alpha = 0;
addChild(swiper);
swiper.y = stage.stageHeight - swiper.height;
swiper.addEventListener(TransformGestureEvent.GESTURE_SWIPE, fl_SwipeToGoToNextPreviousFrame);
addChild(Beau);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
Beau.addEventListener(MouseEvent.MOUSE_DOWN, BeauStartDrag);
Beau.addEventListener(MouseEvent.MOUSE_UP, BeauStopDrag);
redRect = theMap.getBounds(this);
redClipBmpData = new BitmapData(redRect.width,redRect.height,true,0);
redClipBmpData.draw(theMap);
blueRect = Beau.getBounds(this);
blueClipBmpData = new BitmapData(blueRect.width,blueRect.height,true,0);
blueClipBmpData.draw(Beau);
//blueClipBmpData.x = theMap.theStart.x;
//blueClipBmpData.y = theMap.theStart.y - swiper.height;
stage.addEventListener(Event.ENTER_FRAME, enterFrame);
}
}
public function enterFrame(e:Event):void
{
//Beau.x = mouseX;
//Beau.y = mouseY;
if (redClipBmpData.hitTest(new Point(theMap.x, theMap.y),
255,
blueClipBmpData,
new Point(Beau.x, Beau.y),
255
))
{
trace("hit");
clearAll();
//redClip.filters = [new GlowFilter()];
}
else
{
trace("No Hit");
}
}
public function BeauStartDrag(event:MouseEvent):void
{
Beau.startDrag();
drawing = true;
}
public function BeauStopDrag(event:MouseEvent):void
{
drawing = false;
Beau.stopDrag();
}
public function startDrawing(event:MouseEvent):void
{
myshape.graphics.moveTo( mouseX, mouseY);
}
//drawing = true;
public function draw(event:MouseEvent)
{
if (drawing)
{
//checkIt();
myshape.graphics.lineTo(mouseX,mouseY);
}
}
public function stopDrawing(event:MouseEvent)
{
//drawing = false;
}
public function fl_OptionsMenuHandler(event:KeyboardEvent):void
{
if ((event.keyCode == 95) || (event.keyCode == Keyboard.MENU))
{
NativeApplication.nativeApplication.exit(0);
}
}
public function clearAll()
{
myshape.graphics.clear();
myshape.graphics.lineStyle(12, 0x0aa6df);
myshape.graphics.moveTo(mouseX,mouseY);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
drawing = false;
Beau.stopDrag();
}
public function fl_SwipeToGoToNextPreviousFrame(event:TransformGestureEvent):void
{
if (event.offsetX == 1)
{
if (currentGalleryItem > 1)
{
currentGalleryItem--;
trace("swipe Right");
clearAll();
removeChild(theMap);
theMap = new MapOne();
addChild(theMap);
theMap.height = stage.stageHeight - 200;
theMap.theStart.alpha = 0;
theMap.theFinish.alpha = 0;
addChild(Beau);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
}
}
else if (event.offsetX == -1)
{
if (currentGalleryItem < totalGalleryItems)
{
currentGalleryItem++;
trace("swipe Left");
clearAll();
removeChild(theMap);
theMap = new MapTwo();
addChild(theMap);
theMap.height = stage.stageHeight - 200;
theMap.theStart.alpha = 0;
theMap.theFinish.alpha = 0;
addChild(Beau);
Beau.x = theMap.theStart.x;
Beau.y = theMap.theStart.y - swiper.height;
}
}
}
}
}

AS3: Why is this fluid simulation running slower and slower?

I'v got 2 classes. Simulating fluid. Both classes are pretty straight forward and short, but after 2 seconds of running, the simulation gets really slow, looks like a memory leak. But i can't see any leaks in this code.
Please let me know if you can figure out, why this is happening?
FluidLayer.as
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.BitmapData;
import flash.filters.BlurFilter;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.geom.ColorTransform;
import flash.display.IBitmapDrawable;
import flash.events.Event;
import flash.display.MovieClip;
public class FluidLayer extends MovieClip {
private var canvas:Sprite;
private var b:Bitmap;
private var blur:BlurFilter = new BlurFilter(20,20,3);
private var bmd1:BitmapData;
public function FluidLayer() {
canvas = new Sprite();
for(var i:int = 0;i < 600;i++){
var p:Particle = new Particle();
canvas.addChild(p);
p.x = stage.stageWidth * Math.random();
p.y = stage.stageHeight* Math.random();
p.initi(stage);
}
canvas.filters = new Array(blur);
addEventListener(Event.ENTER_FRAME, render);
}
private function render(e:Event):void{
remove();
b = new Bitmap(makeFluid(canvas),"auto", true);
b.alpha = 0.7;
addChild(b);
}
private function makeFluid(o:Sprite):BitmapData{
bmd1 = new BitmapData(stage.stageWidth, stage.stageHeight, true);
bmd1.draw(o,null,null,null,null,true);
bmd1.threshold(bmd1, bmd1.rect, new Point(0,0), ">", 0XFF2b2b2b, 0x55FFFF, 0xFFFFFF, false);
return bmd1;
}
private function remove():void{
if(numChildren > 1)
removeChildAt(1);
if(bmd1){
bmd1.dispose();
bmd1 = null;
}
}
}}
Particle.as
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
public class Particle extends MovieClip {
private var speedX:int;
private var speedY:int;
private var _s:Stage;
public function Particle() {
this.graphics.beginFill(0x00CCFF);
this.graphics.drawCircle(0,0,Math.random() * 30);
speedX = Math.random() * 10 - 5;
speedY = Math.random() * 10 - 5;
this.addEventListener(Event.ADDED_TO_STAGE, initi);
}
public function initi(s:Stage):void{
this._s = s;
addEventListener(Event.ENTER_FRAME, render);
}
private function render(e:Event):void{
this.x += Math.random()*speedX;
this.y += Math.random()*speedY;
if(this.x > _s.stageWidth || this.y > _s.stageHeight){
//this.x = Math.random()*_s.stageWidth;
//this.y = Math.random()*_s.stageHeight;
removeEventListener(Event.ENTER_FRAME, render);
this.parent.removeChild(this);
}
}
}}
You must call bmd1.dispose(); before reinstantiating it or it will not release the bitmap from memory.
Edit:
After looking through your code very carefully, optimizing it, and cleaning up some things, I have come to the conclusion that your simulation is no longer running slower and slower.
The problem was that the way you would calculate the particle's x and y speed. Essentially it would diminish in speed until stopping all together. On top of the massive high quality blur you have placed and the lack of freeing bitmaps, your movie would appear and actually slow to a crawl.
Here is your code I have modified. I benchmarked it and it didn't peak above 10% cpu or 40k memory after 15 minutes.
Particle.as
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
public class Particle extends MovieClip {
private var speedX:int;
private var speedY:int;
private var deleted:Boolean = false;
public function Particle() {
this.graphics.beginFill(0x00CCFF);
this.graphics.drawCircle(0,0,Math.random() * 30);
//The max prevents particle speed from rounding to zero.
speedX = Math.ceil(Math.random() * 10 - 5);
speedY = Math.ceil(Math.random() * 10 - 5);
}
public function render():void{
//It originally appeared to be slowing down. In-fact, it was.
x += Math.random() * speedX;
y += Math.random() * speedY;
deleted = (x > FluidLayer.w || y > FluidLayer.h);
//Comment this below if you want particles to be removed once they go out of bounds.
if(deleted) {
x = Math.random() * FluidLayer.w;
y = Math.random() * FluidLayer.h;
deleted = false;
}
}
public function isDeleted():Boolean {
return deleted;
}
}
}
FluidLayer.as
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.BitmapData;
import flash.filters.BlurFilter;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.geom.ColorTransform;
import flash.display.IBitmapDrawable;
import flash.events.Event;
import flash.display.MovieClip;
public class FluidLayer extends MovieClip {
private var canvas:Sprite;
private var bitmap:Bitmap;
private var bitmapData:BitmapData;
private var particleArray:Array = new Array();
public static const w:uint = 550;
public static const h:uint = 400;
public function FluidLayer() {
addEventListener(Event.ADDED_TO_STAGE, initialize);
}
//By only one event handler to render, we prevent the overhead of 599 bubbling events.
private function render(e:Event):void {
for each(var p:Particle in particleArray) {
p.render();
//uncomment below if you want particles to become removed when they navigate out of bounds.
//if(p.isDeleted()) {
//canvas.removeChild(p);
//particleArray.splice(particleArray.indexOf(p),1);
//}
}
bitmapData.fillRect(bitmapData.rect, 0); //clear the bitmapdata
bitmapData.draw(canvas,null,null,null,null,true);
bitmapData.threshold(bitmapData, bitmapData.rect, new Point(0,0), ">", 0XFF2b2b2b, 0x55FFFF, 0xFFFFFF, false);
}
//We call initialize once the fluid layer has been added to stage
//or else stage values will be null.
private function initialize(e:Event):void {
canvas = new Sprite();
//You DEFINITELY want to lower the blur amount here.
//This is what is ultimately slowing your SWF down to a crawl.
//canvas.filters = new Array(new BlurFilter(20,20,1));
for(var i:uint = 0; i < 600; i++) {
var p:Particle = new Particle();
p.x = Math.random() * w;
p.y = Math.random() * h;
canvas.addChild(p);
particleArray.push(p);
}
//The bitmap and bitmapData only need to be initialized once
bitmapData = new BitmapData(w, h, true);
bitmap = new Bitmap(bitmapData, "auto", true);
bitmap.alpha = 0.7;
addChild(bitmap);
addEventListener(Event.ENTER_FRAME, render);
}
}
}
The original slowdown appears to be the blur filter on the canvas. (Comment the filter out to see proof)
The automatic creation of bitmaps by flash (CacheAsBitmap & Bitmap Filter buffers) to render the filter is likely causing the memory leak and this could be due the constantly changing dimension of canvas, due to the particles movement.
Try adding this line after creating canvas for a quick fix:
canvas.scrollRect = new Rectangle(0,0,stage.stageWidth,stage.stageHeight);
By limiting the size of the canvas with the scrollRect we are stopping this reallocation.
However the fluid no longer goes to the edges of the stage. This could be worked around in the draw and bitmap allocation routines, increasing dimensions and offsetting, i'll let you have a go at that but its connected partially to the blur filter amount.
I'd suggest adapting these idea with the very good ideas in Andreas' code.
So i put together a solution for my question with the help of Andreas and adamh.
Andreas - showed me that i forgot to dispose the bitmapdata (really nice spot!)
Adamh - told me to define scrollrect on the canvas (Upped the performance a lot!)
But what did it in the end and made the performance fluid, was a simple mistake from my side. I noticed in the particle.as > render(), that i was only checking if the particle was out of bounds on 2 sides (facepalm), stupid mistake. When i changed the render function to check the remaining 2 sides, it fixed the performance issue.
Sorry for the stupid question :) and thanks again to Andreas and adamh
the final classes:
FluidLayer.as
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.display.BitmapData;
import flash.filters.BlurFilter;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.geom.ColorTransform;
import flash.display.IBitmapDrawable;
import flash.events.Event;
import flash.display.MovieClip;
import flash.geom.Rectangle;
public class FluidLayer extends MovieClip {
private var canvas:Sprite;
private var b:Bitmap;
private var blur:BlurFilter = new BlurFilter(20,20,3);
private var bmd1:BitmapData;
public function FluidLayer() {
canvas = new Sprite();
canvas.scrollRect = new Rectangle(0,0,1010,550);
for(var i:int = 0;i < 600;i++){
var p:Particle = new Particle();
canvas.addChild(p);
p.x = stage.stageWidth * Math.random();
p.y = stage.stageHeight* Math.random();
p.initi(stage);
}
canvas.filters = new Array(blur);
addEventListener(Event.ENTER_FRAME, render);
}
private function render(e:Event):void{
remove();
b = new Bitmap(makeFluid(canvas),"auto", true);
b.alpha = 0.7;
addChild(b);
}
private function makeFluid(o:Sprite):BitmapData{
bmd1 = new BitmapData(stage.stageWidth, stage.stageHeight, true);
bmd1.draw(o,null,null,null,null,true);
bmd1.threshold(bmd1, bmd1.rect, new Point(0,0), ">", 0XFF2b2b2b, 0x55FFFF, 0xFFFFFF, false);
return bmd1;
}
private function remove():void{
if(numChildren > 1)
removeChildAt(1);
if(bmd1){
bmd1.dispose();
bmd1 = null;
}
}}}
Particle.as
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.display.Stage;
public class Particle extends MovieClip {
private var speedX:int;
private var speedY:int;
private var _s:Stage;
public function Particle() {
this.graphics.beginFill(0x00CCFF);
this.graphics.drawCircle(0,0,Math.random() * 30);
speedX = Math.random() * 10 - 5;
speedY = Math.random() * 10 - 5;
this.addEventListener(Event.ADDED_TO_STAGE, initi);
}
public function initi(s:Stage):void{
this._s = s;
addEventListener(Event.ENTER_FRAME, render);
}
private function render(e:Event):void{
this.x += Math.random()*speedX;
this.y += Math.random()*speedY;
if(this.x > _s.stageWidth || this.y > _s.stageHeight || this.x < 0 && this.y < 0){
this.x = Math.random()*_s.stageWidth;
this.y = Math.random()*_s.stageHeight;
//removeEventListener(Event.ENTER_FRAME, render);
//this.parent.removeChild(this);
}
}
}}

How can I calculate the angle

I'm creating a game where if the enemy is in a certain range and is in front of the player the player can attack the enemy. I have worked out the radius distance and made it facing forward depending in which way the player faces but how can i create the angle so it makes like a cone shape from the player. I have got an image. The thin green line is the radius which I have worked out but how can i calculate the red cone.
Here is the image for more better understanding
http://tinypic.com/view.php?pic=28v63h0&s=6
This is what I done so far
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
public class Player extends MovieClip
{
var radius:Number = 60;
public function Player()
{
addEventListener(Event.ENTER_FRAME, Update);
}
function Update(event:Event)
{
var radiusx:Number = x+radius*Math.cos(rotation/180*Math.PI);
var radiusy:Number = y+radius*Math.sin(rotation/180*Math.PI);
// Rotate to mouse;
var dx = parent.mouseX - x;
var dy = parent.mouseY - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
}
}
}
You can use the definition of tangent:
tan(a/2) = s/(2d)
where s is size (diamerer) of the enemy and d is the shortest distance to the enemy. Here a is the total visible angle (between two red lines).

Need some help completing a bumptop-ish selection tool

I'm in the midst of creating a Bumptop styled selection tool. Right now I got as far as creating the tool itself (which actually works pretty good) and spreading some random square items on the stage. This is the class that creates the selection tool :
package com.reyco1.medusa.selectiontool
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;
public class SelectionBase extends Sprite
{
private var points:Array = [];
public function SelectionBase()
{
super();
addEventListener(Event.ADDED_TO_STAGE, initialize);
}
private function initialize(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, initialize);
points.push(new Point(mouseX, mouseY)); stage.addEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
}
private function handleMouseMove(e:MouseEvent):void
{
graphics.clear();
graphics.beginFill(0x33CCFF, .5);
graphics.drawCircle(0, 0, 20);
graphics.endFill();
graphics.moveTo(0, 0);
graphics.lineStyle(1.5, 0x33CCFF, .5);
graphics.lineTo(mouseX, mouseY);
points.push(new Point(mouseX, mouseY));
graphics.beginFill(0x33CCFF, .1);
graphics.moveTo(points[0].x, points[0].y);
for (var i:uint = 1; i < points.length; i++)
{
graphics.lineTo(points[i].x, points[i].y);
}
graphics.lineTo(points[0].x, points[0].y);
graphics.endFill();
dispatchEvent(new Event("UPDATE"));
}
public function clear():void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, handleMouseMove);
graphics.clear();
}
}
}
And this is the document class that implements it :
package
{
import com.reyco1.medusa.selectiontool.SelectionBase;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.StageAlign;
import flash.display.StageQuality;
import flash.display.StageScaleMode;
[SWF(width = '1024', height = '768', backgroundColor = '0x000000')]
public class SelectionToolPrototype extends Sprite
{
private var selectionTool:SelectionBase;
public function SelectionToolPrototype()
{
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.quality = StageQuality.MEDIUM;
stage.addEventListener(MouseEvent.MOUSE_DOWN, handleDown);
stage.addEventListener(MouseEvent.MOUSE_UP, handleUp);
placeShapesRandomly();
}
private function placeShapesRandomly():void
{
for(var a:Number = 0; a<25; a++)
{
var s:Sprite = new Sprite();
s.graphics.beginFill(Math.random() * 0xCCCCCC);
s.graphics.drawRect(0, 0, 50, 50);
s.graphics.endFill();
s.x = Math.floor(Math.random() * 900 - 40) + 40;
s.y = Math.floor(Math.random() * 700 - 40) + 40;
s.rotation = Math.floor(Math.random() * 360 - 40) + 40;
s.buttonMode = true;
addChild(s);
}
}
private function handleUp(e:MouseEvent):void
{
selectionTool.removeEventListener("UPDATE", handleToolUpdate);
removeChild(selectionTool);
selectionTool = null;
}
private function handleDown(e:MouseEvent):void
{
selectionTool = new SelectionBase();
selectionTool.addEventListener("UPDATE", handleToolUpdate);
selectionTool.x = mouseX;
selectionTool.y = mouseY;
addChild(selectionTool);
}
private function handleToolUpdate(e:Event):void
{
// logic to determin if items are within selection goes here
}
}
}
I've tried using collision detection by means of BitmapData and even using collision libraries like CDK but I cant get anything to work. Anybody have an idea what I should use in the handleToolUpdate(e:MouseEvent); ? Thanks!
Update:
I'll break it down. Basically I am trying to create a prototype of the BumpTop Lasso or Selection tool.
I need help in finding out which objects either collide or have a point within the bounds of the drawn lasso.
I have upload what I have so far to my server here : http://labs.reyco1.com/bumptop/SelectionToolPrototype.html. You can see the source by right clicking and selecting "View Source".
Like I said in my earlier post, I tried using Bitmapdata collision testing and even tried using the Collision Detection Kit to no avail. Thanks in advance.
Loop through the display object you are attaching your random sprites to, and using for each, check their value of hitTestObject against your selectionTool instance.
Here are the Adobe docs for hitTestObject():
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#hitTestObject%28%29