首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >二维Raylib纹理碰撞

二维Raylib纹理碰撞
EN

Stack Overflow用户
提问于 2022-03-10 00:15:16
回答 1查看 984关注 0票数 0

我在想如何正确处理雷利卜的碰撞。设置基础之后,比如窗口,我首先加载播放器的纹理,如下所示:

代码语言:javascript
复制
Texture2D playerTexture = LoadTexture("Player.png");

在此之后,我将绘制纹理,使用Raylib函数DrawTextureEx,它允许我调整纹理的旋转和比例。然后,我会为玩家添加一个简单的移动脚本,这差不多就是了。

至于碰撞,我只是在一个矩形上测试玩家的碰撞。要获得矩形的面积,我只需创建一个简单的矩形结构,如下所示:

代码语言:javascript
复制
Rectangle rect1 = {100, 100, 50, 50};

至于进入球员区,我会做一些类似的事情:

代码语言:javascript
复制
Rectangle playerArea = {player.x, player.y, playerTexture.width*player.scale, playerTexture.height*player.scale} //Values are stored in Player struct

然而,当我试着检查像这样的结肠时,什么都没有发生:

代码语言:javascript
复制
    if (CheckCollisionRecs(playerArea, rect1)) {
        DrawText("Collided", 5, 5, 25, BLACK);
    }

这是我的完整代码,如果需要的话:

代码语言:javascript
复制
#include "raylib.h"
#include <stdio.h>
#include <stdlib.h>

#define WIDTH 1200 
#define HEIGHT 800

typedef struct {
    const int width;
    const int height;
    int FPS;
} Window;

Window window = {
    .FPS = 60,
};

typedef struct {
    Vector2 pos;
    Vector2 acc;
    Vector2 vel;
    int width;
    int height;

    double accSpeed;
    int maxVel;
    double friction;
    double rotation;
    double scale;

} Player;

Player player = {

    .pos = {WIDTH/2, HEIGHT/2},
    .acc = {0, 0},
    .vel = {0, 0},
    .width = 25,
    .height = 25,

    .accSpeed = 0.15,
    .maxVel = 7,
    .friction = 0.2,
    .rotation = 0,
    .scale = 0.5,
};

void movePlayer();
int rectCollide();

int main() {

    InitWindow(WIDTH, HEIGHT, "Window");
    SetTargetFPS(window.FPS);

    Texture2D playerImg = LoadTexture("Player.png");

    Rectangle playerArea = {player.pos.x, player.pos.y, playerImg.width*player.scale, playerImg.height*player.scale};
    Rectangle rect1 = {100, 100, 50, 50};

    Camera2D camera = { 0 };
    camera.target = (Vector2){ player.pos.x + 20.0f, player.pos.y + 20.0f };
    camera.offset = (Vector2){WIDTH/2.0f, HEIGHT/2.0f };
    camera.rotation = 0.0f;
    camera.zoom = 1.0f;

    if (CheckCollisionRecs(playerArea, rect1)) {
        DrawText("Collided", 5, 5, 25, BLACK);
    }

    while (!WindowShouldClose()) {

        BeginDrawing();
        ClearBackground(SKYBLUE);

        movePlayer();

        camera.target = (Vector2){ player.pos.x + 20, player.pos.y + 20 };

        BeginMode2D(camera);
        DrawRectangle(100, 100, 50, 50, BLACK);
        DrawTextureEx(playerImg, player.pos, player.rotation, player.scale, RAYWHITE);
        
        EndMode2D();

        EndDrawing();
    }
    UnloadTexture(playerImg);

    CloseWindow();

    return 0;
}

void movePlayer() {
    if (IsKeyDown(KEY_LEFT) && player.vel.x > -player.maxVel) {
        player.acc.x = -player.accSpeed;
    } else if (IsKeyDown(KEY_RIGHT) && player.vel.x < player.maxVel) {
        player.acc.x = player.accSpeed;
    } else if (abs(player.vel.x) > 0.2) {
        if (player.vel.x < 0) {
            player.acc.x = player.friction;
        } else {
            player.acc.x = -player.friction;
        }
    } else {
        player.vel.x = 0;
        player.acc.x = 0;
    }
    player.vel.x += player.acc.x;
    player.pos.x += player.vel.x;

    if (IsKeyDown(KEY_UP) && player.vel.y > -player.maxVel) {
        player.acc.y = -player.accSpeed;
    } else if (IsKeyDown(KEY_DOWN) && player.vel.x < player.maxVel) {
        player.acc.y = player.accSpeed;
    } else if (abs(player.vel.y) > 0.2) {
        if (player.vel.y < 0) {
            player.acc.y = player.friction;
        } else {
            player.acc.y = -player.friction;
        }
    } else {
        player.vel.y = 0;
        player.acc.y = 0;
    }
    player.vel.y += player.acc.y;
    player.pos.y += player.vel.y;
}

int rectCollide(int x1, int y1, int w1, int h1, int x2, int y2, int w2, int h2) {
  return x1 + w1 > x2 && x1 < x2 + w2 && y1 + h1 > y2 && y1 < y2 + h2;
}

所以,我想知道:首先,是否有更好的方法来获得纹理的面积,而不必为每个纹理创建一个矩形结构,并将比例乘以纹理的宽度和高度?其次,我想知道为什么我的碰撞没有被检测到。我的密码怎么了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-03-10 03:29:04

碰撞检查

代码语言:javascript
复制
if (CheckCollisionRecs(playerArea, rect1))

在事件循环之前。

即使在循环中移动它也不会有任何效果,因为事件循环中从未更新过playerArea

一个快速的解决办法是在移动播放器后更新碰撞框。

( main__的示例片段,没有图像)

代码语言:javascript
复制
Rectangle playerArea;    
Rectangle rect1 = {100, 100, 50, 50};    
    
while (!WindowShouldClose()) {    
    movePlayer();    
        
    playerArea = (Rectangle) {    
        player.pos.x,                
        player.pos.y,                
        player.width,     
        player.height,     
    };    
        
    camera.target = (Vector2){ player.pos.x + 20, player.pos.y + 20 };    
            
    BeginDrawing();    
        ClearBackground(SKYBLUE);    
         
        BeginMode2D(camera);    
        
        DrawRectangleRec(rect1, RED);    
        DrawRectangle(player.pos.x, player.pos.y, player.width, player.height, RAYWHITE);    
    
        EndMode2D();    
            
        if (CheckCollisionRecs(playerArea, rect1))
            DrawText("Collided", 5, 5, 25, BLACK);     
    EndDrawing();    
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71417450

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档