summaryrefslogtreecommitdiff
path: root/examples/platform.c
diff options
context:
space:
mode:
authorKonAki <konaki@anokonaki.org>2026-10-12 03:03:51 +0800
committerKonAki <konaki@anokonaki.org>2026-10-12 03:03:51 +0800
commitdbe7d0e0eeeabf6a4df16ef98d0a1f8d53b62d8b (patch)
tree2b211e3e455f489da9499a786e0aef2632bfc1c0 /examples/platform.c
parentb77cac581ac41d069f20a24e07211cc200c653eb (diff)
platform example uses the 2d module and scrolls
Diffstat (limited to 'examples/platform.c')
-rw-r--r--examples/platform.c97
1 files changed, 39 insertions, 58 deletions
diff --git a/examples/platform.c b/examples/platform.c
index 869e820..1ac48fb 100644
--- a/examples/platform.c
+++ b/examples/platform.c
@@ -1,7 +1,7 @@
/*
- * platform: a box that runs and jumps around a tilemap, and a ray that follows the mouse
+ * platform: a box that runs and jumps around a tilemap with a camera that follows it, and a ray that follows the mouse
*
- * build: ./build.sh -d -m tile,font obj/platform
+ * build: ./build.sh -d -m 2d,font obj/platform
* run: obj/platform
*
* left and right or a and d run, space or up jumps. the line from the box to the mouse stops at the first solid tile
@@ -13,15 +13,17 @@
#include "konprogram.h"
#include "kontile.h"
+#include "kon2d.h"
-#if !defined(KON_MODULE_TILE) || !defined(KON_MODULE_FONT)
-#error "build with: ./build.sh -d -m tile,font obj/platform"
+#if !defined(KON_MODULE_2D) || !defined(KON_MODULE_TILE) || !defined(KON_MODULE_FONT)
+#error "build with: ./build.sh -d -m 2d,font obj/platform"
#endif
#define TILE 16
#define COLUMNS 40
#define ROWS 22
-#define STEP (1.0 / 120.0)
+#define VIEW_WIDTH 320
+#define VIEW_HEIGHT 176
#define COL_BACKGROUND 0xFF1B1826u
#define COL_TILE 0xFF4A4468u
@@ -61,13 +63,10 @@ typedef struct state {
uint16_t tiles[COLUMNS * ROWS];
uint8_t solid[2];
- kon_box2_t player;
- kon_vec2_t velocity;
- int onGround;
- double leftover, coyote;
- int left, right, jumpHeld;
- float gravity, jump;
+ kon_platformer_t player;
+ kon_camera2_t camera;
+ int left, right;
int mouseX, mouseY;
int rayHit;
kon_hit2_t hit;
@@ -86,7 +85,7 @@ static int event(kon_program_t *program, const kon_event_t *ev, void *user)
if (ev->key == KON_KEY_LEFT || ev->key == KON_KEY_A) state->left = down;
else if (ev->key == KON_KEY_RIGHT || ev->key == KON_KEY_D) state->right = down;
- else if (ev->key == KON_KEY_SPACE || ev->key == KON_KEY_UP) state->jumpHeld = down;
+ else if (ev->key == KON_KEY_SPACE || ev->key == KON_KEY_UP) state->player.jumpHeld = down;
else return 0;
} else {
return 0;
@@ -94,46 +93,24 @@ static int event(kon_program_t *program, const kon_event_t *ev, void *user)
return 1;
}
-static void step(state_t *state, float dt)
-{
- float run = (float)(state->right - state->left) * 120.0f;
- int flags;
-
- state->velocity.x += (run - state->velocity.x) * (state->onGround ? 18.0f : 8.0f) * dt;
- state->velocity.y += state->gravity * dt;
-
- if (state->coyote > 0.0) state->coyote -= dt;
- if (state->jumpHeld && state->coyote > 0.0) {
- state->velocity.y = -state->jump;
- state->coyote = 0.0;
- }
- /* letting go early cuts the jump short */
- if (!state->jumpHeld && state->velocity.y < -60.0f) state->velocity.y = -60.0f;
-
- flags = kon_tilemapMove(&state->map, &state->player, state->velocity.x * dt, state->velocity.y * dt, state->solid, 2);
-
- if (flags & (KON_HIT_LEFT | KON_HIT_RIGHT)) state->velocity.x = 0.0f;
- if (flags & (KON_HIT_UP | KON_HIT_DOWN)) state->velocity.y = 0.0f;
- state->onGround = (flags & KON_HIT_DOWN) != 0;
- if (state->onGround) state->coyote = 0.08;
-}
-
static void update(kon_program_t *program, double dt, void *user)
{
state_t *state = user;
- kon_vec2_t from = KON_VEC2(state->player.x + state->player.w * 0.5f, state->player.y + state->player.h * 0.5f);
- kon_vec2_t dir = KON_VEC2((float)state->mouseX - from.x, (float)state->mouseY - from.y);
- float length = kon_vec2Length(dir);
+ kon_box2_t *box = &state->player.box;
+ kon_vec2_t from = KON_VEC2(box->x + box->w * 0.5f, box->y + box->h * 0.5f);
+ kon_vec2_t dir;
+ float length;
int row, column;
(void)program;
- state->leftover += dt;
- while (state->leftover >= STEP) {
- step(state, (float)STEP);
- state->leftover -= STEP;
- }
+ state->player.moveX = state->right - state->left;
+ kon_platformerUpdate(&state->player, &state->map, state->solid, 2, dt);
+ kon_camera2Follow(&state->camera, from.x, from.y, (float)dt);
/* the ray against every solid tile, nothing clever, the nearest one wins */
+ dir = KON_VEC2((float)(state->mouseX + kon_camera2X(&state->camera)) - from.x,
+ (float)(state->mouseY + kon_camera2Y(&state->camera)) - from.y);
+ length = kon_vec2Length(dir);
state->rayHit = 0;
if (length < 1.0f) return;
dir = kon_vec2Scale(dir, 1.0f / length);
@@ -154,27 +131,31 @@ static void update(kon_program_t *program, double dt, void *user)
static void draw(kon_program_t *program, kon_framebuffer_t *game, void *user)
{
state_t *state = user;
+ kon_box2_t *box = &state->player.box;
+ int camX = kon_camera2X(&state->camera), camY = kon_camera2Y(&state->camera);
int row, column, ex, ey;
- int fromX = (int)(state->player.x + state->player.w * 0.5f), fromY = (int)(state->player.y + state->player.h * 0.5f);
+ int fromX = (int)(box->x + box->w * 0.5f) - camX, fromY = (int)(box->y + box->h * 0.5f) - camY;
kon_clearFramebuffer(game, COL_BACKGROUND);
for (row = 0; row < ROWS; row++) {
for (column = 0; column < COLUMNS; column++) {
+ int x = column * TILE - camX, y = row * TILE - camY;
+
if (!state->solid[kon_tilemapAt(&state->map, column, row)]) continue;
- kon_fillRectangle(game, column * TILE, row * TILE, TILE, TILE, COL_TILE);
- if (!state->solid[kon_tilemapAt(&state->map, column, row - 1)]) kon_fillRectangle(game, column * TILE, row * TILE, TILE, 2, COL_TILE_TOP);
+ kon_fillRectangle(game, x, y, TILE, TILE, COL_TILE);
+ if (!state->solid[kon_tilemapAt(&state->map, column, row - 1)]) kon_fillRectangle(game, x, y, TILE, 2, COL_TILE_TOP);
}
}
- ex = state->rayHit ? (int)state->hit.point.x : state->mouseX;
- ey = state->rayHit ? (int)state->hit.point.y : state->mouseY;
+ ex = state->rayHit ? (int)state->hit.point.x - camX : state->mouseX;
+ ey = state->rayHit ? (int)state->hit.point.y - camY : state->mouseY;
kon_drawLine(game, fromX, fromY, ex, ey, COL_RAY);
if (state->rayHit) kon_fillCircle(game, ex, ey, 2, COL_HIT);
- kon_fillRectangle(game, (int)state->player.x, (int)state->player.y, (int)state->player.w, (int)state->player.h, COL_PLAYER);
+ kon_fillRectangle(game, (int)box->x - camX, (int)box->y - camY, (int)box->w, (int)box->h, COL_PLAYER);
- if (program->font) kon_drawText(game, program->font, 24, 40, "arrows or a d to run, space to jump", COL_DIM);
+ if (program->font) kon_drawText(game, program->font, 8, 16, "arrows or a d to run, space to jump", COL_DIM);
}
static int init(kon_program_t *program, void *user)
@@ -192,12 +173,12 @@ static int init(kon_program_t *program, void *user)
for (column = 0; column < COLUMNS; column++) state->tiles[row * COLUMNS + column] = level[row][column] == '#';
}
- state->player = KON_BOX2(40, 280, 10, 14);
- state->gravity = 700.0f;
- state->jump = 260.0f;
+ kon_platformerInit(&state->player, KON_BOX2(40, 280, 10, 14));
+ kon_camera2Init(&state->camera, VIEW_WIDTH, VIEW_HEIGHT, COLUMNS * TILE, ROWS * TILE);
+ kon_camera2Snap(&state->camera, 45.0f, 287.0f);
- kon_debugVar(program->debug, "gravity", KON_VAR_FLOAT, &state->gravity);
- kon_debugVar(program->debug, "jump", KON_VAR_FLOAT, &state->jump);
+ kon_debugVar(program->debug, "gravity", KON_VAR_FLOAT, &state->player.gravity);
+ kon_debugVar(program->debug, "jump", KON_VAR_FLOAT, &state->player.jumpSpeed);
return 1;
}
@@ -207,8 +188,8 @@ int main(void)
kon_programConfig_t config = {0};
config.title = "platform";
- config.gameWidth = 640;
- config.gameHeight = 352;
+ config.gameWidth = VIEW_WIDTH;
+ config.gameHeight = VIEW_HEIGHT;
config.windowWidth = 1280;
config.windowHeight = 704;
config.user = &state;