• Advertisement
Sign in to follow this  

Breakout is finished!

This topic is 4347 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

There it is guys, the finished product. I could even use a bit of the same code as I used in my pong game. Here is the code.
#include <windows.h>
#include <gl/gl.h>
#include <cstdlib>
#include <ctime>
#define pwidth 0.25f
#define pheight 0.05f
#define bwidth 0.04f
#define bheight 0.04f
#define blwidth 0.1f
#define blheight 0.06f
//struct holding the paddle information
typedef struct
{
    float x;
    float y;
    float x2;
    float y2;
} paddle;
//struct holding the ball information
typedef struct
{
    float x;
    float y;
    float x2;
    float y2;
} ball;
//struct holding the block information, there is a flag showing if it is appeared or not.
typedef struct
{
    float x;
    float y;
    float x2;
    float y2;
    bool there;
} block;
//enumeration for the direction of the ball
enum direction {N, S, NW, NE, SW, SE};
//decleration of winproc
LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
WPARAM wParam, LPARAM lParam);
//enables ogl
void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC);
//disables ogl
void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC);
//restart the ball
void startOver();
//function to move the ball
void moveBall();
//function to check the collision
void checkCollision();
//function to initialize game
void gameInit();
//function to run game, taking the device context as a parameter to swap buffers
void gameRun(HDC hDC);
paddle Paddle;
ball Ball;
direction BDIR;
//there are 100 blocks on the screen, 20x5.
block Blocks[20][5];
//how many balls are left
int balls = 3;
//how many blocks there are gone
int blocks = 0;
int WINAPI WinMain (HINSTANCE hInstance,
                    HINSTANCE hPrevInstance,
                    LPSTR lpCmdLine,
                    int iCmdShow)
{
    WNDCLASS wc;
    HWND hWnd;
    HDC hDC;
    HGLRC hRC;        
    MSG msg;
    BOOL bQuit = FALSE;
    float theta = 0.0f;
    wc.style = CS_OWNDC;
    wc.lpfnWndProc = WndProc;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = hInstance;
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.hbrBackground = (HBRUSH) GetStockObject (BLACK_BRUSH);
    wc.lpszMenuName = NULL;
    wc.lpszClassName = "BKOUT";
    RegisterClass (&wc);
    hWnd = CreateWindow (
      "BKOUT", "Breakout",
      WS_CAPTION | WS_POPUPWINDOW | WS_VISIBLE,
      0, 0, 600, 600,
      NULL, NULL, hInstance, NULL);
    EnableOpenGL (hWnd, &hDC, &hRC);
    gameInit();
    while (!bQuit)
    {
        if (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
        {
            if (msg.message == WM_QUIT)
            {
                bQuit = TRUE;
            }
            else
            {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
            }
        }
        else
        {
            //game loop
            gameRun(hDC);
        }
    }
    DisableOpenGL (hWnd, hDC, hRC);
    DestroyWindow (hWnd);

    return msg.wParam;
}


LRESULT CALLBACK WndProc (HWND hWnd, UINT message,
                          WPARAM wParam, LPARAM lParam)
{

    switch (message)
    {
    case WM_CREATE:
        return 0;
    case WM_CLOSE:
        PostQuitMessage (0);
        return 0;

    case WM_DESTROY:
        return 0;

    case WM_KEYDOWN:
        switch (wParam)
        {
        case VK_ESCAPE:
            PostQuitMessage(0);
            return 0;
        //if the left button is pressed, move the paddle left.
        case VK_LEFT:
            Paddle.x -= 0.025f;
            Paddle.x2 -= 0.025f;
            return 0;
        //if the right button is pressed, move the paddle right.
        case VK_RIGHT:
            Paddle.x += 0.025f;
            Paddle.x2 += 0.025f;
            return 0;
        }
        return 0;

    default:
        return DefWindowProc (hWnd, message, wParam, lParam);
    }
}


void EnableOpenGL (HWND hWnd, HDC *hDC, HGLRC *hRC)
{
    PIXELFORMATDESCRIPTOR pfd;
    int iFormat;
    *hDC = GetDC (hWnd);
    ZeroMemory (&pfd, sizeof (pfd));
    pfd.nSize = sizeof (pfd);
    pfd.nVersion = 1;
    pfd.dwFlags = PFD_DRAW_TO_WINDOW | 
      PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pfd.iPixelType = PFD_TYPE_RGBA;
    pfd.cColorBits = 24;
    pfd.cDepthBits = 16;
    pfd.iLayerType = PFD_MAIN_PLANE;
    iFormat = ChoosePixelFormat (*hDC, &pfd);
    SetPixelFormat (*hDC, iFormat, &pfd);
    *hRC = wglCreateContext( *hDC );
    wglMakeCurrent( *hDC, *hRC );

}


void DisableOpenGL (HWND hWnd, HDC hDC, HGLRC hRC)
{
    wglMakeCurrent (NULL, NULL);
    wglDeleteContext (hRC);
    ReleaseDC (hWnd, hDC);
}
void startOver()
{
    int dir = rand()%4;
    Ball.x = -0.01f;
    Ball.x2 = Ball.x + bwidth;
    Ball.y = -0.01f;
    Ball.y2 = Ball.y + bheight;
    Paddle.x = -0.12f;
    Paddle.x2 = Paddle.x + pwidth;
    Paddle.y = -0.96f;
    Paddle.y2 = Paddle.y + pheight;
    switch(dir)
    {
        case 0:
            BDIR = N;
            break;
        case 1:
            BDIR = S;
            break;
        case 2:
            BDIR = NE;
            break;
        case 3:
            BDIR = NW;
            break;
    }
}
void moveBall()
{
    switch(BDIR)
    {
        case N:
            Ball.y += 0.002;
            Ball.y2 += 0.002;
            break;
        case S:
            Ball.y -= 0.002;
            Ball.y2 -= 0.002;
            break;
        case NE:
            Ball.x += 0.0015;
            Ball.x2 += 0.0015;
            Ball.y += 0.0015;
            Ball.y2 += 0.0015;
            break;
        case NW:
            Ball.x -= 0.0015;
            Ball.x2 -= 0.0015;
            Ball.y += 0.0015;
            Ball.y2 += 0.0015;
            break;
        case SE:
            Ball.x += 0.0015;
            Ball.x2 += 0.0015;
            Ball.y -= 0.0015;
            Ball.y2 -= 0.0015;
            break;
        case SW:
            Ball.x -= 0.0015;
            Ball.x2 -= 0.0015;
            Ball.y -= 0.0015;
            Ball.y2 -= 0.0015;
            break;
    }
}
void checkCollision()
{
    if(Ball.y2 >= 0.7)
    {
        for(int y=0; y<5; y++)
        {
            for(int x=0; x<20; x++)
            {

                if(Ball.y2 >= Blocks[x][y].y && Ball.y <= Blocks[x][y].y2 && Ball.x2 >= Blocks[x][y].x && Ball.x <= Blocks[x][y].x2)
                {
                if(Blocks[x][y].there == true)
                {
                    switch(BDIR)
                    {
                        case N:
                            BDIR = S;
                            break;
                        case S:
                            BDIR = N;
                            break;
                        case NW:
                            if(Ball.y2 > Blocks[x][y].y)
                                BDIR = NE;
                            else
                                BDIR = SW;
                            break;
                        case NE:
                            if(Ball.y2 > Blocks[x][y].y)
                                BDIR = NW;
                            else
                                BDIR = SE;
                            break;
                        case SW:
                            if(Ball.y > Blocks[x][y].y2)
                                BDIR = NW;
                            else
                                BDIR = SE;
                            break;
                        case SE:
                            if(Ball.y > Blocks[x][y].y2)
                                BDIR = NE;
                            else
                                BDIR = SW;
                            break;
                        }
                    }
                    Blocks[x][y].there = false;
                    blocks++;
                }
            }
        }
    }
    if(Ball.x <= -1.0f)
    {
        switch(BDIR)
        {
            case NW:
                BDIR = NE;
                break;
            case SW:
                BDIR = SE;
                break;
        }
    }
    if(Ball.x >= 1.0f)
    {
        switch(BDIR)
        {
            case NE:
                BDIR = NW;
                break;
            case SE:
                BDIR = SW;
                break;
        }
    }
    if(Ball.y >= 1.0f)
    {
        switch(BDIR)
        {
            case N:
                BDIR = S;
                break;
            case NE:
                BDIR = SE;
                break;
            case NW:
                BDIR = SW;
                break;
        }
    }
    if(Ball.y <= Paddle.y + pheight && Ball.y >= Paddle.y)
    {
        if(Ball.x2 >= Paddle.x && Ball.x <= Paddle.x2)
        {
            if(Ball.x2 >= Paddle.x && Ball.x <= Paddle.x + 0.07)
            {
                BDIR = NW;
            }
            if(Ball.x >= Paddle.x + 0.08 && Ball.x <= Paddle.x + 0.16)
            {
                BDIR = N;
            }
            if(Ball.x2 >= Paddle.x + 0.17 && Ball.x <= Paddle.x + 0.25)
            {
                BDIR = NE;
            }
        }
    }
    if(Ball.y < -1.0)
    {
        balls--;
        startOver();
    }
    if(balls == 0)
    {
        MessageBox(NULL, "You Lose!", "Breakout", MB_ICONEXCLAMATION);
        PostQuitMessage(0);
    }
    if(blocks == 50)
    {
        MessageBox(NULL, "You Win!", "Breakout", MB_ICONEXCLAMATION);
        PostQuitMessage(0);
    }
}
//function for initializing the game
void gameInit()
{
    int dir;
    srand(time(NULL));
    dir = rand()%4;
    //loop to set block initial values
    for(int y=0; y<5; y++)
    {
        for(int x=0; x<20; ++x)
        {
            if(x == 0)
            {
                Blocks[x][y].x = -1.0f;
                Blocks[x][y].x2 = -1.0f + blwidth;
            }
            else if(x >= 1)
            {
                Blocks[x][y].x = Blocks[x-1][y].x + blwidth;
                Blocks[x][y].x2 = Blocks[x-1][y].x2 + blwidth;
            }
            if(y == 0)
            {
                Blocks[x][y].y = 1.0f - blheight;
                Blocks[x][y].y2 = 1.0f;
            }
            else if(y >= 1)
            {
                Blocks[x][y].y = Blocks[x][y-1].y - blheight;
                Blocks[x][y].y2 = Blocks[x][y].y + blheight;
            }
            Blocks[x][y].there = true;
        }
    }
    //Set the ball to it's starting position
    Ball.x = -0.01f;
    Ball.x2 = Ball.x + bwidth;
    Ball.y = -0.01f;
    Ball.y2 = Ball.y + bheight;
    //Set the paddle to it's starting position
    Paddle.x = -0.12f;
    Paddle.x2 = Paddle.x + pwidth;
    Paddle.y = -0.96f;
    Paddle.y2 = Paddle.y + pheight;
    switch(dir)
    {
        case 0:
            BDIR = N;
            break;
        case 1:
            BDIR = S;
            break;
        case 2:
            BDIR = NE;
            break;
        case 3:
            BDIR = NW;
            break;
    }
}
void gameRun(HDC hDC)
{
    //clear to black
    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    glClear(GL_COLOR_BUFFER_BIT);
    checkCollision();
    //loop for drawing blocks
    
    for(int y=0; y<5; y++)
    {
        for(int x=0; x<20; ++x)
        {
            if(Blocks[x][y].there == true)
            {
                glBegin(GL_QUADS);
                    if(y == 0)
                        glColor3f(1.0f, 0.0f, 0.0f);
                    if(y == 1)
                        glColor3f(0.0f, 1.0f, 0.0f);
                    if(y == 2)
                        glColor3f(0.0f, 0.0f, 1.0f);
                    if(y == 3)
                       glColor3f(1.0f, 1.0f, 0.0f);
                    if(y == 4)
                       glColor3f(0.0f, 1.0f, 1.0f);
                    glVertex2f(Blocks[x][y].x, Blocks[x][y].y);
                    glVertex2f(Blocks[x][y].x, Blocks[x][y].y2);
                    glVertex2f(Blocks[x][y].x2, Blocks[x][y].y2);
                    glVertex2f(Blocks[x][y].x2, Blocks[x][y].y);
                glEnd();
            }
            else
            {
                glBegin(GL_QUADS);
                    glColor3f(0.0f, 0.0f, 0.0f);
                    glVertex2f(Blocks[x][y].x, Blocks[x][y].y);
                    glVertex2f(Blocks[x][y].x, Blocks[x][y].y2);
                    glVertex2f(Blocks[x][y].x2, Blocks[x][y].y2);
                    glVertex2f(Blocks[x][y].x2, Blocks[x][y].y);
                glEnd();
            }
        }
    }
    //draw ball
    glBegin(GL_QUADS);
        glColor3f(1.0f, 1.0f, 1.0f);
        glVertex2f(Ball.x, Ball.y);
        glVertex2f(Ball.x, Ball.y2);
        glVertex2f(Ball.x2, Ball.y2);
        glVertex2f(Ball.x2, Ball.y);
    glEnd();
    //draw paddle
    glBegin(GL_QUADS);
        glVertex2f(Paddle.x, Paddle.y);
        glVertex2f(Paddle.x, Paddle.y2);
        glVertex2f(Paddle.x2, Paddle.y2);
        glVertex2f(Paddle.x2, Paddle.y);
    glEnd();
    moveBall();
    Sleep(1);
    SwapBuffers(hDC);
}


Thanks for everyone's help and encouragement!

Share this post


Link to post
Share on other sites
Advertisement
Very nice coding... I also have my version of Breakout on the works, I hope it come out as nice as yours.

[Edited by - BrasiLokau on May 29, 2006 6:42:47 AM]

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement