I'm new to AS3 and would love some help with collision detection. I'm currently making a game with a similar concept to robot unicorn attack (continuous, 'infinite', level); sidescrolling running platformer. I have found 0 tutorials for a continous/looping running style platformer, so I've come here! I have a player who is stationary, the platforms are scripted to move to the left of the screen for the scrolling/running effect. I have three instances of a the platform on the stage, however the player will only react to the collision with one of them. Collision is being detected from all platforms.
The code below is for the collisions which executes inside my game loop function. Help would be hugely appreciated! :D Thanks.
for (var i = 0; i < numChildren; i++)
{
if (getChildAt(i) is Platform)
{
var platformHolder = getChildAt(i) as Platform
if (platformHolder.hitTestPoint(player.x + leftBumpPoint.x, player.y + leftBumpPoint.y, true))
{
trace("left hit")
leftBumping = true;
}
else
{
leftBumping = false
}
if(platformHolder.hitTestPoint(player.x + rightBumpPoint.x, player.y + rightBumpPoint.y, true))
{
trace("right hit");
rightBumping = true;
}
else
{
rightBumping = false;
}
if(platformHolder.hitTestPoint(player.x + upBumpPoint.x, player.y + upBumpPoint.y, true))
{
trace("Up hit");
upBumping = true;
}
else
{
upBumping = false;
}
if(platformHolder.hitTestPoint(player.x + downBumpPoint.x, player.y + downBumpPoint.y, true))
{
trace("down hit");
downBumping = true;
}
else
{
downBumping = false;
}
}
}
if(leftBumping)
{
if(xSpeed < 0)
{
xSpeed *= -0.5;
}
}
if(rightBumping)
{
if(xSpeed > 0)
{
xSpeed *= -0.5;
}
}
if(upBumping)
{
if(ySpeed < 0)
{
ySpeed *= -0.5;
}
}
if(downBumping)
{
if(ySpeed > 0)
{
ySpeed *= -0.5;
}
}
else
{
//if not touching the floor
ySpeed += gravityConstant;
}
If(platformholder[i].hitTestObject(player))
Add i the very reason you make a loop
Related
I'm trying to build a game in iOS and am currently using Objective-C. The problem I'm running into is Z-sorting different enemy and player nodes. This is my current code for Z-sorting just one enemy type, and I am only copying this code to z-sort every different type of enemy (Mob). This is leading to ALOT of code that all does essentially the same thing for different objects. The only way I know how to fix this problem is by using template functions, but Objective-C doesn't support that to my knowledge. There has to be a better way...
// If two monsters are standing on the same cell, we need to z sort them based on position
// south-western most body will be closest to the "camera" from players perspective
-(void) zSortMobs {
int i = 0;
int j = 0;
for (i = 0; i < self.maxMobs; i++) {
Mob * mob = [self.mobs objectAtIndex: i];
if (mob.state != 0) {
for (j = 0; j < self.maxMobs; j++) {
Mob * mob2 = [self.mobs objectAtIndex: j];
if (mob2.state != 0) {
if (mob != mob2) {
if (mob.z == mob2.z) {
if (mob.y < mob2.y) {
mob.z++;
}
else if (mob.y == mob2.y) {
if (mob.x < mob2.x) {
mob.z++;
}
else {
mob2.z++;
}
}
else {
mob2.z++;
}
}
}
[mob setZPosition: mob.z];
[mob2 setZPosition: mob2.z];
}
}
for (j = 0; j < self.maxTanks; j++) {
Tank * tank = [self.tanks objectAtIndex: j];
if (tank.state != 0) {
if (mob.z == tank.z) {
if (mob.y < tank.y) {
mob.z++;
}
else if (mob.y == tank.y) {
if (mob.x < tank.x) {
mob.z++;
}
else {
tank.z++;
}
}
else {
tank.z++;
}
}
[mob setZPosition: mob.z];
[tank setZPosition: tank.z];
}
}
if (mob.z == self.gameScene.player.z) {
if (mob.y < self.gameScene.player.y) {
mob.z++;
}
else if (mob.y == self.gameScene.player.y) {
if (mob.x < self.gameScene.player.x) {
mob.z++;
}
else {
self.gameScene.player.z++;
}
}
else {
self.gameScene.player.z++;
}
}
[mob setZPosition: mob.z];
[self.gameScene.player setZPosition: self.gameScene.player.z];
}
}
}
Currently I'm working on a project recreating a mario level, my issue is that when I do not hard code the bottomLimit (the floor, currently set to 400) Mario will eventually just fall through.
Another thing I can't quite figure out is how I can move my invisible block that creates the floor boundary to accomodate the flooring. The level chosen is the Fortress level of Super Mario Brothers 3, if that helps picture what I'm trying to do with it.
There are a couple .as files to my code, I will put my troublesome file in along with my collision code.
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.ui.Keyboard;
import flash.events.KeyboardEvent;
import flash.media.Sound;
public class FortressMap extends MovieClip
{
private var _mario:SmallMario;
private var vx:Number = 0;
private var vy:Number = 0;
private var _ceiling:Array = new Array();
private var _floor:Array = new Array();
public const accy:Number = 0.20;
public const termv:Number = 15;
public var onGround:Boolean;
public var bottomLimit:Number;
public function FortressMap()
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
_mario = new SmallMario();
addChild(_mario);
_mario.x = 50;
_mario.y = 400;
//Creating the blocks for the floor
createFloor(16, 416);
//Creating the blocks for the ceiling
createCeiling(16, 352);
}
private function createFloor(xPos:Number, yPos:Number):void
{
var floor:Floor = new Floor();
addChild(floor);
floor.x = xPos;
floor.y = yPos;
floor.height = 16;
_floor.push(floor);
floor.visible = false;
}
private function createCeiling(xPos:Number, yPos:Number):void
{
var ceiling:Ceiling = new Ceiling();
addChild(ceiling);
ceiling.x = xPos;
ceiling.y = yPos;
ceiling.height = 16;
_ceiling.push(ceiling);
ceiling.visible = false;
}
private function addedToStageHandler(event:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
addEventListener(Event.ENTER_FRAME, frameHandler);
addEventListener(Event.REMOVED_FROM_STAGE, removeStageHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
private function frameHandler(event:Event):void
{
_mario.x += vx;
_mario.y += vy;
if (_mario.x < 16)
{
_mario.x = 16;
}
vy += accy;
for (var i:int = 0; i < _ceiling.length; ++i)
{
Collision.block(_mario, _ceiling[i]);
}
for (var j:int = 0; j < _floor.length; ++j)
{
Collision.block(_mario, _floor[j]);
}
bottomLimit = 400;
if(_mario.y >= bottomLimit)
{
_mario.y = bottomLimit;
vy = 0;
onGround = true;
}
else
{
onGround = false;
}
}
private function keyDownHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
vx = -5;
return;
}
if (event.keyCode == Keyboard.RIGHT)
{
vx = 5;
return;
}
if (event.keyCode == Keyboard.UP)
{
if(onGround == true)
{
vy = -5;
trace("My people need me!");
}
return;
}
if (event.keyCode == Keyboard.DOWN)
{
//vy = 5;
return;
}
}
private function keyUpHandler(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT)
{
vx = 0;
return;
}
if (event.keyCode == Keyboard.UP || event.keyCode == Keyboard.DOWN)
{
//vy = 0;
return;
}
}
private function removeStageHandler(event:Event):void
{
removeEventListener(Event.ENTER_FRAME, frameHandler);
removeEventListener(Event.REMOVED_FROM_STAGE, removeStageHandler);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
stage.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
}
}
package
{
import flash.display.Sprite;
public class Collision
{
static public var collisionSide:String = "";
public function Collision()
{
}
static public function block(r1:Sprite, r2:Sprite):Boolean
{
var isBlocked:Boolean;
//Calculate the distance vector
var vx:Number
= (r1.x + (r1.width / 2))
- (r2.x + (r2.width / 2));
var vy:Number
= (r1.y + (r1.height / 2))
- (r2.y + (r2.height / 2));
//Check whether vx
//is less than the combined half widths
if(Math.abs(vx) < r1.width / 2 + r2.width / 2)
{
//A collision might be occurring! Check
//whether vy is less than the combined half heights
if(Math.abs(vy) < r1.height / 2 + r2.height / 2)
{
//A collision has ocurred! This is good!
//Find out the size of the overlap on both the X and Y axes
var overlap_X:Number
= r1.width / 2
+ r2.width / 2
- Math.abs(vx);
var overlap_Y:Number
= r1.height / 2
+ r2.height / 2
- Math.abs(vy);
//The collision has occurred on the axis with the
//*smallest* amount of overlap. Let's figure out which
//axis that is
if(overlap_X >= overlap_Y)
{
//The collision is happening on the X axis
//But on which side? _v0's vy can tell us
if(vy > 0)
{
collisionSide = "Top";
//Move the rectangle out of the collision
r1.y = r1.y + overlap_Y;
//r1 is being blocked
isBlocked = true;
}
else
{
collisionSide = "Bottom";
//Move the rectangle out of the collision
r1.y = r1.y - overlap_Y;
//r1 is being blocked
isBlocked = true;
}
}
else
{
//The collision is happening on the Y axis
//But on which side? _v0's vx can tell us
if(vx > 0)
{
collisionSide = "Left";
//Move the rectangle out of the collision
r1.x = r1.x + overlap_X;
//r1 is being blocked
isBlocked = true;
}
else
{
collisionSide = "Right";
//Move the rectangle out of the collision
r1.x = r1.x - overlap_X;
//r1 is being blocked
isBlocked = true;
}
}
}
else
{
//No collision
collisionSide = "No collision";
//r1 is not being blocked
isBlocked = false;
}
}
else
{
//No collision
collisionSide = "No collision";
//r1 is not being blocked
isBlocked = false;
}
return isBlocked;
}
}
}
I think what you want to do is to set the bottomlimit, but not hardcode the number 400, correct?
I would do change your createFloor method:
private function createFloor(xPos:Number, yPos:Number):void
{
var floor:Floor = new Floor();
addChild(floor);
floor.x = xPos;
floor.y = yPos;
floor.height = 16;
_floor.push(floor);
floor.visible = false;
// set bottom limit here
bottomLimit = yPos;
}
... then you wouldnt need to set it to 400.
However, another option is to change your if statement:
if(_mario.y >= Floor(_floor[0]).y)
{
_mario.y = Floor(_floor[0]).y;
vy = 0;
onGround = true;
}
else
{
onGround = false;
}
... and then you can get rid of the bottomLimit variable completely
(assuming I understood your code, and that the floor tiles are always going to be at the bottomLimit)
I'm creating a game where you as the player is holding a baseball bat and when you click the button you swing your bat. When you swing your bat you hit the enemy the enemy goes flying off in the opposite direction of where you hit them like a golf ball. I have done the moving and attacking function working but how can I register the hittest so it hits the enemy when facing towards it and the enemy going back. 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 walkSpeed:Number = 4;
var walkRight:Boolean = false;
var walkLeft:Boolean = false;
var walkUp:Boolean = false;
var walkDown:Boolean = false;
var attacking:Boolean = false;
public function Player()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN , walk);
addEventListener(Event.ENTER_FRAME, Update);
stage.addEventListener(KeyboardEvent.KEY_UP, stopWalk);
stage.addEventListener(MouseEvent.CLICK, attack);
}
function walk(event:KeyboardEvent)
{
if (event.keyCode == 68)
{
walkRight = true;
}
if (event.keyCode == 87)
{
walkUp = true;
}
if (event.keyCode == 65)
{
walkLeft = true;
}
if (event.keyCode == 83)
{
walkDown = true;
}
}
function Update(event:Event)
{
if (attacking == true)
{
walkRight = false;
walkLeft = false;
walkUp = false;
walkDown = false;
}
else if (attacking == false)
{
var dx = parent.mouseX - x;
var dy = parent.mouseY - y;
var angle = Math.atan2(dy,dx) / Math.PI * 180;
rotation = angle;
if (walkRight == true)
{
x += walkSpeed;
gotoAndStop('walk');
}
if (walkUp == true)
{
y -= walkSpeed;
gotoAndStop('walk');
}
if (walkLeft == true)
{
x -= walkSpeed;
gotoAndStop('walk');
}
if (walkDown == true)
{
y += walkSpeed;
gotoAndStop('walk');
}
}
}
function stopWalk(event:KeyboardEvent)
{
if (attacking == false)
{
if (event.keyCode == 68)
{
event.keyCode = 0;
walkRight = false;
gotoAndStop('stance');
}
if (event.keyCode == 87)
{
event.keyCode = 0;
walkUp = false;
gotoAndStop('stance');
}
if (event.keyCode == 65)
{
event.keyCode = 0;
walkLeft = false;
gotoAndStop('stance');
}
if (event.keyCode == 83)
{
event.keyCode = 0;
walkDown = false;
gotoAndStop('stance');
}
}
}
function attack(event:MouseEvent)
{
if (attacking == false)
{
attacking = true;
gotoAndStop('attack');
}
}
}
}
When the character's direction changes, change a variable depending on the way they are now facing, for example; direction = 0 when they are facing down, 1 when they are facing right, etc. Then use this and the enemy's position to work out whether or not the enemy has been hit. For making the enemy fly back, you would get the character's direction to work out which way they would fly back. I would give some example code to help explain, but I'm on my tablet.
I am making a game where characters come from opposite sides of the screen and collide and attack each other then they are removed when they die. I have managed to enable the lists to stop moving and do damage when they collide but my problem is when 2 of them collide all of them stop moving.
My code for the shortswordsman collisions is:
private void shortMoveCollisions(GameTime gameTime)
{
Rectangle shortRect;
int shortSpeed = 2;
int shortDamage = 20;
bool collided = false;
for (int i = 0; i < shortList.Count; i++)
{
List<Goblin> tempGoblinList = new List<Goblin>(goblinList);
shortRect = new Rectangle((int)shortList[i].position.X, (int)shortList[i].position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
foreach (Goblin goblin in tempGoblinList)
{
Rectangle goblinRect = new Rectangle((int)goblin.position.X, (int)goblin.position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
if (shortRect.Intersects(goblinRect))
{
collided = true;
shortList[i].AnimateAttack(gameTime);
shortTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (shortTimer >= shortDelay)
{
shortTimer -= shortDelay;
goblin.health -= shortDamage;
if (goblin.health <= 0)
{
goblinList.Remove(goblin);
}
}
}
}
if (shortRect.Intersects(background.badCastleRect))
{
collided = true;
shortList[i].AnimateAttack(gameTime);
shortTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (shortTimer >= shortDelay)
{
shortTimer -= shortDelay;
badCastleHealth -= shortDamage;
}
}
if (collided == false)
{
shortList[i].AnimateWalk(gameTime);
shortList[i].position.X += shortSpeed;
}
}
}
And my code for the goblins collisions is:
private void GoblinMoveCollisions(GameTime gameTime)
{
Rectangle goblinRect;
int goblinSpeed = 2;
int goblinDamage = 20;
bool collided = false;
for (int i = 0; i < goblinList.Count; i++)
{
List<ShortSwordsman> tempShortList = new List<ShortSwordsman>(shortList);
goblinRect = new Rectangle((int)goblinList[i].position.X, (int)goblinList[i].position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
foreach (ShortSwordsman shortSwordsman in tempShortList)
{
Rectangle shortRect = new Rectangle((int)shortSwordsman.position.X, (int)shortSwordsman.position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
if (goblinRect.Intersects(shortRect))
{
collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
shortSwordsman.health -= goblinDamage;
if (shortSwordsman.health <= 0)
{
shortList.Remove(shortSwordsman);
}
}
}
}
if (goblinRect.Intersects(background.goodCastleRect))
{
collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
goodCastleHealth -= goblinDamage;
}
}
if (collided == false)
{
goblinList[i].AnimateWalk(gameTime);
goblinList[i].position.X -= goblinSpeed;
}
}
}
Your collided bool shouldn't be a variable of those classes, as those classes seem to operate on the entire lists of all the entities. Instead the collision detection should happen on an entity by entity basis, basically: make the collided bool a property of goblins and swordsmen. This would mean that you'll have to check for intersections with other creatures of the same type as well, probably without an attack command.
This is the code I am using at the moment - shortswordsman and goblin are the same so i will only show one:
In the goblin class:
public Goblin(Vector2 position, float health, bool Collided, Rectangle goblinRect)
{
this.position = position;
this.health = health;
this.Collided = Collided;
this.goblinRect = goblinRect;
}
In the game1 class:
void CreateGoblin()
{
goblinList.Add(new Goblin(new Vector2(1900, 270), 100, false, new Rectangle()));
}
And then for the collisions i tried this - this includes the bit to try and stop them overlapping each other:
private void GoblinMoveCollisions(GameTime gameTime)
{
int goblinSpeed = 2;
int goblinDamage = 20;
for (int i = 0; i < goblinList.Count; i++)
{
goblinList[i].Collided = false;
goblinList[i].goblinRect = new Rectangle((int)goblinList[i].position.X, (int)goblinList[i].position.Y, Goblin.texture.Width / 4 - 20, Goblin.texture.Height);
List<ShortSwordsman> tempShortList = new List<ShortSwordsman>(shortList);
foreach (ShortSwordsman shortSwordsman in tempShortList)
{
Rectangle shortRect = new Rectangle((int)shortSwordsman.position.X, (int)shortSwordsman.position.Y, ShortSwordsman.texture.Width / 4 - 20, ShortSwordsman.texture.Height);
if (goblinList[i].goblinRect.Intersects(shortRect))
{
goblinList[i].Collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
shortSwordsman.health -= goblinDamage;
if (shortSwordsman.health <= 0)
{
shortList.Remove(shortSwordsman);
}
}
}
}
if (goblinList[i].goblinRect.Intersects(background.goodCastleRect))
{
goblinList[i].Collided = true;
goblinList[i].AnimateAttack(gameTime);
goblinAttackTimer += (float)gameTime.ElapsedGameTime.TotalSeconds;
if (goblinAttackTimer >= goblinAttackDelay)
{
goblinAttackTimer -= goblinAttackDelay;
goodCastleHealth -= goblinDamage;
}
}
if (goblinList[i].goblinRect.Intersects(goblinList[i].goblinRect))
{
goblinList[i].Collided = true;
goblinList[i].AnimateStill(gameTime);
}
if (goblinList[i].Collided == false)
{
goblinList[i].AnimateWalk(gameTime);
goblinList[i].position.X -= goblinSpeed;
}
}
}
I am using the following code to tween an movieclip once _global.choiceMade equals 1...
onClipEvent (load) {
import mx.transitions.Tween;
import mx.transitions.easing.*;
}
onClipEvent (enterFrame) {
if (_global.choiceMade == 1) {
var myTweenX:Tween = new Tween(this, "_x", mx.transitions.easing.Back.easeOut, this._x, -349, 0.5, True);
}
}
This is contained within each frame of the main timeline. The first time it runs fine but on the next frame it runs incredibly slow (takes about 12 seconds not 0.5 and is very choppy), if I then return to the first frame and run it again now this time it is extremely slow.
I can't work out why its doing this my CPU stays around 6-15% while its running so it can't be too demanding.
Updated to show rest of my code:
On main timeline have a frame each containing a movieclip. On the timeline of each of these movieclips contains:
//tint an object with a color just like Effect panel
//r, g, b between 0 and 255; amount between 0 and 100
Color.prototype.setTint = function(r, g, b, amount) {
var percent = 100-amount;
var trans = new Object();
trans.ra = trans.ga=trans.ba=percent;
var ratio = amount/100;
trans.rb = r*ratio;
trans.gb = g*ratio;
trans.bb = b*ratio;
this.setTransform(trans);
};//Robert Penner June 2001 - http://www.robertpenner.com
MovieClip.prototype.scaleXY = function(to){
this.onEnterFrame = function(){
this._alpha = to-(to-this._alpha)/1.2;
if(this._alpha > to-1 && this._alpha < to+1){
this._alpha = to;
delete this.onEnterFrame
}
}
}
scoreUpdated = 0;
Answer = 1;
_global.choiceMade = 0;
Buttons = new Array(this.buttonHolder.True, this.buttonHolder.False);
Answers = new Array(this.Correct, this.Wrong);
for (i=0; i<Answers.length; i++) {
Answers[i]._alpha = 0;
}
for (b=0; b<Buttons.length; b++) {
Buttons[b].thisValue = b;
}
In this movieclip there are two movieclip buttons (True and False) containing this code:
onClipEvent (enterFrame) {
this.onRollOver = function() {
this.gotoAndStop("over");
};
this.onRollOut = function() {
this.gotoAndStop("up");
};
this.onPress = function() {
this.gotoAndStop("down");
};
this.onReleaseOutside = function() {
this.gotoAndStop("up");
};
this.onRelease = function() {
this.gotoAndStop("down");
whichChoice = this;
_global.choiceMade = 1;
counter = 0;
};
if (_global.choiceMade == 1) {
this.enabled = false;
this._parent.scoreNow = _global.score;
this._parent.scoreOutOf = (this._parent._parent._currentframe)- 1 + ( _global.choiceMade);
if (thisValue == this._parent._parent.Answer && whichChoice == this) {
myColor = new Color(this);
myColor.setTint(0,204,0,13);
this._parent._parent.Answers[0]._alpha = 100;
this._parent._parent.Answers[0].scaleXY(100);
this.tick.swapDepths(1000);
if (counter == 0) {
_global.score++;
counter++;
}
}
else if (thisValue == this._parent._parent.Answer) {
myColor = new Color(this);
myColor.setTint(0,204,0,13);
this.tick.swapDepths(1000);
}
else if (whichChoice == this) {
this._parent._parent.Answers[1]._alpha = 100;
this._parent._parent.Answers[1].scaleXY(100);
myColor = new Color(this);
myColor.setTint(255,0,0,13);
this.cross.swapDepths(1000);
}
else {
myColor = new Color(this);
myColor.setTint(255,0,0,13);
myColor.setTint(255,0,0,13);
this.cross.swapDepths(1000);
}
}
}
The script at the top is on a movieclip these buttons are contained in called buttonHolder which does what it says, and tweens the buttons across the screen to reveal a next button once an answer is chosen.
From what I can see, as long as you have choiceMade == 1 you create a new effect! which is not ok. because in 1 sec at 15 fps you will have 15 tweens running :(
try yo set choiceMade = 0 or somehting else than 1
onClipEvent (enterFrame)
{
if (_global.choiceMade == 1)
{
_global.choiceMade = -1;
var myTweenX:Tween = new Tween(this, "_x", mx.transitions.easing.Back.easeOut, this._x, -349, 0.5, True);
}
}
Without seeing the rest of your code it's hard to see exactly what's going on. But it looks like you never change choiceMade and it continuously recreates the tween.
onClipEvent (enterFrame) {
if (_global.choiceMade == 1) {
var myTweenX:Tween = new Tween(this, "_x", mx.transitions.easing.Back.easeOut, this._x, -349, 0.5, True);
_global.choiceMade = 0;
}
}