// Hardcoded levels are contained within ! #include "levels.h" // ** BRICK RELATED FUNCTIONS ** //------------------------------- // General function that sets up a 'RECT'. void SetBoxInfo(RECT *rect, long x, long y, long w, long h) { rect->x = x; rect->y = y; rect->w = w; rect->h = h; } // Adds a brick and sets up its collision // boxes accordinly void AddBrick(long x, long y) { SetSpriteInfo(&bricks[bricksInGame].sprite,TILE_TIM,x,y); SetBoxInfo(&bricks[bricksInGame].left,x-6,y-5,3,10); SetBoxInfo(&bricks[bricksInGame].right,x+3,y-5,3,10); SetBoxInfo(&bricks[bricksInGame].top,x-5,y-6,10,3); SetBoxInfo(&bricks[bricksInGame].bottom,x-5,y+3,10,3); bricks[bricksInGame].state = 1; bricksInGame ++; } // Sets up a plane world with no obsticals. void SetupBricksBlank() { bricksInGame =1; // This brick is actual the screen border. SetBoxInfo(&bricks[0].left,300,40,10,210); SetBoxInfo(&bricks[0].right,10,40,10,210); SetBoxInfo(&bricks[0].top,10,230,300,10); SetBoxInfo(&bricks[0].bottom,10,40,300,10); bricks[0].state = 1; } // Simply draws all the bricks that are set to active. void DrawBricks() { u_long index; for(index=1; index < bricksInGame; index++) { if(bricks[index].state == 1) { DrawSprite(&bricks[index].sprite,BRICK_PRIORITY); } } } // long CollisionLeft(RECT rect) { u_long returnedValue = FALSE; u_long index; for(index=0; index < bricksInGame; index++) { if(bricks[index].state == 1) { if ((rect.x+rect.w) >= bricks[index].left.x) if ((rect.y+rect.h) >= bricks[index].left.y) if (rect.x <= (bricks[index].left.x + bricks[index].left.w)) if (rect.y <= (bricks[index].left.y+bricks[index].left.h)) returnedValue = TRUE; } } return returnedValue; } // long CollisionRight(RECT rect) { u_long returnedValue = FALSE; u_long index; for(index=0; index < bricksInGame; index++) { if(bricks[index].state == 1) { if ((rect.x+rect.w) >= bricks[index].right.x) if ((rect.y+rect.h) >= bricks[index].right.y) if (rect.x <= (bricks[index].right.x+bricks[index].right.w)) if (rect.y <= (bricks[index].right.y+bricks[index].right.h)) returnedValue = TRUE; } } return returnedValue; } // long CollisionBottom(RECT rect) { u_long returnedValue = FALSE; u_long index; for(index=0; index < bricksInGame; index++) { if(bricks[index].state == 1) { if ((rect.x+rect.w) >= bricks[index].bottom.x) if ((rect.y+rect.h) >= bricks[index].bottom.y) if (rect.x <= (bricks[index].bottom.x+bricks[index].bottom.w)) if (rect.y <= (bricks[index].bottom.y+bricks[index].bottom.h)) returnedValue = TRUE; } } return returnedValue; } // long CollisionTop(RECT rect) { u_long returnedValue = FALSE; u_long index; for(index=0; index < bricksInGame; index++) { if(bricks[index].state == 1) { if ((rect.x+rect.w) >= bricks[index].top.x) if ((rect.y+rect.h) >= bricks[index].top.y) if (rect.x <= (bricks[index].top.x + bricks[index].top.w)) if (rect.y <= (bricks[index].top.y+bricks[index].top.h)) returnedValue = TRUE; } } return returnedValue; } // ** BALL FUNCTIONS ** //---------------------- // Updates the balls i.e. bounces them off objects void UpdateBalls() { static u_long index; for(index=0 ; index < ballsInGame; index++) { balls[index].sprite.x += balls[index].vx; balls[index].sprite.y += balls[index].vy; balls[index].box.x = balls[index].sprite.x-balls[index].sizeMod; balls[index].box.y = balls[index].sprite.y-balls[index].sizeMod; if(CollisionLeft(balls[index].box)) { if(balls[index].vx > 0) balls[index].vx = -balls[index].vx; } else if(CollisionRight(balls[index].box)) { if(balls[index].vx < 0) balls[index].vx = -balls[index].vx; } if(CollisionTop(balls[index].box)) { if(balls[index].vy > 0) balls[index].vy = -balls[index].vy; } else if(CollisionBottom(balls[index].box)) { if(balls[index].vy < 0) balls[index].vy = -balls[index].vy; } balls[index].box.x = balls[index].sprite.x-balls[index].sizeMod; balls[index].box.y = balls[index].sprite.y-balls[index].sizeMod; } } // Draws all the balls. void DrawBalls() { static u_long index; for(index=0; index < ballsInGame;index++) { DrawSprite(&balls[index].sprite,BALL_PRIORITY); } } // This function attempts to split the balls of a bigger size // into a smaller size. If there are no more smaller sizes // then nothing is created. long SplitBall(long index) { BALL temp; long returnValue=0; temp = balls[index]; returnValue = RemoveBall(index); switch(temp.size) { case 1: { AddBall(temp.sprite.x,temp.sprite.y,2,NE); AddBall(temp.sprite.x,temp.sprite.y,2,NW); } break; case 2: { AddBall(temp.sprite.x,temp.sprite.y,3,NE); AddBall(temp.sprite.x,temp.sprite.y,3,NW); } break; case 3: { AddBall(temp.sprite.x,temp.sprite.y,4,NE); AddBall(temp.sprite.x,temp.sprite.y,4,NW); } break; case 4: // No more Balls break; } return(returnValue); } // Deletes a ball from the array by simply writing over it. long RemoveBall(long index) { u_long counter; long returnValue=0; // Add points to players score. switch(balls[index].size) { case 1: returnValue = 20; break; // biggest case 2: returnValue = 50; break; case 3: returnValue = 100;break; case 4: returnValue = 400;break; // smallest } // Shuffle balls down a position to fill in the gap // created when this ball is removed. if(index < ballsInGame) { for(counter=index; counter < ballsInGame; counter++) { balls[counter] = balls[counter+1]; } ballsInGame--; // now there is one less } return(returnValue); } // No Error check at mo!!! void AddBall(long x, long y, long size, u_long direction) { ballsInGame++; SetSpriteInfo(&balls[ballsInGame-1].sprite,BALL_TIM,x,y); balls[ballsInGame-1].size = size; switch(size) { case 1: balls[ballsInGame-1].box.x=x-19; balls[ballsInGame-1].box.y=y-19; balls[ballsInGame-1].sizeMod=19; balls[ballsInGame-1].box.w=38; balls[ballsInGame-1].box.h=38; balls[ballsInGame-1].sprite.scaley = ONE * 2; balls[ballsInGame-1].sprite.scalex = ONE * 2; break; case 2: // same as above but the sprite is scalled; balls[ballsInGame-1].box.x=x-9; balls[ballsInGame-1].box.y=y-9; balls[ballsInGame-1].sizeMod=9; balls[ballsInGame-1].box.w=18; balls[ballsInGame-1].box.h=18; balls[ballsInGame-1].sprite.scaley = ONE * 1; balls[ballsInGame-1].sprite.scalex = ONE * 1; break; case 3: // same as above but the sprite is scalled; balls[ballsInGame-1].box.x=x-4; balls[ballsInGame-1].box.y=y-4; balls[ballsInGame-1].sizeMod=4; balls[ballsInGame-1].box.w=8; balls[ballsInGame-1].box.h=8; balls[ballsInGame-1].sprite.scaley = ONE * 0.5; balls[ballsInGame-1].sprite.scalex = ONE * 0.5; break; case 4: // same as above but the sprite is scalled; balls[ballsInGame-1].box.x=x-2; balls[ballsInGame-1].box.y=y-2; balls[ballsInGame-1].sizeMod=2; balls[ballsInGame-1].box.w=4; balls[ballsInGame-1].box.h=4; balls[ballsInGame-1].sprite.scaley = ONE * 0.25; balls[ballsInGame-1].sprite.scalex = ONE * 0.25; break; } switch(direction) { case NE: balls[ballsInGame-1].vx = 1; balls[ballsInGame-1].vy =-1; break; case NW: balls[ballsInGame-1].vx =-1; balls[ballsInGame-1].vy =-1; break; case SE: balls[ballsInGame-1].vx = 1; balls[ballsInGame-1].vy = 1; break; case SW: balls[ballsInGame-1].vx =-1; balls[ballsInGame-1].vy = 1; break; } } // ** COLLISION DETECTION FUNCTIONS ** //------------------------------------- // collisions with the balls long CollisionBalls(RECT rect) { u_long returnedValue = FALSE; u_long index; for(index=0; index < ballsInGame; index++) { if ((rect.x+rect.w) >= balls[index].box.x) if ((rect.y+rect.h) >= balls[index].box.y) if (rect.x <= (balls[index].box.x+balls[index].box.w)) if (rect.y <= (balls[index].box.y+balls[index].box.h)) returnedValue = (index+1); } return returnedValue; } // setups up the screen to the entered level // When changing this function you must have at least one // ball else you get a crap boring level and the game goes a bit // weird ! void SetupLevel(u_long level) { // This brick is actual the screen border. SetBoxInfo(&bricks[0].left,300,40,10,210); SetBoxInfo(&bricks[0].right,10,40,10,210); SetBoxInfo(&bricks[0].top,10,230,300,10); SetBoxInfo(&bricks[0].bottom,10,40,300,10); bricks[0].state = 1; bricksInGame = 1; // make sure at least the border shows. //Setup the bricks and balls according to the level switch(level) { case 1: { AddBall(120,60,1,NW); AddBrick(120,140); AddBrick(140,140); AddBrick(160,140); AddBrick(180,140); } break; case 2: { AddBrick(140,200); AddBrick(150,200); AddBrick(160,200); AddBrick(170,200); AddBall(60 ,160,4,SW); AddBall(260,160,4,SE); AddBall(70 ,160,4,SW); AddBall(250,160,4,SE); AddBall(80 ,160,4,SW); AddBall(240,160,4,SE); AddBall(90 ,160,4,SW); AddBall(230,160,4,SE); AddBall(100,160,4,SW); AddBall(220,160,4,SE); AddBall(110,160,4,SW); AddBall(210,160,4,SE); AddBall(120,160,4,SW); AddBall(200,160,4,SE); AddBall(130,160,4,SW); AddBall(190,160,4,SE); } break; case 3: { AddBrick(25,200); AddBrick(35,200); AddBrick(35,190); AddBrick(35,180); AddBrick(35,170); AddBrick(35,160); AddBrick(35,150); AddBrick(35,140); AddBrick(35,130); AddBrick(35,120); AddBrick(35,110); AddBrick(35,100); AddBrick(35,90); AddBrick(35,80); AddBrick(295,200); AddBrick(285,200); AddBrick(285,190); AddBrick(285,180); AddBrick(285,170); AddBrick(285,160); AddBrick(285,150); AddBrick(285,140); AddBrick(285,130); AddBrick(285,120); AddBrick(285,110); AddBrick(285,100); AddBrick(285,90); AddBrick(285,80); AddBall(25,190,4,SW); AddBall(25,180,4,SE); AddBall(25,170,4,SW); AddBall(25,160,4,SE); AddBall(25,150,4,SW); AddBall(25,140,4,SE); AddBall(25,130,4,SW); AddBall(25,120,4,SE); AddBall(295,190,4,SW); AddBall(295,180,4,SE); AddBall(295,170,4,SW); AddBall(295,160,4,SE); AddBall(295,150,4,SW); AddBall(295,140,4,SE); AddBall(295,130,4,SW); AddBall(295,120,4,SE); AddBall(160,120,1,NW); } break; case 4: { AddBrick(30,100); AddBrick(40,100); AddBrick(50,100); AddBrick(80,100); AddBrick(90,100); AddBrick(90,90); AddBrick(90,80); AddBrick(90,70); AddBrick(90,60); AddBrick(230,100); AddBrick(240,100); AddBrick(270,100); AddBrick(280,100); AddBrick(290,100); AddBrick(230,90); AddBrick(230,80); AddBrick(230,70); AddBrick(230,60); AddBrick(100,100); AddBrick(120,100); AddBrick(140,100); AddBrick(160,100); AddBrick(180,100); AddBrick(200,100); AddBrick(220,100); AddBall(30,30,1,SE); AddBall(260,30,1,SE); AddBall(130,80,2,SW); AddBall(160,80,2,SE); AddBall(190,80,2,SW); AddBall(210,80,2,SE); } break; case 5: { AddBrick(100,140); AddBrick(110,140); AddBrick(120,140); AddBrick(130,140); AddBrick(140,140); AddBrick(150,140); AddBrick(160,140); AddBrick(170,140); AddBrick(180,140); AddBrick(190,140); AddBrick(200,140); AddBrick(210,140); AddBall(60 ,90,1,SW); AddBall(100,90,1,SW); AddBall(140 ,90,1,SW); } break; case 6: { AddBrick(30,100); AddBrick(50,100); AddBrick(70,100); AddBrick(90,100); AddBrick(100,100); AddBrick(120,100); AddBrick(140,100); AddBrick(160,100); AddBrick(180,100); AddBrick(200,100); AddBrick(220,100); AddBrick(230,100); AddBrick(250,100); AddBrick(270,100); AddBrick(290,100); AddBrick(140,160); AddBrick(160,160); AddBrick(180,160); AddBrick(200,160); AddBall(60 ,90,3,SW); AddBall(260,90,3,SE); AddBall(70 ,90,3,SW); AddBall(250,90,3,SE); AddBall(80 ,90,3,SW); AddBall(240,90,3,SE); AddBall(90 ,90,3,SW); AddBall(230,90,3,SE); AddBall(100,90,3,SW); AddBall(220,90,3,SE); AddBall(110,90,3,SW); AddBall(210,90,3,SE); AddBall(120,90,3,SW); AddBall(200,90,3,SE); AddBall(130,90,3,SW); AddBall(190,90,3,SE); AddBall(120,120,2,SW); AddBall(200,120,2,SE); AddBall(130,120,2,SW); AddBall(190,120,2,SE); } break; case 7: { AddBrick(30,100); AddBrick(60,105); AddBrick(90,115); AddBrick(120,120); AddBrick(150,125); AddBrick(180,135); AddBrick(210,145); AddBrick(240,150); AddBrick(270,160); AddBall(100,80,2,SE); AddBall(130,80,2,SW); AddBall(160,80,2,SE); AddBall(190,80,2,SW); AddBall(210,80,2,SE); AddBall(240,80,2,SE); AddBall(270,80,2,SW); AddBall(300,80,2,SE); AddBall(70,80,2,SW); AddBall(40,80,2,SE); } break; case 8: { AddBrick(30,100); AddBrick(40,100); AddBrick(50,100); AddBrick(60,100); AddBrick(70,100); AddBrick(80,100); AddBrick(90,100); AddBrick(100,100); AddBrick(120,100); AddBrick(140,100); AddBrick(160,100); AddBrick(180,100); AddBrick(200,100); AddBrick(220,100); AddBrick(230,100); AddBrick(240,100); AddBrick(250,100); AddBrick(260,100); AddBrick(270,100); AddBrick(280,100); AddBrick(290,100); AddBall(60 ,90,4,SW); AddBall(260,90,4,SE); AddBall(70 ,90,4,SW); AddBall(250,90,4,SE); AddBall(80 ,90,4,SW); AddBall(240,90,4,SE); AddBall(90 ,90,4,SW); AddBall(230,90,4,SE); AddBall(100,90,4,SW); AddBall(220,90,4,SE); AddBall(110,90,4,SW); AddBall(210,90,4,SE); AddBall(120,90,4,SW); AddBall(200,90,4,SE); AddBall(130,90,4,SW); AddBall(190,90,4,SE); AddBall(120,120,3,SW); AddBall(160,120,3,SE); } break; case 9: { AddBrick(100,140); AddBrick(110,140); AddBrick(120,140); AddBrick(130,140); AddBrick(160,140); AddBrick(170,140); AddBrick(180,140); AddBrick(190,140); AddBall(60 ,160,4,SW); AddBall(260,160,4,SE); AddBall(70 ,160,4,SW); AddBall(250,160,4,SE); AddBall(80 ,160,4,SW); AddBall(240,160,4,SE); AddBall(90 ,160,4,SW); AddBall(230,160,4,SE); AddBall(100,160,4,SW); AddBall(220,160,4,SE); AddBall(110,160,4,SW); AddBall(210,160,4,SE); AddBall(120,160,4,SW); AddBall(200,160,4,SE); AddBall(130,160,4,SW); AddBall(190,160,4,SE); AddBall(60 ,100,4,SW); AddBall(260,100,4,SE); AddBall(70 ,100,4,SW); AddBall(250,100,4,SE); AddBall(80 ,100,4,SW); AddBall(240,100,4,SE); AddBall(90 ,100,4,SW); AddBall(230,100,4,SE); AddBall(100,100,4,SW); AddBall(220,100,4,SE); AddBall(110,100,4,SW); AddBall(210,100,4,SE); AddBall(120,100,4,SW); AddBall(200,100,4,SE); AddBall(130,100,4,SW); AddBall(190,100,4,SE); } break; case 10: { AddBrick(100,160); AddBrick(110,160); AddBrick(120,160); AddBrick(130,160); AddBrick(140,160); AddBrick(170,160); AddBrick(180,160); AddBrick(190,160); AddBrick(200,160); AddBrick(210,160); AddBrick(100,80); AddBrick(110,80); AddBrick(120,80); AddBrick(130,80); AddBrick(140,80); AddBrick(170,80); AddBrick(180,80); AddBrick(190,80); AddBrick(200,80); AddBrick(210,80); AddBall(280,180,1,SW); AddBall(60 ,180,1,SE); AddBall(60 ,120,1,SE); AddBall(280,120,1,SW); } default: { } break; } }