조금 더 보완해서 대기화면과 랭킹, 그리고 해당 스테이지를 깨면 더 강화되는 형식의 플레이로 수정할 예정입니다. 

 


https://youtu.be/MR97VkKqXpo


해당 프로그램의 헤더파일

#include <stdio.h>
#include <SDL.h>
#include <SDL_mixer.h>
#include <SDL_image.h>
#include <SDL_ttf.h>

#define WIDTH 800  // 화면 너비
#define HEIGHT 600 // 화면 높이
#define Aliens_Count 10

SDL_Window* window; // SDL 창과 렌더러를 가리키는 포인터
SDL_Renderer* renderer;
Mix_Music* music; // 배경 음악
Mix_Chunk* missileSFX; // 미사일 발사 효과음
Mix_Chunk* alienSFX;

// 점수 관리
int score = 0;
TTF_Font* font = NULL;
SDL_Texture* scoreTexture;
SDL_Rect scoreRect;



struct Spaceship {
	SDL_Rect rect; // 위치와 크기 
	int dx, dy; // 이동 속도
	int health; // 체력
	SDL_Texture* texture; // 이미지 텍스처 저장 
} spaceship = { {WIDTH / 2, HEIGHT - 90, 100,100}, 0,0,0, NULL };

struct Alien {
	SDL_Rect rect;
	int dx, dy;
	int health;
	int show;
	SDL_Texture* texture;
} aliens[Aliens_Count];

struct Missle {
	SDL_Rect rect;
	int dx, dy;
	int show; // 미사일 텍스쳐 표시 여부
	SDL_Texture* texture;
}missile = { {WIDTH / 2, HEIGHT - 60, 60, 60}, 1,5,0,NULL };




// 배경음 재생
void musicFinished() {
	Mix_PlayMusic(music, 1);
}

// 충돌 확인
int checkCollision(SDL_Rect rect1, SDL_Rect rect2) { // 두개의 rect 박스가 겹치는지 확인
	if (rect1.x + rect1.w >= rect2.x && // 겹침
		rect2.x + rect2.w >= rect1.x &&
		rect1.y + rect1.h >= rect2.y &&
		rect2.y + rect2.h >= rect1.y) {
		return 1;
	}
	return 0;
}

// 스코어 
void UpdateScoreTexture()
{
	// 점수를 문자열로 변환
	char scoreText[32];
	sprintf(scoreText, "Score: %d", score);

	// (1) 문자 -> 서페이스
	SDL_Color white = { 255, 255, 255, 255 };
	SDL_Surface* textSurface = TTF_RenderText_Solid(font, scoreText, white);
	if (!textSurface) {
		fprintf(stderr, "Failed to render text surface: %s\n", TTF_GetError());
		return;
	}

	// (2) 서페이스 -> 텍스처
	SDL_DestroyTexture(scoreTexture); // 기존 텍스처 있으면 파괴 (갱신)
	scoreTexture = SDL_CreateTextureFromSurface(renderer, textSurface);
	SDL_FreeSurface(textSurface);

	if (!scoreTexture) {
		fprintf(stderr, "Failed to create text texture: %s\n", SDL_GetError());
		return;
	}

	// 텍스처의 너비/높이 가져오기
	int texW = 0, texH = 0;
	SDL_QueryTexture(scoreTexture, NULL, NULL, &texW, &texH);

	// scoreRect 위치/크기 설정 (예: 왼쪽 상단)
	scoreRect.x = 10;
	scoreRect.y = 10;
	scoreRect.w = texW;
	scoreRect.h = texH;
}

소스 코드

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <SDL.h>
#include <SDL_mixer.h>
#include <SDL_image.h>
#include <SDL_ttf.h>
#include "hh.h"



int main(int arc, char** argv) {
	SDL_Event event;
	int quit = 0;

	Mix_Init(SDL_INIT_EVERYTHING);
	SDL_Init(SDL_INIT_VIDEO); // 비디오 서브 시스템 초기화
	SDL_Init(SDL_INIT_AUDIO); // 오디오
	TTF_Init();

	window = SDL_CreateWindow("galaga", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT, 2); // WIDTH 와 HEIGHT의 크기만큼, "galga"라는 제목의 윈도우를 가운데 정렬되게 생성
	renderer = SDL_CreateRenderer(window, -1, 0); // 윈도우에 대한 렌더러(그래픽 요소를 그리기 위해 사용됨) 생성

	Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 2048);

	font = TTF_OpenFont("DungGeunMo.ttf", 24);

	// 배경 음악 로드
	music = Mix_LoadMUS("example.mp3");

	// 효과음 로드
	missileSFX = Mix_LoadWAV("play.wav");
	alienSFX = Mix_LoadWAV("pop.wav");

	// 텍스처 로드, 우주선
	SDL_Surface* bmp = IMG_Load("spaceship_2.png");
	spaceship.texture = SDL_CreateTextureFromSurface(renderer, bmp);
	SDL_FreeSurface(bmp);

	// 외계인
	bmp = IMG_Load("alien_1.png");
	for (int i = 0; i < Aliens_Count; i++) {
		aliens[i].texture = SDL_CreateTextureFromSurface(renderer, bmp);
	}
	SDL_FreeSurface(bmp);

	//미사일
	bmp = IMG_Load("missile_2.png");
	missile.texture = SDL_CreateTextureFromSurface(renderer, bmp);
	SDL_FreeSurface(bmp);


	// 외계인에 대한 구조체 배열값 초기화
	int alienX = 50;
	int alienY = 0;
	for (int i = 0; i < Aliens_Count; i++) {
		aliens[i].rect.w = aliens[i].rect.h = 100;
		aliens[i].dx = aliens[i].dy = 1;
		aliens[i].show = 1;
		aliens[i].rect.x = alienX;
		aliens[i].rect.y = alienY;
		alienX += 100;
		if (alienX >= WIDTH - 100) {
			alienX = 50;
			alienY += 100;
		}
	}

	// 점수 처음 표시 (0점)
	UpdateScoreTexture();

	Mix_PlayMusic(music, -1);
	Mix_VolumeMusic(10);

	while (!quit) {
		//이벤트 처리

		while (SDL_PollEvent(&event)) {
			if (event.type == SDL_QUIT) { // 윈도우의 x 표시를 누르면
				quit = 1;
			}
			else if (event.type == SDL_KEYDOWN) {
				if (event.key.keysym.sym == SDLK_RIGHT) // -> +10
					spaceship.rect.x += 10;
				if (event.key.keysym.sym == SDLK_LEFT) // <- -10
					spaceship.rect.x -= 10;
				if (event.key.keysym.sym == SDLK_SPACE) {
					missile.show = 1;  // spacebar를 누르면 미사일을 표시함
					Mix_PlayChannel(-1, missileSFX, 0);
					missile.rect.x = spaceship.rect.x + 15;
					missile.rect.y = spaceship.rect.y;
				}
			}
		}

		for (int i = 0; i < Aliens_Count; i++) {
			if (aliens[i].show == 0) continue; // 미사일에 맞은 외계인은 값을 변화시킬 필요 없음
			aliens[i].rect.x += aliens[i].dx;
			if (aliens[i].rect.x <= 0 || aliens[i].rect.x > WIDTH) {
				aliens[i].dx *= -1;
				aliens[i].rect.y += 20;
			}
			if (missile.show == 0) continue;
			int collision = checkCollision(aliens[i].rect, missile.rect);
			if (collision) {
				Mix_PlayChannel(-1, alienSFX, 0);

				// 점수 증가
				score++;
				UpdateScoreTexture();  // 텍스처 갱신



				missile.show = 0;
				aliens[i].show = 0;
				missile.rect.y = spaceship.rect.y;

			}
		}

		if (missile.show == 1) {
			missile.rect.y -= missile.dy; // 미사일  y위치 이동
			if (missile.rect.y < 0) // 미사일이 창 상단에 도달하면 미사일을 안보이게 함
				missile.show = 0;
		}


		SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255); // 렌더러의 그리기 색상을 검정색으로
		SDL_RenderClear(renderer); // 렌더러에 설정된 색상으로 화면을 지움

		SDL_RenderCopy(renderer, spaceship.texture, NULL, &(spaceship.rect)); // 두번째 인수에 저장된 텍스처를 렌더러에 복사하여 우주선을 그림, 4번째 인수는 해당 텍스처의 위치와 크기값
		for (int i = 0; i < Aliens_Count; i++) {
			if (aliens[i].show == 1) {
				SDL_RenderCopy(renderer, aliens[i].texture, NULL, &(aliens[i].rect)); // 위와 동일 (외계인)
			}
			if (missile.show == 1) {
				SDL_RenderCopy(renderer, missile.texture, NULL, &(missile.rect)); // spacebar를 눌렀을 경우에만 실행
			}
		}
		// 점수 텍스처
		SDL_RenderCopy(renderer, scoreTexture, NULL, &scoreRect);

		SDL_Delay(10);  // 게임 루프에 딜레이를 주어 프레임 조절 
		SDL_RenderPresent(renderer); // 렌더러에 그려진 내용을 실제 화면에 표시
	}




	Mix_FreeMusic(music);
	Mix_FreeChunk(missileSFX);
	Mix_FreeChunk(alienSFX);

	TTF_CloseFont(font);
	SDL_DestroyTexture(scoreTexture);



	IMG_Quit();
	Mix_Quit();
	SDL_DestroyRenderer(renderer);
	SDL_DestroyWindow(window);
	SDL_Quit(); 

}

 

+ Recent posts