improve world rendering + nametags
parent
ef2ae5a1e6
commit
ef8788d51e
|
@ -53,7 +53,7 @@ void world_viewers_init(uint32_t num_viewers) {
|
|||
zpl_buffer_init(world_viewers, zpl_heap(), num_viewers);
|
||||
|
||||
for (uint32_t i = 0; i < num_viewers; i++) {
|
||||
world_viewers[i] = world_view_create(i);
|
||||
zpl_buffer_append(world_viewers, world_view_create(i));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,6 +72,10 @@ world_view *game_world_view_get_active(void) {
|
|||
return active_viewer;
|
||||
}
|
||||
|
||||
void game_world_view_cycle_active(uint8_t dir) {
|
||||
uint16_t idx = (uint16_t)(active_viewer - world_viewers);
|
||||
game_world_view_set_active_by_idx((idx+dir)%zpl_buffer_count(world_viewers));
|
||||
}
|
||||
void game_world_view_set_active_by_idx(uint16_t idx) {
|
||||
ZPL_ASSERT(idx >= 0 && idx < zpl_buffer_count(world_viewers));
|
||||
game_world_view_set_active(&world_viewers[idx]);
|
||||
|
@ -146,6 +150,6 @@ void game_render() {
|
|||
platform_render();
|
||||
}
|
||||
|
||||
void game_action_send_keystate(double x, double y, uint8_t use) {
|
||||
pkt_send_keystate_send(active_viewer->view_id, x, y, use);
|
||||
void game_action_send_keystate(double x, double y, uint8_t use, uint8_t sprint) {
|
||||
pkt_send_keystate_send(active_viewer->view_id, x, y, use, sprint);
|
||||
}
|
|
@ -10,6 +10,33 @@ const uint16_t screenHeight = 900;
|
|||
|
||||
static Camera2D render_camera;
|
||||
|
||||
void DrawTextEco(const char *text, int posX, int posY, int fontSize, Color color, float spacing) {
|
||||
// Check if default font has been loaded
|
||||
if (GetFontDefault().texture.id != 0) {
|
||||
Vector2 position = { (float)posX, (float)posY };
|
||||
|
||||
int defaultFontSize = 10; // Default Font chars height in pixel
|
||||
int new_spacing = spacing == 0.0f ? fontSize/defaultFontSize : spacing;
|
||||
|
||||
DrawTextEx(GetFontDefault(), text, position, (float)fontSize, (float)new_spacing, color);
|
||||
}
|
||||
}
|
||||
|
||||
int MeasureTextEco(const char *text, int fontSize, float spacing) {
|
||||
Vector2 vec = { 0.0f, 0.0f };
|
||||
|
||||
// Check if default font has been loaded
|
||||
if (GetFontDefault().texture.id != 0) {
|
||||
int defaultFontSize = 10; // Default Font chars height in pixel
|
||||
int new_spacing = spacing == 0.0f ? fontSize/defaultFontSize : spacing;
|
||||
|
||||
vec = MeasureTextEx(GetFontDefault(), text, (float)fontSize, (float)new_spacing);
|
||||
}
|
||||
|
||||
return (int)vec.x;
|
||||
}
|
||||
|
||||
|
||||
void platform_init() {
|
||||
InitWindow(screenWidth, screenHeight, "eco2d - client");
|
||||
SetTargetFPS(60);
|
||||
|
@ -17,7 +44,7 @@ void platform_init() {
|
|||
render_camera.target = (Vector2){0.0f,0.0f};
|
||||
render_camera.offset = (Vector2){screenWidth/2.0f, screenHeight/2.0f};
|
||||
render_camera.rotation = 0.0f;
|
||||
render_camera.zoom = 0.3f;
|
||||
render_camera.zoom = 8.0f;
|
||||
}
|
||||
|
||||
void platform_shutdown() {
|
||||
|
@ -32,21 +59,32 @@ void platform_input() {
|
|||
float mouse_z = GetMouseWheelMove();
|
||||
|
||||
if (mouse_z != 0.0f) {
|
||||
render_camera.zoom = zpl_clamp(render_camera.zoom+mouse_z*0.04f, 0.01f, 1.0f);
|
||||
render_camera.zoom = zpl_clamp(render_camera.zoom+mouse_z*0.04f, 0.01f, 16.0f);
|
||||
}
|
||||
|
||||
// NOTE(zaklaus): keystate handling
|
||||
{
|
||||
double x=0.0, y=0.0;
|
||||
uint8_t use;
|
||||
uint8_t use, sprint;
|
||||
if (IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D)) x += 1.0f;
|
||||
if (IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)) x -= 1.0f;
|
||||
if (IsKeyDown(KEY_UP) || IsKeyDown(KEY_W)) y -= 1.0f;
|
||||
if (IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S)) y += 1.0f;
|
||||
|
||||
use = IsKeyPressed(KEY_SPACE);
|
||||
sprint = IsKeyDown(KEY_LEFT_SHIFT) || IsKeyDown(KEY_RIGHT_SHIFT);
|
||||
|
||||
pkt_send_keystate_send(game_world_view_get_active()->view_id, x, y, use);
|
||||
game_action_send_keystate(x, y, use, sprint);
|
||||
}
|
||||
|
||||
// NOTE(zaklaus): cycle through viewers
|
||||
{
|
||||
if (IsKeyPressed(KEY_Q)) {
|
||||
game_world_view_cycle_active(-1);
|
||||
}
|
||||
else if (IsKeyPressed(KEY_E)) {
|
||||
game_world_view_cycle_active(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -89,12 +127,23 @@ void DEBUG_draw_ground(uint64_t key, entity_view data) {
|
|||
|
||||
int32_t size = view->chunk_size * view->block_size;
|
||||
int32_t half_size = size/2;
|
||||
int32_t half_block_size = view->block_size/2;
|
||||
int16_t offset = 10;
|
||||
int16_t block_offset = 1;
|
||||
|
||||
switch (data.kind) {
|
||||
case EKIND_CHUNK: {
|
||||
DrawRectangle(x+offset-half_size, y+offset-half_size, size-offset, size-offset, GREEN);
|
||||
char lol[80];
|
||||
DrawRectangle(x+offset-half_size, y+offset-half_size, size-offset, size-offset, LIME);
|
||||
for (uint16_t i = 0; i < view->chunk_size*view->chunk_size; i++) {
|
||||
int32_t bx = i % view->block_size * view->block_size + x - half_size + offset;
|
||||
int32_t by = i / view->block_size * view->block_size + y - half_size + offset;
|
||||
DrawRectangle(bx+block_offset-half_block_size,
|
||||
by+block_offset-half_block_size,
|
||||
view->block_size-block_offset,
|
||||
view->block_size-block_offset,
|
||||
GREEN);
|
||||
}
|
||||
|
||||
DrawText(TextFormat("%.01f %.01f", data.x, data.y), x-half_size+5, y-half_size+5, 65, BLACK);
|
||||
}break;
|
||||
|
||||
|
@ -102,12 +151,19 @@ void DEBUG_draw_ground(uint64_t key, entity_view data) {
|
|||
}
|
||||
}
|
||||
|
||||
static inline float lerp(float a, float b, float t) { return a * (1.0f - t) + b * t; }
|
||||
|
||||
void DEBUG_draw_entities(uint64_t key, entity_view data) {
|
||||
world_view *view = game_world_view_get_active();
|
||||
uint16_t size = 100;
|
||||
uint16_t size = 4;
|
||||
uint16_t font_size = (uint16_t)lerp(4, 32, 0.5f/render_camera.zoom);
|
||||
float font_spacing = 1.1f;
|
||||
|
||||
switch (data.kind) {
|
||||
case EKIND_PLAYER: {
|
||||
const char *title = TextFormat("Player %d", key);
|
||||
int title_w = MeasureTextEco(title, font_size, font_spacing);
|
||||
DrawTextEco(title, data.x-title_w/2, data.y-size-font_size, font_size, BLACK, font_spacing);
|
||||
DrawCircle(data.x, data.y, size, RED);
|
||||
}break;
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ world_view *game_world_view_get_active(void);
|
|||
world_view *game_world_view_get(uint16_t idx);
|
||||
void game_world_view_set_active_by_idx(uint16_t idx);
|
||||
void game_world_view_set_active(world_view *view);
|
||||
void game_world_view_cycle_active(uint8_t dir);
|
||||
|
||||
//~ NOTE(zaklaus): viewer -> host actions
|
||||
void game_action_send_keystate(double x, double y, uint8_t use);
|
||||
void game_action_send_keystate(double x, double y, uint8_t use, uint8_t sprint);
|
|
@ -7,14 +7,16 @@ pkt_desc pkt_send_keystate_desc[] = {
|
|||
{ PKT_REAL(pkt_send_keystate, x) },
|
||||
{ PKT_REAL(pkt_send_keystate, y) },
|
||||
{ PKT_UINT(pkt_send_keystate, use) },
|
||||
{ PKT_UINT(pkt_send_keystate, sprint) },
|
||||
{ PKT_END },
|
||||
};
|
||||
|
||||
size_t pkt_send_keystate_send(uint16_t view_id,
|
||||
double x,
|
||||
double y,
|
||||
uint8_t use) {
|
||||
pkt_send_keystate table = { .x = x, .y = y, .use = use };
|
||||
uint8_t use,
|
||||
uint8_t sprint) {
|
||||
pkt_send_keystate table = { .x = x, .y = y, .use = use, .sprint = sprint };
|
||||
return pkt_world_write(MSG_ID_SEND_KEYSTATE, pkt_send_keystate_encode(&table), 1, view_id, NULL);
|
||||
}
|
||||
|
||||
|
@ -37,6 +39,7 @@ int32_t pkt_send_keystate_handler(pkt_header *header) {
|
|||
i->x = table.x;
|
||||
i->y = table.y;
|
||||
i->use = table.use;
|
||||
i->sprint = table.sprint;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -6,11 +6,13 @@ typedef struct {
|
|||
double x;
|
||||
double y;
|
||||
uint8_t use;
|
||||
uint8_t sprint;
|
||||
} pkt_send_keystate;
|
||||
size_t pkt_send_keystate_send(uint16_t view_id,
|
||||
double x,
|
||||
double y,
|
||||
uint8_t use);
|
||||
uint8_t use,
|
||||
uint8_t sprint);
|
||||
size_t pkt_send_keystate_encode(pkt_send_keystate *table);
|
||||
pkt_desc pkt_send_keystate_desc[];
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ uint64_t player_spawn(char *name) {
|
|||
ecs_set(world_ecs(), e, Input, {0});
|
||||
ecs_set(world_ecs(), e, Velocity, {0});
|
||||
ecs_add(world_ecs(), e, Walking);
|
||||
ecs_add(world_ecs(), e, Player);
|
||||
Position *pos = ecs_get_mut(world_ecs(), e, Position, NULL);
|
||||
uint16_t world_dim = world_block_size() * world_chunk_size() * world_world_size();
|
||||
uint16_t half_world_dim = world_dim / 2;
|
||||
|
|
|
@ -25,7 +25,7 @@ typedef struct {
|
|||
|
||||
static world_data world = {0};
|
||||
|
||||
#define WORLD_TRACKER_UPDATE_MS 100
|
||||
#define WORLD_TRACKER_UPDATE_MS 10
|
||||
|
||||
int32_t world_gen();
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@ ECS_STRUCT(Input, {
|
|||
double x;
|
||||
double y;
|
||||
uint8_t use;
|
||||
uint8_t sprint;
|
||||
});
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -4,15 +4,19 @@
|
|||
#include "modules/physics.h"
|
||||
#include "zpl.h"
|
||||
|
||||
#define PLR_MOVE_SPEED 50.0
|
||||
#define PLR_MOVE_SPEED_MULT 4.0
|
||||
|
||||
void MovementImpulse(ecs_iter_t *it) {
|
||||
Input *in = ecs_column(it, Input, 1);
|
||||
Velocity *v = ecs_column(it, Velocity, 2);
|
||||
|
||||
for (int i = 0; i < it->count; i++) {
|
||||
if (zpl_abs(v[i].x) < 1000.0f)
|
||||
v[i].x = in[i].x*1000.0;
|
||||
if (zpl_abs(v[i].x) < 1000.0f)
|
||||
v[i].y = in[i].y*1000.0;
|
||||
double speed = PLR_MOVE_SPEED * (in[i].sprint ? PLR_MOVE_SPEED_MULT : 1.0);
|
||||
if (zpl_abs(v[i].x) < speed)
|
||||
v[i].x = in[i].x*speed;
|
||||
if (zpl_abs(v[i].y) < speed)
|
||||
v[i].y = in[i].y*speed;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,13 @@ void MoveWalk(ecs_iter_t *it) {
|
|||
p[i].y += v[i].y * it->delta_time;
|
||||
v[i].x = zpl_lerp(v[i].x, 0.0f, PHY_WALK_DRAG);
|
||||
v[i].y = zpl_lerp(v[i].y, 0.0f, PHY_WALK_DRAG);
|
||||
|
||||
// NOTE(zaklaus): world bounds
|
||||
/*{
|
||||
double w = (double)world_world_size()*world_chunk_size()*world_block_size();;
|
||||
p[i].x = zpl_clamp(p[i].x, -w, w);
|
||||
}*/
|
||||
|
||||
librg_entity_chunk_set(world_tracker(), it->entities[i], librg_chunk_from_realpos(world_tracker(), p[i].x, p[i].y, 0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19979,7 +19979,8 @@ librg_chunk librg_chunk_from_chunkpos(librg_world *world, int16_t chunk_x, int16
|
|||
int16_t chz = librg_util_chunkoffset_line(chunk_z, wld->chunkoffset.z, wld->worldsize.z);
|
||||
#define kk(aax,aay) (aax > -aay && aax < aay)
|
||||
#define ll(aax,aay) (aax <= -aay || aax >= aay)
|
||||
if (ll(chx, wld->worldsize.x) || ll(chy, wld->worldsize.y) /*|| ll(chz, wld->worldsize.z)*/)
|
||||
|
||||
if (ll(chx, wld->worldsize.x) || ll(chy, wld->worldsize.y) /*|| ll(chz, wld->worldsize.z)*/)
|
||||
return LIBRG_CHUNK_INVALID;
|
||||
|
||||
librg_chunk id = (chz * wld->worldsize.y * wld->worldsize.z) + (chy * wld->worldsize.y) + (chx);
|
||||
|
|
Loading…
Reference in New Issue