Move projectile to mouse-click position AS3 - actionscript-3

I have a cannon and cannonball. How do I make a cannonball to move in a line from cannon to the Mouse Click position and stop/disappear/activate Explode animation?
I've tried different solutions and none of them would seem to work for me so I cleared it a bit.
And yes, I know it's ugly.
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.display.MovieClip;
import flash.events.Event;
import flash.ui.Mouse;
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.utils.Timer;
import flash.display.Sprite;
addEventListener(Event.ENTER_FRAME, enterFr);
function enterFr(e:Event)
{
aims.x = mouseX;
aims.y = mouseY;
}
Mouse.hide();
zamok.addEventListener(MouseEvent.CLICK, fire);
function fire(m:MouseEvent)
{
var s:Sound = new cannonFire();
s.play();
var explo:boom = new boom();
explo.x = mouseX;
explo.y = mouseY;
addChild(explo);
}

Well you should think of the process that you want to implement.
First of all it is not instant, it takes some time for cannonball to move to the point where mouse clicked.
Let's start with some function that will create a cannonball:
private function fireCannonBall(target: Point):void
{
const cannonBall:CannonBall = new CannonBall(); // you need to implement this class, or just use some MovieClip from library;
cannonBall.x = initialPosition.x; // initial position is a point where your cannon is located.
cannonBall.y = initialPosition.y;
addChild(cannonBall);
// I suggest using TweenNano, but it has some limitations, read the License Agreement carefully
TweenNano.to(cannonBall, 15 /* animation duration */, {x: target.x, y: target.y, onComplete: makeExplosion, onCompleteParams: [cannonBall]});
}
private function makeExplosion(cannonBall: CannonBall):void
{
/* I leave this part to you, here you might want to launch some explosion animation */
}
Now we need to handle the click:
private function onMouseClick(e: MouseEvent):void
{
const target: Point = new Point(stage.mouseX, stage.mouseY);
//and launch the cannonBall:
fireCannonBall(target);
}
That's it, roughly.
To know more about TweenNano please follow the link:
https://greensock.com/tweennano-as

Related

Unable to addChild on MouseCoordinations

What i am trying to do is, to place a new tower each time on MouseX and MouseY. but it seems it isn't working Any Idea guys?
or if you can create a tileMap array and add new child of PrototypeTower each time when we click on the Tower (on x=50, y=400) to select and place wherever we want. When i click the the box at x=50, y=400, the startDrag() doesn't work.
Main.as
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.ui.Mouse;
public class Main extends Sprite
{
private var pTower:PrototypeTower = new PrototypeTower;
private var zTower:PrototypeTower = new PrototypeTower;
private var fTower:PrototypeTower = new PrototypeTower;
public function Main()
{
pTower.x = 50;
pTower.y = 400;
addChild(pTower);
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
private function onAddedToStage(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
pTower.addEventListener(MouseEvent.CLICK, onClicked);
}
private function onClicked(e:Event):void
{
removeEventListener(MouseEvent.CLICK, onClicked);
zTower.x = mouseX;
zTower.y = mouseY;
addChild(zTower);
zTower.startDrag();
addEventListener(MouseEvent.CLICK, onPlaced);
}
private function onPlaced(e:Event):void
{
removeEventListener(MouseEvent.CLICK, onPlaced);
zTower.stopDrag();
fTower.x = mouseX
fTower.y = mouseY;
addChild(fTower);
}
}
}
PrototypeTower.as
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.Event;
public class PrototypeTower extends MovieClip
{
public function PrototypeTower()
{
this.graphics.beginFill(0x00FF00);
this.graphics.drawRect(this.x, this.y, 20, 20);
this.graphics.endFill();
}
}
}
Thank you, i am totally noob, wondering around from days!
Sorry this is just a schematic for now. I'll try to refine it later if you need. Hopefully this clears some things up for you though
When you click the tower, add a new tower at the x,y of the mouse and do some sort of startDrag(tower) on the new tower you just added. Then when you click on the stage, stop the drag and set the new X,y
edit
You might try getting rid of all your removeEventListener calls
I think your problem is you are removing the event listener that gets added in your main function. Keep in mind that the main function (class constructor) for the document class only gets called once, so you add an event listener for ADDED_TO_STAGE only once, and then you remove it the first time you try to add anything to the stage, and you never put it back. Just don't remove it in the first place.
You are calling zTower.startDrag() before you add it to the stage. Do addChild(zTower) and then zTower.startDrag()

Unable to stop spawning an enemy

Okay so here's the dealio.
The code below is what I use to spawn a single enemy periodically in my horror game. He spawns at the window every 10 seconds, then every 6 seconds later, he enters the room and you're essentially dead already, because 5 seconds after that you get a lovely jumpscare. The moment the enemy shifts from the window to the bedroom is when I want the window enemy to stop spawning.
EnemyShipTimer is the timer that spawns the enemy.
enemyTimer is the timer that counts how long the enemy has been at
the window, and then in the room.
In the main file, I've attempted to get rid of the enemy a number of ways, to no effect.
So function gtfo is my latest attempt at removing the enemy, by trying to stop the spawning from the class file itself. It still hasn't worked. Maybe I need to somehow remove the class file from my game, but I have no idea how. Please help! ;A;
PS, countClick counts how many clicks you've done to make the enemy go away, although when I make him go away, room enemy still spawns :c
package
{
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.utils.Timer;
import flash.utils.getTimer;
import flash.events.TimerEvent;
import flash.text.TextField;
public class EnemyShip extends MovieClip
{
private var clickCount:int = 0;
private var enemyShipTimer:Timer;
private var enemyTimer:Timer;
public function EnemyShip()
{
this.x = 900;
this.y = 214;
addEventListener(MouseEvent.CLICK, addClick);
addEventListener(MouseEvent.CLICK, countclick);
addEventListener(TimerEvent.TIMER, gtfo);
}
function gtfo(e:TimerEvent):void{
if (enemyTimer.currentCount==5)
enemyShipTimer.stop();
stage.removeChild(this);
}
function addClick(event:MouseEvent):void
{
clickCount = clickCount + 1;
trace("Clickage : " + clickCount);
}
function countclick(event:MouseEvent):void
{
if (clickCount ==4)
{
stage.removeChild(this);
}
}
}
}
The following is the relevant main timeline code that may be clashing with the code (I have updated the package class as per #Karma 's helpful instructions c: though the enemy still spawns; I think what the problem is now is that the timer functions clash with timer functions I've put in my main timeline, and I attempted to sort of move them into the package class but I don't know how to add the necessary movieclips so that I won't get access of undefined property errors so I separated the two once more
enemy is the window spawning enemy.
mosnta is the room spawning enemy.
sod is the screen of death (game over screen) which does not play at all.
var enemyShipTimer:Timer;
function sendEnemy(e:Event)
{
var enemy = new EnemyShip();
stage.addChild(enemy);
var enemytimer = new Timer (1000, count);
enemytimer.start();
enemyShipTimer = new Timer(10000);
enemyShipTimer.addEventListener("timer", sendEnemy);
enemyShipTimer.start();
enemytimer.addEventListener(TimerEvent.TIMER, countdowndesu);
function countdowndesu(e:Event):void{
if (enemytimer.currentCount>5){
trace("ur ded");
enemytimer.removeEventListener(TimerEvent.TIMER, countdowndesu);
mosnta.visible=true;
enemy.visible=false;
if (enemytimer.currentCount==8){
sod.visible=true;
sod.gotoAndPlay(2);
}
}
}
}
Not really understanding the dynamics of how your game works, but here's an altered version of your code with working Timers. Maybe this will help you figure out how to fix your issues
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
public class EnemyShip extends MovieClip
{
private var clickCount:int = 0;
private var enemyShipTimer:Timer;
private var enemyTimer:Timer;
public function EnemyShip()
{
this.x = 900;
this.y = 214;
//only need one click handler
addEventListener(MouseEvent.CLICK, addClick);
//Instantiate Timers
enemyShipTimer = new Timer(10000); //10 seconds
enemyTimer = new Timer(6000); //6 seconds
//add TimerEvent listeners onto Timer Objects
enemyShipTimer.addEventListener(TimerEvent.TIMER, gtfo);
enemyTimer.addEventListener(TimerEvent.TIMER, enemyTimerHandler);
//Start the timers
enemyShipTimer.start();
enemyTimer.start();
}
//This gets called every 10 seconds
private function gtfo(e:TimerEvent):void
{
trace("enemy spawns at window");
if (enemyTimer.currentCount == 5) {
enemyShipTimer.stop();
stage.removeChild(this);
}
}
//This gets called every 6 seconds
private function enemyTimerHandler(e:TimerEvent):void
{
trace("enemy moves to room");
}
private function addClick(event:MouseEvent):void
{
clickCount ++;
trace("Clickage : " + clickCount);
if (clickCount == 4)
{
stage.removeChild(this);
}
}
}
}

AS3/AIR Mobile Click and/or touchevents on moving objects

few weeks ago i asked a question about a similair issue, but within the Starling Framework (Starling TouchEvent on Sprite)
Now, i am working on another mobile app/game with Away3d. I seem to have the same problem touching/tapping a moving sphere or box. When the sphere is not moving, i can just tap it exactly at its position, but when it rotates, the click-event doesnt fire very accurate.
this only happens on Mobile (tested on Android 4.2.2: Nexus7/Galaxy S2 and iOS: iPad2/iPad Retina)
package {
import away3d.containers.ObjectContainer3D;
import away3d.containers.View3D;
import away3d.core.pick.PickingColliderType;
import away3d.core.pick.PickingType;
import away3d.debug.AwayStats;
import away3d.entities.Mesh;
import away3d.events.MouseEvent3D;
import away3d.primitives.SphereGeometry;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Vector3D;
[SWF(frameRate="60")]
public class Main extends Sprite {
private var _container:ObjectContainer3D;
private var _view:View3D;
private var _sphere:Mesh;
public function Main()
{
super();
addEventListener(Event.ADDED_TO_STAGE, onAdded_toStage);
}
private function onAdded_toStage(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, onAdded_toStage);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(Event.RESIZE, onResize_stage);
init3d();
}
private function onResize_stage(e:Event):void {
_view.width = stage.stageWidth;
_view.height = stage.stageHeight;
}
private function onEnter_frame(e:Event):void {
_container.rotationY += 1;
_view.render();
}
private function onClick_sphere(e:MouseEvent3D):void {
//reposition the sphere
var deg:Number = Math.random() * 360;
_sphere.x = 250 * Math.cos(deg);
_sphere.z = 250 * Math.sin(deg);
_sphere.y = 80 + (Math.random() * 40);
}
private function init3d():void {
//create the 3d-view
_view = new View3D();
_view.width = stage.stageWidth;
_view.height = stage.stageWidth;
addChild(_view);
//create a cub
_view.camera.z = -400;
_view.camera.y = 75;
_view.camera.lookAt(new Vector3D(0, 125, 0));
//create container
_container = new ObjectContainer3D();
_view.scene.addChild(_container);
//create sphere to tap
_sphere = new Mesh(new SphereGeometry(10));
_sphere.pickingCollider = PickingColliderType.AS3_FIRST_ENCOUNTERED;
_sphere.y = 100;
_sphere.z = -250;
_sphere.mouseEnabled = true;
_sphere.addEventListener(MouseEvent3D.CLICK , onClick_sphere);
_container.addChild(_sphere);
var stats:AwayStats = new AwayStats(_view);
addChild(stats);
addEventListener(Event.ENTER_FRAME, onEnter_frame);
}
}
NOTE: i also tried different framerates, more events(Mouse_up, down etc), different pickers.
As this problem also happens with 2d moving sprites (in starling) my guess is that is might be Stage3D or AIR related, instead of starling/away3d.
Anyone has some suggestions? Maybe i'm forgetting to set something in the app.xml?
Both framework have to deal with an event less system (Stage3D). Stage3D doesn't catch or receive any events and certianly not touch or mouse event. So both frameworks simulate those events with an internal system that catches events on the stage and try to reproduce an accurate estimation. I personally find those systems too CPU expensive and not accurate enough so my advice is to do like me, create your own system. Simply catch event on the stage and decide which of displayed objects (on Stage3D using their position) has been touched. I personally get a performance boost out of it (especially with starling) and much more accuracy.

Drawing on Live Video in Flex - Snapshot issue

I am working on a project, where I have to make an annotation video player!
Basically, I followed this tutorial[1] where the author presents how to draw(in this case just a rectangle) on the own web camera, using Flex.
Everything went great, but now I want to add a listener to get a snapshot of the image(what I draw + the web camera image) and then save it on my computer.
I have created the listener, but the problem is that this listener saves only the image from the web camera without my drawing(even though I added that draw to the camera).
private function save():void {
var bitmapData:BitmapData = new BitmapData(videoDisplay.width,videoDisplay.height);
bitmapData.draw(videoDisplay);
var ba:ByteArray = (new PNGEncoder()).encode(bitmapData);
(new FileReference()).save(ba, "doodle.png");
}
I don't have experience at all with Flex/Flash so maybe I did smth wrong.
Can you please help me?
[1]http://narinderkumar.wordpress.com/2012/02/16/drawing-on-live-video-in-flex/
this example works fine - i dont see the problem in that codesnippet of yours but maybe you are just drawing vis graphics on the video, in thatcase the graphics layer is behind the camera... hope hat helps ;)
package
{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.media.Camera;
import flash.media.Video;
public class cameratest extends Sprite
{
private var holder:Sprite;
private var layover:Sprite;
private var display:Sprite;
public function cameratest()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
var cam:Camera = Camera.getCamera();
var video:Video =new Video(cam.width, cam.height);
video.attachCamera(cam);
//holder hollds the video and on top the layover to draw on
holder = new Sprite();
stage.addChild(holder);
holder.addChild(video);
//layover to draw on
layover = new Sprite();
holder.addChild(layover);
//will show the snapshot
display = new Sprite();
display.x= 350;
stage.addChild(display);
//listener for onclick do snapshot
stage.addEventListener(MouseEvent.CLICK, drawAndSave);
}
private function drawAndSave(E:Event=null):void{
layover.graphics.beginFill(0xff0000,1);
layover.graphics.drawCircle(10,10,10);
var bmd:BitmapData=new BitmapData(holder.width,holder.height);
bmd.draw(holder);
var bmp:Bitmap = new Bitmap(bmd,'auto',true);
display.addChild(bmp);
}
}
}

beginBitmapFill() is not working for existing movieclip, help me

I want to fill the image to the movie clip using beginBitmapFill(), but I don't see the image. Actually, I have created a movie clip with box and I skewed it. I want to show the image inside the skewed box. And Image also should look skewed (needs to fill inside the box)
Here is my action script code :
package{
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.events.Event;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.LoaderInfo;
public class AttachMovieClipExample extends Sprite{
public var rect:MovieClip;
public function AttachMovieClipExample()
{
rect = new redRectangle();
var bitmapData:BitmapData;
var loader:Loader = new Loader();
loader.load(new URLRequest("sam.jpg"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
function onComplete (event:Event):void
{
bitmapData = Bitmap(LoaderInfo(event.target).content).bitmapData;
rect.graphics.clear();
rect.graphics.beginBitmapFill(bitmapData,null,false,true);
// rect.graphics.endFill();
rect.x = 400;
rect.y = 210;
addChild(rect);
}
}
}
}
In your onComplete method you are missing the call to drawRect
function onComplete (event:Event):void
{
bitmapData = Bitmap(LoaderInfo(event.target).content).bitmapData;
rect.graphics.clear();
rect.graphics.beginBitmapFill(bitmapData,null,false,true);
rect.graphics.drawRect(x,y,height,width) //where x, y, height and width are values
rect.graphics.endFill();
rect.x = 400;
rect.y = 210;
addChild(rect);
}
The docs for the graphics class give you more information.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/Graphics.html#drawRect()
Try this: 1. beginBitmapFill() 2. drawRect() 3. endFill() (never forget step 3!)