Multiple local inputs. You can now play with your 3 friends locally, fighting over the same keyboard.
This commit is contained in:
@@ -26,7 +26,7 @@ static void state_enter(Presentation_State *state) {
|
||||
.offset = (Vector2) { 0, 0 },
|
||||
.target = (Vector2) { 0, 0 },
|
||||
.rotation = 0.0f,
|
||||
.zoom = 3.0f
|
||||
.zoom = 2.0f
|
||||
};
|
||||
|
||||
// TODO: SS - Maybe put the textures in an array and index them using an enum?
|
||||
@@ -43,6 +43,47 @@ static void state_enter(Presentation_State *state) {
|
||||
assert(IsTextureValid(ctx->texture_snake_body));
|
||||
}
|
||||
|
||||
static Simulation_Game_Input gather_input_for_local_player(uint8_t local_player_index) {
|
||||
switch(local_player_index) {
|
||||
case 0: {
|
||||
return (Simulation_Game_Input) {
|
||||
.up = IsKeyDown(KEY_W),
|
||||
.down = IsKeyDown(KEY_S),
|
||||
.right = IsKeyDown(KEY_D),
|
||||
.left = IsKeyDown(KEY_A)
|
||||
};
|
||||
}
|
||||
case 1: {
|
||||
return (Simulation_Game_Input) {
|
||||
.up = IsKeyDown(KEY_UP),
|
||||
.down = IsKeyDown(KEY_DOWN),
|
||||
.right = IsKeyDown(KEY_RIGHT),
|
||||
.left = IsKeyDown(KEY_LEFT)
|
||||
};
|
||||
}
|
||||
case 2: {
|
||||
return (Simulation_Game_Input) {
|
||||
.up = IsKeyDown(KEY_I),
|
||||
.down = IsKeyDown(KEY_K),
|
||||
.right = IsKeyDown(KEY_L),
|
||||
.left = IsKeyDown(KEY_J)
|
||||
};
|
||||
}
|
||||
case 3: {
|
||||
return (Simulation_Game_Input) {
|
||||
.up = IsKeyDown(KEY_T),
|
||||
.down = IsKeyDown(KEY_G),
|
||||
.right = IsKeyDown(KEY_H),
|
||||
.left = IsKeyDown(KEY_F)
|
||||
};
|
||||
}
|
||||
default: {
|
||||
assert(false);
|
||||
return (Simulation_Game_Input) {0};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void state_tick(Presentation_State *state) {
|
||||
Presentation_State_Ingame_Context *ctx = (Presentation_State_Ingame_Context *)state->context;
|
||||
(void)ctx;
|
||||
@@ -53,16 +94,31 @@ static void state_tick(Presentation_State *state) {
|
||||
assert(session != NULL);
|
||||
|
||||
{ // Push local input to queue.
|
||||
Simulation_Game_Input input = (Simulation_Game_Input) { // NOTE: SS - This needs to be slightly modified to support N local players.
|
||||
.up = IsKeyDown(KEY_UP) || IsKeyDown(KEY_W),
|
||||
.down = IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S),
|
||||
.right = IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D),
|
||||
.left = IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)
|
||||
};
|
||||
if(instance->amount_of_local_players == 1) { // If playing alone (either singleplayer or online-multiplayer), more inputs are allowed.
|
||||
Simulation_Game_Input input = (Simulation_Game_Input) {
|
||||
.up = IsKeyDown(KEY_UP) || IsKeyDown(KEY_W),
|
||||
.down = IsKeyDown(KEY_DOWN) || IsKeyDown(KEY_S),
|
||||
.right = IsKeyDown(KEY_RIGHT) || IsKeyDown(KEY_D),
|
||||
.left = IsKeyDown(KEY_LEFT) || IsKeyDown(KEY_A)
|
||||
};
|
||||
|
||||
if(!simulation_input_equal(input, ctx->prev_local_input)) {
|
||||
game_instance_push_local_input(instance, input);
|
||||
ctx->prev_local_input = input;
|
||||
Locally_Controlled_Player *player = &instance->locally_controlled_players[0];
|
||||
|
||||
if(!simulation_input_equal(input, player->prev_input)) {
|
||||
game_instance_push_local_input(instance, 0, input);
|
||||
player->prev_input = input;
|
||||
}
|
||||
}
|
||||
else if(instance->amount_of_local_players > 1) {
|
||||
for(uint8_t i = 0; i < instance->amount_of_local_players; i++) {
|
||||
Simulation_Game_Input input = gather_input_for_local_player(i);
|
||||
Locally_Controlled_Player *player = &instance->locally_controlled_players[i];
|
||||
|
||||
if(!simulation_input_equal(input, player->prev_input)) {
|
||||
game_instance_push_local_input(instance, i, input);
|
||||
player->prev_input = input;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,12 +128,14 @@ static void state_tick(Presentation_State *state) {
|
||||
const double sim_dt = 1.0f / session->settings.tickrate;
|
||||
|
||||
while (ctx->simulation_accumulator >= sim_dt) {
|
||||
// Pop input from instance's local_input_queue and set the local player's input to it, if we have one.
|
||||
Simulation_Game_Input input = {0};
|
||||
if(game_instance_pop_local_input(instance, &input)) {
|
||||
// TODO: SS - We should probably check if this input is invalid for the snake. (pressing "go right" when going left, for example.)
|
||||
// If it is invalid, the next input in the queue should be tried.
|
||||
game_session_set_player_input(session, instance->local_player_id, input);
|
||||
for(uint16_t i = 0; i < instance->amount_of_local_players; i++) {
|
||||
// Pop input from local-player's input_queue and set the player's input to it, if we have one.
|
||||
Simulation_Game_Input input = {0};
|
||||
if(game_instance_pop_local_input(instance, i, &input)) {
|
||||
// TODO: SS - We should probably check if this input is invalid for the snake. (pressing "go right" when going left, for example.)
|
||||
// If it is invalid, the next input in the queue should be tried.
|
||||
game_session_set_player_input(session, i, input);
|
||||
}
|
||||
}
|
||||
|
||||
game_session_tick(session);
|
||||
@@ -325,6 +383,9 @@ static void state_render(Presentation_State *state) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: SS - Let the main-camera follow the entity you're controlling?
|
||||
|
||||
|
||||
// TODO: SS - Switch on 'sim_world->match_state'.
|
||||
|
||||
if(ctx->debug_draw_session_details) {
|
||||
@@ -362,7 +423,7 @@ static void state_render(Presentation_State *state) {
|
||||
networking->is_host ? "true" : "false",
|
||||
networking->session_id,
|
||||
networking->local_client_id,
|
||||
instance->local_player_id,
|
||||
instance->locally_controlled_players[0].player_id,
|
||||
game_session_get_amount_of_active_players(session), sim_world->max_players
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user