Wednesday, 14 December 2011

Game development

Using my check list as reference I finally started making my game.

  • 360 degree rotation using <- and -> arrow keys
  • Push forward and gradually slow down when up key is pressed
  • pick up knocked out penguins when walked into
  • automatically build raft when you have 6 penguins
  • random movement
  • timer
  • scoreboard
  • shooting
  • timer if you stand still too long, melt ice, dead.
The first thing on my list to do was to code the movement of my player, we had already gone through how to make the player move using the corresponding arrow keys (left key moves your left ect.) but I wanted to have my character move like the player does in the asteroid's game so after talking to our lecturers the five of us who wanted to do this kind of movement were given a script to start with:


var player:MovieClip;

// player settings
var _maxSpeed:Number = 5;
var _rotationSpeed:Number = 5;
var _thrust:Number = .5;
var _decay:Number = .90;

var _currentSpeed:Number = 0;
var _speedX:Number = 0;
var _speedY:Number = 0;

// movement flags
var _movingUp:Boolean = false;
var _movingLeft:Boolean = false;
var _movingRight:Boolean = false;

var penArray:Array=new Array();
var xArray:Array=new Array();
var yArray:Array=new Array();

// add listeners
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
stage.addEventListener(KeyboardEvent.KEY_DOWN, myOnPress);
stage.addEventListener(KeyboardEvent.KEY_UP, myOnRelease);

createPlayer();

function createPlayer():void
{
player = new Player();
player.x = stage.stageWidth / 2;
player.y = stage.stageHeight / 2;
addChild(player);
}
//adds player to middle of screen

function myOnPress(event:KeyboardEvent):void
{
switch ( event.keyCode )
{
case Keyboard.UP :
_movingUp = true;
break;

case Keyboard.LEFT :
_movingLeft = true;
break;

case Keyboard.RIGHT :
_movingRight = true;
break;
}
}

/**
 * Key Release Handlers
 */
function myOnRelease(event:KeyboardEvent):void
{
switch ( event.keyCode )
{
case Keyboard.UP :
_movingUp = false;
break;

case Keyboard.LEFT :
_movingLeft = false;
break;

case Keyboard.RIGHT :
_movingRight = false;
break;
}
}

/**
 * EnterFrame Handlers
 */
function enterFrameHandler(event:Event):void
{

if (_movingRight)
{
player.rotation +=  _rotationSpeed;
}
if (_movingLeft)
{
player.rotation -=  _rotationSpeed;
}
if (_movingUp)
{
_speedX += _thrust * Math.sin(player.rotation * (Math.PI / 180));
_speedY += _thrust * Math.cos(player.rotation * (Math.PI / 180));
if (player.x < 63)
{
gotoAndStop(53);
}
if (player.x > 491)
{
gotoAndStop(53);
}
if (player.y < 58)
{
gotoAndStop(53);
}
if (player.y > 297)
{
gotoAndStop(53);
}
}
else
{
// Deccelerate when Up Arrow key is released
_speedX *=  _decay;
_speedY *=  _decay;
}

// Maintain speed limit
_currentSpeed = Math.sqrt((_speedX * _speedX) + (_speedY * _speedY));

if (_currentSpeed > _maxSpeed)
{
_speedX *=  _maxSpeed / _currentSpeed;
_speedY *=  _maxSpeed / _currentSpeed;
}

// Move player based on calculations above
player.y -=  _speedY;
player.x +=  _speedX;
}
}

Using this base code I was able to start my game, I played around with the setting until I was happy then I started work on adding the backgrounds.

Right after the add affect listeners I added my background and the array for the penguins, after I made the background a movie clip I made two new frames inside it and added the level two backgrount to the second frame and the third to the third. When I had my timer coded I would set it to go to the net frame on the background every 5 minuites. At first I had fifteen penguins in my array but that was too much so I reduced it to four, but then back up again to seven because it was too easy before. Another thing I changed for my final game is that instead of the penguins spawning randomly on the stage, I made them spawn randomly along the x axis (the top) but at -50 on the y axis, so they all come from the top of the screen, this was because when I first coded it, the penguins sometimes appeared on top of the player or two close to avoid. I used the coding we learned when making the file with smoother movement to add the child.

//===============================================================add back'nd

var bg1:MovieClip=new BG1();



bg1.x=275

bg1.y=200
//add to center of stage



addChild(bg1);

//=================================================================add penguins

for (var i:int = 0; i < 7; i++) {

                  var pen:MovieClip = new Pen();

                  pen.x=Math.random()*550

                  pen.y=-50

                  addChild(pen);

                  //adds the pens above the top of the screen

                  penArray[i]=pen; 

After talking a lot with Marnie about how I wanted my penguins to move we came up with an idea, the problem was that I wanted my penguins to move randomly along the x and y axis, so our best plan was to make two new arrays, one for the x value, one for the y value. Each array will hold 6 numbers, they would be 1-6 but by adding a -3 at the end we get -3, -2, -1, 0 , 1, 2, this ensures that the x and y values can be posive or negative, if not the penguins would only move right and down.

                  xArray[i]= Math.random()*6 -3

                  yArray[i]= Math.random()*6 -3    

}
Finally I set up the final but of then penguin code so that when they go 50 pixels outside the area of the screen, they choose a new x and y value and come back onto the screen. To do this I made an if statement that when any penguin goes that far to choose the new values, but the problem was, how to make it choose numbers that make it go back towards the centre of the game. To start with I wrote the if statement
if (penArray[i].y>450) {
this picks up if it goes below the game by 50 pixels
xArray[i]= Math.random()*6 -3
The second line is easy enough as it can go in whatever x angle it wants. But as for the y axis I don't want it to do down any further, therefore I don't want a positive number.
yArray[i]= Math.random()*3 -3
}
So I set only half of the possible numbers and made sure that they're all negative. Using this knowledge it wasn't hard to do the rest.


Now I have a moving player character, a background and the penguins. The next thing I wanted to do was to add the transpaent blue overlay for each level, I made the first one a movie clip then added the second and third to frames after the first inside the movie clip, then I tried to add the overlay by using the same code I used before to add the background, but for some reason it would.nt show up above the background, even when placed at the end of the code, aftert consulting marnie we worked out that I had copied code from the movement text form onlie, and the reason we couldn't get it to work was becuase it was added differntly because there was a 'stage.' before the add child, when I worded the same as the others it worked fine. This problem took a lot of time to solve so I decided to prioritise and take some items off my to do list as I didn't have much time left, I scrapped the 'timer if you stand still too long, melt ice, dead.' and 'scoreboard.' Therefore I went right on to adding the hit test for the penguins hitting the player, but I had another problem, it just wouldn't pick up the hit test. While waiting for help I managed to set up the start screen, start button, game over screen and restart button. 


Between these two frames, I originally had only the frame with the game coding on it, but then I decided to add an instructions screen for round 50 frames, then I added a stop(); at the top of the game coding.

After this with the help of Lee we worked out that if we changed
 if (penArray[i].hitTestPoint(player.X,player.Y, true)) {
to

if (penArray[i].hitTestObject(player)) {
it worked therefore I set it to take you to the end game frame when the hit test occurred. After all this I regrettably realised I had hardly any time left, so I decided to not add the shooting aspect, or have levels as the other aspects were more important. 
Next I edited the code we used to make a timer in a tutorial and added into my file, but when I tested it the background was added on top of it so I deleted it from the stage and added it as a child instead.

var time:MovieClip=new Time();

time.x=350
time.y=5

addChild(time);


import flash.utils.Timer;

var seconds:int=0
var mins:int=0

var mainTimer:Timer = new Timer(1000)
//1000 miliseconds = a second 300 times
mainTimer.addEventListener(TimerEvent.TIMER, runOnce);
mainTimer.start();

function runOnce(event:TimerEvent):void {
seconds++
if (seconds<10){
time.timee.text=String(mins)+":"+"0"+String(seconds);
}
if (seconds>9){
time.timee.text=String(mins)+":"+String(seconds);
}
if (seconds>=60){
mins++
seconds=0
}
}

This seemed to work fine so I moved onto my final thing to do, the health bar. Much like how I set up the background I made three frames inside the health bar movie clip for each stage then one more, for some code to take you to the end game frame, then deleted it from the stage and added it in the code. Then I set the hit test if statement to 'hp.nextFrame();' and added a stop on every frame of the health bar. Unfortunately this didn't work and after a consultation with Lee we worked out that the hit-test happened the second the penguin touched you, and then was being triggered again and again as the penguin passed over the player. 
So we decided to add two more lines to the if statement 
'penArray[i].x=Math.random()*550
penArray[i].y=-50'
this code makes the penguin move the second it hit's you to somewhere else on the screen, so it doesn't constantly trigger the hit test. The original plan was to have it move anywhere randomly on the screen but I changed it to appear 50 pixels above the screen like at the begging of the game. 
Finally my game was nearly finished, the last bit of code was on that last frame of the health bar, a code to take you to the end game page.