Пример #1
0
int main()
{
  Invader invaders[ROWS][COLS];
  Defender player;
  Bullet playerBullet;
  Ship spaceShip;
  Bullet invaderBullet[bulletNumber];
  Shelter shelter[shelterNumber];

  initializeInvaders(invaders);

  //Initialise playerBullet and initial invader bullet firing setting
  playerBullet.fire=0;
  playerBullet.invaderCount=0;
  playerBullet.score=0;
  playerBullet.lives=3;
  playerBullet.bulletHitPlayer=0;
  for(int i=0; i<bulletNumber; ++i)
  {
    invaderBullet[i].fire=1;
    invaderBullet[i].active=1;
  }


  // initialise SDL and check that it worked otherwise exit
  // see here for details http://wiki.libsdl.org/CategoryAPI
  if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
  {
    printf("%s\n",SDL_GetError());
    return EXIT_FAILURE;
  }
  // we are now going to create an SDL window

  SDL_Window *win = 0;
  win = SDL_CreateWindow("Invaders", 100, 100, WIDTH, HEIGHT, SDL_WINDOW_SHOWN);
  if (win == 0)
  {
    printf("%s\n",SDL_GetError());
    return EXIT_FAILURE;
  }

  // the renderer is the core element we need to draw, each call to SDL for drawing will need the
  // renderer pointer
  SDL_Renderer *ren = 0;
  ren = SDL_CreateRenderer(win, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
  // check to see if this worked
  if (ren == 0)
  {
    printf("%s\n",SDL_GetError() );
    return EXIT_FAILURE;
  }
  // this will set the background colour to white.
  // however we will overdraw all of this so only for reference
  SDL_SetRenderDrawColor(ren, 255, 255, 255, 255);

//  // SDL image is an abstraction for all images
  SDL_Surface *image;
//  // we are going to use the extension SDL_image library to load a png, documentation can be found here
//  // http://www.libsdl.org/projects/SDL_image/
  image=IMG_Load("invaders.png");
  if(!image)
  {
    printf("IMG_Load: %s\n", IMG_GetError());
    return EXIT_FAILURE;
  }
//  // SDL texture converts the image to a texture suitable for SDL rendering  / blitting
//  // once we have the texture it will be store in hardware and we don't need the image data anymore

  SDL_Texture *tex = 0;
  tex = SDL_CreateTextureFromSurface(ren, image);
  // free the image
  SDL_FreeSurface(image);

  // Initialise player
  player.move = NONE;
  player.pos.x = WIDTH/2;
  player.pos.y = HEIGHT - 30;
  player.pos.w = DEFENDERSIZE;
  player.pos.h = DEFENDERSIZE/2;

  player.srcDefender.w=188;
  player.srcDefender.h=105;
  player.srcDefender.x=0;
  player.srcDefender.y=0;

  // Initialise player bullet
  playerBullet.pos.x = (WIDTH/2)+(DEFENDERSIZE/2);
  playerBullet.pos.y = HEIGHT - 50;
  playerBullet.pos.w = 2;
  playerBullet.pos.h = 15;

  playerBullet.srcBullet.w=bulletWidth;
  playerBullet.srcBullet.h=250;
  playerBullet.srcBullet.x=0;
  playerBullet.srcBullet.y=0;

  // Initialise invader bullet
  for(int i=0; i<bulletNumber; ++i)
  {
    //a random column is chosen, it then goes through the invaders one by one starting with the bottom one
    //if the invader is active then it will shoot and break the loop
    //otherwise it will go to the next invader up until it finds the top
    //so only the bottom invader for each column is firing
    int x = 0;
    int y = rand()%(COLS-2);
    y +=2;
    for(int j=ROWS-1; j>=0; j--)
    {
      if(invaders[j][y].active==1)
      {
        invaders[j][y].shooting=1;
        x=j;
        break;
      }
    }

    //if the invader rnadomly chosen is active then the bullet is placed at it's x and y coordinates and fired
    if(invaders[x][y].shooting==1)
    {
      invaderBullet[i].pos.y=invaders[x][y].pos.y;
      invaderBullet[i].pos.x=((SPRITEWIDTH/2)-(5))+invaders[x][y].pos.x;
    }
    else if(invaders[x][y].shooting==0)
    {
      invaderBullet[i].fire=0;
    }

    invaderBullet[i].pos.w = 10;
    invaderBullet[i].pos.h = 20;

    invaderBullet[i].srcBullet.w=24;
    invaderBullet[i].srcBullet.h=56;
    invaderBullet[i].srcBullet.x=0;
    invaderBullet[i].srcBullet.y=0;
  }

  //randomise spaceship start direction
  //will end up either appearing from the right or the left
  //if its from the left the shipDelay has to be minus so the image is off screen and the opposite for the right
  srand(time(NULL));
  spaceShip.randomDir = rand()%2;
  int x;
  if (spaceShip.randomDir==0)
  {
    x=-shipDelay;
  }
  else if (spaceShip.randomDir==1)
  {
    x=shipDelay;
  }

  //initialise shelter
  for(int j=0; j<shelterNumber; j++)
  {
    shelter[j].pos.y=500;
    shelter[j].pos.x=(j*200)+50;
    shelter[j].pos.w=75;
    shelter[j].pos.h=25;

    shelter[j].srcShelter.y=0;
    shelter[j].srcShelter.w=shelterWidth;
    shelter[j].srcShelter.h=shelterHeight;
  }

  //initialise space ship
  spaceShip.pos.x=(spaceShip.randomDir*(WIDTH-spaceShipWidth)+x);
  spaceShip.pos.y=20;
  spaceShip.pos.w=spaceShipWidth;
  spaceShip.pos.h=25;

  spaceShip.srcShip.x=0;
  spaceShip.srcShip.y=204;
  spaceShip.srcShip.w=196;
  spaceShip.srcShip.h=88;

  int quit=0;
  // now we are going to loop forever, process the keys then draw

  //loading in the Defender spritesheet
  SDL_Surface *imageDefender;
  imageDefender=IMG_Load("Defender.png");
  if(!imageDefender)
  {
    printf("IMG_Load: %s\n", IMG_GetError());
    return EXIT_FAILURE;
  }
  SDL_Texture *texDefender = 0;
  texDefender = SDL_CreateTextureFromSurface(ren, imageDefender);
  SDL_FreeSurface(imageDefender);

  //loading in the enemy fire spritesheet
  SDL_Surface *imageenemyFire;
  imageenemyFire=IMG_Load("EnemyShot1.png");
  if(!imageenemyFire)
  {
    printf("IMG_Load: %s\n", IMG_GetError());
    return EXIT_FAILURE;
  }
  SDL_Texture *texEnemyFire = 0;
  texEnemyFire = SDL_CreateTextureFromSurface(ren, imageenemyFire);
  SDL_FreeSurface(imageenemyFire);

  //loading in the Shelter spritesheet
  SDL_Surface *imageShelter;
  imageShelter=IMG_Load("bunker.png");
  if(!imageShelter)
  {
    printf("IMG_Load: %s\n", IMG_GetError());
    return EXIT_FAILURE;
  }
  SDL_Texture *texShelter = 0;
  texShelter = SDL_CreateTextureFromSurface(ren, imageShelter);
  SDL_FreeSurface(imageShelter);

  //loading in the laser spritesheet
  SDL_Surface *imageBullet;
  imageBullet=IMG_Load("laser.png");
  if(!imageBullet)
  {
    printf("IMG_Load: %s\n", IMG_GetError());
    return EXIT_FAILURE;
  }
  SDL_Texture *texBullet = 0;
  texBullet = SDL_CreateTextureFromSurface(ren, imageBullet);
  SDL_FreeSurface(imageBullet);

  while (quit !=1)
  {
    SDL_Event event;
    // grab the SDL even (this will be keys etc)
    while (SDL_PollEvent(&event))
    {
      player.move=NONE;
      playerBullet.start=NONE;
      // look for the x of the window being clicked and exit
      if (event.type == SDL_QUIT)
        quit = 1;
      // check for a key down
      if (event.type == SDL_KEYDOWN)
      {
        switch (event.key.keysym.sym)
        {
          // if we have an escape quit
          case SDLK_ESCAPE :
          {
            quit=1;
            break;
          }
          //if we have a right key then the defender moves right along with the bullet before its fired
          case SDLK_RIGHT :
          case SDLK_d :
          {
            player.move=RIGHT;
            playerBullet.start=RIGHT;
            break;
          }
          //if we have a left key then the defender moves left along with the bullet before its fired
          case SDLK_LEFT :
          case SDLK_a :
          {
            player.move=LEFT;
            playerBullet.start=LEFT;
            break;
          }
          //if we have a space key then the player bullet is fired
          case SDLK_SPACE :
          {
            playerBullet.fire=1;
            break;
          }
        }
      }
    }


    // now we clear the screen (will use the clear colour set previously)
    SDL_SetRenderDrawColor(ren, 0, 0, 0, 255);
    SDL_RenderClear(ren);

    updateInvaders(invaders);
    drawInvaders(ren,tex,invaders);
    // Up until now everything was drawn behind the scenes.
    // This will show the new, red contents of the window.

    moveDefender(ren, texDefender, &player);
    playerFire(ren, texBullet, &playerBullet, &player, shelter);
    invaderFire(ren, texEnemyFire, shelter, invaderBullet, &playerBullet, &player);
    invaderHit(&playerBullet, invaders);
    drawSpaceShip(ren, tex, &spaceShip);
    spaceShipHit(&playerBullet, &spaceShip);
    invaderReachBottom(&player,invaders, &playerBullet);
    drawShelter(ren, texShelter, shelter);

    SDL_RenderPresent(ren);

    //if the player is hit or the bullet has gone offscreen, or has hit the shelter then
    //the random position for the next invader is chosen
    for(int i=0; i<bulletNumber; ++i)
    {
      if((invaderBullet[i].bulletHitPlayer==1)||
         (invaderBullet[i].bulletOffScreen==1)||
         (invaderBullet[i].bulletHitShelter==1))
      {
        //a random column is chosen, it then goes through the invaders one by one starting with the bottom one
        //if the invader is active then it will shoot and break the loop
        //otherwise it will go to the next invader up until it finds the top
        //so only the bottom invader for each column is firing
        int x = 0;
        int y = rand()%COLS;
        for(int j=ROWS-1; j>=0; j--)
        {

          invaders[j][y].shooting=0;
          if(invaders[j][y].active==1)
          {
            invaders[j][y].shooting=1;
            x=j;
            break;
          }
        }

        //only if the invader is active and is the bottom of it's column will the shooting value be set to 1
        //then the bullet is placed at the coordinates of the random invader chosen
        if(invaders[x][y].shooting==1)
        {
          invaderBullet[i].pos.y=invaders[x][y].pos.y;
          invaderBullet[i].pos.x=((SPRITEWIDTH/2)-(5))+invaders[x][y].pos.x;
          invaderBullet[i].active=1;
          invaderBullet[i].fire=1;
        }
        else if(invaders[x][y].shooting==0)
        {
          invaderBullet[i].fire=0;
        }

        invaderBullet[i].bulletOffScreen=0;
        invaderBullet[i].bulletHitPlayer=0;

      }
    }

    //when the invaders shot = the amount of invaders on screen then they redraw and
    // reset themselves at the top of the screen along with the counter
    //shelters do not reset
    if(playerBullet.invaderCount==ROWS*COLS)
    {
      initializeInvaders(invaders);
      updateInvaders(invaders);
      drawInvaders(ren,tex,invaders);
      playerBullet.invaderCount=0;
      playerBullet.lives+=1;
    }

    //if the escpae button is hit or player loses all of their lives then the game ends
    if((playerBullet.lives<=0)||(player.gameOver==1))
    {
      printf("you lose!\n");
      quit=1;
    }
  }

  printf("Your score = [%d]\n",playerBullet.score);
  printf("Your lives = [%d]\n",playerBullet.lives);

  SDL_Quit();
  return 0;
}
Пример #2
0
void Player::keyActions() // player действия при нажатии клавиши
{
    game->centerOn(this);

    lastX = x();
    lastY = y();
    lastDeg = degree;
    lastHDeg = hdegree;
    lastHealth = health;

    // эффект получения урона (должен стоять перед движением)
    if (wou)
    {
        /*
        int x1 = centralX();
        int y1 = centralY();
        wound->setPos(x1-game->width()/2,y1-game->height()/2);
        */
    }

    // движение вперед, назад
    if (mf)
    {
        moveForward();
        if (game->createBots)
            *bot << "mf ";
    }
    if (mb)
    {
        moveBack();
        if (game->createBots)
            *bot << "mb ";
    }

    // если player вышел за границы
    if (this->x() < game->dop - pixsize/2 ||
        this->x() > game->scene->width()-game->dop*2 + 20 ||
        this->y() < game->dop - pixsize/2 ||
        this->y() > game->scene->height()-game->dop*2 + 20)
    {
        // координата Х в центре экрана
        int x1 = centralX();

        // координата Y в центре экрана
        int y1 = centralY();

        if (out == false)
        {
            out = true;
            outTime = QTime::currentTime();
            outTimer = outMaxTime;

            QString image = ":/images/images/out.png";
            caution = new Caution(image, "CAUTION", 5);
            caution->setPos(x1-200,y1-88);
            game->scene->addItem(caution);
        }
        caution->setPos(x1-200, y1-88);

        if (outTime.msecsTo(QTime::currentTime()) > 1000)
        {
            if (outTimer > 0)
            {
                outTimer--;
                outTime = outTime.addSecs(1);
                caution->decTimer();
            }
            else
            {
                // DIE M**********R!
                //qDebug() << "you died";
                out = false;
                outTimer = outMaxTime;
                delete caution;

                // убить
                killPlayer();
                // BUHAHA
            }
        }
    }
    else
    {
        if (out == true)
        {
            out = false;
            outTimer = outMaxTime;
            delete caution;
        }
    }

    // универсальный поворот
    if (rl || rr)
    {
        playerRotate();
        spin++;
    }

    // ты ничего не видел
    if (rl == false && rr == false)
        spin = 0;
    // совершенно ничего
    if (spin == 540)
    {
        QMediaPlayer *sound = new QMediaPlayer();
        sound->setMedia(QUrl("qrc:/sounds/sounds/spin.mp3"));
        sound->play();
    }

    // поворот башни
    if (hl)
    {
        headLeft();
        if (game->createBots)
            *bot << "hl ";
    }
    if (hr)
    {
        headRight();
        if (game->createBots)
            *bot << "hr ";
    }

    // звук поворота башни
    if ((hr || hl) &&  tankhrotate->state() == QMediaPlayer::StoppedState) // если звук поворота еще не проигрывался
        tankhrotate->play();

    if (hr == false && hl == false && tankhrotate->state() == QMediaPlayer::PlayingState)
        tankhrotate->stop();

    // стрельба + звуки стрельбы
    if (fr && fireReady)
    {
        playerFire();
        reloading = false; // звук перезарядки еще на начат
        isFiring = 1;

        // анимация перезарядки
        reloadAnim = new QLabel();
        reloadAnim->setStyleSheet("background-color: transparent;");
        QMovie *movie = new QMovie(":/images/images/anim/Reload.gif");
        reloadAnim->setMovie(movie);
        reloadAnim->move(x()+20,y()+20);
        movie->setScaledSize(QSize(180,180));
        //movie->setSpeed(100);
        movie->start();
        QGraphicsProxyWidget *proxy = game->scene->addWidget(reloadAnim);

        if (game->createBots)
            *bot << "fr ";
    }
    if (fireReady == false) // счетчик для ожидания между выстрелами
    {
        fireCount += keyDelay;

        reloadAnim->move(x()+20,y()+20);
    }
    if ((fireCount > fireTime - bulletready->duration()) && reloading == false) // звук перезарядки
    {
        reloading = true; // перезарядка уже начата (защита от нескольких)
        bulletready->play();
    }
    if (fireCount > fireTime) // готовность выстрела
    {
        fireReady = true;
        fireCount = 0;

        delete reloadAnim;
    }

    if (game->createBots)
        *bot << endl;

    if (lastX != x() || lastY != y() || lastDeg != degree || lastHDeg != hdegree || lastHealth != health)
        emit KeyPressed();

    if (alive == false || (mf == false && mb == false && rl == false && rr == false && hl == false && hr == false && fr == false &&
                          fireReady == true && tankhrotate->state() == QMediaPlayer::StoppedState && out == false))
    {
        action = false;
        timer->stop();
    }
}