大一上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.h
、Object.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.h
、Resourse.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)