debug drawing api + physics tweaks
parent
73e7575525
commit
d81de3b63a
|
@ -1,40 +1,41 @@
|
||||||
file(GLOB PKT_SRCS ../game/src/packets/*.h ../game/src/packets/*.c)
|
file(GLOB PKT_SRCS ../game/src/packets/*.h ../game/src/packets/*.c)
|
||||||
|
|
||||||
add_executable(eco2d
|
add_executable(eco2d
|
||||||
src/platform_raylib.c
|
src/platform_raylib.c
|
||||||
src/main.c
|
src/main.c
|
||||||
|
|
||||||
src/network.c
|
src/network.c
|
||||||
src/game.c
|
src/game.c
|
||||||
src/camera.c
|
src/camera.c
|
||||||
src/world_view.c
|
src/world_view.c
|
||||||
src/prediction.c
|
src/prediction.c
|
||||||
|
|
||||||
src/assets.c
|
src/assets.c
|
||||||
src/items.c
|
src/items.c
|
||||||
src/compress.c
|
src/compress.c
|
||||||
src/entity.c
|
src/entity.c
|
||||||
src/entity_view.c
|
src/entity_view.c
|
||||||
src/packet.c
|
src/packet.c
|
||||||
src/player.c
|
src/player.c
|
||||||
src/vehicle.c
|
src/vehicle.c
|
||||||
src/signal_handling.c
|
src/signal_handling.c
|
||||||
src/profiler.c
|
src/profiler.c
|
||||||
src/debug_ui.c
|
src/debug_ui.c
|
||||||
|
src/debug_draw.c
|
||||||
src/utils/options.c
|
|
||||||
|
|
||||||
src/network.h
|
src/utils/options.c
|
||||||
|
|
||||||
src/world/blocks.c
|
src/network.h
|
||||||
src/world/perlin.c
|
|
||||||
src/world/world.c
|
|
||||||
|
|
||||||
src/gen/texgen.c
|
src/world/blocks.c
|
||||||
|
src/world/perlin.c
|
||||||
|
src/world/world.c
|
||||||
|
|
||||||
src/world/worldgen/worldgen_test.c
|
src/gen/texgen.c
|
||||||
|
|
||||||
${PKT_SRCS}
|
src/world/worldgen/worldgen_test.c
|
||||||
|
|
||||||
|
${PKT_SRCS}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_definitions(eco2d PRIVATE CLIENT)
|
target_compile_definitions(eco2d PRIVATE CLIENT)
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
#include "debug_draw.h"
|
||||||
|
|
||||||
|
static debug_draw_queue draw_queue = {0};
|
||||||
|
|
||||||
|
#ifdef ECO2D_PROD
|
||||||
|
static bool draw_is_enabled = false;
|
||||||
|
#else
|
||||||
|
static bool draw_is_enabled = true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
debug_draw_queue *debug_draw_samples(void) {
|
||||||
|
return &draw_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_draw_flush(void) {
|
||||||
|
draw_queue.num_entries = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_draw_enable(bool state) {
|
||||||
|
draw_is_enabled = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool debug_draw_state(void) {
|
||||||
|
return draw_is_enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void debug_push_entry(debug_draw_entry entry) {
|
||||||
|
if (!draw_is_enabled) return;
|
||||||
|
ZPL_ASSERT(draw_queue.num_entries < DEBUG_DRAW_MAX_ENTRIES);
|
||||||
|
draw_queue.entries[draw_queue.num_entries++] = entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_push_line(debug_v2 a, debug_v2 b, int32_t color) {
|
||||||
|
debug_push_entry((debug_draw_entry){
|
||||||
|
.kind = DDRAW_LINE,
|
||||||
|
.color = color,
|
||||||
|
|
||||||
|
.a = a,
|
||||||
|
.b = b,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_push_circle(debug_v2 pos, float radius, int32_t color) {
|
||||||
|
debug_push_entry((debug_draw_entry){
|
||||||
|
.kind = DDRAW_CIRCLE,
|
||||||
|
.color = color,
|
||||||
|
|
||||||
|
.pos = pos,
|
||||||
|
.radius = radius,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void debug_push_rect(debug_v2 bmin, debug_v2 bmax, int32_t color) {
|
||||||
|
debug_push_entry((debug_draw_entry){
|
||||||
|
.kind = DDRAW_RECT,
|
||||||
|
.color = color,
|
||||||
|
|
||||||
|
.bmin = bmin,
|
||||||
|
.bmax = bmax,
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
#pragma once
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
// NOTE(zaklaus): Debug drawing queue
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
DDRAW_LINE,
|
||||||
|
DDRAW_CIRCLE,
|
||||||
|
DDRAW_RECT,
|
||||||
|
} debug_draw_kind;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
float x,y;
|
||||||
|
} debug_v2;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
debug_draw_kind kind;
|
||||||
|
int32_t color;
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
debug_v2 a, b;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
debug_v2 bmin, bmax;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct {
|
||||||
|
debug_v2 pos;
|
||||||
|
float radius;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
} debug_draw_entry;
|
||||||
|
|
||||||
|
#ifndef DEBUG_DRAW_MAX_ENTRIES
|
||||||
|
#define DEBUG_DRAW_MAX_ENTRIES 65535
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
size_t num_entries;
|
||||||
|
debug_draw_entry entries[DEBUG_DRAW_MAX_ENTRIES];
|
||||||
|
} debug_draw_queue;
|
||||||
|
|
||||||
|
debug_draw_queue *debug_draw_samples(void);
|
||||||
|
void debug_draw_flush(void);
|
||||||
|
void debug_draw_enable(bool state);
|
||||||
|
bool debug_draw_state(void);
|
||||||
|
|
||||||
|
void debug_push_line(debug_v2 a, debug_v2 b, int32_t color);
|
||||||
|
void debug_push_circle(debug_v2 pos, float radius, int32_t color);
|
||||||
|
void debug_push_rect(debug_v2 bmin, debug_v2 bmax, int32_t color);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "debug_ui.h"
|
#include "debug_ui.h"
|
||||||
|
#include "debug_draw.h"
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "vehicle.h"
|
#include "vehicle.h"
|
||||||
#include "camera.h"
|
#include "camera.h"
|
||||||
|
@ -289,6 +290,9 @@ debug_draw_result debug_draw_list(debug_item *list, float xpos, float ypos, bool
|
||||||
}
|
}
|
||||||
|
|
||||||
void debug_draw(void) {
|
void debug_draw(void) {
|
||||||
|
// NOTE(zaklaus): Flush old debug samples
|
||||||
|
debug_draw_flush();
|
||||||
|
|
||||||
float xpos = debug_xpos;
|
float xpos = debug_xpos;
|
||||||
float ypos = debug_ypos;
|
float ypos = debug_ypos;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
void debug_draw(void);
|
void debug_draw(void);
|
||||||
|
|
|
@ -197,8 +197,8 @@ ActSpawnDemoNPCs(void) {
|
||||||
pos->y=rand() % world_dim();
|
pos->y=rand() % world_dim();
|
||||||
|
|
||||||
Velocity *v = ecs_get_mut(world_ecs(), e, Velocity, NULL);
|
Velocity *v = ecs_get_mut(world_ecs(), e, Velocity, NULL);
|
||||||
v->x = (rand()%3-1) * 100;
|
v->x = (rand()%3-1) * 10;
|
||||||
v->y = (rand()%3-1) * 100;
|
v->y = (rand()%3-1) * 10;
|
||||||
|
|
||||||
zpl_array_append(demo_npcs, e);
|
zpl_array_append(demo_npcs, e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,15 @@ void platform_input() {
|
||||||
renderer_switch(1-gfx_kind);
|
renderer_switch(1-gfx_kind);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE(zaklaus): toggle debug drawing
|
||||||
|
#ifndef ECO2D_PROD
|
||||||
|
{
|
||||||
|
if (IsKeyPressed(KEY_T)) {
|
||||||
|
debug_draw_enable(!debug_draw_state());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void platform_render() {
|
void platform_render() {
|
||||||
|
@ -116,6 +125,7 @@ void platform_render() {
|
||||||
profile (PROF_RENDER) {
|
profile (PROF_RENDER) {
|
||||||
renderer_draw();
|
renderer_draw();
|
||||||
}
|
}
|
||||||
|
renderer_debug_draw();
|
||||||
debug_draw();
|
debug_draw();
|
||||||
display_conn_status();
|
display_conn_status();
|
||||||
}
|
}
|
||||||
|
|
|
@ -131,3 +131,8 @@ void renderer_shutdown_3d(void) {
|
||||||
blocks_destroy();
|
blocks_destroy();
|
||||||
assets_destroy();
|
assets_destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void renderer_debug_draw_3d(void) {
|
||||||
|
|
||||||
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "debug_draw.h"
|
||||||
#include "renderer_3d.c"
|
#include "renderer_3d.c"
|
||||||
#include "renderer_v0.c"
|
#include "renderer_v0.c"
|
||||||
|
|
||||||
|
@ -6,12 +7,14 @@
|
||||||
#define renderer_init renderer_init_v0
|
#define renderer_init renderer_init_v0
|
||||||
#define renderer_shutdown renderer_shutdown_v0
|
#define renderer_shutdown renderer_shutdown_v0
|
||||||
#define renderer_draw renderer_draw_v0
|
#define renderer_draw renderer_draw_v0
|
||||||
|
#define renderer_debug_draw renderer_debug_draw_v0
|
||||||
void renderer_switch(int kind) {}
|
void renderer_switch(int kind) {}
|
||||||
#elif GFX_KIND == 1
|
#elif GFX_KIND == 1
|
||||||
// NOTE(zaklaus): renderer_3d
|
// NOTE(zaklaus): renderer_3d
|
||||||
#define renderer_init renderer_init_3d
|
#define renderer_init renderer_init_3d
|
||||||
#define renderer_shutdown renderer_shutdown_3d
|
#define renderer_shutdown renderer_shutdown_3d
|
||||||
#define renderer_draw renderer_draw_3d
|
#define renderer_draw renderer_draw_3d
|
||||||
|
#define renderer_debug_draw renderer_debug_draw_3d
|
||||||
void renderer_switch(int kind) {}
|
void renderer_switch(int kind) {}
|
||||||
#elif GFX_KIND == 2
|
#elif GFX_KIND == 2
|
||||||
// NOTE(zaklaus): hybrid mode
|
// NOTE(zaklaus): hybrid mode
|
||||||
|
@ -50,6 +53,17 @@ void renderer_shutdown(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderer_debug_draw(void) {
|
||||||
|
switch (gfx_kind) {
|
||||||
|
case 0:{
|
||||||
|
renderer_debug_draw_v0();
|
||||||
|
}break;
|
||||||
|
case 1:{
|
||||||
|
renderer_debug_draw_3d();
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void renderer_bake_chunk(uint64_t key, entity_view * data) {
|
void renderer_bake_chunk(uint64_t key, entity_view * data) {
|
||||||
if (data->kind != EKIND_CHUNK) return;
|
if (data->kind != EKIND_CHUNK) return;
|
||||||
world_view *view = game_world_view_get_active();
|
world_view *view = game_world_view_get_active();
|
||||||
|
|
|
@ -67,8 +67,8 @@ void DEBUG_draw_entities(uint64_t key, entity_view * data) {
|
||||||
DrawCircleEco(x, y, size, ColorAlpha(PURPLE, data->tran_time));
|
DrawCircleEco(x, y, size, ColorAlpha(PURPLE, data->tran_time));
|
||||||
}break;
|
}break;
|
||||||
case EKIND_ITEM: {
|
case EKIND_ITEM: {
|
||||||
float x = data->x;
|
float x = data->x - 32.f;
|
||||||
float y = data->y;
|
float y = data->y - 32.f;
|
||||||
DrawTexturePro(GetSpriteTexture2D(assets_find(data->asset)), ASSET_SRC_RECT(), ASSET_DST_RECT(x,y), (Vector2){0.5f,0.5f}, 0.0f, ALPHA(WHITE));
|
DrawTexturePro(GetSpriteTexture2D(assets_find(data->asset)), ASSET_SRC_RECT(), ASSET_DST_RECT(x,y), (Vector2){0.5f,0.5f}, 0.0f, ALPHA(WHITE));
|
||||||
}break;
|
}break;
|
||||||
default:break;
|
default:break;
|
||||||
|
@ -132,3 +132,43 @@ void renderer_shutdown_v0(void) {
|
||||||
blocks_destroy();
|
blocks_destroy();
|
||||||
assets_destroy();
|
assets_destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void renderer_debug_draw_v0(void) {
|
||||||
|
BeginMode2D(render_camera);
|
||||||
|
debug_draw_queue *que = debug_draw_samples();
|
||||||
|
|
||||||
|
for (size_t i = 0; i < que->num_entries; i += 1) {
|
||||||
|
debug_draw_entry *e = &que->entries[i];
|
||||||
|
Color color = GetColor(e->color);
|
||||||
|
|
||||||
|
switch (e->kind) {
|
||||||
|
case DDRAW_LINE: {
|
||||||
|
float x = e->a.x;
|
||||||
|
float y = e->a.y;
|
||||||
|
float x2 = e->b.x;
|
||||||
|
float y2 = e->b.y;
|
||||||
|
DrawLine(x, y, x2, y2, color);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case DDRAW_CIRCLE:{
|
||||||
|
float x = e->a.x;
|
||||||
|
float y = e->a.y;
|
||||||
|
DrawCircleLines(x, y, e->radius, color);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case DDRAW_RECT:{
|
||||||
|
float x = e->bmin.x;
|
||||||
|
float y = e->bmin.y;
|
||||||
|
float w = e->bmax.x - e->bmin.x;
|
||||||
|
float h = e->bmax.y - e->bmin.y;
|
||||||
|
DrawRectangleLines(x, y, w, h, color);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EndMode2D();
|
||||||
|
}
|
|
@ -4,6 +4,7 @@
|
||||||
#include "world/world.h"
|
#include "world/world.h"
|
||||||
#include "world/blocks.h"
|
#include "world/blocks.h"
|
||||||
#include "profiler.h"
|
#include "profiler.h"
|
||||||
|
#include "debug_draw.h"
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
|
|
||||||
#define PHY_BLOCK_COLLISION 1
|
#define PHY_BLOCK_COLLISION 1
|
||||||
|
@ -50,6 +51,12 @@ void IntegratePositions(ecs_iter_t *it) {
|
||||||
|
|
||||||
p[i].x += v[i].x * it->delta_time;
|
p[i].x += v[i].x * it->delta_time;
|
||||||
p[i].y += v[i].y * it->delta_time;
|
p[i].y += v[i].y * it->delta_time;
|
||||||
|
|
||||||
|
{
|
||||||
|
debug_v2 a = {p[i].x, p[i].y};
|
||||||
|
debug_v2 b = {p[i].x+v[i].x, p[i].y+v[i].y};
|
||||||
|
debug_push_line(a, b, 0xFFFFFFFF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +66,12 @@ void UpdateTrackerPos(ecs_iter_t *it) {
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++){
|
for (int i = 0; i < it->count; i++){
|
||||||
librg_entity_chunk_set(world_tracker(), it->entities[i], librg_chunk_from_realpos(world_tracker(), p[i].x, p[i].y, 0));
|
librg_entity_chunk_set(world_tracker(), it->entities[i], librg_chunk_from_realpos(world_tracker(), p[i].x, p[i].y, 0));
|
||||||
|
|
||||||
|
{
|
||||||
|
debug_v2 a = {p[i].x-2.5f, p[i].y-2.5f};
|
||||||
|
debug_v2 b = {p[i].x+2.5f, p[i].y+2.5f};
|
||||||
|
debug_push_rect(a, b, 0x00FFFFFF);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +141,7 @@ void SystemsImport(ecs_world_t *ecs) {
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, IntegratePositions, EcsOnValidate, components.Position, components.Velocity);
|
ECS_SYSTEM(ecs, IntegratePositions, EcsOnValidate, components.Position, components.Velocity);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, UpdateTrackerPos, EcsPostUpdate, components.Position);
|
ECS_SYSTEM(ecs, UpdateTrackerPos, EcsPostUpdate, components.Position, components.Velocity);
|
||||||
|
|
||||||
ECS_SYSTEM(ecs, ClearVehicle, EcsUnSet, components.Vehicle);
|
ECS_SYSTEM(ecs, ClearVehicle, EcsUnSet, components.Vehicle);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,11 @@
|
||||||
|
|
||||||
#define DEMO_NPC_CHANGEDIR_FACTOR 0.1
|
#define DEMO_NPC_MOVE_SPEED 150
|
||||||
#define DEMO_NPC_MOVE_SPEED 1500
|
|
||||||
|
|
||||||
void DemoNPCMoveAround(ecs_iter_t *it) {
|
void DemoNPCMoveAround(ecs_iter_t *it) {
|
||||||
Velocity *v = ecs_column(it, Velocity, 1);
|
Velocity *v = ecs_column(it, Velocity, 1);
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
v[i].x = zpl_lerp(v[i].x, (rand()%3-1)*DEMO_NPC_MOVE_SPEED, DEMO_NPC_CHANGEDIR_FACTOR);
|
v[i].x += (rand()%3-1)*DEMO_NPC_MOVE_SPEED;
|
||||||
v[i].y = zpl_lerp(v[i].y, (rand()%3-1)*DEMO_NPC_MOVE_SPEED, DEMO_NPC_CHANGEDIR_FACTOR);
|
v[i].y += (rand()%3-1)*DEMO_NPC_MOVE_SPEED;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,16 @@
|
||||||
#define PLR_MOVE_SPEED 50.0
|
#define PLR_MOVE_SPEED 30.0
|
||||||
#define PLR_MOVE_SPEED_MULT 4.0
|
#define PLR_MOVE_SPEED_MULT 4.0
|
||||||
|
|
||||||
void MovementImpulse(ecs_iter_t *it) {
|
void MovementImpulse(ecs_iter_t *it) {
|
||||||
Input *in = ecs_column(it, Input, 1);
|
Input *in = ecs_column(it, Input, 1);
|
||||||
Velocity *v = ecs_column(it, Velocity, 2);
|
Velocity *v = ecs_column(it, Velocity, 2);
|
||||||
Position *p = ecs_term(it, Position, 3);
|
Position *p = ecs_column(it, Position, 3);
|
||||||
|
|
||||||
for (int i = 0; i < it->count; i++) {
|
for (int i = 0; i < it->count; i++) {
|
||||||
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
world_block_lookup lookup = world_block_from_realpos(p[i].x, p[i].y);
|
||||||
float drag = zpl_clamp(blocks_get_drag(lookup.block_id), 0.0f, 1.0f);
|
float drag = zpl_clamp(blocks_get_drag(lookup.block_id), 0.0f, 1.0f);
|
||||||
double speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0);
|
double speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0);
|
||||||
if (zpl_abs(v[i].x) < speed && in[i].x)
|
v[i].x += in[i].x*speed*drag;
|
||||||
v[i].x += in[i].x*speed*drag;
|
v[i].y += in[i].y*speed*drag;
|
||||||
if (zpl_abs(v[i].y) < speed && in[i].y)
|
|
||||||
v[i].y += in[i].y*speed*drag;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include "debug_draw.h"
|
||||||
|
|
||||||
#define VEH_ENTER_RADIUS 45.0f
|
#define VEH_ENTER_RADIUS 45.0f
|
||||||
|
|
||||||
|
@ -124,6 +125,17 @@ void VehicleHandling(ecs_iter_t *it) {
|
||||||
v[i].x += (fr_x + bk_x) / 2.0f - p[i].x;
|
v[i].x += (fr_x + bk_x) / 2.0f - p[i].x;
|
||||||
v[i].y += (fr_y + bk_y) / 2.0f - p[i].y;
|
v[i].y += (fr_y + bk_y) / 2.0f - p[i].y;
|
||||||
car->heading = zpl_arctan2(fr_y - bk_y, fr_x - bk_x);
|
car->heading = zpl_arctan2(fr_y - bk_y, fr_x - bk_x);
|
||||||
|
|
||||||
|
{
|
||||||
|
debug_v2 b2 = {p[i].x + zpl_cos(car->heading)*(car->wheel_base), p[i].y + zpl_sin(car->heading)*(car->wheel_base)};
|
||||||
|
debug_push_line((debug_v2){p[i].x, p[i].y}, b2, 0x0000FFFF);
|
||||||
|
|
||||||
|
{
|
||||||
|
float dx = zpl_cos(car->heading);
|
||||||
|
float dy = zpl_sin(car->heading);
|
||||||
|
debug_push_circle((debug_v2){p[i].x+dx*car->force, p[i].y+dy*car->force}, 5.0f, 0x00FF00FF);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue