Friction, velocity, rendering
This commit is contained in:
@@ -63,6 +63,7 @@ void cameraPushMatrix(camera_t *camera) {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED:
|
||||||
case CAMERA_PROJECTION_TYPE_PERSPECTIVE:
|
case CAMERA_PROJECTION_TYPE_PERSPECTIVE:
|
||||||
const float_t aspect = (
|
const float_t aspect = (
|
||||||
(float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND) /
|
(float_t)frameBufferGetWidth(FRAMEBUFFER_BOUND) /
|
||||||
@@ -75,6 +76,12 @@ void cameraPushMatrix(camera_t *camera) {
|
|||||||
camera->farClip,
|
camera->farClip,
|
||||||
projection
|
projection
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(camera->projType == CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED) {
|
||||||
|
// Flip Y axis
|
||||||
|
projection[1][1] *= -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(camera->viewType) {
|
switch(camera->viewType) {
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
CAMERA_PROJECTION_TYPE_PERSPECTIVE,
|
CAMERA_PROJECTION_TYPE_PERSPECTIVE,
|
||||||
|
CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED,
|
||||||
CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC
|
CAMERA_PROJECTION_TYPE_ORTHOGRAPHIC
|
||||||
} cameraprojectiontype_t;
|
} cameraprojectiontype_t;
|
||||||
|
|
||||||
|
@@ -56,12 +56,21 @@ void entityUpdate(entity_t *entity) {
|
|||||||
|
|
||||||
worldChunkPosAdd(&entity->position[i], entity->velocity[i]);
|
worldChunkPosAdd(&entity->position[i], entity->velocity[i]);
|
||||||
|
|
||||||
if(entity->velocity[i] < 0) {
|
// Friction
|
||||||
entity->velocity[i] += ENTITY_FRICTION;
|
worldsubtile_t v = entity->velocity[i];
|
||||||
if(entity->velocity[i] >= -ENTITY_MIN_VELOCITY) entity->velocity[i] = 0;
|
|
||||||
} else {
|
if (v > 0) {
|
||||||
entity->velocity[i] -= ENTITY_FRICTION;
|
v -= ENTITY_FRICTION;
|
||||||
if(entity->velocity[i] <= ENTITY_MIN_VELOCITY) entity->velocity[i] = 0;
|
if (v < ENTITY_MIN_VELOCITY) v = 0;
|
||||||
|
} else if (v < 0) {
|
||||||
|
v += ENTITY_FRICTION;
|
||||||
|
if (v > -ENTITY_MIN_VELOCITY) v = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((v > 0 && v < ENTITY_FRICTION) || (v < 0 && v > -ENTITY_FRICTION)) {
|
||||||
|
v = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
entity->velocity[i] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -18,49 +18,46 @@ void playerMovement(entity_t *entity) {
|
|||||||
assertNotNull(entity, "Entity pointer cannot be NULL");
|
assertNotNull(entity, "Entity pointer cannot be NULL");
|
||||||
|
|
||||||
// Get movement angle as 0-> normalized vector.
|
// Get movement angle as 0-> normalized vector.
|
||||||
{
|
vec2 dir = {
|
||||||
vec2 dir = {
|
inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT),
|
||||||
inputAxis(INPUT_ACTION_LEFT, INPUT_ACTION_RIGHT),
|
inputAxis(INPUT_ACTION_DOWN, INPUT_ACTION_UP)
|
||||||
inputAxis(INPUT_ACTION_DOWN, INPUT_ACTION_UP)
|
};
|
||||||
};
|
if(dir[0] == 0 && dir[1] == 0) return;
|
||||||
if(dir[0] == 0 && dir[1] == 0) return;
|
glm_vec2_normalize(dir);
|
||||||
glm_vec2_normalize(dir);
|
|
||||||
|
entity->velocity[0] += (worldsubtile_t)(PLAYER_SPEED * dir[0]);
|
||||||
entity->velocity[0] += (worldsubtile_t)(PLAYER_SPEED * dir[0]);
|
entity->velocity[1] += (worldsubtile_t)(PLAYER_SPEED * dir[1]);
|
||||||
entity->velocity[1] += (worldsubtile_t)(PLAYER_SPEED * dir[1]);
|
|
||||||
|
// Update direction.
|
||||||
|
if(dir[0] > 0) {
|
||||||
|
if(entity->direction == DIRECTION_RIGHT) {
|
||||||
|
entity->direction = DIRECTION_RIGHT;
|
||||||
|
} else {
|
||||||
|
if(dir[1] < 0) {
|
||||||
|
entity->direction = DIRECTION_UP;
|
||||||
|
} else if(dir[1] > 0) {
|
||||||
|
entity->direction = DIRECTION_DOWN;
|
||||||
|
} else {
|
||||||
|
entity->direction = DIRECTION_RIGHT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(dir[0] < 0) {
|
||||||
|
if(entity->direction == DIRECTION_LEFT) {
|
||||||
|
entity->direction = DIRECTION_LEFT;
|
||||||
|
} else {
|
||||||
|
if(dir[1] < 0) {
|
||||||
|
entity->direction = DIRECTION_UP;
|
||||||
|
} else if(dir[1] > 0) {
|
||||||
|
entity->direction = DIRECTION_DOWN;
|
||||||
|
} else {
|
||||||
|
entity->direction = DIRECTION_LEFT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(dir[1] < 0) {
|
||||||
|
entity->direction = DIRECTION_UP;
|
||||||
|
} else if(dir[1] > 0) {
|
||||||
|
entity->direction = DIRECTION_DOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// // Update direction.
|
|
||||||
// if(dir[0] > 0) {
|
|
||||||
// if(entity->direction == DIRECTION_RIGHT) {
|
|
||||||
// entity->direction = DIRECTION_RIGHT;
|
|
||||||
// } else {
|
|
||||||
// if(dir[1] < 0) {
|
|
||||||
// entity->direction = DIRECTION_UP;
|
|
||||||
// } else if(dir[1] > 0) {
|
|
||||||
// entity->direction = DIRECTION_DOWN;
|
|
||||||
// } else {
|
|
||||||
// entity->direction = DIRECTION_RIGHT;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else if(dir[0] < 0) {
|
|
||||||
// if(entity->direction == DIRECTION_LEFT) {
|
|
||||||
// entity->direction = DIRECTION_LEFT;
|
|
||||||
// } else {
|
|
||||||
// if(dir[1] < 0) {
|
|
||||||
// entity->direction = DIRECTION_UP;
|
|
||||||
// } else if(dir[1] > 0) {
|
|
||||||
// entity->direction = DIRECTION_DOWN;
|
|
||||||
// } else {
|
|
||||||
// entity->direction = DIRECTION_LEFT;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// } else if(dir[1] < 0) {
|
|
||||||
// entity->direction = DIRECTION_UP;
|
|
||||||
// } else if(dir[1] > 0) {
|
|
||||||
// entity->direction = DIRECTION_DOWN;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void playerInteraction(entity_t *entity) {
|
void playerInteraction(entity_t *entity) {
|
||||||
|
@@ -8,7 +8,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "dusk.h"
|
#include "dusk.h"
|
||||||
|
|
||||||
#define PLAYER_SPEED 4
|
#define PLAYER_SPEED 3
|
||||||
#define PLAYER_INTERACTION_RANGE 1.0f
|
#define PLAYER_INTERACTION_RANGE 1.0f
|
||||||
#define PLAYER_INTERACTION_SIZE 0.5f
|
#define PLAYER_INTERACTION_SIZE 0.5f
|
||||||
|
|
||||||
|
@@ -8,32 +8,33 @@
|
|||||||
#include "worldunit.h"
|
#include "worldunit.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
|
|
||||||
void worldChunkPosAdd(
|
void worldChunkPosAdd(worldchunkpos_t *pos, worldsubtile_t amt) {
|
||||||
worldchunkpos_t *pos,
|
assertNotNull(pos, "Position pointer cannot be NULL");
|
||||||
const worldsubtile_t amt
|
|
||||||
) {
|
|
||||||
int8_t a = pos->subtile; // current signed subtile
|
|
||||||
int8_t b = amt; // signed delta
|
|
||||||
uint8_t unsignedAdded = (uint8_t)a + (uint8_t)b; // well-defined wrap add
|
|
||||||
int8_t r = (int8_t)unsignedAdded; // result in signed domain
|
|
||||||
|
|
||||||
pos->subtile = r;
|
/*
|
||||||
|
int32_t sum = (int32_t)pos->subtile + (int32_t)amt;
|
||||||
|
int32_t shifted = sum + 128; // may be negative or large
|
||||||
|
int32_t carry = div_floor(shifted, 256); // tiles to add (can be neg)
|
||||||
|
int32_t rem = mod_floor(shifted, 256); // 0..255
|
||||||
|
int32_t new_sub = rem - 128; // back to [-128,127]
|
||||||
|
|
||||||
// Signed-overflow detection for a + b -> r:
|
pos->subtile = (int8_t)new_sub;
|
||||||
// overflow if sign(a) == sign(b) and sign(r) != sign(a)
|
pos->tile = (uint8_t)((int32_t)pos->tile + carry); // wrap mod 256
|
||||||
uint8_t ov = (uint8_t)((a ^ r) & (b ^ r)) >> 7; // 1 if overflow, else 0
|
*/
|
||||||
|
|
||||||
// Direction of carry: +1 for b >= 0, -1 for b < 0 (computed branchlessly)
|
int32_t shiftedTotal = (int32_t)pos->subtile + (int32_t)amt + 128;
|
||||||
uint8_t neg = ((uint8_t)b) >> 7; // 0 if b>=0, 1 if b<0
|
int32_t tileCarry = shiftedTotal >> 8; // divide by 256
|
||||||
int8_t dir = (int8_t)(1 - (neg << 1)); // +1 or -1
|
int32_t wrappedSubtile = shiftedTotal - (tileCarry << 8);
|
||||||
|
pos->subtile = (int8_t)(wrappedSubtile - 128);
|
||||||
// Apply tile adjustment (mod-256 via uint8_t arithmetic)
|
pos->tile = (uint8_t)(pos->tile + (uint8_t)tileCarry);
|
||||||
pos->tile = (uint8_t)(pos->tile + (uint8_t)(ov * (uint8_t)dir));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float_t worldChunkPosToF32(
|
|
||||||
const worldchunkpos_t pos,
|
|
||||||
const uint8_t tileSize
|
float_t worldChunkPosToF32(worldchunkpos_t pos, const uint8_t tileSize) {
|
||||||
) {
|
const float scaleFactor = (float)tileSize * (1.0f / 256.0f);
|
||||||
return (float_t)(pos.tile * tileSize) + ((float_t)pos.subtile / 256.0f);
|
return (
|
||||||
|
(float)pos.tile * (float)tileSize + ((float)pos.subtile + 128.0f) *
|
||||||
|
scaleFactor
|
||||||
|
);
|
||||||
}
|
}
|
@@ -12,11 +12,12 @@
|
|||||||
#include "rpg/entity/entity.h"
|
#include "rpg/entity/entity.h"
|
||||||
#include "display/screen.h"
|
#include "display/screen.h"
|
||||||
|
|
||||||
#define TILE_WIDTH 1
|
#define TILE_WIDTH 8
|
||||||
#define TILE_HEIGHT TILE_WIDTH
|
#define TILE_HEIGHT TILE_WIDTH
|
||||||
|
|
||||||
errorret_t sceneMapInit(scenedata_t *data) {
|
errorret_t sceneMapInit(scenedata_t *data) {
|
||||||
cameraInitPerspective(&data->sceneMap.camera);
|
cameraInitPerspective(&data->sceneMap.camera);
|
||||||
|
data->sceneMap.camera.projType = CAMERA_PROJECTION_TYPE_PERSPECTIVE_FLIPPED;
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -25,7 +26,7 @@ void sceneMapUpdate(scenedata_t *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void sceneMapRender(scenedata_t *data) {
|
void sceneMapRender(scenedata_t *data) {
|
||||||
const float_t camOffset = 12.0f;
|
const float_t camOffset = 32.0f;
|
||||||
const float_t pixelPerfectOffset = tanf(
|
const float_t pixelPerfectOffset = tanf(
|
||||||
data->sceneMap.camera.perspective.fov / 2.0f
|
data->sceneMap.camera.perspective.fov / 2.0f
|
||||||
) * ((float_t)SCREEN.height / 2.0f);
|
) * ((float_t)SCREEN.height / 2.0f);
|
||||||
@@ -56,6 +57,8 @@ void sceneMapRenderEntity(const entity_t *entity) {
|
|||||||
|
|
||||||
float_t x = worldChunkPosToF32(entity->position[0], TILE_WIDTH);
|
float_t x = worldChunkPosToF32(entity->position[0], TILE_WIDTH);
|
||||||
float_t y = worldChunkPosToF32(entity->position[1], TILE_HEIGHT);
|
float_t y = worldChunkPosToF32(entity->position[1], TILE_HEIGHT);
|
||||||
|
x -= TILE_WIDTH * 0.5f;
|
||||||
|
y -= TILE_HEIGHT * 0.5f;
|
||||||
|
|
||||||
spriteBatchPush(
|
spriteBatchPush(
|
||||||
NULL,
|
NULL,
|
||||||
|
Reference in New Issue
Block a user