Raylib C语言简易平台游戏报错:下标值非数组/指针/向量
解决Raylib平台游戏的编译错误与碰撞问题
编译错误原因
报错行Platform platform = platform[i];的核心问题是参数名与局部变量名重名:函数参数platform是平台数组,循环里又定义了同名局部变量platform,编译器无法区分哪个是数组,因此抛出“subscripted value is neither array nor pointer nor vector”错误。
同时还有两个隐藏问题:
- 函数内用
sizeof(platform)/sizeof(Platform)计算平台数量无效:C语言中数组作为函数参数会退化成指针,sizeof(platform)得到的是指针大小,不是数组总字节数。 main函数里重复给platforms[1]赋值,未初始化platforms[2],导致第三个平台为垃圾值。
最简修改方案(尽量少改代码)
1. 修改变量重名冲突
将循环内的局部变量名从platform改为p,避免与参数混淆。
2. 传递数组长度给碰撞函数
给ball_on_ground增加platform_count参数,传入平台数组的实际长度,替代错误的sizeof计算。
3. 修复平台初始化错误
把main里重复的platforms[1]赋值改为platforms[2],让三个平台都正常初始化。
4. 优化碰撞逻辑(避免穿模)
碰撞检测到后,将球的位置调整到平台顶部,而非仅设置速度为0,防止球陷入平台内部。
修改后的完整代码
#include "raylib.h" //------------------------------------------------------------------------------------ // Program main entry point //------------------------------------------------------------------------------------ typedef struct{ int x; int y; float size; int velocity; }Ball; typedef struct{ int x; int y; int width; int height; }Platform; // 修改:增加platform_count参数,局部变量改名p int ball_on_ground(Ball ball, Platform platform[], int platform_count){ for(int i=0; i < platform_count; i++){ Platform p = platform[i]; Rectangle platform_rec = {.x = p.x, .y = p.y, .width = p.width, .height = p.height}; Vector2 ball_position = {.x = ball.x, .y = ball.y}; if (CheckCollisionCircleRec(ball_position, ball.size, platform_rec)){ return 1; } } return 0; } int main(){ int width = 800; int height = 600; Ball ball = { .x = width/2, .y = height/2, .size = 40.0, .velocity = 4 }; int gravity = 2; Platform platforms[3]; platforms[0].x = 0; platforms[0].y = height-10; platforms[0].width = width; platforms[0].height = 10; platforms[1].x = abs(width*0.1); platforms[1].y = abs(height*0.7); platforms[1].width = abs(width*0.3); platforms[1].height = abs(height *0.05); // 修改:修复重复赋值,初始化platforms[2] platforms[2].x = abs(width*0.6); platforms[2].y = abs(height*0.4); platforms[2].width = abs(width*0.3); platforms[2].height = abs(height *0.05); InitWindow( width, height, "MyGame" ); SetTargetFPS( 60 ); // 提前计算平台数量,避免重复计算 int platform_count = sizeof(platforms)/sizeof(Platform); while(!WindowShouldClose()){ BeginDrawing(); // 修改:传入platform_count参数 if(ball_on_ground(ball, platforms, platform_count)){ ball.velocity = 0; // 修改:把球的位置调整到平台顶部,避免穿模 for(int i=0; i<platform_count; i++){ Platform p = platforms[i]; Rectangle rec = {.x=p.x, .y=p.y, .width=p.width, .height=p.height}; if(CheckCollisionCircleRec((Vector2){ball.x, ball.y}, ball.size, rec)){ ball.y = p.y - ball.size; break; } } if(IsKeyPressed(KEY_SPACE)){ ball.velocity = -30; } } if(IsKeyDown(KEY_LEFT)){ ball.x -= 6; } if(IsKeyDown(KEY_RIGHT)){ ball.x += 6; } ball.y += ball.velocity; ball.velocity += gravity; ClearBackground(WHITE); for(int i=0; i < platform_count; i++){ DrawRectangle(platforms[i].x,platforms[i].y,platforms[i].width,platforms[i].height,BLACK); } DrawCircle(ball.x, ball.y , ball.size, BLUE); EndDrawing(); } return 0; }
修改效果说明
- 编译错误彻底解决,代码可正常运行。
- 球碰到平台后会停在顶部,不会陷入平台内部,按空格键可正常跳跃。
- 三个平台均正常显示,无垃圾值平台。
内容的提问来源于stack exchange,提问作者Jitesh
相关产品推荐
相关产品推荐

