【C语言/SDL2】大一上期中项目 Chrome小恐龙 (划掉) 小猫飞行中

初学编程,代码屎山,仅供参考。

主函数中的一些操作可以适当用函数块代替,减少代码复杂度。

在该项目中没有使用渲染器,直接用的BlitSurface。但还是建议大家使用renderer。

参考教程:www.bilibili.com/video/BV1rK411V7eu

游戏演示:www.bilibili.com/video/BV1r84y1s7Gf

试玩版:https://pan.baidu.com/s/1GlOw62K8ZVM8-gtsBCBgHg 提取码:1919

#define _CRT_SECURE_NO_WARNINGS
#define SDL_MAIN_HANDLED
 
#include <stdio.h>
#include <stdlib.h>
#include "SDL2/SDL.h"
#include "SDL2/SDL_image.h"
#include "SDL2/SDL_ttf.h"
 
#define WIDTH 1280
#define HEIGHT 720
#define FONT_SIZE 35
 
 
// 图片
struct SDL_Surface* background;
struct SDL_Surface* cat_1, * cat_2, * cat_flag;
struct SDL_Surface* obstacle_1, * obstacle_2;
// 字体
SDL_Color color = { 0, 0, 0, 255 };
TTF_Font* font;
TTF_Font* font_gameover;
 
int score = 1, plus = 1; // 得分
int speed = 7;
 
int temp_score, temp_plus, temp_speed;
 
int ret1; // 随机数生成
 
int x_cat = 130, y_cat = 350;
int x_ob = 1920, y_ob1 = 450, y_ob2 = 300;
int x_bg = 0;
 
int start = 0;
 
void draw_bg(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win);
void draw_cat(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win);
void draw_catflag(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win);
void draw_ob1(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win);
void draw_ob2(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win);
 
void PrintInfo_Start(TTF_Font* font, SDL_Surface* screen, SDL_Window* win);
void PrintInfo_End(SDL_Surface* screen, SDL_Window* win);
void PrintInfo_Restart(TTF_Font* font, SDL_Surface* screen, SDL_Window* win);
void PrintInfo_Pause(TTF_Font* font, SDL_Surface* screen, SDL_Window* win);
void print_score(TTF_Font* font, SDL_Surface* screen, SDL_Window* win);
void print_score_end(TTF_Font* font, SDL_Surface* screen, SDL_Window* win);
 
void draw_screen1(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win);
void draw_screen2(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win);
void draw_gameover(SDL_Surface* screen, SDL_Window* win);
 
void end();
 
int main(int argc, char* argv[])
{
 
    ret1 = rand() % 10 + 1; //障碍物随机数.
    float x0 = x_cat, y0 = y_cat;
 
    // 图片
    cat_1 = IMG_Load("IMAGE/cat_1.png");
    cat_2 = IMG_Load("IMAGE/cat_2.png");
    cat_flag = IMG_Load("IMAGE/cat_flag.png");
    obstacle_1 = IMG_Load("IMAGE/obstacle_1.png");
    obstacle_2 = IMG_Load("IMAGE/obstacle_2.png");
    background = IMG_Load("IMAGE/background.png");
    // 字体
    TTF_Init();
    font = TTF_OpenFont("TTF/Minecraft.ttf", 35);
    font_gameover = TTF_OpenFont("TTF/Minecraft.ttf", 60);
 
 
    if (font == NULL) {
        SDL_Log("Can not open font");
        return 1;
    }
    if (TTF_Init()) {
        SDL_Log("Can not init ttf, %s", TTF_GetError());
        return 1;
    }
 
    SDL_Window* win = SDL_CreateWindow(
        "Cat, cat, I really surrendered.", // 窗口标题
        SDL_WINDOWPOS_CENTERED,
        SDL_WINDOWPOS_CENTERED, WIDTH, HEIGHT,
        SDL_WINDOW_SHOWN);
    if (win == NULL) {
        SDL_Log("Can not create window, %s", SDL_GetError());
        return 2;
    }
 
 
    struct SDL_Surface* screen = SDL_GetWindowSurface(win);
 
    while (1) {
        if (start == 0) {
            draw_bg(background, screen, win);
            draw_cat(cat_1, screen, win);
            PrintInfo_Start(font, screen, win);
            SDL_UpdateWindowSurface(win);
            SDL_Delay(50);
        }
        if (start == 1) {
            if (score >= 5000 && speed == 7) {
                speed += 2;
                plus *= 2;
            }
            else if (score >= 15000 && speed == 9) {
                speed += 2;
                plus *= 2;
            }
            else if (score >= 50000 && speed == 11) {
                speed += 2;
                plus *= 2;
            }
            draw_screen1(cat_1, screen, win);
        }
        if (start == 2) {
            draw_gameover(screen, win);
        }
        SDL_Event event;
    UP:
        if (SDL_PollEvent(&event)) {
            if (start == 0 && event.type == SDL_KEYDOWN) {
                switch (event.key.keysym.sym) {
                case SDLK_SPACE:
                    start = 1;
                    break;
                }
            }
            else if (start == 1 && event.type == SDL_KEYDOWN) {
                switch (event.key.keysym.sym) {
                case SDLK_UP:
                    for (int t = 1; t <= 72; t++) {
                        float a = 0.5, v = -18;
                        float h = 0;
                        h = v * t + 0.5 * a * t * t;
                        y_cat = y0 + h;
                        draw_screen1(cat_1, screen, win);
                        if (start == 2)
                            break;
                        if (SDL_PollEvent(&event) && event.type == SDL_KEYDOWN) {
                            switch (event.key.keysym.sym) {
                            case SDLK_1:
                            {
                                PrintInfo_Pause(font, screen, win);
                                SDL_UpdateWindowSurface(win);
                                while (1)
                                {
                                    SDL_Delay(20);
                                    if (SDL_PollEvent(&event) && event.type == SDL_KEYDOWN)
                                        switch (event.key.keysym.sym)
                                        {
                                        case SDLK_1:
                                            goto CONTINUE2;
                                        }
                                    if (event.type == SDL_QUIT)
                                        goto END;
                                }
                            CONTINUE2:;
                            }
                            }
                        }
                    }
                    break;
                case SDLK_SPACE:
                    for (int t = 1; t <= 72; t++) {
                        float a = 0.5, v = -18;
                        float h = 0;
                        h = v * t + 0.5 * a * t * t;
                        y_cat = y0 + h;
                        if (start == 2)
                            break;
                        if (SDL_PollEvent(&event) && event.type == SDL_KEYDOWN) {
                            switch (event.key.keysym.sym) {
                            case SDLK_1:
                            {
                                PrintInfo_Pause(font, screen, win);
                                SDL_UpdateWindowSurface(win);
                                while (1)
                                {
                                    SDL_Delay(20);
                                    if (SDL_PollEvent(&event) && event.type == SDL_KEYDOWN)
                                        switch (event.key.keysym.sym)
                                        {
                                        case SDLK_1:
                                            goto CONTINUE3;
                                        }
                                    if (event.type == SDL_QUIT)
                                        goto END;
                                }
                            CONTINUE3:;
                            }
                            }
                        }
                        draw_screen1(cat_1, screen, win);
                    }
                    break;
                case SDLK_DOWN: {
                    while (1) {
                        if (start == 2)
                            break;
                        if (SDL_PollEvent(&event) && event.type == SDL_KEYUP)
                            switch (event.key.keysym.sym) {
                            case SDLK_DOWN: {
                                goto UP;
                            }
                            }
                        else if (event.type == SDL_KEYDOWN) {
                            switch (event.key.keysym.sym) {
                            case SDLK_1:
                            {
                                PrintInfo_Pause(font, screen, win);
                                SDL_UpdateWindowSurface(win);
                                while (1)
                                {
                                    SDL_Delay(20);
                                    if (SDL_PollEvent(&event) && event.type == SDL_KEYDOWN)
                                        switch (event.key.keysym.sym)
                                        {
                                        case SDLK_1:
                                            goto UP;
                                        }
                                    if (event.type == SDL_QUIT)
                                        goto END;
                                }
                            }
                            }
                        }
                        draw_screen2(cat_2, screen, win);
                    }
                }
                              break;
                case SDLK_1: {
                    PrintInfo_Pause(font, screen, win);
                    SDL_UpdateWindowSurface(win);
                    while (1) {
                        SDL_Delay(20);
                        if (SDL_PollEvent(&event) && event.type == SDL_KEYDOWN)
                            switch (event.key.keysym.sym) {
                            case SDLK_1:
                                goto CONTINUE1;
                            }
                        if (event.type == SDL_QUIT)
                            goto END;
                    }
                CONTINUE1:;
                }
                }
            }
            else if (start == 2 && event.type == SDL_KEYDOWN) {
                switch (event.key.keysym.sym) {
                case SDLK_SPACE: {
                    start = 0;
                    score = 1, plus = 1;
                    speed = 7;
                    x_cat = 130, y_cat = 350;
                    x_ob = 1920, y_ob1 = 450;
                    x_bg = 0;
                }
                }
            }
 
            if (event.type == SDL_QUIT) {
                break;
            }
        }
    }
 
END:
    SDL_FreeSurface(background);
    SDL_FreeSurface(cat_1), SDL_FreeSurface(cat_2), SDL_FreeSurface(cat_flag);
    SDL_FreeSurface(obstacle_1), SDL_FreeSurface(obstacle_2);
    TTF_CloseFont(font), TTF_CloseFont(font_gameover);
    SDL_FreeSurface(screen);
    SDL_DestroyWindow(win);
 
    return 0;
}
 
void draw_bg(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win) {
    SDL_Rect src1 = { x_bg, 0, img->w, img->h };          // 捕获图片区域1
    SDL_Rect src2 = { 0, 0, x_bg, img->h };               // 捕获图片区域2
    SDL_Rect put1 = { 0, 0, img->w - x_bg, img->h };      // 显示区域1
    SDL_Rect put2 = { img->w - x_bg, 0, img->w, img->h }; // 显示区域2
    SDL_BlitSurface(img, &src1, screen, &put1);
    SDL_BlitSurface(img, &src2, screen, &put2);
    // SDL_UpdateWindowSurface(win);
}
 
void draw_cat(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win) {
    SDL_Rect get_image = { 0, 0, img->w, img->h };
    SDL_Rect put_screen = { x_cat, y_cat, x_cat + img->w, y_cat + img->h };
    SDL_BlitSurface(img, &get_image, screen, &put_screen);
}
 
void draw_catflag(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win) {
    SDL_Rect get_image = { 0, 0, img->w, img->h };
    SDL_Rect put_screen = { 500, 280, 600 + img->w, 280 + img->h };
    SDL_BlitSurface(img, &get_image, screen, &put_screen);
}
 
void draw_ob1(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win) {
    SDL_Rect get_image = { 0, 0, img->w, img->h };
    SDL_Rect put_screen = { x_ob, y_ob1, x_ob + img->w, y_ob1 + img->h };
    SDL_BlitSurface(img, &get_image, screen, &put_screen);
}
void draw_ob2(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win) {
    SDL_Rect get_image = { 0, 0, img->w, img->h };
    SDL_Rect put_screen = { x_ob, y_ob2, x_ob + img->w, y_ob2 + img->h };
    SDL_BlitSurface(img, &get_image, screen, &put_screen);
}
 
void PrintInfo_Start(TTF_Font* font, SDL_Surface* screen, SDL_Window* win) {
    struct SDL_Surface* text = TTF_RenderUTF8_Blended(font, "Press 'SPACE' to start !", color);
    SDL_Rect src = { 0, 0, text->w, text->h };
    SDL_Rect put_screen = { 100, 100, 100 + text->w, 100 + text->h };
    SDL_BlitSurface(text, &src, screen, &put_screen);
    SDL_FreeSurface(text);
}
void PrintInfo_End(SDL_Surface* screen, SDL_Window* win) {
    char s[10086] = { 0 };
    sprintf(s, "SCORE : %d", score);
    struct SDL_Surface* text = TTF_RenderUTF8_Blended(font_gameover, "G A M E   O V E R", color);
 
    SDL_Rect src = { 0, 0, text->w, text->h };
    SDL_Rect put_screen = { 350, 150, 350 + text->w, 150 + text->h };
    SDL_BlitSurface(text, &src, screen, &put_screen);
    SDL_FreeSurface(text);
}
void PrintInfo_Restart(TTF_Font* font, SDL_Surface* screen, SDL_Window* win) {
    struct SDL_Surface* text = TTF_RenderUTF8_Blended(font, "Press 'SPACE' to restart !", color);
    SDL_Rect src = { 0, 0, text->w, text->h };
    SDL_Rect put_screen = { 350, 550, 350 + text->w, 550 + text->h };
    SDL_BlitSurface(text, &src, screen, &put_screen);
    SDL_FreeSurface(text);
}
void PrintInfo_Pause(TTF_Font* font, SDL_Surface* screen, SDL_Window* win) {
    struct SDL_Surface* text = TTF_RenderUTF8_Blended(font, "Press '1' to continue !", color);
    SDL_Rect src = { 0, 0, text->w, text->h };
    SDL_Rect put_screen = { 720, 150, 720 + text->w, 150 + text->h };
    SDL_BlitSurface(text, &src, screen, &put_screen);
    SDL_FreeSurface(text);
}
 
void print_score(TTF_Font* font, SDL_Surface* screen, SDL_Window* win) {
    char s[10086] = { 0 };
    sprintf(s, "SCORE : %d", score);
    struct SDL_Surface* text = TTF_RenderUTF8_Blended(font, s, color);
    SDL_Rect src = { 0, 0, text->w, text->h };
    SDL_Rect put_screen = { 900, 50, 50 + text->w, 50 + text->h };
    SDL_BlitSurface(text, &src, screen, &put_screen);
    SDL_FreeSurface(text);
}
 
void print_score_end(TTF_Font* font, SDL_Surface* screen, SDL_Window* win) {
    char s[10086] = { 0 };
    sprintf(s, "SCORE : %d", score);
    struct SDL_Surface* text = TTF_RenderUTF8_Blended(font, s, color);
    SDL_Rect src = { 0, 0, text->w, text->h };
    SDL_Rect put_screen = { 350, 225, 350 + text->w, 225 + text->h };
    SDL_BlitSurface(text, &src, screen, &put_screen);
    SDL_FreeSurface(text);
}
 
 
void end() {
    speed = 0, plus = 0, start = 2;
    ret1 = rand() % 100 + 1;
    SDL_Delay(600);
}
 
void draw_screen1(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win)
{
    if (x_bg >= 1280) {
        x_bg = 0;
    }
    if (x_ob <= -100) {
        x_ob = 1680;
        ret1 = rand() % 100 + 1;
    }
 
    x_bg += speed, x_ob -= speed;
    score += plus;
 
    draw_bg(background, screen, win);
    draw_cat(img, screen, win);
    if (ret1 <= 80)
        draw_ob1(obstacle_1, screen, win);
    else if (ret1 > 80)
        draw_ob2(obstacle_2, screen, win);
    print_score(font, screen, win);
 
    if (start == 1) {
        SDL_UpdateWindowSurface(win);
        SDL_Delay(5);
    }
 
    if (ret1 <= 80
        && x_ob + obstacle_1->w >= x_cat + 80
        && x_ob <= x_cat + 150
        && y_ob1 <= y_cat + 220) {
        end();
    }
    else if (ret1 > 80
        && x_ob + obstacle_2->w >= x_cat + 75
        && x_ob <= x_cat + 140
        && y_ob2 + obstacle_2->h >= y_cat + 30
        && y_ob2 <= y_cat + 223) {
        end();
    }
 
}
void draw_screen2(SDL_Surface* img, SDL_Surface* screen, SDL_Window* win)
{
    if (x_bg >= 1280) {
        x_bg = 0;
    }
    if (x_ob <= -100) {
        x_ob = 1680;
        ret1 = rand() % 100 + 1;
    }
 
    x_bg += speed, x_ob -= speed;
    score += plus;
 
    draw_bg(background, screen, win);
    draw_cat(img, screen, win);
    if (ret1 <= 80)
        draw_ob1(obstacle_1, screen, win);
    else if (ret1 > 80)
        draw_ob2(obstacle_2, screen, win);
    print_score(font, screen, win);
 
    if (start == 1) {
        SDL_UpdateWindowSurface(win);
        SDL_Delay(5);
    }
 
    if (ret1 <= 80
        && x_ob + obstacle_1->w >= x_cat + 80
        && x_ob <= x_cat + 220
        && y_ob1 <= y_cat + 110) {
        end();
    }
}
 
void draw_gameover(SDL_Surface* screen, SDL_Window* win) {
 
    SDL_Surface* screen0 = SDL_GetWindowSurface(win);
    SDL_Rect r = { 0, 0, WIDTH, HEIGHT };
    SDL_FillRect(screen0, &r, 0xffffffff);
    // 绘制矩形背景板,ARGB
 
    draw_catflag(cat_flag, screen, win);
    PrintInfo_End(screen, win);
    print_score_end(font, screen, win);
    PrintInfo_Restart(font, screen, win);
 
    SDL_UpdateWindowSurface(win);
    SDL_Delay(20);
}
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值