AS3: Symbol won't move to x and y on collision - actionscript-3

function bucMove(event: MouseEvent) {
buc.x = mouseX;
buc.y = mouseY;
}
function OnEntFrame(e:Event)
{
sun.y += 25;
}
function hitTest(event: Event) {
if (buc.hitTestObject(sun)) {
sun.x = 259.85;
sun.y = 142.15;
}
}
I want to make the symbol "sun" move to the specific coordinates when it hits "buc" but it just stops when it collides with buc and continues to move if it no longer collides with buc.

Related

How do I stop automatic stretching of the other axis for instances when stretching one of its axis?

When applying code for a laser weapon projectile (an instance of the laser beam itself) which would enable the laser to to act similarly to that of a real one, I had everything working great... except for the fact that the projectile kept stretching in the y axis as well as the x axis, instead of just the x axis. Now, I've found out that something like scaleMode needs to be disabled, but the best I've found is a line of code that goes like "stage.scaleMode = StageScaleMode.NO_SCALE;", which is meant for the stage and not instances themselves and if I tried to apply something like this for an ADDED event within the laser beam's class code I get error 1120 saying . Here is the code I think is necessary to present here from the beam's class:
package
{
import flash.display.MovieClip;
import flash.events.*;
public class weapon3projectileCode extends MovieClip
{
private var _root:Object;
public function weapon3projectileCode()
{
addEventListener(Event.ADDED, beginClass);
}
private function beginClass(event:Event):void
{
_root = MovieClip(root);
this.scaleMode = StageScaleMode.NO_SCALE;
this.scaleX = .25;
this.scaleY = .2;
}
private function entFrame(event:Event):void
{
if (_root.gamePaused == false)
{
x += speed;
if (stretchWhile < stretchTill)
{
this.width += 25;
this.x = _root.playerShip.x;
this.y = _root.playerShip.y;
}
else if (stretchWhile < shrinkTill)
{
this.width -= 25;
}
else if (stretchWhile >= shrinkTill)
{
this.width = .25;
removeEventListener(Event.ENTER_FRAME, entFrame);
_root.projectilePlayerContainer.removeChild(this);
}
stretchWhile ++;
if(this.x > (stage.width+ this.width))
{
removeEventListener(Event.ENTER_FRAME, entFrame);
_root.projectilePlayerContainer.removeChild(this);
}
}
if (_root.removeProjectiles == true)
{
removeEventListener(Event.ENTER_FRAME, entFrame);
_root.projectilePlayerContainer.removeChild(this);
}
}
}
}
You should specifically alter scaleX instead of width. You need to have your laser drawn by say 100 pixels long and say 10 pixels wide (to taste), then once you determine the desired distance of your laser, you set its scaleX to desiredWidth/100, this should eliminate your laser scaling by Y.

AS3 move towards mouse click

In a side-scroller type game, I want the object to move wherever I click the mouse and then stop at that location. What is the best way to accomplish this? The object can only move on the x-axis so I don't have to worry about moving on the y-axis.
What I would do is set a target x coordinate, then move towards it each frame (or timer tick) based on a constant movement speed.
const moveSpeed:Number = 5;
var targetX:Number = 0;
stage.addEventListener(MouseEvent.CLICK, click);
function click(e:MouseEvent):void {
targetX = mouseX;
addEventListener(Event.ENTER_FRAME, update);
}
function update(e:Event):void {
if (Math.abs(targetX - player.x) < moveSpeed) {
// reached target
player.x = targetX;
} else if (targetX > player.x) {
// move right
player.x += moveSpeed;
} else {
// move left
player.x -= moveSpeed;
}
}
Use tweener:
http://hosted.zeh.com.br/tweener/docs/en-us/
And apply a tween like this:
Tweener.addTween(myObject, {_x:myObject.parent.mouseX, time:1, transition:"linear"});
And you can play with the time and the transition type. Good overview of transition types can be found here:
http://hosted.zeh.com.br/tweener/docs/en-us/misc/transitions.html

Can't make MovieClip in function dissapear

I'm trying to make simple shooting game with Fiat Multipla falling up to bottom of the screen. I have created function to generate falling multipla and within this function I have a problem.
The main issue is that after change of multideath status to 1 "Death" function does nothing even if It is kept with ENTER_FRAME. Child becomes invisible as I implemented it in multipla movieclip, but even after response from there with Death = 1, nothing happens.
I'm new to all this, I've met and solved few issues during programming, but here's my brickwall for now. Code's either failing completely or I don't know something that's obvious. As I said, I'm newbie.
Thanks a lot for help!
Here's the function:
import flash.events.Event;
import flash.desktop.NativeApplication;
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
Mouse.hide();
var velocity = 0;
var ammo = 6;
LGUI.LGUIammo.gotoAndStop(6);
var counter = 0;
function multiplarain()
{
var x1 = Math.ceil(Math.random() * 280);
var y1 = -200;
var random:Multipla = new Multipla();
var life = 265;
var multideath = 0;
random.x = 100 + x1;
random.y = y1
addChild(random);
random.gotoAndStop(1);
setChildIndex(random, +1);
addEventListener(Event.ENTER_FRAME, Death);
function Death(event:Event):void
{
if(multideath >= 1)
{
removeEventListener(Event.ENTER_FRAME, Death);
removeChild(random);
}
}
addEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
function fl_EnterFrameHandler(event:Event):void
{
if(random.y >= 680)
{
removeEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler)
removeChild(random);
trace("rofl");
}
}
random.addEventListener(Event.ENTER_FRAME, fl_AnimateVertically);
function fl_AnimateVertically(event:Event)
{
velocity = velocity + 0.000035;
random.y += 1.5 + velocity;
}
random.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler);
function fl_TapHandler(event:TouchEvent):void
{
counter = counter + 1;
ammo -= 1;
}
if(ammo == 6)
{
LGUI.LGUIammo.gotoAndStop(6);
}
if(ammo == 5)
{
LGUI.LGUIammo.gotoAndStop(5);
}
if(ammo == 4)
{
LGUI.LGUIammo.gotoAndStop(4);
}
if(ammo == 3)
{
LGUI.LGUIammo.gotoAndStop(3);
}
if(ammo == 2)
{
LGUI.LGUIammo.gotoAndStop(2);
}
if(ammo == 1)
{
LGUI.LGUIammo.gotoAndStop(1);
}
if(ammo <= 0)
{
LGUI.LGUIammo.gotoAndStop(7);
}
HGUI.saved.text = counter;
this.addEventListener( Event.ENTER_FRAME, handleCollision)
var kucyk = LGUI.LGUIlife.lifeitself;
function handleCollision(e:Event):void
{
if (random.hitTestObject(LGUI))
{
kucyk = LGUI.LGUIlife.lifeitself;
kucyk.width -= 0.1;
}
/*if (kucyk.width == 0.75)
{
trace("cycki");
NativeApplication.nativeApplication.exit();
}*/
}
}
and here's multipla's movieclip in library code:
Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;
this.addEventListener(TouchEvent.TOUCH_TAP, fl_TapHandler2);
function fl_TapHandler2(event:TouchEvent):void
{
this.gotoAndPlay(2);
}
addEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
function fl_EnterFrameHandler(event:Event):void
{
if(this.currentFrame == 60)
{
this.visible = false;
MovieClip(root).multideath = 1;
trace(MovieClip(root).multideath);
removeEventListener(Event.ENTER_FRAME, fl_EnterFrameHandler);
removeEventListener(Event.ENTER_FRAME, fl_TapHandler2);
}
}
it's been like 10 years since I last time worked with AS2 but I'd guess that this Multipla sets the multideath property in the wrong place. If i remember corrctly, root is the top-most level (your application). So if your first code is not on the main timeline but in a movieclip that is on the main timeline it won't work. Try to put a trace into the Death function to see if the multideath is really changing there:
trace(multideath);
try this in the multipla code:
parent.multideath = 1;
instead of
MovieClip(root).multideath = 1;
And I'm asking myself why do you need so many enter frame listeners? You can have just one and combine all animations in one function.
Also you don't need to check for multideath on every frame, just remove the movieclip in a separate function:
function removeMultipla():void
{
removeChild(random);
}
Just call this function from your Multipla instead of setting the multideath property:
parent.removeMultipla();

I added animation to the timeline of my movie clip, now its no longer colliding with objects as it did before

I'm working on a platform game in AS3 for Flash. There is of course a player character and enemies for him to interact with. I first made a simple placeholder graphic for the enemy while I worked on the code. I got the enemy to move back and forth between two bumpers with code. He also collides with the player, sending them back to the start screen. Now that I got the code working, I wanted to add some animations to the enemies so they walk instead of just skate across the ground. I added the animations to the timeline of the enemy movie clip. Now when I test the game, the animations play fine and the enemy begins to move, but he passes through the first bumper and doesn't collide with the player at all. If I force the movie clip to stop and not play the collision starts to work again. What would be causing this?
This is the code within the main timeline of the .fla file.
addEnemiesToLevel1();
addBumpersToLevel1();
function addEnemiesToLevel1():void
{
addEnemy(700, -54);
addEnemy(1341, -54);
addEnemy(2187, -54);
}
function addBumpersToLevel1():void
{
addBumper(900, -80);
addBumper(644, -80);
addBumper(1135, -90);
addBumper(1380, -90);
addBumper(2053, -90);
addBumper(2226, -90);
}
function addEnemy(xLocation:int, yLocation:int):void
{
var enemy:Enemy = new Enemy(xLocation, yLocation);
back.addChild(enemy);
enemy.addEventListener(Event.REMOVED, enemyRemoved);
enemyList.push(enemy);
}
function addBumper(xLocation:int, yLocation:int):void
{
var bumper:Bumper = new Bumper(xLocation, yLocation);
back.addChild(bumper);
bumper.visible = false;
bumperList.push(bumper);
}
//corralling the bad guys with bumpers
if (enemyList.length > 0){ //enemies left in the enemyList?
for (var k:int = 0; k < enemyList.length; k++){ // for each enemy in the enemyList
if (bumperList.length > 0){
for (var h:int = 0; h < bumperList.length; h++){ // for each bumper in the List
if ( enemyList[k].hitTestObject(bumperList[h]) ){
enemyList[k].changeDirection();
}
}
}
}
}
//player and enemy collisions
if (enemyList.length > 0){ //enemies left?
for (var m:int = 0; m < enemyList.length; m++){ // for each enemy in the enemyList
if ( enemyList[m].hitTestObject(player) ){
trace("player collided with enemy");
gotoAndStop(4);
enemyList[m].removeSelf();
}
}
}
}
This is the enemy class file.
package {
import flash.display.MovieClip;
import flash.events.Event;public class Enemy extends MovieClip {
private var xSpeedConst:int = 2;
private var flip:int = 1;
public function Enemy(xLocation:int, yLocation:int) {
// constructor code
x = xLocation;
y = yLocation;
addEventListener(Event.ENTER_FRAME, loop);
}
public function loop(e:Event):void {
if ((flip%2) == 1){
x += xSpeedConst;
} else if((flip%2) == 0){
x += (-xSpeedConst);
}
}
public function removeSelf():void {
trace("remove enemy");
removeEventListener(Event.ENTER_FRAME, loop);
this.parent.removeChild(this);
}
public function changeDirection():void{
trace("x ="+x);
flip++;
this.scaleX *= -1;
}
}
}
I had a problem that was very similar to this:
2D Platform Game using hitTestPoint:glitches
My problem was that my character's hitTestPoint wouldn't work after I animated the character. However, it wasn't because of the animation, it was because of my turning code for the character. I was using scaleX to flip the character. However, this flipped the points nested within the character as well (which were used to handle my collisions). I notice that you also flipped the character's scale:
public function changeDirection():void{
trace("x ="+x);
flip++;
this.scaleX *= -1;
}
Perhaps you are having the same problem as I did. If so, try removing this line of code for now:
this.scaleX *= -1;
...and see what happens...We can figure out what to do next from there
Drake Swartzy

startDrag - stop diagonal movement

Is there a way to have a MovieClip with startDrag, but to force only horizontal and vertical (i.e. not diagonal) movement?
Here is my solution. It tracks the mouseX and mouseY on click and compares it to last position. Finds out which direction the mouse is mainly moving then moves the object there. You may want to add some extra logic to lock the object to the nearest 10th unit or whatever unit size you want to form a snap grid for use in games or organized placement of the object.
Update: I went ahead and added a snapNearest function to help control the movement.
import flash.events.MouseEvent;
import flash.events.Event;
dragObj.addEventListener(MouseEvent.MOUSE_DOWN, dragIt);
var curX:Number = 0;
var curY:Number = 0;
var oldX:Number = 0;
var oldY:Number = 0;
var gridUnit:Number = 25;
function dragIt(e:MouseEvent):void
{
// set x,y on down
oldX = mouseX;
oldY = mouseY;
// add mouse up listener so you know when it is released
stage.addEventListener(MouseEvent.MOUSE_UP, dropIt);
stage.addEventListener(Event.ENTER_FRAME, moveIt);
trace("Start Drag")
}
function moveIt(e:Event):void
{
// figure out what the main drag direction is and move the object.
curX = mouseX;
curY = mouseY;
// figure out which is the larger number and subtract the smaller to get diff
var xDiff:Number = curX > oldX ? curX - oldX : oldX - curX;
var yDiff:Number = curY > oldY ? curY - oldY : oldY - curY;
if(xDiff > yDiff) {
dragObj.x = snapNearest(mouseX, gridUnit);
}else{
dragObj.y = snapNearest(mouseY, gridUnit);
}
oldX = mouseX;
oldY = mouseY;
}
function dropIt(e:MouseEvent):void
{
//remove mouse up event
stage.removeEventListener(MouseEvent.MOUSE_UP, dropIt);
stage.removeEventListener(Event.ENTER_FRAME, moveIt);
trace("Stop Drag")
}
// snap to grid
function snapNearest(n:Number, units:Number):Number
{
var num:Number = n/units ;
num = Math.round(num);
num *= units;
return num;
}
yes. there are a few options.
A. you can choose to use the startDrag() function and supply it's 2nd parameter with a bounds rectangle for your draggable object. something like;
dragSprite.startDrag(false, new Rectangle(0, 0, 20, stage.stageHeight));
B. you can set your draggable object to listen for mouse events, moving it according to the mouse movements. something like:
dragSprite.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEventHandler);
function mouseDownEventHandler(evt:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
}
function mouseMoveEventHandler(evt:MouseEvent):void
{
//only move dragSprite horizontally
//dragSprite.y = evt.stageY;
dragSprite.x = evt.stageX;
}
function mouseUpEventHandler(evt:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveEventHandler);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpEventHandler);
}
You could use a modifier key, for instance normal behavior would be horizontal & press down the shift key to move vertically.
function mouseMoveEventHandler(evt:MouseEvent):void
{
if(!evt.shiftKey)
dragSprite.x = evt.stageX;
else
dragSprite.y = evt.stageY;
}
You can only constrain to one axis or the other (using a constraint rectangle) But diagonal movement would be possible in the method you propose, unless you also define some other limits... for example a grid.