60day
12-04-2008, 07:53 AM
Hi, I've been trying several forums to find an answer to this problem.
I'm building a pong game as a way of learning Flash and actionscript 3. and I'm using CS 4. Almost have it done.
The game consists of 4 frames: begin, play, win, and lose.
The code for begin works fine and the code for win and lose is the same so I will concentrate on the code for play and lose.
The actual game code in play works fine. Collision detection, score tracking, player paddle movement, AI paddle movment, etc. But there is one problem.
Problem: After the player or the computer gets to 5 points the game is supposed to go to the win or lose frame. I use gotoAndStop for this: gotoAndStop("lose"). This is where I get the "Error #1009: Cannot access a property or method of a null object reference."
From what I can tell it has to do with the gotoAndStop statements that are in the checkBoundaries function. One of the guys on the Adobe forum said this:
"in your code here the call is within the scope of 'ball' - you need to target the parent or main timeline - ie. parent.gotoAndStop("win"); "
It makes sense to me but I tried it and got a new error:
1061: Call to a possibly undefined method gotoAndStop through a reference with static type flash.display:DisplayObjectContainer.
Looking around it seemed like it might be the compiler not understanding the parent is a movieclip? To fix this I tried the code:
MovieClip(parent).gotoAndStop("lose");
The code compiled but I got a new error once I lost to the computer:
TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::Stage@b485b51 to flash.display.MovieClip.
at MethodInfo-9()
at pong3_fla::MainTimeline/fnBallEnterFrame()
I also trie MovieClip(root).gotoAndStop("lose"); which caused a 1009 error again.
My latest try is from a post on this site called "Trying (and Failing) to change things on the main time line (Root?)". The solution for this post made sense to me also. It said to have the movieclip dispatch an event, have the main timeline listen for the event, and then call the gotoAndStop function once the main timeline hears the event. Unfortunately, I couldn't get the code to work. Seems to be a common theme with me.
The attached zip has the full fla file. And below is the code from the play and lose frames.
Any thoughts?
//PLAY FRAME CODE
var playerScore:int = 0;
var computerScore:int = 0;
var relY:int;
var relPerc:Number;
var newDy:Number;
init();
function init(){
//turns off mouse pointer
Mouse.hide();
//gives ball initial direction
ball.dx = 15;
ball.dy = 6;
//Sets the speed of the computer's paddle. Higher speed equals a better
//opponent.
computerPaddle.speed = 8;
}
playerPaddle.addEventListener(Event.ENTER_FRAME, fnPlayerEnterFrame);
computerPaddle.addEventListener(Event.ENTER_FRAME, fnComputerEnterFrame);
ball.addEventListener(Event.ENTER_FRAME, fnBallEnterFrame);
function fnPlayerEnterFrame(event:Event):void{
//Player's paddle follows mouse
playerPaddle.y = stage.mouseY - (playerPaddle.height / 2);
}
function fnComputerEnterFrame(event:Event):void{
//Move the computer's paddle relative to the ball and difficulty
//setting (computerPaddle.speed)
if ((ball.y + (ball.height/2)) < (computerPaddle.y + (computerPaddle.height/2))){
computerPaddle.dy = -computerPaddle.speed;
} else {
computerPaddle.dy = computerPaddle.speed;
}
computerPaddle.y += computerPaddle.dy;
}
function fnBallEnterFrame(event:Event):void{
//move the ball
ball.move();
//check if it hit the top or bottom
ball.checkBoundaries();
//check if it hit a paddle
ball.checkPaddles();
}
ball.move = function(){
ball.x += ball.dx;
ball.y += ball.dy;
}
ball.checkBoundaries = function(){
if (ball.y < 0){
ball.dy = -ball.dy;
}
if (ball.y > stage.stageHeight){
ball.dy = -ball.dy;
}
if (ball.x < 0){
computerScore++;
computerScoreField.text = computerScore.toString();
if (computerScore >= 5){
gotoAndStop("lose");
}
ball.x = computerPaddle.x-50;
ball.y = computerPaddle.y + (computerPaddle.height / 2);
ball.dy = 0;
}
if (ball.x > stage.stageWidth){
playerScore++;
playerScoreField.text = playerScore.toString();
if (playerScore >= 5){
gotoAndStop("win");
}
ball.x = playerPaddle.x + 50;
ball.y = playerPaddle.y + (playerPaddle.height / 2);
ball.dy = 0;
}
}
ball.checkPaddles = function(){
if (ball.hitTestObject(playerPaddle)){
ball.dx = -ball.dx;
ball.dy = getDy(playerPaddle);
}
if (ball.hitTestObject(computerPaddle)){
ball.dx = -ball.dx;
ball.dy = getDy(computerPaddle);
}
}
function getDy(paddle){
relY = (ball.y + (ball.height/2)) - (paddle.y + (paddle.height/2));
relPerc = relY / paddle.height;
newDy = relPerc * 30;
return newDy;
}
//LOOSE FRAME CODE
Mouse.show();
btnPlay.addEventListener(MouseEvent.CLICK, fnPlay);
I'm building a pong game as a way of learning Flash and actionscript 3. and I'm using CS 4. Almost have it done.
The game consists of 4 frames: begin, play, win, and lose.
The code for begin works fine and the code for win and lose is the same so I will concentrate on the code for play and lose.
The actual game code in play works fine. Collision detection, score tracking, player paddle movement, AI paddle movment, etc. But there is one problem.
Problem: After the player or the computer gets to 5 points the game is supposed to go to the win or lose frame. I use gotoAndStop for this: gotoAndStop("lose"). This is where I get the "Error #1009: Cannot access a property or method of a null object reference."
From what I can tell it has to do with the gotoAndStop statements that are in the checkBoundaries function. One of the guys on the Adobe forum said this:
"in your code here the call is within the scope of 'ball' - you need to target the parent or main timeline - ie. parent.gotoAndStop("win"); "
It makes sense to me but I tried it and got a new error:
1061: Call to a possibly undefined method gotoAndStop through a reference with static type flash.display:DisplayObjectContainer.
Looking around it seemed like it might be the compiler not understanding the parent is a movieclip? To fix this I tried the code:
MovieClip(parent).gotoAndStop("lose");
The code compiled but I got a new error once I lost to the computer:
TypeError: Error #1034: Type Coercion failed: cannot convert flash.display::Stage@b485b51 to flash.display.MovieClip.
at MethodInfo-9()
at pong3_fla::MainTimeline/fnBallEnterFrame()
I also trie MovieClip(root).gotoAndStop("lose"); which caused a 1009 error again.
My latest try is from a post on this site called "Trying (and Failing) to change things on the main time line (Root?)". The solution for this post made sense to me also. It said to have the movieclip dispatch an event, have the main timeline listen for the event, and then call the gotoAndStop function once the main timeline hears the event. Unfortunately, I couldn't get the code to work. Seems to be a common theme with me.
The attached zip has the full fla file. And below is the code from the play and lose frames.
Any thoughts?
//PLAY FRAME CODE
var playerScore:int = 0;
var computerScore:int = 0;
var relY:int;
var relPerc:Number;
var newDy:Number;
init();
function init(){
//turns off mouse pointer
Mouse.hide();
//gives ball initial direction
ball.dx = 15;
ball.dy = 6;
//Sets the speed of the computer's paddle. Higher speed equals a better
//opponent.
computerPaddle.speed = 8;
}
playerPaddle.addEventListener(Event.ENTER_FRAME, fnPlayerEnterFrame);
computerPaddle.addEventListener(Event.ENTER_FRAME, fnComputerEnterFrame);
ball.addEventListener(Event.ENTER_FRAME, fnBallEnterFrame);
function fnPlayerEnterFrame(event:Event):void{
//Player's paddle follows mouse
playerPaddle.y = stage.mouseY - (playerPaddle.height / 2);
}
function fnComputerEnterFrame(event:Event):void{
//Move the computer's paddle relative to the ball and difficulty
//setting (computerPaddle.speed)
if ((ball.y + (ball.height/2)) < (computerPaddle.y + (computerPaddle.height/2))){
computerPaddle.dy = -computerPaddle.speed;
} else {
computerPaddle.dy = computerPaddle.speed;
}
computerPaddle.y += computerPaddle.dy;
}
function fnBallEnterFrame(event:Event):void{
//move the ball
ball.move();
//check if it hit the top or bottom
ball.checkBoundaries();
//check if it hit a paddle
ball.checkPaddles();
}
ball.move = function(){
ball.x += ball.dx;
ball.y += ball.dy;
}
ball.checkBoundaries = function(){
if (ball.y < 0){
ball.dy = -ball.dy;
}
if (ball.y > stage.stageHeight){
ball.dy = -ball.dy;
}
if (ball.x < 0){
computerScore++;
computerScoreField.text = computerScore.toString();
if (computerScore >= 5){
gotoAndStop("lose");
}
ball.x = computerPaddle.x-50;
ball.y = computerPaddle.y + (computerPaddle.height / 2);
ball.dy = 0;
}
if (ball.x > stage.stageWidth){
playerScore++;
playerScoreField.text = playerScore.toString();
if (playerScore >= 5){
gotoAndStop("win");
}
ball.x = playerPaddle.x + 50;
ball.y = playerPaddle.y + (playerPaddle.height / 2);
ball.dy = 0;
}
}
ball.checkPaddles = function(){
if (ball.hitTestObject(playerPaddle)){
ball.dx = -ball.dx;
ball.dy = getDy(playerPaddle);
}
if (ball.hitTestObject(computerPaddle)){
ball.dx = -ball.dx;
ball.dy = getDy(computerPaddle);
}
}
function getDy(paddle){
relY = (ball.y + (ball.height/2)) - (paddle.y + (paddle.height/2));
relPerc = relY / paddle.height;
newDy = relPerc * 30;
return newDy;
}
//LOOSE FRAME CODE
Mouse.show();
btnPlay.addEventListener(MouseEvent.CLICK, fnPlay);