How to make Movie clip stretch and contract to follow another Movie clip on stage - actionscript-3

Hey everyone so I am working on a fishing pole and I created a hook in AS3 that the user controls when they touch the screen the playerHook is allowed to move anywhere on the screen in any direction that the user directs it to.
So what i want is for the hookLine to be attached to the hook and follow it everywhere also the hookLine to be attached to the fishing pole as well, but i want the hook line to of course act like one, in the way that when the user moves the Hook to the end of the screen then the hook line stretches with it and when it is moved back, the hook line contracts. Hope you understand what I'm trying to convey. Just basically how a fishing pole acts.
Here is the code that I am using for the user to control the playerHook :
In my Main Function:
//Add hook to stage
playerHook = new mcHook;
stage.addChild(playerHook);
playerHook.x = (stage.stageWidth / 2);
playerHook.y = (stage.stageWidth / 2);
//Event listeners
playerHook.addEventListener(Event.ENTER_FRAME, playerHookMove);
In my playerHookMove function:
private function playerHookMove(e:Event):void
{
var xCoord = playerHook.x - mouseX;
var yCoord = playerHook.y - mouseY;
playerHook.x = playerHook.x - (xCoord / 3.5);
playerHook.y = playerHook.y - (yCoord / 3.5);
}
If anyone has any idea on how to have the hookLine object do what I stated above i would really appreciate it. I have ideas such as scaling and transforming. But not too sure. Please help!

Related

Flash AS3 | Removing or Stopping a Function

I need the answer to what seems like it should be a very obvious question, yet I can't find it anywhere:
How do you stop a function in Flash AS3? For basic example, when I push a button, the function starts working. When I press the button again, the function stops.
More specifically, how can I tailor this to an if/boolean (or similar) statement so that when/while the variable is true, the function starts working. Once the variable goes false, the function stops. When it goes true again, the process repeats.
The code in issue is this panning function that another user helped create for me.
if(Zoomed == true) {
MovieClip.y = stage.stageHeight / 2;
MovieClip.x = stage.stageWidth / 2;
addEventListener(MouseEvent.MOUSE_MOVE, panFunction);
function panFunction(me: MouseEvent): void {
MovieClip.x = stage.stageWidth / 2 - (stage.mouseX - stage.stageWidth / 2);
MovieClip.y = stage.stageHeight / 2 - (stage.mouseY - stage.stageHeight / 2);
}
}
As you can see, I want it so that when the boolean function 'Zoomed' is true, the function activates and the panning feature works. The problem is that when I go back to Zoomed == false, the function is still running. I am looking to find out how to stop this from happening.
I have tried a 'while' loop but it ultimately just freezes the animation (likely because its a moving image and it's trying to render every frame with this code).
Summarising: I need a way for a function to be able to be toggled on and off. Alternatively, being able to add it and remove it when it's needed/not needed should work the same. Any help on this would be a great help, thanks!
What you need to do is remove the event listener when you no longer want panning.
Something like this, which assumes you change the value of zoomed on a click:
var zoomed:Boolean = false; //a var to store whether we are currently zoomed
//change the zoom on mouse click
addEventListener(MouseEvent.CLICK, zoomClick);
function panFunction(me:MouseEvent): void {
mc.x = stage.stageWidth / 2 - (stage.mouseX - stage.stageWidth / 2);
mc.y = stage.stageHeight / 2 - (stage.mouseY - stage.stageHeight / 2);
}
function zoomClick(me:MouseEvent):void {
zoomed = !zoomed; //toggle the zoomed value
if(zoomed){
//we're zoomed, so add the panning mouse move listener
addEventListener(MouseEvent.MOUSE_MOVE, panFunction);
//do whatever else you need to when first zoomed.
}else{
//no longer zoomed, remove the mouse move listener
removeEventListener(MouseEvent.MOUSE_MOVE, panFunction);
}
}
Some notes, the word MovieClip is not a good instance name, as it may conflict the class name MovieClip, I'd recommend renaming it mc or something else to avoid potential problems later on.
Also, avoid inline functions (functions declared/contained within other functions), they can be especially problematical when attached to event listeners and are a good way to introduce memory leaks into your program.

AS3 tween object not working with .hitTestObject()

I am having a major problem in my new browser app.
Okay so I made game where different cubes (squares) spawn at the top of the screen and I use the Tween class to make them go down the screen and then disappear.
However I want to detect a collision when a cube hits the player (that is also a flying cube).
I tried everything, truly everything but it does not seem to work. The problematic thing is that when I remove the "Tween" function it does detect collision with the hitTestObject method but when I add the "Tween" line collision won't be detected anymore.
It looks like this:
function enemiesTimer (e:TimerEvent):void
{
newEnemy = new Enemy1();
layer2.addChild(newEnemy);
newEnemy.x = Math.random() * 700;
newEnemy.y = 10;
if (enemiesThere == 0)
{
enemiesThere = true;
player.addEventListener(Event.ENTER_FRAME, collisionDetection)
}
var Tween1:Tween = new Tween(newEnemy, "y", null, newEnemy.y, newEnemy.y+distance, movingTime, true);
}
And the collision detection part:
private function collisionDetection (e:Event):void
{
if (player.hitTestObject(newEnemy))
{
trace("aaa");
}
}
I am desperate for some information/help on the topic, it's been bugging me for days.
Thanks for your time, I would be very happy if someone could help me out^^
First, make sure the "newEnemy" instance and the "player" instance are within the same container. If they are not, their coordinate systems might not match up and could be the source of your problem.
Otherwise, you need to keep a reference to each enemy instance you create. It looks like you are only checking against a single "newEnemy" variable which is being overwritten every time you create a new enemy. This might be why you can successfully detect collision between the player and the most recent "enemy" instance.
So... you need a list of the enemies, you can use an Array for that.
private var enemyList:Array = [];
Every time you create an enemy, push it to the Array.
enemyList.push(newEnemy);
In your "collisionDetection" function, you need to loop through all of the enemies and check if the player is touching any of them.
for(var i:int = 0; i < enemyList.length; i++)
{
var enemy = enemies[i];
if (player.hitTestObject(enemy))
{
trace("Collision Detected!");
enemy.parent.removeChild(enemy); // remove the enemy from the stage
enemies.splice(i, 1); // remove the enemy from the list
}
}
I'd suggest that you move to TweenMax, it just might solve your problem, and in my experience it's much better in every possible way.
Scroll down the following page to see a few variations of this library, I myself use TweenNano, they're completely free of charge:
https://greensock.com/gsap-as
I think some plugins cost money, but I doubt you'll ever need them.

Remove Object when Collision Detected in AS3

I'm making a game where your player (gun) shoots enemies (baddie) to gain score. I've set it up so you have three lives (lives) until it is game over. I am trying to add an addLife function that works by when your player collects an object (waterMelon), it gets a life. I have added a timer event that runs the function addLife, that adds an instance of the Movie clip to the stage every 5 seconds. In that function, ive created another function called checkCollisions, that is meant to check the collision of the player, to the object, remove the object from the stage, then add a life.
var timer2:Timer = new Timer(5000);
timer2.addEventListener(TimerEvent.TIMER, addLife);
timer2.start();
var watermelon:waterMelon = new waterMelon();
function addLife(evt:TimerEvent):void{
watermelon.x = Math.random() * stage.stageWidth;
watermelon.y = Math.random() * stage.stageHeight;
addChild(watermelon);
watermelon.push(waterMelon);
checkCollision();
}
function checkCollision(){
if (gun.hitTestObject(watermelon)){
removeChild(watermelon);
lives++;
livesDisplay.gotoAndStop(livesDisplay.currentFrame-1);
}
}
The only part of the code that works is the adding the watermelon to the stage, but when my player collides with it, it does not remove from the stage. Could someone please tell me how I make my watermelon completely be removed from the stage when the player collides with it, and add a life to my player. Once again, each object equals this; gun = player, waterMelon = object/watermelon, lives = lives, livesDisplay = physical display of lives.
You have tried to delete the array(watermelon) from the stage instead of the object(waterMelon). Although by the looks you are using arrays so you will have to find the index of the object colliding with the gun from the array watermelon. You do this with a for loop.
for (melonCount:int = 0; melonCount>watermelon.length;melonCount--)
{
if (gun.hitTestObject(watermelon[melonCount]))
{
removeChild(watermelon[melonCount])
watermelon.splice(melonCount, 1)
melonCount--
}
}

How to check if mouse is on a shpae in Flash

I am building a simple flash game in AS3 and I was wondering if I could use code similar to "hitTestPoint()" except it applies to a shape and not a symbol?
The maze is simply a line shape, so if the ball moves off the shape then the game is terminated. Is this possible?
Thanks,
Peter
Simple enough. Just test if the maze is found at the current location of the ball.
function test():Boolean {
// First we get the absolute coordinates of the ball
var loc:Point = ball.localToGlobal(new Point(0,0));
// Next we collect all the DisplayObjects at that coordinate.
var stack:Array = getObjectsUnderPoint(loc);
var found:Boolean = false;
// Now we cycle through the array looking for our maze
for each (var item in stack) {
if (item.name == "mazeShape") {
found = true;
}
}
return found;
}
If you're really interested in whether the mouse (and not the ball) is off the maze, just replace the first line with this:
var loc:Point = new Point(mouseX, mouseY);
Depending how your game looks, you could also use coordinates for this.
Just tell the game if Player > 100 Y it is off the game it's limits = Restart.
It might won't be the most solid solution but it is definetely a way to solve it as I don't believe there is a function for it, please do correct me if I am wrong.
The AS3 Collision Detection Kit will let you detect hits based on color if separating the maze into smaller symbols is not appropriate.

action script 3 - is it possible to trigger click event only when mouse is clicked on the image part?

I have a problem and I have potential solution. But I wanted to confirm if there is an easy and simple way to solve my problem.
App type:
Isometric Game
Problem statement:
I am loading images in my flash app and have mouse events attached to them.
The images I load are prop images like vehicles, trees, buildings etc., and all of them are transparent.
Example: Red ball asset (please ignore the yellow background which I applied to describe the problem)
If I click on the actual image area (colored in red), then every thing works perfect
I don't want to trigger mouseevent when I click on empty image part (or transparent area, which I have shown in yellow color)
There is one way I know by creating masks in flash. I don't want to do it unless that is the final option left because I load image assets instead of flash assets and I don't want to create a new mask asset for all the assets
There is another method I was going to adopt by using getPixel method of Bitmap. Which is discussed here.
But there is another problem with this method.
I might be able to ignore the click event when I click on the empty part of the asset but if there is some other asset is behind the image in the same location, then I need to process the click event for the occluded image.
Well, thinking of solution to this problem takes me to the getObjectsUnderPoint where I can scan the occluded assets
Well, what you proposed as a solution is 100% valid. Just move the logic of determining what game object is clicked outside of that object.
Listen for MOUSE_DOWN/MOUSE_UP events at container which contains your game objects.
Catch an event
Check if the game object which is the target of this event is transparent at this point using BitmapData.getPixel32
If it is use getObjectsUnderPoint to find out all other game objects at this point
Find in a loop the first object which is not transparent at this point
Now you got the actual object which is hit.
One interesting solution is to use Sprite objects with the individual non-transparent pixels burnt onto them.
Suppose this is your Loader "complete" handler:
private function loaderCompleteHandler(event:Event):void
{
// Loader is not our child, we use a Sprite instead (below).
var loader:Loader = Loader(event.target);
var sprite:Sprite = new Sprite();
addChild(sprite);
var w:Number = loader.content.width;
var h:Number = loader.content.height;
// Use transparent bitmap.
var bitmapData:BitmapData = new BitmapData(w, h, true, 0);
bitmapData.draw(loader.content);
// Now burn the image onto the Sprite object, ignoring
// the transparent pixels.
for (var xPos:int = 0; xPos < w; xPos++) {
for (var yPos:int = 0; yPos < h; yPos++) {
var pixel32:uint = bitmapData.getPixel32(xPos, yPos);
var alpha:int = pixel32 >>> 24;
if (alpha != 0) {
sprite.graphics.beginFill(pixel32 & 0xFFFFFF, alpha / 0xFF);
sprite.graphics.drawRect(xPos, yPos, 1, 1);
sprite.graphics.endFill();
}
}
}
}
Essentially you want "empty" pixels that aren't clickable, and fully transparent pixels aren't quite the same thing. With this solution you get empty pixels.
Only problem is that this might be slow. Give it a shot.