You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 08:04:59