Breakout hitbox system - actionscript-3

I've been working on this for several weeks now and I can get it to work as It to work. It's almost there I guess there is just something I'm missing. I basically cant get the collision detection betwen the blocks and the ball to work like I wnat them to work.
Dump SWF
The ball still has a chance to plow loads of block within seconds. I would love to hear form people who have had a similiar problem.
Here's the code;
private function checkCollision():void
{
grdx = Math.floor((ball.x) / 28);
grdy = Math.floor((ball.y) / 14);
ngrdx = Math.floor((ball.x + dx) / 28);
ngrdy = Math.floor((ball.y + dy) / 14);
if (grdy <= level.length - 1 && ngrdy <= level.length - 1 && grdy >= 0 && ngrdy >= 0)
{
if(level[grdy][ngrdx] > 0)
{
level[grdy][ngrdx] = 0;
bnm = "Block_" + grdy + "_" + ngrdx;
if (this.getChildByName(bnm) != null)
{
this.removeChild(this.getChildByName(bnm));
dx *= -1;
totalBreaks++;
trace("Hit on X");
trace("Block: " + totalBreaks + " / " + totalBlocks);
}
}
else if(level[ngrdy][grdx] > 0)
{
bnm = "Block_" + ngrdy + "_" + grdx;
level[ngrdy][grdx] = 0;
if (this.getChildByName(bnm) != null)
{
this.removeChild(this.getChildByName(bnm));
dy *= -1;
totalBreaks++;
trace("Hit on Y");
trace("Block: " + totalBreaks + " / " + totalBlocks);
}
}
if(level[ngrdy][ngrdx] > 0)
{
bnm = "Block_" + ngrdy + "_" + ngrdx;
level[ngrdy][ngrdx] = 0;
if (this.getChildByName(bnm) != null)
{
this.removeChild(this.getChildByName(bnm));
dy *= -1;
dx *= -1;
totalBreaks++;
trace("hit on X,Y");
trace("Block: " + totalBreaks + " / " + totalBlocks);
}
}
}
}

I'm not sure I got this right but I think one problem can be with your if else if statements.
From your example, a call to checkCollision() might change twice your dx and dy vars, resulting in the ball keep going in the same direction while it hit a brick.
If I'm right then you may refactor your if statements like the following:
if (level[ngrdy][ngrdx] > 0)
{
[...]
}
else if (level[grdy][ngrdx] > 0)
{
[...]
}
else if (level[ngrdy][grdx] > 0)
{
[...]
}
Besides, it's a good practice to enclose simple tests into parenthesis. So instead of writing that:
if (grdy <= level.length - 1 && ngrdy <= level.length - 1 && grdy >= 0 && ngrdy >= 0)
I would write this :
if ((grdy <= level.length - 1) && (ngrdy <= level.length - 1) && (grdy >= 0) && (ngrdy >= 0))
thus making the code more readable.
Good work though, keep going on!
EDIT:
As your comment suggest it is not a correct answer, I dig a bit more and I now have another suggestion, using some booleans to check whether the direction should be flipped on both axes. I also did a bit of refactoring:
private function checkCollision():void
{
grdx = Math.floor((ball.x) / 28);
grdy = Math.floor((ball.y) / 14);
ngrdx = Math.floor((ball.x + dx) / 28);
ngrdy = Math.floor((ball.y + dy) / 14);
var flipX:Boolean = false;
var flipY:Boolean = false;
if ((grdy <= level.length - 1) && (ngrdy <= level.length - 1) && (grdy >= 0 && ngrdy >= 0))
{
if (testBlock(grdx, ngrdy))
{
flipY = true;
}
if (testBlock(ngrdx, grdy))
{
flipX = true;
}
if (testBlock(ngrdx, ngrdy))
{
flipX = true;
flipY = true;
}
dx *= flipX ? -1 : 1;
dy *= flipY ? -1 : 1;
}
}
private function testBlock(xPos:int, yPos:int):Boolean
{
if (level[yPos][xPos] > 0)
{
trace("hit on X,Y");
level[yPos][xPos] = 0;
breakBlock("Block_" + yPos + "_" + xPos);
trace("Block: " + totalBreaks + " / " + totalBlocks);
return true;
}
return false;
}
private function breakBlock(blockName:String):void
{
if (this.getChildByName(blockName))
{
this.removeChild(this.getChildByName(blockName));
totalBreaks++;
}
}
If it happened to be the correct solution, I'd clean this answer...

Related

Problems with a simple physics system in AS3

Well, first of all, I'm a student, so I really beg to you to be patient in the answer. I'm not a english speaker too, by the way.
Everything begins because I'll attend a Game Jam and I already started to write (or trying to write) a simple "physics" code, who I really was thinking would be easy.
I was working with classes and using hitTestObject for colision detection.
Actually I was having issues since the begin, but I was constantly trying to fix it. At this time the code really sucks and I'm already thinking in another way to do it. But something puzzles me.
Here's a part of the the code who I'd already written (It probably seems very newbie). Most part of the code is bullshit, just take a look in the last "else if".
Note: this is the "block" class, and the "obj" it's the Movie Clip of the player.
public function checkObj(obj:MovieClip):void
{
if (this.hitTestObject (obj))
{
if (this.y < obj.y)
{
if (this.x - this.width/2 <= obj.x+obj.width/2 && this.x + this.width/2 >= obj.x-obj.width/2)
{
downCol = true;
}
}
else if (this.y + this.height/2 > obj.y-obj.height/2)
{
if (this.x - this.width/2+2 <= obj.x+obj.width/2 && this.x + this.width/2-2 >= obj.x-obj.width/2)
{
upCol = true;
onBox = true;
}
}
if (this.x - this.width/2 >= obj.x+obj.width/2-2)
{
if (this.y - this.height/2<= obj.y+obj.height/2&& this.y + this.height/2>= obj.y-obj.height/2)
{
leftCol = true;
}
}
else if (this.x + this.width/2 <= obj.x-obj.width/2-2)
{
if (this.y + 5>= obj.y-obj.height/2 && this.y - 5<= obj.y+obj.height/2)
{
trace ("Collided on right");
rightCol = true;
}
}
}
}
For some reason, this way it doesn't work. It never returns me the message.
But if I do a little change:
public function checkObj(obj:MovieClip):void
{
if (this.x + this.width/2 <= obj.x-obj.width/2-2)
{
objOnRight = true;
}
if (this.hitTestObject (obj))
{
//...
else if (objOnRight == true)
{
if (this.y + 5>= obj.y-obj.height/2 && this.y - 5<= obj.y+obj.height/2)
{
rightCol = true;
trace ("Collided on right");
}
}
}
}
It works. Just because I checked the X axis of "obj " before testing the collision. I know this code it's bad at all, but if someone could help me to understand that error and maybe guide me to a more efficient solution I'll really appreciate it! Thank you.
Try this for the last else if
else if (this.x + this.width / 2 <= obj.x + obj.width / 2 - 2) {
if (this.y + 5 >= obj.y - obj.height / 2 && this.y - 5 <= obj.y + obj.height / 2) {
trace("Collided on right");
rightCol = true;
}
}
just change the "-" to "+" .
Ok, forget it. I wrote a brand new code, without hitTest, and it works like a charm. I think the Math.abs solved the problem with negative numbers.
Thanks for your help, kare81.
Here's the code:
public function checkObj(obj:MovieClip,place:int):void
{
if (obj.x + obj.width / 2 > this.x - width / 2 && obj.x < this.x - width / 2 + 7 && Math.abs (obj.y - y) < height / 2)
{
obj.x = this.x - width / 2 - obj.width / 2;
}
if (obj.x - obj.width / 2 < this.x +width / 2 && obj.x > this.x + width / 2 - 7 && Math.abs (obj.y - y) < height / 2)
{
obj.x = this.x +width / 2 + obj.width / 2;
}
if (Math.abs (obj.x- this.x) < width / 2 + obj.width / 2 && obj.y<y-height/2 && obj.onFloor > y-height/2 && obj.onBlock != place)
{
obj.onFloor = y - height / 2;
obj.onBlock = place;
}
if (Math.abs (obj.x - this.x) >= width / 2 + obj.width / 2 && obj.onBlock == place)
{
obj.onFloor = 450;
}
if (obj.y - obj.height / 2 < y + height /2 && obj.y > y && Math.abs (obj.x - this.x) < width / 2 + obj.width / 2)
{
obj.y = y + height / 2 + obj.height / 2;
}
}

Best pattern to reduce excessive conditionals

I have the following code for a game that manages display patterns for items by randomly deciding on one, creating the items based on the pattern chosen and then animating them.
The problem is that cleaning code and managing changes can be cumbersome due to the sheer size, I have been studying design patterns lately and I was wondering which would be the best one to apply here, so far I have considered strategy and command as possible options
"The strategy pattern is used to create an interchangeable family of algorithms from which the required process is chosen at run-time." Seems like something I could use to apply the positioning of the items depending on the pattern selected.
And by looking at previous questions here when asked about reducing the amount of if/elses the command pattern came up quite a bit.
" The command pattern is used to express a request, including the call to be made and all of its required parameters, in a command object. The command may then be executed immediately or held for later use."
Still, I don't know if I may be finding relevance where there is not, so I thought I'd ask if such patterns can be applied to the following scenarios.
Below is the relevant code, I'm specially interested in learning about this because almost the same code is repeated for enemies.
/**
* Set items pattern.
*
*/
private function setItemsPattern():void
{
// Change until enough flight distance has been accumulated.
if (patternChange > 0)
{
patternChange -= playerSpeed * elapsed;
}
else
{
// As the player moves, change item patterns.
if ( Math.random() < 0.7 )
{
// If < normal item chance (0.7), get a random pattern.
pattern = Math.ceil(Math.random() * 4);
}
else
{
// If random number is > normal item chance (0.3), create special item.
pattern = Math.ceil(Math.random() * 2) + 9;
}
if (pattern == GameConstants.ITEM_PATTERN_VERTICAL)
{
// Vertical
patternStep = 15;
patternChange = Math.random() * 500 + 500;
}
else if (pattern == GameConstants.ITEM_PATTERN_HORIZONTAL)
{
// Horizontal
patternOnce = true;
patternStep = 40;
patternChange = patternGap * Math.random() * 3 + 5;
}
else if (pattern == GameConstants.ITEM_PATTERN_ZIGZAG)
{
// ZigZag
patternStep = Math.round(Math.random() * 2 + 2) * 10;
if ( Math.random() > 0.5 )
{
patternDirection *= -1;
}
patternChange = Math.random() * 800 + 800;
}
else if (pattern == GameConstants.ITEM_PATTERN_RANDOM)
{
// Random
patternStep = Math.round(Math.random() * 3 + 2) * 50;
patternChange = Math.random() * 400 + 400;
}
else
{
patternChange = 0;
}
}
}
/**
* Creates items - called by createPattern()
*
*/
private function createItems():void
{
var itemToTrack:Item;
switch (pattern)
{
case GameConstants.ITEM_PATTERN_HORIZONTAL:
// Horizontal.
if (Math.random() > 0.9)
{
// Asignes items not too close to border.
patternPosY = Math.floor(Math.random() * (gameArea.bottom - gameArea.top + 1)) + gameArea.top;
}
itemToTrack = itemFactory.getItem(GameConstants.ITEM_TYPE_1);
this.addChild(itemToTrack);
// Sets pos
itemToTrack.x = stage.stageWidth + itemToTrack.width ;
itemToTrack.y = patternPosY;
// Marks item for animation
itemsToAnimate.push(itemToTrack);
break;
case GameConstants.ITEM_PATTERN_VERTICAL:
// Vertical
if (patternOnce == true)
{
patternOnce = false;
patternPosY = Math.floor(Math.random() * (gameArea.bottom - gameArea.top + 1)) + gameArea.top;
patternLength = (Math.random() * 0.4 + 0.4) * stage.stageHeight;
}
patternPosYstart = patternPosY;
while (patternPosYstart + patternStep < patternPosY + patternLength && patternPosYstart + patternStep < stage.stageHeight * 0.8)
{
itemToTrack = itemFactory.getItem(GameConstants.ITEM_TYPE_1);
this.addChild(itemToTrack);
itemToTrack.x = stage.stageWidth + itemToTrack.width;
itemToTrack.y = patternPosYstart;
itemsToAnimate.push(itemToTrack)
patternPosYstart += patternStep;
}
break;
case GameConstants.ITEM_PATTERN_ZIGZAG:
// ZigZag
if (patternDirection == 1 && patternPosY > gameArea.bottom - 50)
{
patternDirection = -1;
}
else if ( patternDirection == -1 && patternPosY < gameArea.top )
{
patternDirection = 1;
}
if (patternPosY >= gameArea.top && patternPosY <= gameArea.bottom)
{
itemToTrack = itemFactory.getItem(GameConstants.ITEM_TYPE_1);
this.addChild(itemToTrack);
itemToTrack.x = stage.stageWidth + itemToTrack.width;
itemToTrack.y = patternPosY;
itemsToAnimate.push(itemToTrack)
patternPosY += patternStep * patternDirection;
}
else
{
patternPosY = gameArea.top;
}
break;
case GameConstants.ITEM_PATTERN_RANDOM:
// Random, creates N amount of items on screen.
if (Math.random() > 0.3)
{
patternPosY = Math.floor(Math.random() * (gameArea.bottom - gameArea.top + 1)) + gameArea.top;
while (patternPosY + patternStep < gameArea.bottom)
{
itemToTrack = itemFactory.getItem(GameConstants.ITEM_TYPE_1);
this.addChild(itemToTrack);
itemToTrack.x = stage.stageWidth + itemToTrack.width;
itemToTrack.y = patternPosY;
itemsToAnimate.push(itemToTrack)
patternPosY += Math.round(Math.random() * 100 + 100);
}
}
break;
case GameConstants.ITEM_PATTERN_SPEED:
// special item
patternPosY = Math.floor(Math.random() * (gameArea.bottom - gameArea.top + 1)) + gameArea.top;
itemToTrack = itemFactory.getItem(GameConstants.ITEM_TYPE_MANA);
this.addChild(itemToTrack);
itemToTrack.x = stage.stageWidth + itemToTrack.width;
itemToTrack.y = patternPosY;
itemsToAnimate.push(itemToTrack);
break;
case GameConstants.ITEM_PATTERN_STR:
// special item
patternPosY = Math.floor(Math.random() * (gameArea.bottom - gameArea.top + 1)) + gameArea.top;
itemToTrack = itemFactory.getItem(GameConstants.ITEM_TYPE_REFERENCIA);
this.addChild(itemToTrack);
itemToTrack.x = stage.stageWidth + itemToTrack.width;
itemToTrack.y = patternPosY;
itemsToAnimate.push(itemToTrack);
break;
}
}
/**
* Animates the vector itemsToAnimate.
*
*/
private function animateItems():void
{
var itemToTrack:Item;
for(var i:uint = 0;i<itemsToAnimate.length;i++)
{
itemToTrack = itemsToAnimate[i];
if (itemToTrack != null)
{
if (referencia > 0 && itemToTrack.itemType <= GameConstants.ITEM_TYPE_REFERENCIA)
{
itemToTrack.x -= (itemToTrack.x - brujaX) * 0.2;
itemToTrack.y -= (itemToTrack.y - brujaY) * 0.2;
}
else
{
itemToTrack.x -= playerSpeed * elapsed;
}
if (itemToTrack.x < -80 || gameState == GameConstants.GAME_STATE_OVER)
{
disposeItemTemporarily(i, itemToTrack);
}
else
{
brujaItem_xDist = itemToTrack.x - brujaX;
brujaItem_yDist = itemToTrack.y - brujaY;
brujaItem_sqDist = brujaItem_xDist * brujaItem_xDist + brujaItem_yDist * brujaItem_yDist;
if (brujaItem_sqDist < 5000)
{
if (itemToTrack.itemType == GameConstants.ITEM_TYPE_1)
{
scoreItems += itemToTrack.itemType;
hud.itemScore = scoreItems;
if (!Sounds.muted) Sounds.sndPag.play();
}
else if (itemToTrack.itemType == GameConstants.ITEM_TYPE_MANA)
{
scoreItems += 1;
mana = 5;
if (isHardwareRendering) particleMana.start(mana);
if (!Sounds.muted) Sounds.sndMana.play();
if (!Sounds.muted) Sounds.sndRisa.play();
}
else if (itemToTrack.itemType == GameConstants.ITEM_TYPE_REFERENCIA)
{
scoreItems += 1;
referencia = 20;
partRef = 0.5;
if (isHardwareRendering) particleRef.start(partRef);
playRandomRef();
}
if(referencia > 0){referencia--;}
disposeItemTemporarily(i, itemToTrack);
}
}
}
}
}
Your function setItemsPattern and createItems both contain a switch-case statement, so you could create a base class contains two functions hanlde the switch-case work.
For example, you get the base class like this
Class BaseBehavior
{
//if the variable shouldn't be accessed by other class, change public to protected
public var patternOnce:Boolean;
public var patternStep:int;
public var patternChange:int;
public var patternDirection:int;
public var itemToTrack:Object;
public var gameArea:Object;
//used in setItemsPattern function
public function initPatternData():void {};
//used in createItems function
public function createItems():void {};
public function dispose():void {};
}
And here is the vertical class
Class VerticalBehavior extends BaseBehavior
{
override public function initPatternData():void
{
patternStep = 15;
patternChange = Math.random() * 500 + 500;
}
override public function createItems():void
{
if (Math.random() > 0.9)
{
// Asignes items not too close to border.
patternPosY = Math.floor(Math.random() * (gameArea.bottom - gameArea.top + 1)) + gameArea.top;
}
itemToTrack = itemFactory.getItem(GameConstants.ITEM_TYPE_1);
// Sets pos
itemToTrack.x = stage.stageWidth + itemToTrack.width ;
itemToTrack.y = patternPosY;
}
}
Other sub classes are most same.
Now you need a factory class to create the sub class
Class BehaviorFactory
{
public static function create(type:int):BaseBehavior
{
switch(type)
{
case 1://vertical
return new VerticalBehavior();
case 2:
return ...
...
}
}
}
After these work, you can use them in your old logic code
private var behavior:BaseBehavior;
private function setItemsPattern():void
{
if (behavior && behavior.patternChange > 0)
{
behavior.patternChange -= playerSpeed * elapsed;
}
else
{
// As the player moves, change item patterns.
if ( Math.random() < 0.7 )
{
// If < normal item chance (0.7), get a random pattern.
pattern = Math.ceil(Math.random() * 4);
}
else
{
// If random number is > normal item chance (0.3), create special item.
pattern = Math.ceil(Math.random() * 2) + 9;
}
//here to create the sub class
//dispose old behavior
if (behavior)
{
behavior.dispose();
}
behavior = BehaviorFactory.create(pattern);
}
private function createItems():voidh
{
//you may check behavior is null here
var itemToTrack:Item = behavior.createItems();
this.addChild(itemToTrack);
// Marks item for animation
itemsToAnimate.push(itemToTrack);
}
At last, if you want add a new type, you just need to create a sub behavior class and add it to the factory class.But be careful if the variables in the behavior increase too many, you may need to use composition class.

No keyboard input AS3

So I'm trying to get keyboard input from the user to move a character. It works in another program that I was using, and I copy pasted, but it isn't working in this one. It gives me Line 87, Column 38 1119: Access of possibly undefined property EVENT_FRAME through a reference with static type Class. I can't seem to figure out what the issue is.
This is the buttonClick function that is used to when I hit the start button.
public function buttonClick(ev:MouseEvent):void
{
createGameScreen();
this.mcLink.gotoAndPlay("Idle");
this.mcLink.x=50;
this.mcLink.y=200;
this.mcLink.scaleX=this.mcLink.scaleY=3;
this.stage.addEventListener(Event.EVENT_FRAME, this.enterFrameHandler, false, 0, true);
}
This is the event handler function for the keyboard input.
public function enterFrameHandler($e:Event):void
{
if (this.mcLink)
{
if (KeyboardManager.instance.isKeyDown(KeyCode.DOWN))
{
if (this.mcLink.y + this.mcLink.height > this.stage.stageHeight || this.mcLink.y - this.mcLink.height <= 0)
{
this.mcLink.y += -15;
mcLink.gotoAndPlay("Idle");
return;
}
this.mcLink.y += _nHeroMovementSpeed;
mcLink.gotoAndPlay("Down");
}
else if (KeyboardManager.instance.isKeyDown(KeyCode.UP))
{
if (this.mcLink.y + this.mcLink.height > this.stage.stageHeight || this.mcLink.y - this.mcLink.height <= 0)
{
this.mcLink.y += 15;
mcLink.gotoAndPlay("Idle");
return;
}
this.mcLink.y -= _nHeroMovementSpeed;
mcLink.gotoAndPlay("Up");
}
if (KeyboardManager.instance.isKeyDown(KeyCode.LEFT))
{
if (this.mcLink.x + this.mcLink.width > this.stage.stageWidth || this.mcLink.x - this.mcLink.width <= 0)
{
this.mcLink.x += 15;
mcLink.gotoAndPlay("Idle");
return;
}
this.mcLink.x -= _nHeroMovementSpeed;
mcLink.gotoAndPlay("Left");
}
else if (KeyboardManager.instance.isKeyDown(KeyCode.RIGHT))
{
if (this.mcLink.x + this.mcLink.width > this.stage.stageWidth || this.mcLink.x - this.mcLink.width <= 0)
{
this.mcLink.x += -15;
mcLink.gotoAndPlay("Idle");
return;
}
this.mcLink.x += _nHeroMovementSpeed;
mcLink.gotoAndPlay("Right");
}
}
}
Did you mean Event.ENTER_FRAME?
this.stage.addEventListener(Event.ENTER_FRAME, this.enterFrameHandler, false, 0, true);
// ^^^^^^^^^^^ EVENT_FRAME isn't a known Event.

Button only clickable when visible

Ok i want my button to only be clickabe once it is visibe, it is invisible til you win the game(1 score of pong)
here is what i have
var buttonsStates:Object = {
"scoreBoard_W" : false
};
function checkVisibility () {
for (var scoreBoard_W:String in buttonsStates) {
if(visible == true)
{
scoreBoard_W.addEventListener(MouseEvent.CLICK, goto3);
function goto3(Event:MouseEvent)
{
gotoAndStop(1,"Menu");
}
and here is the error: Pong, Layer 'Pong', Frame 2, Line 129 1061: Call to a possibly undefined method addEventListener through a reference with static type String.
im not sure what it means, or if im on the right track any help is apperciaed
Here is all of the code
stop();
var buttonsStates:Object = {
"scoreBoard_W" : false
};
var ballSpeedX:int = -3;
var ballSpeedY:int = -2;
var cpuPaddleSpeed:int = 3;
var playerScore:int = 0;
var cpuScore:int = 0;
scoreBoard_W.visible = false;
scoreBoard_L.visible = false;
init();
function init():void
{
stage.addEventListener(Event.ENTER_FRAME, loop);
}
function calculateBallAngle(paddleY:Number, ballY:Number):Number
{
var ySpeed:Number = 5 * ((ballY - paddleY) / 25);
return ySpeed;
}
function updateTextFields():void
{
playerScoreText.text = ("Player Score: " + playerScore);
cpuScoreText.text = ("CPU Score: " + cpuScore);
}
function loop(e:Event):void
{
if (playerPaddle.hitTestObject(ball) == true)
{
if (ballSpeedX < 0)
{
ballSpeedX *= -1;
ballSpeedY = calculateBallAngle(playerPaddle.y, ball.y);
}
}
else if (cpuPaddle.hitTestObject(ball) == true )
{
if (ballSpeedX > 0)
{
ballSpeedX *= -1;
ballSpeedY = calculateBallAngle(cpuPaddle.y, ball.y);
}
}
if (cpuPaddle.y < ball.y - 10)
{
cpuPaddle.y += cpuPaddleSpeed;
}
else if (cpuPaddle.y > ball.y + 10)
{
cpuPaddle.y -= cpuPaddleSpeed;
}
playerPaddle.y = mouseY;
if (playerPaddle.y - playerPaddle.height / 2 < 0)
{
playerPaddle.y = playerPaddle.height / 2;
}
else if (playerPaddle.y + playerPaddle.height/2 > stage.stageHeight)
{
playerPaddle.y = stage.stageHeight - playerPaddle.height / 2;
}
ball.x += ballSpeedX;
ball.y += ballSpeedY;
if (ball.x <= ball.width / 2)
{
ball.x = ball.width / 2;
ballSpeedX *= -1;
cpuScore++;
updateTextFields();
}
else if (ball.x >= stage.stageWidth-ball.width/2)
{
ball.x = stage.stageWidth - ball.width / 2;
ballSpeedX *= -1;
playerScore++;
updateTextFields();
}
if (ball.y <= ball.height / 2)
{
ball.y = ball.height / 2;
ballSpeedY *= -1;
}
else if (ball.y >= stage.stageHeight-ball.height/2)
{
ball.y = stage.stageHeight - ball.height / 2;
ballSpeedY *= -1;
}
if (playerScore >= 1)
{
stage.removeEventListener(Event.ENTER_FRAME, loop);
scoreBoard_W.visible = true;
}
if (cpuScore >= 1)
{
stage.removeEventListener(Event.ENTER_FRAME, loop);
scoreBoard_L.visible = true;
}
}
Mouse.hide();
mywelcome.text = "Good Luck, " + myName;
function checkVisibility () {
for (var scoreBoard_W:String in buttonsStates) {
if(visible == true)
{
scoreBoard_W.addEventListener(MouseEvent.CLICK, goto3);
function goto3(Event:MouseEvent)
{
gotoAndStop(1,"Menu");
}
}
}
}
The problem is in this line
scoreBoard_W.addEventListener(MouseEvent.CLICK, goto3);
As you using for (var scoreBoard_W:String in buttonsStates){...} inside definition of function function checkVisibility () {...} you declare local String-type variable which block your access to button with same name.
Changing
scoreBoard_W.addEventListener(MouseEvent.CLICK, goto3);
to
this.scoreBoard_W.addEventListener(MouseEvent.CLICK, goto3);
will do the trick.

Error with jump function when putting script on movieclip

I'm having a problem with my jump function for a platformer engine. I've moved all of the hit testing onto the individual platforms in the level, so I don't have to write things out for each individual one. The problem with this is that only the first movieclip added to the stage can be jumped on to. The others just make the player sink through the floor if up is held down (as they should- as he's not meant to be there there's nothing to stop him).
So the problem is that the check for the jump just isn't registering properly on the second block. Here's the code (sorry about the excessive MovieClip(parent) s)
var playerRef:MovieClip = MovieClip(parent).player;
stage.addEventListener(Event.ENTER_FRAME, hitUpdate);
function hitUpdate(e:Event):void {
if (playerRef.hitTestPoint(playerRef.x,this.y - (playerRef.height/2)) && playerRef.x + playerRef.width > this.x && playerRef.x < this.x + this.width && !MovieClip(parent).upDown) {
MovieClip(parent).downMomentum = 0;
playerRef.y = this.y - playerRef.height;
}
if (playerRef.hitTestPoint(playerRef.x,this.y + this.height) && playerRef.x + playerRef.width > this.x && playerRef.x < this.x + this.width) {
MovieClip(parent).downMomentum = 0;
playerRef.y = this.y + this.height + MovieClip(parent).gravity;
}
if (playerRef.hitTestPoint(this.x,playerRef.y) && playerRef.y + playerRef.height > this.y && playerRef.y < this.y + this.height) {
MovieClip(parent).speed = 0;
playerRef.x = this.x - playerRef.width;
}
if (playerRef.hitTestPoint(this.x + this.width,playerRef.y) && playerRef.y + playerRef.height > this.y && playerRef.y < this.y + this.height) {
MovieClip(parent).speed = 0;
playerRef.x = this.x + this.width;
}
if (playerRef.hitTestObject(this)) {
MovieClip(parent).groundTouch = true;
} else {
MovieClip(parent).groundTouch = false;
}
}
And the jump function runs like this:
stage.addEventListener(Event.ENTER_FRAME, updates);
function updates(e:Event):void{
player.y += downMomentum;
if(!groundTouch && downMomentum < downMomCap){
downMomentum += gravity;
}
if(downMomentum > downMomCap){
downMomentum = downMomCap;
}
if(upDown && !jumping && groundTouch){
jumping = true;
jumpTimer.reset();
jumpTimer.start();
}
}
jumpTimer.addEventListener(TimerEvent.TIMER, jumpTick);
function jumpTick(e:TimerEvent):void{
if(downMomentum*-1 < downMomCap){
downMomentum -= jumpProg * jumpIncrement;
}else{
downMomentum = downMomCap * -1;
}
jumpProg -= 1;
}
jumpTimer.addEventListener(TimerEvent.TIMER_COMPLETE, jumpDone);
function jumpDone(e:TimerEvent):void{
jumpTimer.stop();
jumping = false;
jumpProg = 5;
}
I just can't find a solution to this, though I suspect it's something to do with how it checks for the player touching the platform.