【C语言/SDL2】大一上期末项目 - 落井大战,但是须弥

大一上C语言程序设计基础写的期末项目。
初学编程,代码屎山,仅供参考。

  • 主函数中的一些操作可以适当用函数块代替,减少代码复杂度。
  • 虽然完全使用C语言编写代码,但为方便理解和使用起见,参考了一些面向对象的思想,但不完全面向对象,领会精神。
  • 当然还有许多骚操作和亟待改进的部分,尤其是混乱的全局变量。
  • 半成品,下降到一定高度将不再会生成任何障碍。受int范围影响,当高度值为2147483647时……你懂的

参考教程:www.bilibili.com/video/BV1rK411V7eu
游戏演示:www.bilibili.com/video/BV1wT411o7E4

实现的功能 (特性)

  • 操作系统: Windows 10/11 x64

  • C语言环境: mingw, Clion

  • 编译选项: CMakeLists

  • 第三方库: SDL2, SDL2_image, SDL2_ttf

  • 按键操作:

    • 跳跃/攻击: SPACE
    • 向左/右移动: 方向键 ← / →
    • 交互: 数字键 1/2/3
    • 退出游戏: 右上角 X / alt+F4
  • 游戏说明:

    • 分辨率:540 * 960,如显示不完整请右键属性->兼容性->更改高DPI设置,或更改系统设置中的缩放比例。
    • 双击运行"/bin/win_x64/Sumeru.exe"即可开始游戏。
    • 在该游戏中,玩家将操控主角穿越纵向卷轴场景,避开障碍、拾取原石获得更高分数。
    • 在空中按SPACE键,会向下方一段距离发射子弹,且子弹槽-1。落地后子弹槽会自动回满。
    • 平台:分为砖块和大蘑菇两种,其中砖块可以被攻击破坏。
    • 障碍物:刺儿、飘浮灵和水蕈兽。
    • 进行到一定阶段会遇到头上带感叹号的兰那罗,与其交互会消耗一枚原石,并得到对应奖励。
    • 直到主角生命值减为0,游戏结束,显示GAME OVER界面(七天神像奶我一口.jpg)。
    • 游戏结束后,按下SPACE键即可重新开始。
    • 原石-648,但不会真的-648。
    • 重新开始后,已获得的子弹槽和原石数量会保留。
  • 其他信息:

    • 出现的物体种类和位置由生成的随机数决定。
    • 主角初始拥有5点生命值、5点子弹槽。
    • 怪物拥有2点生命值。
    • 落在怪物头顶会被弹起,落在刺儿上会被扎。
    • 碰到障碍物:主角生命值-1,障碍物消失。正所谓一命换一命。
    • 为了找出内存泄漏的地方,在下的头发就快要掉光光。
    • 是爷就下100层! 实际上没有做到100层。

main.c

  • 主程序
// main.c
#define SDL_MAIN_HANDLED

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_ttf.h>
#include "Resource.h"
#include "Object.h"

#define BLOCK_SIZE 40
#define BLOCK_COUNT 200
#define PLAT_COUNT 160
#define STAR_COUNT 60
#define SHOP_COUNT 10
#define FLOATING_COUNT 80
#define MUSHROOM_COUNT 60

char info[10086];

Object *bg;
Object *heart;
Object *blt;
Object *gg;
Object *star_info;
Object *chara;
Object *skill;
Object *blocks[BLOCK_COUNT][9];
Object *nails[BLOCK_COUNT][9];
Object *plats[PLAT_COUNT];
Object *stars[STAR_COUNT];
Object *shops[SHOP_COUNT];
Object *tips[SHOP_COUNT];
Object *floatings[FLOATING_COUNT];
Object *mushrooms[MUSHROOM_COUNT];


float speedX = 0, speedY = 0;
#define SPEEDMAX 9

int stage = 1; // 1为开始游戏,0为gg
int direct_chara = 0; // 0为 ->,1为 <-。
int air = 0; // 滞空;0为处于地面。
int shoot = 0; // 1为发射。
int skill_display = 0; // 1为显示。
int HP_chara = 5;
int bullet = 5;
int bullet_max = 5;
int star = 0;

#define CD_SKILL 10
int time_skill = CD_SKILL;


SDL_Renderer *renderer;
SDL_Window *window;
SDL_Surface *text;
SDL_Texture *texture;

#define PTSIZE 30
TTF_Font *font_white;
TTF_Font *font_red;
SDL_Color white = {255, 255, 255, 255};
SDL_Color red = {255, 10, 10, 255};

void event_loop();
void timer();

void Info_star();
void Info_hit();

void createBlocks();
void destroyBlocks();
void destroyNails();

void createPlats();
void destroyPlats();

void createStars();
void destroyStars();

void createShops();
void destroyShops();

void createTips();
void destroyTips();

void createFloatings();
void destroyFloatings();

void createMushrooms();
void destroyMushrooms();


void draw_chara();
void draw_tips();
void draw();

void init();
void create();
void destroy();

int main() {
    SDL_Init(SDL_INIT_VIDEO);
    TTF_Init();

    window = SDL_CreateWindow(
            "Down the Forest",
            SDL_WINDOWPOS_CENTERED,
            SDL_WINDOWPOS_CENTERED,
            540, 960,
            SDL_WINDOW_SHOWN
    );
    if (window == NULL) {
        SDL_Log("Can not create window, %s", SDL_GetError());
        return 1;
    }
    renderer = SDL_CreateRenderer(
            window, -1,
            SDL_RENDERER_ACCELERATED
    );
    if (renderer == NULL) {
        SDL_Log("Can not create renderer, %s", SDL_GetError());
        return 1;
    }
    if (Resource_Load1(renderer)) {
        return 1;
    }

    font_white = TTF_OpenFont("TTF/8bit.ttf", PTSIZE);
    font_red = TTF_OpenFont("TTF/8bit.ttf", 20);

    create();

    event_loop();

    destroy();

    Resource_Unload();

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    TTF_Quit();
    SDL_Quit();

    return 0;
}

void event_loop() {
    HP_chara = 5;
    bullet = bullet_max;


    while (stage == 1) {
        uint32_t begin = SDL_GetTicks();
        draw();
        shoot = 0;

        timer();
        if (HP_chara <= 0) {
            stage = 0;
        }
        SDL_Event event;
        while (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                return;
            }
            if (event.type == SDL_KEYDOWN) {
                switch (event.key.keysym.sym) {
                    case SDLK_RIGHT:
                        speedX = 3;
                        direct_chara = 0;
                        break;
                    case SDLK_LEFT:
                        speedX = 3;
                        direct_chara = 1;
                        break;
                    case SDLK_SPACE:
                        if (time_skill >= CD_SKILL && bullet > 0) {
                            if (air == 0)
                                speedY = -10;
                            else {
                                speedY = -3;
                                shoot = 1;
                                bullet--;
                            }
                            time_skill = 0;
                            skill_display = 1;
                        }
                        break;
                }
            }
            if (event.type == SDL_KEYUP) {
                switch (event.key.keysym.sym) {
                    case SDLK_RIGHT:
                        speedX = 0;
                        break;
                    case SDLK_LEFT:
                        speedX = 0;
                        break;
                }
            }
        }
        // 滞空判定:
        for (int i = 0; i < BLOCK_COUNT; i++) {
            for (int j = 0; j < 5; j++) {
                if (blocks[i][j] != 0) {
                    if (chara->dest.x + 35 >= blocks[i][j]->dest.x &&
                        chara->dest.x + 15 <= blocks[i][j]->dest.x + blocks[i][j]->dest.w &&
                        chara->dest.y + chara->dest.h >= blocks[i][j]->dest.y &&
                        chara->dest.y + chara->dest.h <= blocks[i][j]->dest.y + 10) {
                        air = 0;
                        goto COMPLETE_AIR;
                    } else {
                        air = 1;
                    }
                }
            }
        }
        for (int i = 0; i < PLAT_COUNT; i++) {
            if (chara->dest.x + 30 >= plats[i]->dest.x &&
                chara->dest.x + 15 <= plats[i]->dest.x + plats[i]->dest.w &&
                chara->dest.y + chara->dest.h >= plats[i]->dest.y &&
                chara->dest.y + chara->dest.h <= plats[i]->dest.y + 10) {
                air = 0;
                goto COMPLETE_AIR;
            } else {
                air = 1;
            }
        }
        

        COMPLETE_AIR:;
        if (air == 0)
            bullet = bullet_max;

        // 碰撞判定
        for (int i = 0; i < BLOCK_COUNT; i++) {
            for (int j = 0; j < 5; j++) {
                if (blocks[i][j] != 0) {
                    if (nails[i][j] != 0 &&
                        chara->dest.x + 25 >= blocks[i][j]->dest.x &&
                        chara->dest.x + 15 <= blocks[i][j]->dest.x + blocks[i][j]->dest.w &&
                        chara->dest.y + chara->dest.h >= blocks[i][j]->dest.y &&
                        chara->dest.y + chara->dest.h <= blocks[i][j]->dest.y + 10) {
                        HP_chara--;
                        Info_hit();
                        nails[i][j] = 0;
                    }
                    if (skill->dest.x + skill->dest.w >= blocks[i][j]->dest.x &&
                        skill->dest.x <= blocks[i][j]->dest.x + blocks[i][j]->dest.w &&
                        skill->dest.y + skill->dest.h >= blocks[i][j]->dest.y &&
                        skill->dest.y <= blocks[i][j]->dest.y + blocks[i][j]->dest.h) {
                        blocks[i][j] = 0;
                        skill_display = 0;
                    }
                }
            }
        }
        for (int i = 0; i < FLOATING_COUNT; i++) {
            if (floatings[i] != 0) {
                if (chara->dest.x + 25 >= floatings[i]->dest.x + 5 &&
                    chara->dest.x + 15 <= floatings[i]->dest.x + 55 &&
                    chara->dest.y + chara->dest.h >= floatings[i]->dest.y + 15 &&
                    chara->dest.y <= floatings[i]->dest.y + 45) {
                    HP_chara--;
                    Info_hit();
                    floatings[i] = 0;
                    break;
                }
                if (chara->dest.x + 25 >= floatings[i]->dest.x + 5 &&
                    chara->dest.x + 15 <= floatings[i]->dest.x + 55 &&
                    chara->dest.y + chara->dest.h >= floatings[i]->dest.y &&
                    chara->dest.y + chara->dest.h <= floatings[i]->dest.y + 10) {
                    speedY = -7;
                }
                if (skill->dest.x + skill->dest.w >= floatings[i]->dest.x + 5 &&
                    skill->dest.x <= floatings[i]->dest.x + 55 &&
                    skill->dest.y + skill->dest.h >= floatings[i]->dest.y &&
                    skill->dest.y <= floatings[i]->dest.y + 45) {
                    floatings[i]->HP--;
                    if (floatings[i]->HP == 0) {
                        floatings[i] = 0;
                    }
                    skill_display = 0;
                    break;
                }
            }
        }
        for (int i = 0; i < MUSHROOM_COUNT; i++) {
            if (mushrooms[i] != 0) {
                if (chara->dest.x + 35 >= mushrooms[i]->dest.x + 5 &&
                    chara->dest.x + 15 <= mushrooms[i]->dest.x + 40 &&
                    chara->dest.y + chara->dest.h >= mushrooms[i]->dest.y + 15 &&
                    chara->dest.y <= mushrooms[i]->dest.y + 45) {
                    HP_chara--;
                    Info_hit();
                    mushrooms[i] = 0;
                    break;
                }
                if (chara->dest.x + 35 >= mushrooms[i]->dest.x + 5 &&
                    chara->dest.x + 15 <= mushrooms[i]->dest.x + 40 &&
                    chara->dest.y + chara->dest.h >= mushrooms[i]->dest.y &&
                    chara->dest.y + chara->dest.h <= mushrooms[i]->dest.y + 10) {
                    speedY = -7;
                }
                if (skill->dest.x + skill->dest.w >= mushrooms[i]->dest.x + 5 &&
                    skill->dest.x <= mushrooms[i]->dest.x + 55 &&
                    skill->dest.y + skill->dest.h >= mushrooms[i]->dest.y &&
                    skill->dest.y <= mushrooms[i]->dest.y + 45) {
                    mushrooms[i]->HP--;
                    if (mushrooms[i]->HP == 0) {
                        mushrooms[i] = 0;
                    }
                    skill_display = 0;
                    break;
                }
            }
        }
        for (int i = 0; i < STAR_COUNT; i++) {
            if (stars[i] != 0) {
                if (chara->dest.x + 35 >= stars[i]->dest.x &&
                    chara->dest.x + 5 <= stars[i]->dest.x + 35 &&
                    chara->dest.y + chara->dest.h >= stars[i]->dest.y + 5 &&
                    chara->dest.y <= stars[i]->dest.y + 35) {
                    star++;
                    stars[i] = 0;
                    break;
                }
            }
        }

        


        
        if (speedY > 0 && air == 0) {
            speedY = 0;
        }
        if (air == 1 && speedY <= SPEEDMAX) {
            speedY += 0.4;
        }

        
        uint32_t current = SDL_GetTicks();
        long cost = current - begin;
        long frame = 1000 / 60;
        long delay = frame - cost;

        if (delay > 0) {
            SDL_Delay(delay);
        }

        while (stage == 0) {
            SDL_Delay(500);
            SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
            SDL_RenderClear(renderer);
            GG_Draw(gg, renderer);
            SDL_RenderPresent(renderer);
            while (SDL_PollEvent(&event)) {
                if (event.type == SDL_QUIT) {
                    return;
                }
                else if (event.type == SDL_KEYUP) {
                    switch (event.key.keysym.sym) {
                        case SDLK_SPACE:
                            init();
                            create();
                    }
                }
            }
        }
    }
}


void timer() {
    time_skill++;
}

void Info_star() {
    sprintf(info, "x %d", star);
    text = TTF_RenderText_Blended(font_white, info, white);
    texture = SDL_CreateTextureFromSurface(renderer, text);
    SDL_Rect dest = {450, 25, text->w, text->h};
    SDL_RenderCopy(renderer, texture, NULL, &dest);
    Star_Draw(star_info, renderer);
    SDL_FreeSurface(text);
    SDL_DestroyTexture(texture);
}
void Info_hit() {
    text = TTF_RenderText_Blended(font_red, "-1", red);
    texture = SDL_CreateTextureFromSurface(renderer, text);
    int x = chara->dest.x + 20, y = chara->dest.y - 20;
    SDL_Rect dest = {x, y, text->w, text->h};
    SDL_RenderCopy(renderer, texture, NULL, &dest);
    SDL_RenderPresent(renderer);
    SDL_Delay(200);
    SDL_FreeSurface(text);
    SDL_DestroyTexture(texture);
}

void createBlocks() {
    for (int j = 0; j < 5; j++) {
        blocks[0][j] = Block_Create(j * BLOCK_SIZE + 200, 500);
    }
    for (int i = 1; i < BLOCK_COUNT; i++) {
        int ret_x = rand() % 200 + 50;
        int ret_y = rand() % 100 + 400;
        int count = rand() % 3 + 3;
        for (int j = 0; j < count; j++) {
            blocks[i][j] = Block_Create(j * BLOCK_SIZE + ret_x, (i + 1) * 400 + ret_y);
            int ret_nail = rand() % 10;
            if (ret_nail <= 2) {
                nails[i][j] = Nail_Create(j * BLOCK_SIZE + ret_x, (i + 1) * 400 + ret_y - 11);
            }
        }
    }
}

void destroyBlocks() {
    for (int i = 0; i < BLOCK_COUNT; i++) {
        for (int j = 0; j < 5; j++) {
            Object_Destroy(blocks[i][j]);
        }
    }
}

void destroyNails() {
    for (int i = 0; i < BLOCK_COUNT; i++) {
        for (int j = 0; j < 5; j++) {
            Object_Destroy(nails[i][j]);
        }
    }
}

void createPlats() {
    for (int i = 0; i < PLAT_COUNT; i++) {
        int x[PLAT_COUNT], y[PLAT_COUNT];
        int ret = rand() % 10;
        if (ret <= 4) {
            x[i] = rand() % 100 + 270;
        } else {
            x[i] = -130 + rand() % 100;
        }
        y[i] = rand() % 300 + i * 500 + 500;
        plats[i] = Plat_Create(x[i], y[i]);
    }
}

void destroyPlats() {
    for (int i = 0; i < PLAT_COUNT; i++) {
        Object_Destroy(plats[i]);
    }
}

void createStars() {
    int a[PLAT_COUNT], i = 0, j, r;
    srand((int) time(0));
    while (i < PLAT_COUNT) {
        r = rand() % PLAT_COUNT;
        for (j = i; j >= 0; j--) {
            if (r == a[j])
                break;
        }
        if (j < 0)
        {
            a[i] = r;
            i++;
        }
    }
    for (i = 0; i < STAR_COUNT; i++) {
        int num = a[i];
        float x = plats[num]->dest.x + 150;
        if (x > 500)
            x = 500;
        stars[i] = Star_Create(x, plats[num]->dest.y - 40);
    }
}

void destroyStars() {
    for (int i = 0; i < STAR_COUNT; i++) {
        Object_Destroy(stars[i]);
    }
}
void createShops() {
    for (int i = 0; i < SHOP_COUNT; i++) {
        int num = (i + 1) * 15;
        float x = plats[num]->dest.x + 100;
        if (x > 500)
            x = 480;
        else if (x < 0)
            x = 0;
        shops[i] = Shop_Create(x, plats[num]->dest.y - 60);
    }
}

void destroyShops() {
    for (int i = 0; i < SHOP_COUNT; i++) {
        Object_Destroy(shops[i]);
    }
}
void createTips() {
    for (int i = 0; i < SHOP_COUNT; i++) {
        int x = shops[i]->dest.x;
        if (x + 132 > 540)
            x = 540 - 132;
        tips[i] = Tips_Create(x, shops[i]->dest.y - 80);
    }
}

void destroyTips() {
    for (int i = 0; i < SHOP_COUNT; i++) {
        Object_Destroy(tips[i]);
    }
}

void createFloatings() {
    for (int i = 0; i < FLOATING_COUNT; i++) {
        int x[FLOATING_COUNT], y[FLOATING_COUNT];
        int ret = rand() % 10;
        if (ret <= 4) {
            x[i] = rand() % 100 + 270;
        } else {
            x[i] = -130 + rand() % 100;
        }
        y[i] = rand() % 300 + (i + 1) * 1000;
        floatings[i] = Floating_Create(x[i], y[i]);
    }
}

void destroyFloatings() {
    for (int i = 0; i < FLOATING_COUNT; i++) {
        Object_Destroy(floatings[i]);
    }
}

void createMushrooms() {
    int a[PLAT_COUNT], i = 0, j, r;
    srand((int) time(0));
    while (i < PLAT_COUNT) {
        r = rand() % PLAT_COUNT;
        for (j = i; j >= 0; j--) {
            if (r == a[j])
                break;
        }
        if (j < 0)
        {
            a[i] = r;
            i++;
        }
    }
    for (i = 0; i < MUSHROOM_COUNT; i++) {
        int num = a[i];
        mushrooms[i] = Mushroom_Create(plats[num]->dest.x + 150, plats[num]->dest.y - 40);
    }
}
void destroyMushrooms() {
    for (int i = 0; i < MUSHROOM_COUNT; i++) {
        Object_Destroy(mushrooms[i]);
    }
}

void draw_chara() {
    if (direct_chara == 0) {
        if (chara->dest.x + 40 >= 540) {
            speedX = 0;
        }
        chara->dest.x += speedX;
        Chara_Draw_R(chara, renderer);
    } else {
        if (chara->dest.x + 5 <= 0) {
            speedX = 0;
        }
        chara->dest.x -= speedX;
        Chara_Draw_L(chara, renderer);
    }
}
void draw_tips() {
    for (int i = 0; i < SHOP_COUNT; i++) {
        if (shops[i] != 0) {
            if (chara->dest.x + 55 >= shops[i]->dest.x &&
                chara->dest.x + 5 <= shops[i]->dest.x + 55 &&
                chara->dest.y + chara->dest.h >= shops[i]->dest.y + 5 &&
                chara->dest.y <= shops[i]->dest.y + 35) {
                Tips_Draw(tips[i], renderer);
                SDL_Event event;
                while (SDL_PollEvent(&event)) {
                    if (event.type == SDL_QUIT) {
                        return;
                    }
                    if (event.type == SDL_KEYDOWN) {
                        switch (event.key.keysym.sym) {
                            case SDLK_RIGHT:
                                speedX = 3;
                                direct_chara = 0;
                                break;
                            case SDLK_LEFT:
                                speedX = 3;
                                direct_chara = 1;
                                break;
                            case SDLK_SPACE:
                                if (time_skill >= CD_SKILL && bullet > 0) {
                                    if (air == 0)
                                        speedY = -10;
                                    else {
                                        speedY = -3;
                                        shoot = 1;
                                        bullet--;
                                    }
                                    time_skill = 0;
                                    skill_display = 1;
                                }
                                break;
                        }
                    }
                    if (event.type == SDL_KEYUP) {
                        switch (event.key.keysym.sym) {
                            case SDLK_1:
                                HP_chara++;
                                star--;
                                shops[i] = 0;
                                break;
                            case SDLK_2:
                                bullet_max += 2;
                                star--;
                                shops[i] = 0;
                                break;
                            case SDLK_3:
                                star += 648;
                                shops[i] = 0;
                                break;
                            default:
                                speedX = 0;
                                break;
                        }
                    }
                }
            }
        }
    }
}
void draw() {
    SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
    SDL_RenderClear(renderer);

    BG_Draw(bg, renderer);

    for (int i = 0; i < PLAT_COUNT; i++) {
        if (plats[i]->dest.x < 270) {
            Plat_Draw_L(plats[i], renderer);
        } else {
            Plat_Draw_R(plats[i], renderer);
        }
    }

    for (int i = 0; i < BLOCK_COUNT; i++) {
        for (int j = 0; j < 5; j++) {
            if (blocks[i][j] != 0) {
                Block_Draw(blocks[i][j], renderer);
                if (nails[i][j] != 0) {
                    Nail_Draw(nails[i][j], renderer);
                }
            }
        }
    }

    for (int i = 0; i < STAR_COUNT; i++) {
        if (stars[i] != 0) {
            Star_Draw(stars[i], renderer);
        }
    }
    for (int i = 0; i < SHOP_COUNT; ++i) {
        if (shops[i] != 0) {
            Shop_Draw(shops[i], renderer);
        }
    }
    for (int i = 0; i < MUSHROOM_COUNT; i++) {
        if (mushrooms[i] != 0) {
            if (mushrooms[i]->dest.x >= 500 ||
                (mushrooms[i]->dest.x >= 150 && mushrooms[i]->dest.x <= 250)) {
                mushrooms[i]->speedX = -1;
            } else if (mushrooms[i]->dest.x <= 0 ||
                       (mushrooms[i]->dest.x >= 250 && mushrooms[i]->dest.x <= 350)) {
                mushrooms[i]->speedX = 1;
            }
            if (mushrooms[i]->speedX > 0) {
                Mushroom_Draw_R(mushrooms[i], renderer);
            } else {
                Mushroom_Draw_L(mushrooms[i], renderer);
            }
        }
    }

    for (int i = 0; i < FLOATING_COUNT; i++) {
        if (floatings[i] != 0) {
            if (floatings[i]->dest.x >= 500) {
                floatings[i]->speedX = -2;
            } else if (floatings[i]->dest.x <= 0) {
                floatings[i]->speedX = 2;
            }
            if (floatings[i]->speedX > 0) {
                Floating_Draw_R(floatings[i], renderer);
            } else {
                Floating_Draw_L(floatings[i], renderer);
            }
        }
    }
    // 位移 X
    for (int i = 0; i < FLOATING_COUNT; i++) {
        if (floatings[i] != 0) {
            floatings[i]->dest.x += floatings[i]->speedX;
        }
    }
    for (int i = 0; i < MUSHROOM_COUNT; i++) {
        if (mushrooms[i] != 0) {
            mushrooms[i]->dest.x += mushrooms[i]->speedX;
        }
    }
    // 位移 Y
    for (int i = 0; i < BLOCK_COUNT; i++) {
        for (int j = 0; j < 5; j++) {
            if (blocks[i][j] != 0) {
                blocks[i][j]->dest.y -= speedY;
                if (nails[i][j] != 0) {
                    nails[i][j]->dest.y -= speedY;
                }
            }
        }
    }
    for (int i = 0; i < PLAT_COUNT; i++) {
        plats[i]->dest.y -= speedY;
    }
    for (int i = 0; i < STAR_COUNT; i++) {
        if (stars[i] != 0) {
            stars[i]->dest.y -= speedY;
        }
    }
    for (int i = 0; i < SHOP_COUNT; i++) {
        if (shops[i] != 0) {
            shops[i]->dest.y -= speedY;
            tips[i]->dest.y -= speedY;
        }
    }
    for (int i = 0; i < FLOATING_COUNT; i++) {
        if (floatings[i] != 0) {
            floatings[i]->dest.y -= speedY;
        }
    }
    for (int i = 0; i < MUSHROOM_COUNT; i++) {
        if (mushrooms[i] != 0) {
            mushrooms[i]->dest.y -= speedY;
        }
    }
    

    draw_chara();

    heart->dest.x = 25;
    for (int i = 1; i <= HP_chara; i++) {
        Heart_Draw(heart, renderer);
        heart->dest.x += 30;
    }
    blt->dest.x = 25;
    for (int i = 1; i <= bullet; i++) {
        Bullet_Draw(blt, renderer);
        blt->dest.x += 30;
    }

    if (air == 1 && bullet >= 0 && shoot == 1) {
        skill->dest.x = chara->dest.x + 15;
        skill->dest.y = chara->dest.y + chara->dest.h;
    }
    if (time_skill <= CD_SKILL && skill_display == 1) {
        Skill_Draw(skill, renderer);
        skill->dest.y += 15 - speedY;
    } else {
        skill->dest.x = 1000;
    }

    draw_tips();
    Info_star();
    SDL_RenderPresent(renderer);
}

void init() {
    speedX = 0;
    stage = 1;
    HP_chara = 5;
    bullet = 5;
    for (int i = 0; i < BLOCK_COUNT; i++) {
        for (int j = 0; j < 5; j++) {
            blocks[i][j] = 0;
            nails[i][j] = 0;
        }
    }
}

void create() {
    createBlocks();
    createPlats();
    createStars();
    createShops();
    createTips();
    createFloatings();
    createMushrooms();
    chara = Chara_Create(540 / 2, 960 / 2 - 160);
    skill = Skill_Create(1000, 0);

    bg = BG_Create(0, 0);
    gg = GG_Create(0, 0);
    heart = Heart_Create(25,25);
    blt = Bullet_Create(25, 60);
    star_info = Star_Create(390, 18);
}

void destroy() {
    destroyBlocks();
    destroyPlats();
    destroyNails();
    destroyStars();
    destroyShops();
    destroyTips();
    destroyFloatings();
    destroyMushrooms();
    Object_Destroy(chara);
    Object_Destroy(bg);
    Object_Destroy(gg);
    Object_Destroy(heart);
    Object_Destroy(blt);
    Object_Destroy(star_info);
    Object_Destroy(skill);
}

Object.hObject.c

  • 包含各种实体的属性、行为等。
// Object.h
//
// Created by Morin on 2023/2/3.
//

#ifndef SUMERU_OBJECT_H
#define SUMERU_OBJECT_H

#include <SDL2/SDL.h>

typedef struct {
    SDL_FRect dest;
    float speedX, speedY;
    int HP;
} Object;

Object *BG_Create(float x, float y);
Object *GG_Create(float x, float y);

Object *Heart_Create(float x, float y);
Object *Bullet_Create(float x, float y);
Object *Block_Create(float x, float y);
Object *Chara_Create(float x, float y);
Object *Plat_Create(float x, float y);
Object *Nail_Create(float x, float y);
Object *Skill_Create(float x, float y);
Object *Star_Create(float x, float y);
Object *Shop_Create(float x, float y);
Object *Tips_Create(float x, float y);

Object *Floating_Create(float x, float y);
Object *Mushroom_Create(float x, float y);

void BG_Draw(Object *self, SDL_Renderer *renderer);
void GG_Draw(Object *self, SDL_Renderer *renderer);

void Heart_Draw(Object *self, SDL_Renderer *renderer);
void Bullet_Draw(Object *self, SDL_Renderer *renderer);

void Block_Draw(Object *self, SDL_Renderer *renderer);
void Chara_Draw_R(Object *self, SDL_Renderer *renderer);
void Chara_Draw_L(Object *self, SDL_Renderer *renderer);
void Plat_Draw_R(Object *self, SDL_Renderer *renderer);
void Plat_Draw_L(Object *self, SDL_Renderer *renderer);
void Nail_Draw(Object *self, SDL_Renderer *renderer);
void Skill_Draw(Object *self, SDL_Renderer *renderer);
void Star_Draw(Object *self, SDL_Renderer *renderer);
void Shop_Draw(Object *self, SDL_Renderer *renderer);
void Tips_Draw(Object *self, SDL_Renderer *renderer);

void Floating_Draw_R(Object *self, SDL_Renderer *renderer);
void Floating_Draw_L(Object *self, SDL_Renderer *renderer);
void Mushroom_Draw_R(Object *self, SDL_Renderer *renderer);
void Mushroom_Draw_L(Object *self, SDL_Renderer *renderer);

void Object_Destroy(Object *object);

#endif //SUMERU_OBJECT_H

// Object.c
//
// Created by Morin on 2023/2/3.
//

#include "Object.h"
#include "Resource.h"

Object *Block_Create(float x, float y) {
    Object *b = malloc(sizeof(Object));
    b->dest.x = x;
    b->dest.y = y;
    b->dest.w = 40;
    b->dest.h = 40;
    b->speedX = 0;
    b->speedY = 0;
    return b;
}

Object *Chara_Create(float x, float y) {
    Object *c = malloc(sizeof(Object));
    c->dest.x = x;
    c->dest.y = y;
    c->dest.w = 46;
    c->dest.h = 60;
    c->speedX = 0;
    c->speedY = 0;
    return c;
}

Object *Plat_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 300;
    p->dest.h = 111;
    p->speedX = 0;
    p->speedY = 0;
    return p;
}

Object *BG_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 540;
    p->dest.h = 960;
    p->speedX = 0;
    p->speedY = 0;
    return p;
}
Object *GG_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 540;
    p->dest.h = 960;
    p->speedX = 0;
    p->speedY = 0;
    return p;
}

Object *Heart_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 28;
    p->dest.h = 28;
    p->speedX = 0;
    p->speedY = 0;
    return p;
}Object *Bullet_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 28;
    p->dest.h = 28;
    p->speedX = 0;
    p->speedY = 0;
    return p;
}


Object *Nail_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 40;
    p->dest.h = 11;
    p->speedX = 0;
    p->speedY = 0;
    return p;
}
Object *Skill_Create(float x, float y){
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 15;
    p->dest.h = 38;
    p->speedX = 0;
    p->speedY = 0;
    return p;

}

Object *Star_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 46;
    p->dest.h = 46;
    p->speedX = 0;
    p->speedY = 0;
    return p;
}
Object *Shop_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 44;
    p->dest.h = 51;
    p->speedX = 0;
    p->speedY = 0;
    return p;
}
Object *Tips_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 132;
    p->dest.h = 80;
    p->speedX = 0;
    p->speedY = 0;
    return p;
}


Object *Floating_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 60;
    p->dest.h = 52;
    p->speedX = 2;
    p->speedY = 0;
    p->HP = 2;
    return p;
}

Object *Mushroom_Create(float x, float y) {
    Object *p = malloc(sizeof(Object));
    p->dest.x = x;
    p->dest.y = y;
    p->dest.w = 40;
    p->dest.h = 40;
    p->speedX = 1;
    p->speedY = 0;
    p->HP = 2;
    return p;
}

void Block_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetBlockTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Chara_Draw_R(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetCharaTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Chara_Draw_L(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetCharaTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_HORIZONTAL
    );
}
void Plat_Draw_R(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetPlatTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Plat_Draw_L(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetPlatTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_HORIZONTAL
    );
}
void BG_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetBGTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void GG_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetGGTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}

void Heart_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetHeartTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Bullet_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetBulletTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Nail_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetNailTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Skill_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetSkillTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Floating_Draw_R(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetFloatingTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Floating_Draw_L(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetFloatingTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_HORIZONTAL
    );
}

void Mushroom_Draw_R(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetMushroomTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Mushroom_Draw_L(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetMushroomTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_HORIZONTAL
    );
}

void Star_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetStarTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Shop_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetShopTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Tips_Draw(Object *self, SDL_Renderer *renderer) {
    SDL_RenderCopyExF(
            renderer,
            Resource_GetTipsTexture(),
            NULL,
            &(self->dest),
            0,
            NULL,
            SDL_FLIP_NONE
    );
}
void Object_Destroy(Object *object) {
    free(object);
}

Resourse.hResourse.c

  • 包含使用的资源文件(如图片、字体等)信息
// Resourse.h
//
// Created by Morin on 2023/2/3.
//

#ifndef SUMERU_RESOURCE_H
#define SUMERU_RESOURCE_H

#include <SDL2/SDL.h>

int Resource_Load1(SDL_Renderer *renderer);

SDL_Texture *Resource_GetBGTexture();
SDL_Texture *Resource_GetGGTexture();
SDL_Texture *Resource_GetHeartTexture();
SDL_Texture *Resource_GetBulletTexture();
SDL_Texture *Resource_GetCharaTexture();
SDL_Texture *Resource_GetBlockTexture();
SDL_Texture *Resource_GetPlatTexture();
SDL_Texture *Resource_GetSkillTexture();
SDL_Texture *Resource_GetNailTexture();
SDL_Texture *Resource_GetStarTexture();
SDL_Texture *Resource_GetShopTexture();
SDL_Texture *Resource_GetTipsTexture();
SDL_Texture *Resource_GetFloatingTexture();
SDL_Texture *Resource_GetMushroomTexture();

void Resource_Unload();

#endif //SUMERU_RESOURCE_H
// Resource.c
//
// Created by Morin on 2023/2/3.
//

#include "Resource.h"
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>

SDL_Texture *bgTexture;
SDL_Texture *ggTexture;
SDL_Texture *heartTexture;
SDL_Texture *bulletTexture;

SDL_Texture *charaTexture;
SDL_Texture *blockTexture;
SDL_Texture *platTexture;
SDL_Texture *skillTexture;
SDL_Texture *nailTexture;
SDL_Texture *starTexture;
SDL_Texture *shopTexture;
SDL_Texture *tipsTexture;

SDL_Texture *floatingTexture;
SDL_Texture *mushroomTexture;

int Resource_Load1(SDL_Renderer *renderer) {
    bgTexture = IMG_LoadTexture(renderer, "IMAGE/bg1.png");
    ggTexture = IMG_LoadTexture(renderer, "IMAGE/gameover.png");
    heartTexture = IMG_LoadTexture(renderer, "IMAGE/heart.png");
    bulletTexture = IMG_LoadTexture(renderer,"IMAGE/bullet.png");

    charaTexture = IMG_LoadTexture(renderer, "IMAGE/lumine.png");
    blockTexture = IMG_LoadTexture(renderer, "IMAGE/block1.png");
    platTexture = IMG_LoadTexture(renderer, "IMAGE/platform1.png");
    skillTexture = IMG_LoadTexture(renderer, "IMAGE/skill.png");
    nailTexture = IMG_LoadTexture(renderer, "IMAGE/nail.png");
    starTexture = IMG_LoadTexture(renderer, "IMAGE/star.png");
    shopTexture = IMG_LoadTexture(renderer, "IMAGE/shop.png");
    tipsTexture = IMG_LoadTexture(renderer, "IMAGE/tips.png");

    floatingTexture = IMG_LoadTexture(renderer, "IMAGE/floating.png");
    mushroomTexture = IMG_LoadTexture(renderer, "IMAGE/mushroom.png");

    return 0;
}

SDL_Texture *Resource_GetBGTexture() {
    return bgTexture;
}
SDL_Texture *Resource_GetGGTexture() {
    return ggTexture;
}

SDL_Texture *Resource_GetHeartTexture() {
    return heartTexture;
}
SDL_Texture *Resource_GetBulletTexture() {
    return bulletTexture;
}

SDL_Texture *Resource_GetCharaTexture() {
    return charaTexture;
}
SDL_Texture *Resource_GetBlockTexture() {
    return blockTexture;
}
SDL_Texture *Resource_GetPlatTexture() {
    return platTexture;
}
SDL_Texture *Resource_GetSkillTexture() {
    return skillTexture;
}
SDL_Texture *Resource_GetNailTexture() {
    return nailTexture;
}
SDL_Texture *Resource_GetStarTexture() {
    return starTexture;
}
SDL_Texture *Resource_GetShopTexture() {
    return shopTexture;
}
SDL_Texture *Resource_GetTipsTexture() {
    return  tipsTexture;
}
SDL_Texture *Resource_GetFloatingTexture() {
    return floatingTexture;
}
SDL_Texture *Resource_GetMushroomTexture() {
    return mushroomTexture;
}

void Resource_Unload() {
    SDL_DestroyTexture(bgTexture);
    SDL_DestroyTexture(ggTexture);

    SDL_DestroyTexture(heartTexture);
    SDL_DestroyTexture(bulletTexture);

    SDL_DestroyTexture(charaTexture);
    SDL_DestroyTexture(blockTexture);
    SDL_DestroyTexture(platTexture);
    SDL_DestroyTexture(skillTexture);
    SDL_DestroyTexture(nailTexture);
    SDL_DestroyTexture(floatingTexture);
    SDL_DestroyTexture(starTexture);
    SDL_DestroyTexture(shopTexture);
    SDL_DestroyTexture(tipsTexture);
    SDL_DestroyTexture(mushroomTexture);
}

CMakeLists

cmake_minimum_required(VERSION 3.23)
project(Sumeru C)

set(CMAKE_C_STANDARD 99)

link_libraries(SDL2 SDL2_image SDL2_ttf)

add_executable(Sumeru WIN32 main.c Resource.c Resource.h Object.c Object.h)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值