Hi,
Hope you all will be fine. I am new to Flash and AS3 and also to game programming. I am creating a game which is very simple. There is a bar (bouncing bar) on which when ball hits it bounce and there are bricks , when ball strikes with the brick the brick disappear.
What is happening that when ball strikes with the brick sometimes more than one bricks disappear.Also when ball strikes from the top bricks first it strike with something that is not visible. It seems that there are bricks which are not visible and ball strikes with them first.
Also i want that when ball strikes with the left side of bar(the portion that is left from the middle) the ball goes to left side and when it strikes with the right side(from middle onwards) the ball goes to right side.
I think i have some problem with collision detection. Please tell me why this is happening that more than one bricks disappear and how can i correct it.
Also i want that there is also game over screen come when all the bricks disappear. I created a GameOverScreen , which is very simple, just set it background color with black and have a text gameOver. But when i created a instance of it it shows me null object reference. For testing purpose what i did that when i press space bar then GameOverScreen should be shown but it gives me null pointer reference. Please tell me what is going wrong . Here is my code. I am using Flash Cs5
Code:
package {
[SWF(backgroundColor="0x000000")]
public class PlayScreen extends Sprite {
private var bar:BouncingBar;
private var ball:Ball;
private var bricks:Array;
private var bouncingBar:Sprite;
private var brick:Sprite;
private var bouncingBarPosition:Point;
private var bouncingBarVelocity:Point;
private var ballPosition:Point;
private var ballVelocity:Point;
private var bounce:Number = -1.0;
private var left:Number = 0;
private var right:Number = stage.stageWidth;
private var top:Number = 0;
private var bottom:Number = stage.stageHeight;
private var gameOverScreen:GameOverScreen;
//Constructor
public function PlayScreen() {
makeBouncingBar();
makeBricks();
makeBall();
init();
}
private function makeBouncingBar():void {
bar = new BouncingBar();
bouncingBar = bar.drawBouncingBar();
addChild(bar);
bouncingBar.x = stage.stageWidth / 2;
bouncingBar.y = stage.stageHeight - bouncingBar.height - 2 ;
bar.setvx(15);
bouncingBarVelocity = new Point(bar.getvx(), 0);
bouncingBarPosition = new Point(bouncingBar.x, bouncingBar.y);
} // end of makeBouncingBar()
private function makeBricks():void {
bricks = new Array();
for (var j:uint = 0; j < stage.stageHeight/50; j++) { //rows
for (var i:uint = 0; i < stage.stageWidth/65; i++) { //column
brick = bar.drawBricks((j / 5.0) * 0xf3ff8f);
brick.x = i * brick.width+50;
brick.y = j * brick.height+50;
addChild(brick);
bricks.push(brick);
} // end of columns
} // end of rows
} // end of makeBricks()
private function makeBall():void {
ball = new Ball(7); // radius
ball.draw();
ball.setMoving(false);
addChild(ball);
ball.x = bouncingBar.x - ball.getRadius() + bouncingBar.width / 2 ;
ball.y = bouncingBar.y - ball.getRadius() - 2 ;
ballVelocity = new Point(ball.getvx(), ball.getvy());
ballPosition = new Point(ball.x, ball.y);
} // end of makeBall()
private function init():void {
stage.frameRate = 30;
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownListener);
stage.addEventListener(KeyboardEvent.KEY_UP, keyUpListener);
} // end of init()
private function keyDownListener(event:KeyboardEvent):void {
switch(event.keyCode) {
case Keyboard.LEFT:
if(bouncingBarPosition.x - bouncingBarVelocity.x > 0){
bouncingBarPosition.x -= bouncingBarVelocity.x;
bouncingBar.x = bouncingBarPosition.x;
if (ball.getMoving() == false) {
ballPosition.x -= bouncingBarVelocity.x;
ball.x = ballPosition.x;
}
}
break;
case Keyboard.RIGHT:
if (bouncingBarPosition.x + bouncingBarVelocity.x + bouncingBar.width < stage.stageWidth){
bouncingBarPosition.x += bouncingBarVelocity.x;
bouncingBar.x = bouncingBarPosition.x;
if (ball.getMoving() == false) {
ballPosition.x += bouncingBarVelocity.x;
ball.x = ballPosition.x;
}
}
break;
case Keyboard.SPACE:
gameOverScreen = new GameOverScreen();
gameOverScreen.x = 0;
gameOverScreen.y = 0;
if (ball.getMoving() == false){
ball.setMoving(true);
ball.setvx(5);
ball.setvy(-5);
ballVelocity = new Point(ball.getvx(), ball.getvy());
ballPosition = new Point(ball.x, ball.y);
addEventListener(Event.ENTER_FRAME, enterFrameListener);
} // end of if
break;
default:
break;
} // end of switch
} // end of keyDownListener()
private function keyUpListener(event:KeyboardEvent):void {
//bouncingBar.x += 0;
bouncingBarPosition.x += 0;
} // end of keyUpListener()
private function enterFrameListener(event:Event):void {
//Check to see the ball is hit on the bar
if ((ballPosition.y + ball.getRadius()) >= bouncingBarPosition.y &&
(ballPosition.y + ball.getRadius()) <= bouncingBar.y + bouncingBar.height &&
(ballPosition.x - ball.getRadius()) >= bouncingBarPosition.x &&
(ballPosition.x + ball.getRadius()) <= (bouncingBarPosition.x + bouncingBar.width)) {
ballVelocity.y *= bounce;
}
//else if(ball.hitTestObject(bouncingBar)){ballVelocity.x *= bounce;}
//Method to check whether ball striking of the edges of screen
checkWall()
//Method to check the collision between ball and bricks
checkCollision();
ballPosition.x += ballVelocity.x;
ballPosition.y += ballVelocity.y;
ball.x = ballPosition.x;
ball.y = ballPosition.y;
} // end of enterFrameListener()
private function checkCollision():void {
/*******************************
Uses the for statement to go backward through the array instead of forward. This is
necessary because, if you use splice on the array, the indexing of the array will
change, and when you increment i, you will wind up skipping over one of the
elements.
*/
for (var i:Number = bricks.length - 1; i > 0; i-- ) {
//Cast to Sprite
var brick:Sprite = Sprite(bricks[i]);
//if (ball.hitTestObject(brick)) {
if (PixelPerfectCollisionDetection.isColliding( brick, ball, this, true ) ) {
//brick.x = -100;
//brick.y = -100
removeChild(brick);
if ((ballPosition.y - ball.getRadius() <= brick.y + brick.height) || (ballPosition.y + ball.getRadius() >= brick.y)) {
ballVelocity.y *= bounce;
}
if ((ballPosition.x + ball.getRadius <= brick.x) || (ballPosition.x - ball.getRadius() < brick.x + brick.width)) {
ballVelocity.x *= bounce;
}
//ballVelocity.y *= bounce;
/******
Uses Array.splice() function to remove the reference from the array.
Array.splice() takes the index at which you want to start removing elements
and how many elements you want to remove. In our case, we are removing
only one element ; the element at the current index
*/
bricks.splice(i, 1);
//brick = null;
if (bricks.length <= 0) {
removeEventListener(Event.ENTER_FRAME, enterFrameListener);
}
}
} // end of for()
} // end of checkCollision()
private function checkWall():void {
if ((ballPosition.x + ball.getRadius()) > right) {
ballVelocity.x *= bounce;
} else if ((ballPosition.x - ball.getRadius()) < left) {
ballVelocity.x *= bounce;
}
if ((ballPosition.y + ball.getRadius()) > bottom) {
ball.setMoving(false);
ballVelocity.x=0;
ballVelocity.y=0;
ballPosition.x = bouncingBar.x - ball.getRadius() + bouncingBar.width / 2 ;
ballPosition.y = bouncingBar.y - ball.getRadius() - 2 ;
removeEventListener(Event.ENTER_FRAME, enterFrameListener);
} else if ((ballPosition.y - ball.getRadius()) < top) {
ballVelocity.y *= bounce;
}
} // end of checkWall()
} // end of class DocumentClass
} // end of package
Here is my gameOver Screen class
Code:
package {
[SWF(backgroundColor="0x000000")]
public class GameOverScreen extends Sprite {
private var gameOverText:TextField;
private var myFormat:TextFormat;
//Constructor
public function GameOverScreen() {
init();
} // end of constructor
private function init():void {
/*****
Using the TextFormat class requires creating an instance of this class, setting its
properties, and then assigning it as teh default text format for a text field.
*/
myFormat = new TextFormat();
myFormat.font = "Arial";
//Adding some bigger text size
myFormat.size = 50;
myFormat.align = TextFormatAlign.CENTER;
//Given the format a hex decimal color code
myFormat.color = 0xAACC00;
myFormat.bold = "BOLD";
/***
TextField class has a number of helpful properties, but it doesnot control formatting
aspects of the text, such as the text size, the text alignment and the font. Such
properties are configured by usign the TextFormat class.
*/
gameOverText = new TextField();
//set your TextFormat instance as the default format for your TextField.
gameOverText.defaultTextFormat = myFormat;
gameOverText.text = "GAME OVER"
addChild(gameOverText);
gameOverText.border = true;
//gameOverText.background = true;
gameOverText.width = 320;
gameOverText.height = 70;
gameOverText.selectable = false;
//Change the position of TextField by setting it's x and y properties
gameOverText.x = stage.stageWidth / 4;
gameOverText.y = stage.stageHeight / 3;
} // end of init()
} // end of class GameOverScreen
} // end of package
Error is
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at GameOverScreen/init()
at GameOverScreen()
at PlayScreen/keyDownListener()
Please tell me what i am doing wrong
Thanks