New separate key/button input for interact

main
parent 7c56a43517
commit 516fd2db37

@ -96,6 +96,10 @@
{
filepath: "shift_icon.png",
}
@image e_icon:
{
filepath: "e_icon.png",
}
@image space_icon:
{
filepath: "space_icon.png",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -370,8 +370,8 @@
"rotation":0,
"visible":true,
"width":32,
"x":551.333333333333,
"y":458
"x":520.833333333333,
"y":577.5
},
{
"class":"",
@ -493,6 +493,17 @@
"width":32,
"x":482.666666666667,
"y":433.333333333333
},
{
"class":"",
"height":32,
"id":15,
"name":"OldMan",
"rotation":0,
"visible":true,
"width":32,
"x":581,
"y":584
}],
"opacity":1,
"type":"objectgroup",
@ -501,7 +512,7 @@
"y":0
}],
"nextlayerid":5,
"nextobjectid":15,
"nextobjectid":16,
"orientation":"orthogonal",
"renderorder":"right-down",
"tiledversion":"1.9.2",

124
main.c

@ -41,15 +41,22 @@
#define ENTITIES_ITER(ents) for(Entity *it = ents; it < ents + ARRLEN(ents); it++) if(it->exists)
double clamp(double d, double min, double max) {
double clamp(double d, double min, double max)
{
const double t = d < min ? min : d;
return t > max ? max : t;
}
float clampf(float d, float min, float max) {
float clampf(float d, float min, float max)
{
const float t = d < min ? min : d;
return t > max ? max : t;
}
float clamp01(float f)
{
return clampf(f, 0.0f, 1.0f);
}
// so can be grep'd and removed
#define dbgprint(...) { printf("Debug | %s:%d | ", __FILE__, __LINE__); printf(__VA_ARGS__); }
Vec2 RotateV2(Vec2 v, float theta)
@ -1101,8 +1108,10 @@ bool maybe_deactivate(TouchMemory *memory, uintptr_t ended_identifier)
TouchMemory movement_touch = {0};
TouchMemory roll_pressed_by = {0};
TouchMemory attack_pressed_by = {0};
TouchMemory interact_pressed_by = {0};
bool mobile_roll_pressed = false;
bool mobile_attack_pressed = false;
bool mobile_interact_pressed = false;
float thumbstick_base_size()
{
@ -1133,6 +1142,10 @@ Vec2 roll_button_pos()
return V2(screen_size().x - mobile_button_size(), screen_size().y * 0.4f);
}
Vec2 interact_button_pos()
{
return V2(screen_size().x - mobile_button_size()*2.0f, screen_size().y * (0.4f + (0.4f - 0.25f)));
}
Vec2 attack_button_pos()
{
return V2(screen_size().x - mobile_button_size()*2.0f, screen_size().y * 0.25f);
@ -1777,7 +1790,7 @@ float y_coord_sorting_at(Vec2 pos)
y_coord_sorting = 1.0f - y_coord_sorting;
// debug draw the y cord sorting value
#if 1
#if 0
char *to_draw = tprint("%f", y_coord_sorting);
draw_text((TextParams){true, false, to_draw, pos, BLACK, 1.0f});
#endif
@ -2176,9 +2189,10 @@ double elapsed_time = 0.0;
double last_frame_processing_time = 0.0;
uint64_t last_frame_time;
Vec2 mouse_pos = {0}; // in screen space
bool roll_just_pressed = false; // to use to initiate dialog, shouldn't initiate dialog if the button is simply held down
bool interact_just_pressed = false;
float learned_shift = 0.0;
float learned_space = 0.0;
float learned_e = 0.0;
#ifdef DEVTOOLS
bool mouse_frozen = false;
#endif
@ -2230,7 +2244,7 @@ void frame(void)
// better for vertical aspect ratios
if(screen_size().x < 0.7f*screen_size().y)
{
cam.scale = 2.5f;
cam.scale = 2.2f;
}
else
{
@ -2243,6 +2257,7 @@ void frame(void)
Vec2 movement = {0};
bool attack = false;
bool roll = false;
bool interact = false;
if(mobile_controls)
{
movement = SubV2(thumbstick_nub_pos, thumbstick_base_pos);
@ -2252,6 +2267,7 @@ void frame(void)
}
attack = mobile_attack_pressed;
roll = mobile_roll_pressed;
interact = interact_just_pressed;
}
else
{
@ -2264,6 +2280,7 @@ void frame(void)
attack = attack || keydown[SAPP_KEYCODE_LEFT_CONTROL];
#endif
roll = keydown[ROLL_KEY];
interact = interact_just_pressed;
}
if(LenV2(movement) > 1.0)
{
@ -2814,44 +2831,45 @@ void frame(void)
}
}
// roll input management, sometimes means talk to the npc
if(player->state != CHARACTER_TALKING && roll_just_pressed && closest_interact_with)
if(interact)
{
if(closest_interact_with->is_npc)
{
// begin dialog with closest npc
player->state = CHARACTER_TALKING;
player->talking_to = frome(closest_interact_with);
}
else if(closest_interact_with->is_item)
if(closest_interact_with)
{
// pick up item
closest_interact_with->held_by_player = true;
player->holding_item = frome(closest_interact_with);
if(closest_interact_with->is_npc)
{
// begin dialog with closest npc
player->state = CHARACTER_TALKING;
player->talking_to = frome(closest_interact_with);
}
else if(closest_interact_with->is_item)
{
// pick up item
closest_interact_with->held_by_player = true;
player->holding_item = frome(closest_interact_with);
}
else
{
assert(false);
}
}
else
{
assert(false);
if(gete(player->holding_item))
{
// throw item if not talking to somebody with item
Entity *thrown = gete(player->holding_item);
assert(thrown);
thrown->vel = MulV2F(player->to_throw_direction, 20.0f);
thrown->held_by_player = false;
player->holding_item = (EntityRef){0};
}
}
}
else
if(roll && !player->is_rolling && player->time_not_rolling > 0.3f && (player->state == CHARACTER_IDLE || player->state == CHARACTER_WALKING))
{
// in this branch, we know that no interacting with npcs or items is going to happen.
// but we still have to process roll input
if(roll_just_pressed && gete(player->holding_item))
{
// throw item
Entity *thrown = gete(player->holding_item);
assert(thrown);
thrown->vel = MulV2F(player->to_throw_direction, 20.0f);
thrown->held_by_player = false;
player->holding_item = (EntityRef){0};
}
else if(roll_just_pressed && !player->is_rolling && player->time_not_rolling > 0.3f && (player->state == CHARACTER_IDLE || player->state == CHARACTER_WALKING))
{
player->is_rolling = true;
player->roll_progress = 0.0;
}
player->is_rolling = true;
player->roll_progress = 0.0;
}
if(attack && (player->state == CHARACTER_IDLE || player->state == CHARACTER_WALKING))
@ -2940,8 +2958,7 @@ void frame(void)
reset_level();
}
}
roll_just_pressed = false;
interact_just_pressed = false;
} // while loop
}
@ -2951,6 +2968,14 @@ void frame(void)
// if somebody, show their dialog panel
if(interacting_with)
{
// interaction keyboard hint
if(!mobile_controls)
{
float size = 100.0f;
Vec2 midpoint = MulV2F(AddV2(interacting_with->pos, player->pos), 0.5f);
draw_quad((DrawParams){true, quad_centered(AddV2(midpoint, V2(0.0, 5.0f + sinf((float)elapsed_time*3.0f)*5.0f)), V2(size, size)), IMG(image_e_icon), blendalpha(WHITE, clamp01(1.0f - learned_e)), .y_coord_sorting = Y_COORD_IN_FRONT, .queue_for_translucent = true});
}
// interaction circle
draw_quad((DrawParams){true, quad_centered(interacting_with->pos, V2(TILE_SIZE, TILE_SIZE)), image_dialog_circle, full_region(image_dialog_circle), WHITE});
if(interacting_with->is_npc)
@ -3221,6 +3246,10 @@ void frame(void)
draw_quad((DrawParams){false, quad_centered(thumbstick_base_pos, V2(thumbstick_base_size(), thumbstick_base_size())), IMG(image_mobile_thumbstick_base), WHITE, .y_coord_sorting = Y_COORD_IN_FRONT});
draw_quad((DrawParams){false, quad_centered(thumbstick_nub_pos, V2(thumbstick_nub_size, thumbstick_nub_size)), IMG(image_mobile_thumbstick_nub), WHITE, .y_coord_sorting = Y_COORD_IN_FRONT});
if(interacting_with)
{
draw_quad((DrawParams){false, quad_centered(interact_button_pos(), V2(mobile_button_size(), mobile_button_size())), IMG(image_mobile_button), WHITE, .y_coord_sorting = Y_COORD_IN_FRONT});
}
draw_quad((DrawParams){false, quad_centered(roll_button_pos(), V2(mobile_button_size(), mobile_button_size())), IMG(image_mobile_button), WHITE, .y_coord_sorting = Y_COORD_IN_FRONT});
draw_quad((DrawParams){false, quad_centered(attack_button_pos(), V2(mobile_button_size(), mobile_button_size())), IMG(image_mobile_button), WHITE, .y_coord_sorting = Y_COORD_IN_FRONT});
}
@ -3353,12 +3382,17 @@ void event(const sapp_event *e)
{
roll_pressed_by = activate(point.identifier);
mobile_roll_pressed = true;
roll_just_pressed = true;
}
if(LenV2(SubV2(touchpoint_screen_pos, interact_button_pos())) < mobile_button_size()*0.5f)
{
interact_pressed_by = activate(point.identifier);
mobile_interact_pressed = true;
interact_just_pressed = true;
}
if(LenV2(SubV2(touchpoint_screen_pos, attack_button_pos())) < mobile_button_size()*0.5f)
{
mobile_attack_pressed = true;
attack_pressed_by = activate(point.identifier);
mobile_attack_pressed = true;
}
}
}
@ -3386,6 +3420,10 @@ void event(const sapp_event *e)
for(int i = 0; i < e->num_touches; i++)
if(e->touches[i].changed) // only some of the touch events are released
{
if(maybe_deactivate(&interact_pressed_by, e->touches[i].identifier))
{
mobile_interact_pressed = false;
}
if(maybe_deactivate(&roll_pressed_by, e->touches[i].identifier))
{
mobile_roll_pressed = false;
@ -3408,9 +3446,9 @@ void event(const sapp_event *e)
assert(e->key_code < sizeof(keydown)/sizeof(*keydown));
keydown[e->key_code] = true;
if(e->key_code == ROLL_KEY)
if(e->key_code == SAPP_KEYCODE_E)
{
roll_just_pressed = true;
interact_just_pressed = true;
}
if(e->key_code == SAPP_KEYCODE_LEFT_SHIFT)
@ -3421,6 +3459,10 @@ void event(const sapp_event *e)
{
learned_space += 0.15f;
}
if(e->key_code == SAPP_KEYCODE_E)
{
learned_e += 0.15f;
}
#ifdef DESKTOP // very nice for my run from cmdline workflow, escape to quit
if(e->key_code == SAPP_KEYCODE_ESCAPE)
{

@ -16,7 +16,6 @@ DONE - nockin git thing
DONE - Make TREE1 prop work
- Instead of roll animation, 5 sprite long trail of past moves for juice
- Enemy hitting NPC is enemy perception not player peception of player hitting them
- GodRock spawns skeletons like a boss when he fights you
- Sword combat for sword npcs
- Third button for dialog/item stuff, not roll button. E on desktop. Touchscreen button only visible when appropriate to let player know what it's for
DON'T NEED, SET BACKGROUND COLOR - Clamp camera to boundaries of level
@ -35,6 +34,7 @@ SHIP BETA
Later:
- Respond to cancel with stripe, redirect to ?cancelled=true that clears day pass ticket cookie and ui value
- Strange ring item from braid that slows down time?
- GodRock spawns skeletons like a boss when he fights you
- Put playgpt.io in twitch title
- Portal at end, exit level
- Keep people away from skeletons, make aggroed/chase state where you can't talk to people

Loading…
Cancel
Save