···1111struct kf_actor
1212{
1313 struct kf_spritesheet sprites;
1414- struct kf_vec2(f32) pos, vel, size;
1414+ struct kf_vec2(f32) pos, vel, size, sizeoffset;
1515 f32 speed, speedmod, friction;
1616- bool collide;
1616+ bool collide, controlled;
1717 enum kf_direction pointing;
1818 void (*tick)(struct kf_world *world, struct kf_actor *self);
1919 void (*draw)(struct kf_world *world, struct kf_actor *self);
···21212222struct kf_actor *kf_actor_new(struct kf_spritesheet sprites, f32 width, f32 height, bool collides);
23232424+/* Load a spritesheet, filling in the details for loading character spritesheets. */
2525+struct kf_spritesheet kf_actor_loadspritesheet(char *filename);
2626+2427/* Check if the actor can move in the given direction. */
2528int kf_actor_canmovetowards(struct kf_world *world, struct kf_actor *actor, struct kf_vec2(f32) dir);
2629/* Add the given force to the actor's velocity. */
2730void kf_actor_addforce(struct kf_actor *self, struct kf_vec2(f32) force);
2831/* Move the actor according to their velocity. */
2932void kf_actor_move(struct kf_world *world, struct kf_actor *actor, f32 deltatime);
3333+/* Draw the actor. */
3434+void kf_actor_draw(struct kf_actor *actor);
30353136#endif
+15
include/keraforge/graphics.h
···11+#ifndef __kf_graphics__
22+#define __kf_graphics__
33+44+#include <keraforge/_header.h>
55+66+/* Number of frames since the game opened.
77+ You should only use this for animations!
88+ It's not consistent enough for precise timing use deltatime (kf_dts/kf_dtms) for that. */
99+extern u64 kf_frame;
1010+/* Deltatime in milliseconds */
1111+extern f32 kf_dtms;
1212+/* Deltatime in seconds. */
1313+extern f32 kf_dts;
1414+1515+#endif
+3
include/keraforge/input.h
···2121 GamepadAxis axis[KF_INPUTBIND_MAX];
2222};
23232424+/* Deadzone for gamepads. Default is 0.2f. */
2525+extern f32 kf_deadzone;
2626+2427extern struct _kf_inputbinds kf_inputbinds;
25282629/* Add a new input binding. */
+1
include/keraforge/sprites.h
···1212};
13131414struct kf_spritesheet kf_loadspritesheet(char *filename, int spritewidth, int spriteheight);
1515+void kf_drawsprite(struct kf_spritesheet *sheet, f32 x, f32 y, int spritex, int spritey);
15161617#endif
+4
include/keraforge/world.h
···4040/* Get a pointer to the tile ID at a given position. */
4141kf_tileid_t *kf_world_gettile(struct kf_world *world, u32 x, u32 y);
42424343+/* Draw visible collision rectangles. */
4444+struct kf_actor;
4545+void kf_world_drawcolliders(struct kf_world *world, struct kf_actor *player, Camera2D camera);
4646+4347/* Draw the part of the world visible to the given camera. */
4448void kf_world_draw(struct kf_world *world, Camera2D camera);
4549
+51-6
src/actor.c
···13131414 actor->speed = 25;
1515 actor->speedmod = 1;
1616- actor->friction = 1.25f;
1616+ actor->friction = 1.5f;
1717 actor->pointing = kf_north;
18181919 return actor;
2020}
21212222+struct kf_spritesheet kf_actor_loadspritesheet(char *filename)
2323+{
2424+ return kf_loadspritesheet(filename, 20, 20);
2525+}
2626+2227int kf_actor_canmovetowards(struct kf_world *world, struct kf_actor *actor, struct kf_vec2(f32) dir)
2328{
2424- Rectangle r = {actor->pos.x - actor->size.x / 2, actor->pos.y - actor->size.y / 2, actor->size.x, actor->size.y};
2929+ Rectangle r = {
3030+ actor->pos.x + (actor->size.x / 2) + actor->sizeoffset.x,
3131+ actor->pos.y + (actor->size.y / 2) + actor->sizeoffset.y,
3232+ actor->size.x,
3333+ actor->size.y
3434+ };
2535 r.x += dir.x;
2636 r.y += dir.y;
2737···3747 Rectangle tr = {
3848 trx,
3949 sy * KF_TILE_SIZE_PX,
4040- KF_TILE_SIZE_PX + 1,
4141- KF_TILE_SIZE_PX + 1,
5050+ /* TODO:
5151+ Subtracting 1 as a bandaid fix to high velocities causing the player to be stopped early in collisions.
5252+ This is a very notorious problem in 3D collision and fwik there are plenty of 2D solutions.
5353+ I'll research and implement one eventually:tm: */
5454+ KF_TILE_SIZE_PX - 1,
5555+ KF_TILE_SIZE_PX - 1,
4256 }; /* tile rect */
4357 u32 x;
4458 kf_tileid_t *tile = kf_world_gettile(world, sx, sy);
···7892 delta.y = 0;
7993 }
80948181- if (delta.y > 0)
8282- self->pointing = kf_north;
9595+ if (!self->controlled)
9696+ {
9797+ if (delta.y > 0)
9898+ self->pointing = kf_south;
9999+ else if (delta.y < 0)
100100+ self->pointing = kf_north;
101101+ else if (delta.x < 0)
102102+ self->pointing = kf_west;
103103+ else if (delta.x > 0)
104104+ self->pointing = kf_east;
105105+ }
8310684107 self->pos = kf_add_vec2(f32)(self->pos, delta);
85108···100123 else if (self->speedmod)
101124 self->speedmod -= self->friction * self->friction * dt;
102125}
126126+127127+void kf_actor_draw(struct kf_actor *actor)
128128+{
129129+ int x = 0, y = 0;
130130+131131+ switch (actor->pointing)
132132+ {
133133+ case kf_south: y = 0; break;
134134+ case kf_east: y = 1; break;
135135+ case kf_west: y = 2; break;
136136+ case kf_north: y = 3; break;
137137+ }
138138+139139+ if (actor->vel.x != 0 || actor->vel.y != 0)
140140+ x += 7; /* walk sprites */
141141+142142+ x += (kf_frame / 15) % 4;
143143+144144+ /* todo: run and jump */
145145+146146+ kf_drawsprite(&actor->sprites, actor->pos.x, actor->pos.y, x, y);
147147+}