Skip to content

Commit

Permalink
add comments
Browse files Browse the repository at this point in the history
  • Loading branch information
dimweak authored and Dimweaker committed Apr 18, 2023
1 parent 50dc1dc commit ecaef71
Show file tree
Hide file tree
Showing 14 changed files with 283 additions and 197 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ set(SDL2_DIR D:/CLion 2022.1.3/bin/mingw/x86_64-w64-mingw32)
include_directories(${SDL2_DIR}/include)
link_directories(${SDL2_DIR}/bin)

add_executable(parkour main.c Rect_Queue.c Rect_Queue.h parameter.h load_resource.c load_resource.h Player_Action.c Player_Action.h Monster_Model.c Monster_Model.h collision.c collision.h score.c score.h record.c record.h)
add_executable(parkour main.c Rect_Queue.c Rect_Queue.h parameter.h Player_Action.c Player_Action.h Monster_Model.c Monster_Model.h collision.c collision.h score.c score.h record.c record.h)

target_link_libraries(parkour mingw32 SDL2main SDL2 SDL2_image SDL2_ttf)

25 changes: 19 additions & 6 deletions Monster_Model.c
Original file line number Diff line number Diff line change
@@ -1,15 +1,28 @@
#include "Monster_Model.h"

void Destroy_Monster_Model(MonsterModel* model){
SDL_DestroyTexture(model->texture);
SDL_FreeSurface(model->surface);
/**
* 释放怪物模型的内存
* @param model 怪物模型的指针
* @param n 该模型怪物的类型数量
*/
void Destroy_Monster_Model(MonsterModel* model, int n){
int i;
for(i = 0; i < n; i++){
SDL_DestroyTexture(model->texture[i]);
SDL_FreeSurface(model->surface[i]);
}
free(model);
}

/**
* 绘制怪物
* @param renderer 窗口的渲染器
* @param model 怪物模型的数组
* @param node 怪物的位置信息
*/
void Draw_Monster_Model(SDL_Renderer* renderer, MonsterModel* model[], RectNode* node){
int monster_type = node->rect_type;

int monster_type = node->rect_type, monster = node->monster;
SDL_Rect rect = node->rect;
SDL_RenderCopy(renderer, model[monster_type]->texture, NULL, &rect);
SDL_RenderCopy(renderer, model[monster_type]->texture[monster], NULL, &rect);
}

11 changes: 6 additions & 5 deletions Monster_Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
#include "Rect_Queue.h"
#ifndef PARKOUR_MONSTER_MODEL_H
#define PARKOUR_MONSTER_MODEL_H
#define MAX_TYPE 3

/* 怪物模型,用于存储怪物的texture和surface */
typedef struct MonsterModel{
SDL_Rect rect;
SDL_Texture* texture;
SDL_Surface* surface;
SDL_Texture* texture[MAX_TYPE];
SDL_Surface* surface[MAX_TYPE];
}MonsterModel;

void Destroy_Monster_Model(MonsterModel* model);
void Destroy_Monster_Model(MonsterModel* model, int n);
void Draw_Monster_Model(SDL_Renderer* renderer, MonsterModel* model[], RectNode* node);

#endif
27 changes: 25 additions & 2 deletions Player_Action.c
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
#include "Player_Action.h"

/**
* 创建一个PlayerAction结构体
* @return 一个PlayerAction结构体
*/
PlayerAction* Create_Player_Action(){
PlayerAction* action = (PlayerAction*)malloc(sizeof(PlayerAction));
return action;
}

/**
* 设置PlayerAction的surface
* @param action PlayerAction结构体指针
* @param path_format 路径格式
*/
void Set_Player_Action_Surface(PlayerAction* action, char* path_format){
int i;
for(i = 0; i < (action->nums_of_frames); i++) {
char path[100];
sprintf(path, path_format, i+1);
action->surface[i] = IMG_Load(path);
sprintf(path, path_format, i+1); /* 格式化路径 */
action->surface[i] = IMG_Load(path); /* 加载图片 */
}
}

/**
* 设置PlayerAction的texture
* @param action PlayerAction结构体指针
* @param renderer 窗口的渲染器
*/
void Set_Player_Action_Texture(PlayerAction* action, SDL_Renderer* renderer){
int i;
for(i = 0; i < action->nums_of_frames; i++) {
action->texture[i] = SDL_CreateTextureFromSurface(renderer, action->surface[i]);
}
}

/**
* 销毁PlayerAction结构体
* @param action PlayerAction结构体指针
*/
void Destroy_Player_Action(PlayerAction* action){
int i;
for(i = 0; i < action->nums_of_frames; i++) {
Expand All @@ -31,6 +49,11 @@ void Destroy_Player_Action(PlayerAction* action){

}

/**
* 绘制PlayerAction
* @param renderer 窗口的渲染器
* @param action PlayerAction结构体指针
*/
void Draw_Player_Action(SDL_Renderer* renderer, PlayerAction* action){
int frame = action->current_frame;

Expand Down
13 changes: 7 additions & 6 deletions Player_Action.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,18 @@
#ifndef PARKOUR_PLAYER_ACTION_H
#define PARKOUR_PLAYER_ACTION_H
#define MAX_FRAMES 60
/* 玩家动作,用于存储玩家动作的帧数、位置、texture和surface */
typedef struct PlayerAction{
int nums_of_frames;
int current_frame;
SDL_Rect rect;
SDL_Texture* texture[MAX_FRAMES];
SDL_Surface* surface[MAX_FRAMES];
int nums_of_frames; /* 动作的总帧数 */
int current_frame; /* 当前帧 */
SDL_Rect rect; /* 动作的位置 */
SDL_Texture* texture[MAX_FRAMES]; /* 动作的texture */
SDL_Surface* surface[MAX_FRAMES]; /* 动作的surface */
}PlayerAction;

PlayerAction* Create_Player_Action();
void Set_Player_Action_Texture(PlayerAction* action, SDL_Renderer* renderer);
void Set_Player_Action_Surface(PlayerAction* action, char* path_format);
void Destroy_Player_Action(PlayerAction* action);
void Draw_Player_Action(SDL_Renderer* renderer, PlayerAction* action);
#endif //PARKOUR_PLAYER_ACTION_H
#endif
73 changes: 60 additions & 13 deletions Rect_Queue.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,55 @@
#include <stdlib.h>
#include "Rect_Queue.h"

/**
* 初始化队列
* @return 返回一个队列的指针
*/
RectQueue* InitRectQueue() {
RectQueue* queue = (RectQueue*)malloc(sizeof(RectQueue));
queue->front = queue->rear = NULL;
queue->size = 0;
return queue;
}

void EnRectQueue(RectQueue* queue, SDL_Rect rect, int rect_type) {
/**
* 入队
* @param queue 队列的指针
* @param rect 怪物的位置
* @param rect_type 怪物的种类
* @param monster 怪物的类型
*/
void EnRectQueue(RectQueue* queue, SDL_Rect rect, int rect_type, int monster) {
RectNode* node = (RectNode*)malloc(sizeof(RectNode));
node->rect = rect;
node->rect_type = rect_type;
node->is_passed = 0;
node->next = NULL;
node->monster = monster;

if(queue->rear == NULL) {
node->rect_index = 0;
queue->front = queue->rear = node;
} else {
}
else {
node->rect_index = queue->rear->rect_index + 1;
queue->rear->next = node;
queue->rear = node;
}
queue->size++;
}

/**
* 出队
* @param queue 队列的指针
* @return 返回一个怪物节点的指针
*/
RectNode* DeRectQueue(RectQueue* queue) {
if(queue->front == NULL) {
printf("Error: DeRectQueue() failed, queue is empty");
exit(1);
}
RectNode* node = queue->front;
SDL_Rect rect = node->rect;
queue->front = node->next;
if(queue->front == NULL) {
queue->rear = NULL;
Expand All @@ -41,6 +59,10 @@ RectNode* DeRectQueue(RectQueue* queue) {
return node;
}

/**
* 销毁队列
* @param queue 队列的指针
*/
void DestroyRectQueue(RectQueue* queue) {
while(queue->front != NULL) {
RectNode* node = queue->front;
Expand All @@ -50,20 +72,27 @@ void DestroyRectQueue(RectQueue* queue) {
free(queue);
}

/**
* 创建怪物队列,生成初始怪物的节点
* @param queue
*/
void CreateMonsterRectQueue(RectQueue* queue){
int i, rect_type;
int i, rect_type, monster;
for(i = 0; i < NUMS_OF_MONSTER; i++) {
rect_type = rand() % 2;
rect_type = rand() % 2; /* 随机生成怪物的种类 */
monster = random_monster(rect_type); /* 随机生成怪物的类型 */

/* 根据怪物的种类和类型,生成怪物的位置 */
switch (rect_type) {
case MONSTER_GROUND:
EnRectQueue(queue,
(SDL_Rect) {500 + i * 400, MONSTER_GROUND_Y, MONSTER_GROUND_WIDTH, MONSTER_GROUND_HEIGHT},
rect_type);
rect_type, monster);
break;
case MONSTER_AIR:
EnRectQueue(queue,
(SDL_Rect) {500 + i * 400, MONSTER_AIR_Y, MONSTER_AIR_WIDTH, MONSTER_AIR_HEIGHT},
rect_type);
rect_type, monster);
break;
default:
printf("error type");
Expand All @@ -72,27 +101,45 @@ void CreateMonsterRectQueue(RectQueue* queue){
}
}

/**
* 填充怪物队列,生成新的怪物节点
* @param queue
*/
void FillMonsterRectQueue(RectQueue* queue){
int rect_type, rand_distance_x, rand_distance_y;
rect_type = rand() % 10 < 8 ? MONSTER_GROUND : MONSTER_AIR;
rand_distance_x = rand() % 150 - 40;
rand_distance_y = rand() % 30 - 15;
int rect_type, rand_distance_x, rand_distance_y, monster;
rect_type = rand() % 10 < 8 ? MONSTER_GROUND : MONSTER_AIR; /* 随机生成怪物的种类,以0.8的概率生成地面怪物,0.2的概率生成空中怪物 */
rand_distance_x = rand() % 150 - 40; /* 随机生成怪物的x坐标偏移量 */
rand_distance_y = rand() % 30 - 15; /* 随机生成怪物的y坐标偏移量 */
monster = random_monster(rect_type); /* 随机生成怪物的类型 */

/* 根据怪物的种类和类型,生成怪物的位置 */
switch (rect_type) {
case MONSTER_GROUND:
EnRectQueue(queue,
(SDL_Rect) {500 + rand_distance_x, MONSTER_GROUND_Y + rand_distance_y, MONSTER_GROUND_WIDTH, MONSTER_GROUND_HEIGHT},
rect_type);
rect_type, monster);
break;
case MONSTER_AIR:
EnRectQueue(queue,
(SDL_Rect) {500 + rand_distance_x, MONSTER_AIR_Y + rand_distance_y, MONSTER_AIR_WIDTH, MONSTER_AIR_HEIGHT},
rect_type);
rect_type, monster);
break;

default:
printf("error type");
}
}

/**
* 随机生成怪物的类型
* @param monster_type 怪物的种类
* @return 返回怪物的类型
*/
int random_monster(int monster_type){
int monster, n;
n = monster_type == MONSTER_GROUND ? GROUND_TYPE : AIR_TYPE;
monster = rand() % n;
return monster;
}


47 changes: 41 additions & 6 deletions collision.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
#include "collision.h"

/**
* 获取指定(x,y)坐标的像素值
* @param surface 获取像素值的目标surface
* @param x 像素的x坐标
* @param y 像素的y坐标
* @return 指定位置的像素值(Uint32)
*/
Uint32 get_pixel(SDL_Surface* surface, int x, int y) {
int bpp = surface->format->BytesPerPixel;
Uint8* p = (Uint8*)surface->pixels + y * surface->pitch + x * bpp;

int bpp = surface->format->BytesPerPixel; /* 每个像素的字节数 */
Uint8* p = (Uint8*)surface->pixels + y * surface->pitch + x * bpp; /* 指向目标像素的指针 */

/* 根据不同的像素格式,进行不同的位运算 */
switch (bpp) {
case 1:
return *p;
Expand All @@ -17,33 +27,58 @@ Uint32 get_pixel(SDL_Surface* surface, int x, int y) {
}
}

/**
* 两个矩形的碰撞检测
* @param rect1 矩形1的位置
* @param surface1 矩形1的surface
* @param rect2 矩形2的位置
* @param surface2 矩形2的surface
* @return 是否相撞,1为相撞,0为不相撞
*/
int CollisionDetect(SDL_Rect rect1, SDL_Surface* surface1, SDL_Rect rect2, SDL_Surface* surface2){
SDL_Rect intersect_rect;

SDL_Rect intersect_rect; /* 两个矩形的交集矩形 */
Uint8 alpha1, alpha2, red1, red2, green1, green2, blue1, blue2; /* 两个矩形的像素的RGBA值 */

/* 如果两个矩形相交 */
if(SDL_IntersectRect(&rect1, &rect2, &intersect_rect)==SDL_TRUE) {
int x, y;

for(y = intersect_rect.y; y < intersect_rect.y + intersect_rect.h; y++) {
for(x = intersect_rect.x; x < intersect_rect.x + intersect_rect.w; x++) {
/* 获取两个矩形的交集矩形中的每个像素 */
Uint32 pixel1 = get_pixel(surface1, x - rect1.x, y - rect1.y);
Uint32 pixel2 = get_pixel(surface2, x - rect2.x, y - rect2.y);
Uint8 alpha1, alpha2, red1, red2, green1, green2, blue1, blue2;

/* 获取像素的RGBA值 */
SDL_GetRGBA(pixel1, surface1->format, &red1, &green1, &blue1, &alpha1);
SDL_GetRGBA(pixel2, surface2->format, &red2, &green2, &blue2, &alpha2);

/* 如果两个像素的alpha值都不为0,则两个矩形相交 */
if(alpha1 != 0 && alpha2 != 0) {
return 1;
}
}
}
}
/* 如果两个矩形不相交 */
else{
return 0;
}
}

/**
* 玩家与怪物的碰撞检测
* @param action 玩家的动作
* @param state 玩家的状态
* @param model 怪物的模型
* @param node 怪物的位置
* @return 是否相撞,1为相撞,0为不相撞
*/
int CollisionDetectPlayerMonster(PlayerAction* action[], int state, MonsterModel* model[], RectNode* node){
int monster_type = node->rect_type;
int monster_type = node->rect_type, monster = node->monster;
SDL_Rect rect = node->rect;
SDL_Surface* surface = model[monster_type]->surface;
SDL_Surface* surface = model[monster_type]->surface[monster];
SDL_Rect player_rect = action[state]->rect;
SDL_Surface* player_surface = action[state]->surface[action[state]->current_frame];
return CollisionDetect(player_rect, player_surface, rect, surface);
Expand Down
Loading

0 comments on commit ecaef71

Please sign in to comment.