예제 #1
0
파일: main.cpp 프로젝트: Hellkipz/Discord
int main ( int argc, char** argv )
{
    // Inicializa el video en SDL
    if ( SDL_Init( SDL_INIT_VIDEO| SDL_INIT_TIMER ) < 0 )
    {
        printf( "Unable to init SDL: %s\n", SDL_GetError() );
        return 1;
    }

    // Inicializa el TTF
    TTF_Init();

    // Limpia datos al Salir
    atexit(TTF_Quit);
    atexit(SDL_Quit);

    // Comentario de Ventana
    SDL_WM_SetCaption("Discord", NULL);

    // Crea la ventana
    SDL_Surface* screen = SDL_SetVideoMode(1024, 768, 16,
                                           SDL_HWSURFACE|SDL_DOUBLEBUF/*|SDL_FULLSCREEN*/);
    if ( !screen )
    {
        printf("Unable to set 640x480 video: %s\n", SDL_GetError());
        return 1;
    }

    // Semilla del Random
    srand(time(0));

    // Carga el sprite de Platy, de los enemigos y de las balas
    SDL_Surface* Bmp = IMG_Load("PlatyRight.png");
    SDL_Surface* BmpDst = IMG_Load("PlatyRight.png");
    SDL_Surface* Malo = IMG_Load("Hexapuss.png");
    SDL_Surface* Bala = IMG_Load("Bala.png");

    // Crea el area de juego
    SDL_Surface* PlayArea = IMG_Load("Background.png");

    // Crea el rectangulo de lo que se vera en la pantalla
    SDL_Rect ViewSize;
    ViewSize.x = 0;
    ViewSize.y = 0;
    ViewSize.w = screen->w;
    ViewSize.h = screen->h;

    // Coordenadas de Platy en la pantalla
    SDL_Rect ScreenCoords;

    // Coordenadas para colocar el sprite de Platy y Enemigos
    SDL_Rect SpriteCoords;
    SDL_Rect SpriteCoordsM;
    SDL_Rect SpriteBalas;

    // Crea al jugador y lo ponemos en el centro del Area de juego
    Platy Jugador1(PlayArea->w/2, PlayArea->h/2);

    // Crea lo necesario para la pantalla de Game Over
    SDL_Rect TextRect;
    TTF_Font* Fuente = TTF_OpenFont("18holes.ttf", 24);
    SDL_Color BgColor, FgColor;
    const char GO[10] = "Game Over";

    BgColor.r = 0;
    BgColor.g = 0;
    BgColor.b = 0;

    FgColor.r = 255;
    FgColor.g = 0;
    FgColor.b = 0;

    SDL_Surface* Texto = TTF_RenderText_Shaded(Fuente, GO, FgColor, BgColor);

    TextRect.x = screen->w - Texto->w /2;
    TextRect.y = screen->h - Texto->h /2;

    // Crea el manejador de eventos y los manejadores de teclas
    SDL_Event event;
    SDL_Event Salida;
    Uint8* Keys = NULL;
    bool Boton1 = false;
    SDL_Rect MousePos;
    float Bl = 0.0f, Bu = 0.0f, Br = 0.0f, Bd = 0.0f;
    float Tiempo = 0.0f, FireRate = 0.0f;
    int CantidadEnemigos = 0;
    int CantidadBalas = 0;
    int Aux = 0;
    int Vidas = 3;

    /// CICLO DEL PROGRAMA
    bool done = false;
    while (!done)
    {
        // Ciclo de proceso de mensajes
        while (SDL_PollEvent(&event))
        {
            // Checa si hay mensajes
            switch (event.type)
            {
                // Salir si la ventana es cerrada
            case SDL_QUIT:
                done = true;
                break;

                // Checa si alguna tecla fue presionada
            case SDL_KEYDOWN:
                {
                    switch (event.key.keysym.sym)
                    {
                        case SDLK_ESCAPE:
                            done = true;
                            break;
                        case SDLK_n:
                            if (!gamestarted)
                            {
                                gamestarted = true;
                                g_server.Init();
                            }
                            break;
                        case SDLK_m:
                            if (!gamestarted)
                            {
                                gamestarted = true;
                                g_netclient.Init();
                            }
                            break;
                    }
                    break;
                }
            case SDL_MOUSEMOTION:
                MousePos.x = event.motion.x;
                MousePos.y = event.motion.y;
                break;
            case SDL_MOUSEBUTTONDOWN:
                Boton1 = SDL_BUTTON(1);
                MousePos.x = event.button.x;
                MousePos.y = event.button.y;
                break;
            case SDL_MOUSEBUTTONUP:
                Boton1 = false;
                break;
            } // Termina switch
        } // Finaliza ciclo de proceso de mensajes

        /// EMPIEZA CICLO DE JUEGO

        Keys = SDL_GetKeyState(NULL);

        //no entramos al ciclo del juego
        if (gamestarted == false)
            continue;


        //Crea un enemigo cada 4 segundos (aprox)
        if (Tiempo > 2.0f * CantidadEnemigos && CantidadEnemigos <= 29)
        {
            Aux = 0;
            while (Enemigo[Aux] != NULL)
            {
                Aux ++;
            }
            Enemigo[Aux] = new MalosBasico(PlayArea->w, PlayArea->h);
            CantidadEnemigos ++;
        }

        // Disparos
        FireRate += 0.02;
        if(Boton1 && CantidadBalas <= 29 && FireRate >= 0.1f)
        {
            Aux = 0;
            while (B[Aux] != NULL)
            {
                Aux ++;
            }
            B[Aux] = new Bullet(Jugador1.DameX(), Jugador1.DameY());
            CantidadBalas ++;
            FireRate = 0.0f;
        }

        //Gira a Platy segun a donde se este apuntando
        BmpDst = sge_transform_surface(Bmp, 16,  Jugador1.DameAnguloGiro(MousePos.x, MousePos.y, ScreenCoords.x, ScreenCoords.y) * -180/PI, 0.7f, 0.7f, SGE_TSAFE);

        // Checa las teclas de dirección y mueve al personaje en dicha direccion
        if (Keys[SDLK_UP] || Keys[SDLK_w])
        {
            Jugador1.PlatyMov(0, PlayArea);
        }

        if (Keys[SDLK_RIGHT] || Keys[SDLK_d])
        {
            Jugador1.PlatyMov(1, PlayArea);
        }

        if (Keys[SDLK_DOWN] || Keys[SDLK_s])
        {
            Jugador1.PlatyMov(2, PlayArea);
        }

        if (Keys[SDLK_LEFT]|| Keys[SDLK_a])
        {
            Jugador1.PlatyMov(3, PlayArea);
        }

        // Obtiene las nuevas coordenadas de Platy y previene que este salga del area de juego
        ScreenCoords.x = (Jugador1.DameX() * screen->w / PlayArea->w);
        ScreenCoords.y = (Jugador1.DameY() * screen->h / PlayArea->h);

        Bl = (screen->w * screen->w) / (2*PlayArea->w);
        Bu = (screen->h * screen->h) / (2*PlayArea->h);

        Br = screen->w - ((screen->w * screen->w) / (2*PlayArea->w));
        Bd = screen->h - ((screen->h * screen->h) / (2*PlayArea->h));

        if (ScreenCoords.x > Bl && ScreenCoords.x < Br)
        {
            ScreenCoords.x = screen->w /2;
        }

        else
        {
            if (ScreenCoords.x >= Br)
                ScreenCoords.x = screen->w/2 + ((PlayArea->w/screen->w) * (ScreenCoords.x-Br));

            if (ScreenCoords.x <= Bl)
                ScreenCoords.x = screen->w/2 - ((PlayArea->w/screen->w) * (Bl - ScreenCoords.x));
        }

        if (ScreenCoords.y > Bu && ScreenCoords.y < Bd)
        {
            ScreenCoords.y = screen->h /2;
        }

        else
        {
            if (ScreenCoords.y >= Bd)
                ScreenCoords.y = screen->h/2 + (((float)PlayArea->h/(float)screen->h) * (ScreenCoords.y-Bd));

            if (ScreenCoords.y <= Bu)
                ScreenCoords.y = screen->h/2 - (((float)PlayArea->h/(float)screen->h) * (Bu - ScreenCoords.y));
        }

        // Obtiene las coordenadas donde se dibujara el sprit de Platy
        SpriteCoords.x = ScreenCoords.x - BmpDst->w /2;
        SpriteCoords.y = ScreenCoords.y - BmpDst->h /2;

        // Obtiene la nueva vista para mantener siempre centrado a Platy y previene que la vista salga del area de juego
        ViewSize.x = Jugador1.DameX() - screen->w/2;
        ViewSize.y = Jugador1.DameY() - screen->h/2;

        //printf("ViewSize.x: %i,\tViewSize.y: %i\n", ViewSize.x, ViewSize.y);

        if (ViewSize.x <= 0)
            ViewSize.x = 0;
        if (ViewSize.y <= 0)
            ViewSize.y = 0;
        if (ViewSize.x >= PlayArea->w - screen->w)
            ViewSize.x = PlayArea->w - screen->w;
        if (ViewSize.y >= PlayArea->h - screen->h)
            ViewSize.y = PlayArea->h - screen->h;

        // El enemigo sigue al jugador
        for (int i = 0; i < CantidadEnemigos; i++)
        {
            if (Enemigo[i] != NULL)
            {
                Enemigo[i]->SeguirJugador(Jugador1.DameX(), Jugador1.DameY());
                for (int j = 0; j < CantidadEnemigos; j++)
                {
                    if (j != i && Enemigo[i] != NULL && Enemigo[j] != NULL)
                        Enemigo[i]->ReajustarPosicion(Enemigo[j]->MaloX(), Enemigo[j]->MaloY(), 50);
                }
            }
        }

        // Movimiento de las balas
        for (int i = 0; i < CantidadBalas; i++)
        {
            if(B[i] != NULL)
            {
                B[i]->Movimiento(MousePos.x, MousePos.y, screen, &ScreenCoords);
            }
        }

        // Detecta colisiones de balas con el enemigo
        for (int i = 0; i < CantidadEnemigos; i++)
        {
            for (int j = 0; j < CantidadBalas; j++)
            {
                if(Enemigo[i] != NULL && B[j] != NULL)
                {
                    Aux = abs(sqrt(pow(Enemigo[i]->MaloX()-B[j]->BalaX(),2) + pow(Enemigo[i]->MaloY()-B[j]->BalaY(),2)));
                    //printf ("Distancia: %i\n", Aux);
                    if (Aux < 25 && Enemigo[i] != NULL && B[j] != NULL)
                    {
                        //free(Enemigo[i]);
                        delete Enemigo[i];
                        //free (B[j]);
                        delete B[j];
                        Enemigo[i] = NULL;
                        B[j] = NULL;
                        CantidadBalas --;
                        CantidadEnemigos --;
                    }
                }
            }
        }

        // Detecta colisiones de los enemigos con Platy y finaliza el juego
        for (int i = 0; i < CantidadEnemigos; i++)
        {
            if (Enemigo[i] != NULL)
            {
                Aux = abs(sqrt(pow(Enemigo[i]->MaloX()-Jugador1.DameX(),2) + pow(Enemigo[i]->MaloY()-Jugador1.DameY(),2)));
                if (Aux < 25 && Enemigo[i] != NULL)
                {
                    Vidas --;
                    for (int j = 0; j < CantidadEnemigos; j++)
                    {
                            delete Enemigo[j];
                            Enemigo[j] = NULL;
                    }
                    CantidadEnemigos = 0;
                }
            }
        }

        if (Vidas  <= 0)
        {
            //TODO: implementar game over
            SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 0, 0, 0));
            SDL_BlitSurface(Texto, 0, screen, &TextRect);
        }

        else
        {
        // Limpia pantalla y el area de juego
        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 255, 255, 255));
        //SDL_BlitSurface(PlayAreaClear, 0, PlayArea, 0);

        // Dibuja la respectiva parte de area de juego en la pantalla
        SDL_BlitSurface(PlayArea, &ViewSize, screen, 0);

        // Dibuja a los Enemigos en la pantalla, solo si estan en una posicion visible
        for (int i = 0; i < CantidadEnemigos; i++)
        {
            if (Enemigo[i] != NULL)
            {
                if ((Enemigo[i]->MaloX() > ViewSize.x -20 && Enemigo[i]->MaloX() < ViewSize.x + ViewSize.w + 20) && (Enemigo[i]->MaloY() > ViewSize.y -20 && Enemigo[i]->MaloY() < ViewSize.y + ViewSize.h + 20))
                {
                    SpriteCoordsM.x = Enemigo[i]->MaloX() - ViewSize.x - Malo->w/2;
                    SpriteCoordsM.y = Enemigo[i]->MaloY() - ViewSize.y - Malo->h/2;
                    SDL_BlitSurface(Malo, 0, screen, &SpriteCoordsM);
                }
            }
        }

        // Dibuja las balas en la pantalla, solo si estan en una posición visible. Las elimina si salen de la apantalla.
        for (int i = 0; i < CantidadBalas; i++)
        {
            if (B[i] != NULL)
            {
                if ((B[i]->BalaX() > ViewSize.x -20 && B[i]->BalaX() < ViewSize.x + ViewSize.w + 20) && (B[i]->BalaY() > ViewSize.y -20 && B[i]->BalaY() < ViewSize.y + ViewSize.h + 20))
                {
                    SpriteBalas.x = B[i]->BalaX() - ViewSize.x - Bala->w/2;
                    SpriteBalas.y = B[i]->BalaY() - ViewSize.y - Bala->h/2;
                    SDL_BlitSurface(Bala, 0, screen, &SpriteBalas);
                }
                else
                {
                    delete B[i];
                    B[i] = NULL;
                    CantidadBalas --;
                }
            }
        }

        // Dibuja a Platy en el area de juego
        SDL_BlitSurface(BmpDst, 0, screen, &SpriteCoords);
        }

        /// TERMINA CICLO DEL JUEGO

        // Finalmente muestra la pantalla
        SDL_Flip(screen);
        SDL_Delay(20);
        Tiempo += 0.02f;

    } /// TERMINA CICLO DEL PROGRAMA

    // Libera bitmaps y fuentes creados
    SDL_FreeSurface(screen);
    SDL_FreeSurface(Bmp);
    SDL_FreeSurface(PlayArea);
    SDL_FreeSurface(BmpDst);
    SDL_FreeSurface(Malo);
    SDL_FreeSurface(Bala);
    SDL_FreeSurface(Texto);
    TTF_CloseFont(Fuente);

    // Todo Bien ;)
    printf("Exited cleanly\n");
    return 0;
}
////////////////////////////////////////////////////////////
// SDL displaying 1000 sprites
////////////////////////////////////////////////////////////
int SpritesRotatingSDL()
{
    // Initialize the random numbers generator
    srand(static_cast<unsigned int>(time(NULL)));

    // Initialize SDL
    if (SDL_Init(SDL_INIT_VIDEO) != 0)
        return 1;

    // Create the main window
    SDL_Surface* App = SDL_SetVideoMode(800, 600, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
    if (App == NULL)
        return 1;

    // Load five images
    SDL_Surface* Images[5];
    Images[0] = SDL_DisplayFormat(SDL_LoadBMP("image1.bmp"));
    Images[1] = SDL_DisplayFormat(SDL_LoadBMP("image2.bmp"));
    Images[2] = SDL_DisplayFormat(SDL_LoadBMP("image3.bmp"));
    Images[3] = SDL_DisplayFormat(SDL_LoadBMP("image4.bmp"));
    Images[4] = SDL_DisplayFormat(SDL_LoadBMP("image5.bmp"));
    if (!Images[0] || !Images[1] || !Images[2] || !Images[3] || !Images[4])
    {
        return 1;
    }

    // Create a lot of sprites
    struct Sprite
    {
        SDL_Rect Rect;
        SDL_Surface* Image;
    };
    Sprite Sprites[NbSprites];
    for (int i = 0; i < NbSprites; ++i)
    {
        Sprites[i].Image  = Images[rand() % 5];
        Sprites[i].Rect.x = rand() % 700;
        Sprites[i].Rect.y = rand() % 500;
        Sprites[i].Rect.w = Sprites[i].Image->w;
        Sprites[i].Rect.h = Sprites[i].Image->h;
    }

    // Start the timer
    Uint32 Time = SDL_GetTicks();
    int NbFrames = 0;

    // Start game loop
    while (SDL_GetTicks() < Time + 5000)
    {
        // Clear the screen
        SDL_FillRect(App, NULL, SDL_MapRGB(App->format, 0, 0, 0));

        // Draw the sprites
        float Angle = (SDL_GetTicks() - Time) / 10.f;
        for (int i = 0; i < NbSprites; ++i)
        {
            Uint32 Background = SDL_MapRGB(Sprites[i].Image->format, 0, 0, 0);
            SDL_Surface* Surface = sge_transform_surface(Sprites[i].Image, Background, Angle, 1.f, 1.f, SGE_TTMAP);

            Sprites[i].Rect.w = Surface->w;
            Sprites[i].Rect.h = Surface->h;
            SDL_BlitSurface(Surface, NULL, App, &Sprites[i].Rect);
            SDL_FreeSurface(Surface);
        }

        // Finally, display rendered frame on screen
        SDL_Flip(App);
        NbFrames++;
    }

    // Exit SDL
    SDL_Quit();

    return NbFrames;
}