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; }
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(); } }