조금 더 보완해서 대기화면과 랭킹, 그리고 해당 스테이지를 깨면 더 강화되는 형식의 플레이로 수정할 예정입니다.
해당 프로그램의 헤더파일
#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();
}
'C' 카테고리의 다른 글
[C언어 | SDL을 이용한 게임 작성] Visual Studio에서 SDL 개발 환경 설정하기 (0) | 2025.02.24 |
---|---|
[쉽게 풀어쓴 C언어 Express 개정 4판] 17장 Programming (1) | 2024.10.18 |
[쉽게 풀어쓴 C언어 Express 개정 4판] 16장 Programming (1) | 2024.10.16 |
[쉽게 풀어쓴 C언어 Express 개정 4판] 15장 Programming (0) | 2024.10.15 |
[쉽게 풀어쓴 C언어 Express 개정 4판] 14장 Programming (14) | 2024.10.11 |