//determines whether the ball touches the brick //and takes the necessary action void whetherBallTouchesBrick(){ for(int i=0;i<20;i++){ for(int j=0;j<8;j++){ if(isBrick[i][j]==1&&b.cy<240){ int touchCx=abs(b.cx+5); int touchCy=abs(b.cy+5); int brickLeft=i*brickLen; int brickRight=brickLeft+brickLen; int brickUp=j*brickBred; int brickDown=brickUp+brickBred; if((touchCx==brickRight)&&(abs(b.upy-brickUp)<=abs(brickBred-b.radius)&&abs(b.downy-brickDown)<=abs(brickBred-b.radius))){ touchLeft(); isBrick[i][j]=0; } else if((touchCx==brickLeft)&&(abs(b.upy-brickUp)<=abs(brickBred-b.radius)&&abs(b.downy-brickDown)<=abs(brickBred-b.radius))){ touchRight(); isBrick[i][j]=0; } else if((touchCy==brickDown)&&(abs(b.leftx-brickLeft)<=abs(brickLen-b.radius)&&abs(b.rightx-brickRight)<=abs(brickLen-b.radius))){ touchUp(); isBrick[i][j]=0; } else if((touchCy==brickUp)&&(abs(b.leftx-brickLeft)<=abs(brickLen-b.radius)&&abs(b.rightx-brickRight)<=abs(brickLen-b.radius))){ touchDown(); isBrick[i][j]=0; } else if((abs(abs(b.cx)-brickLeft)+abs(abs(b.cx)-brickRight)==brickLen)&&(abs(abs(b.cy)-brickUp)+abs(abs(b.cy)-brickDown)==brickBred)){ touchCorner(); isBrick[i][j]=0; } if(isBrick[i][j]==0){ score=score+(10*abs(j-8)); setScoreString(); int brick[8]; setcolor(0); brick[0]=brick[6]=brickLeft; brick[1]=brick[3]=brickUp; brick[2]=brick[4]=brickRight; brick[5]=brick[7]=brickDown; setfillstyle(1,0); fillpoly(4,brick); rectangle(brick[0],brick[1],brick[2],brick[5]); drawBricks(); i=0,j=0; } } } } }
// This function does boundary checking on the ball, also determines where // it hits the paddle, and changes the behavior of the ball depending. void checkBallCollisions(int paddlePos) { // first check for any brick collisions char detected = drawBricks(&ball); // if no bricks hit, continue with normal collision detection if(detected == 'n') { // right wall if(ball.x >= SCREEN_WIDTH - BALL_RADIUS) { ball.x = SCREEN_WIDTH - (BALL_RADIUS + 1); xdir = -xdir; playTone(500, 50); return; } // left wall if(ball.x <= BALL_RADIUS) { ball.x = BALL_RADIUS + 1; xdir = -xdir; playTone(500, 50); return; } // ceiling if(ball.y >= SCREEN_HEIGHT - BALL_RADIUS) { ydir = -1.0; playTone(500, 50); return; } // middle of paddle if(ball.y <= 19 && (ball.x <= paddlePos + (PADDLE_WIDTH / 2) + (BALL_RADIUS + 1) && ball.x >= paddlePos + (PADDLE_WIDTH / 2) - (BALL_RADIUS + 1))) { paddleHits++; // increase ball speed slightly with every 6 paddle hits if((paddleHits % 18 == 0) && (paddleHits <= 36)) speed += 1.0; ball.y = 20; ydir = 1.0; playTone(500,50); return; } // right side of paddle else if(ball.y <= 19 && ((ball.x <= paddlePos + PADDLE_WIDTH) && (ball.x > paddlePos + (PADDLE_WIDTH / 2) + (BALL_RADIUS + 1)))) { paddleHits++; // increase ball speed slightly with every 6 paddle hits if((paddleHits % 18 == 0) && (paddleHits <= 36)) speed += 1.0; ball.y = 20; ydir = 1.0; xdir += 1.0; playTone(500, 50); return; } // left side of paddle else if(ball.y <= 19 && ((ball.x >= paddlePos) && (ball.x < paddlePos + (PADDLE_WIDTH / 2) - (BALL_RADIUS + 1)))) { paddleHits++; // increase ball speed slightly with every 6 paddle hits if((paddleHits % 18 == 0) && (paddleHits <= 36)) speed += 1.0; ball.y = 20; ydir = 1.0; xdir -= 1.0; playTone(500, 50); return; } // ball hits floor, lives lost, score deducted if(ball.y <= 10 && ((ball.x < paddlePos) || (ball.x > paddlePos + PADDLE_WIDTH))) { playTone(50,500); tft.fillCircle(ball.y, ball.x, BALL_RADIUS, ST7735_BLACK); drawPaddle(); initializeBall(getDifficulty()); decreaseLives(); displayStats(); delay(20); } } // brick collision detected, adjust ball accordingly else { // corner of brick hit if(detected == 'c') { xdir = -xdir; ydir = -ydir; playTone(200,50); return; } else { // left/right side of brick hit if(detected == 'x') { xdir = -xdir; playTone(200,50); return; } // top/bottom of brick hit else if(detected == 'y') { ydir = -ydir; playTone(200,50); return; } } } }
//function which centrally controls the execution of game void gameHandler(){ settextstyle(0,0,6); outtextxy(180,200,"DX-Ball"); getch(); clearviewport(); brickLen=25,brickBred=15; for(int i=0;i<20;i++) for(int j=0;j<8;j++) isBrick[i][j]=1; drawBricks(); b.cx=20; b.cy=240; b.xIncre=1; b.yIncre=1; b.radius=5; br.size=80; br.movement=10; score=0; livesRemain[0]=' '; livesRemain[1]=' '; strcat(livesRemain,"live(s) remaining."); b.lives=3; line(500,0,500,480); settextstyle(0,0,2); outtextxy(535,200,"Score:"); settextstyle(0,0,2); setScoreString(); outtextxy(535,230,scoreString); outtextxy(535,320,"Lives:"); setLivesString(); outtextxy(565,350,livesString); b.ulimit=0; b.llimit=0; b.rlimit=500; br.llimit=0; br.rlimit=500; br.rePositionBar(0); br.drawBar(); int ch='a'; while(1){ while(!kbhit()){ delay(4); b.removePreviousBall(); changeScore(); initializeVariables(); whetherBallTouchesBrick(); b.drawBall(); br.removePreviousBar(); br.drawBar(); line(500,0,500,480); } ch=getch(); if(ch=='a'){ br.removePreviousBar(); br.rePositionBar('a'); br.drawBar(); } if(ch=='s'){ br.removePreviousBar(); br.rePositionBar('s'); br.drawBar(); } if(ch=='p') ch=getch(); if(ch=='q'){ displayAbout(); getch(); exit(0); } } }
int playLevel(int levelNo, int pause) { lcdClear(); lcdFill(GLOBAL(nickbg)); // load level int bricks[FIELD_HEIGHT][FIELD_WIDTH]; memcpy(bricks, levels[levelNo], sizeof(bricks)); // initialisation int ball[2] = {SCREEN_WIDTH / 2, FIELD_HEIGHT * (BRICK_HEIGHT + BRICK_SPACING) + 1}; int direction[2] = {1,1}; int paddleX = SCREEN_WIDTH / 2 - PADDLE_WIDTH / 2; int lives = LIVES_INITIAL; drawBricks(bricks); while ( 1 ) { // ball drawBall(ball, GLOBAL(nickbg)); ball[0] += direction[0]; ball[1] += direction[1]; // paddle / user input drawPaddle(paddleX, GLOBAL(nickbg)); int key = getInputRaw(); switch (key) { case BTN_ENTER: // exit return 0; case BTN_LEFT: paddleX -= PADDLE_SPEED; if (paddleX < 0) paddleX = 0; break; case BTN_RIGHT: paddleX += PADDLE_SPEED; if (paddleX + PADDLE_WIDTH > SCREEN_WIDTH) paddleX = SCREEN_WIDTH - PADDLE_WIDTH; break; } drawPaddle(paddleX, GLOBAL(nickfg)); // collisions // bricks int x = ball[0] / ((BRICK_WIDTH + BRICK_SPACING)); int y = ball[1] / ((BRICK_HEIGHT + BRICK_SPACING)); if (0 <= x && x < FIELD_WIDTH && 0 <= y && y < FIELD_HEIGHT) { if (bricks[y][x] == 1) { // collision with brick int xRel = ball[0] - x * (BRICK_WIDTH + BRICK_SPACING); int yRel = ball[1] - y * (BRICK_HEIGHT + BRICK_SPACING); if (xRel == 0 || xRel == BRICK_WIDTH) direction[0] *= -1; // hit top or bottom if (yRel == 0 || yRel == BRICK_HEIGHT) direction[1] *= -1; // hit left or right bricks[y][x] = 0; if (fieldIsCleared(bricks)) return 1; // next level } } // paddle / bottom if (direction[1] > 0) { // moving to the bottom if (ball[1] >= PADDLE_Y) { if (paddleX <= ball[0] && ball[0] <= paddleX + PADDLE_WIDTH) { // collision with paddle direction[1] = - abs(direction[1]); if (key == BTN_LEFT) direction[0] = -2; else if (key == BTN_RIGHT) direction[0] = 2; else direction[0] = (direction[0] > 0) ? 1 : -1; } else { // ball lost lives--; if (lives == 0) { lcdClear(); lcdPrintln(""); lcdPrintln(""); lcdPrintln(""); lcdPrintln(""); lcdPrintln(" GAME OVER"); lcdDisplay(); delayms(2000); return 0; } ball[0] = SCREEN_WIDTH / 2; ball[1] = FIELD_HEIGHT * (BRICK_HEIGHT + BRICK_SPACING) + 1; direction[0] = (paddleX + PADDLE_WIDTH / 2 < ball[0]) ? -1 : 1; direction[1] = 1; } } } // walls if (ball[1] <= 0) direction[1] = abs(direction[1]); if (ball[0] <= 0) direction[0] = abs(direction[0]); else if (ball[0] >= SCREEN_WIDTH - 1) direction[0] = - abs(direction[0]); drawBricks(bricks); drawBall(ball, GLOBAL(nickfg)); lcdDisplay(); delayms(pause); } return 0; }