我想知道如何在Raylib中正确处理碰撞。在设置了基本的东西之后,比如一个窗口,我会首先加载播放器纹理,像这样:
Texture2D playerTexture = LoadTexture("Player.png");
之后,我将绘制纹理,使用Raylib函数DrawTextureEx
,它允许我调整纹理的旋转和缩放。然后,我会为玩家添加一个简单的移动脚本,这将是它。
至于碰撞,我只是在一个矩形上测试玩家的碰撞。为了得到矩形的面积,我只需要创建一个简单的Rectangle结构,如下所示:
Rectangle rect1 = {100, 100, 50, 50};
至于获得玩家区域,我会做类似的事情:
Rectangle playerArea = {player.x, player.y, playerTexture.width*player.scale, playerTexture.height*player.scale} //Values are stored in Player struct
然而,当我试图像这样检查碰撞时,什么也没有发生:
if (CheckCollisionRecs(playerArea, rect1)) {
DrawText("Collided", 5, 5, 25, BLACK);
}
如果需要的话,下面是我的完整代码:
#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;
}
所以,我想知道:首先,有没有更好的方法来获得纹理的面积,而不必为每个纹理创建一个Rectangle结构,并将比例乘以纹理的宽度和高度?其次,我想知道为什么我的碰撞没有被检测到。我的代码有什么问题?
1条答案
按热度按时间kmbjn2e31#
碰撞检查
在事件循环之前。
即使将其移动到循环中也不会有任何效果,因为
playerArea
永远不会在事件循环中更新。一个快速的解决办法是在移动玩家后更新碰撞框。
main
的示例片段,无图像)*