phpgl / php-towerdefense

A 3D tower defense game written in PHP.
78 stars 3 forks source link

Action System (Input Handling) #6

Closed mario-deluna closed 1 year ago

mario-deluna commented 1 year ago

We require a simple abstraction system in VISU to handle inputs context dependent. My plan is to have 2 layers:

Action Map

Action Contexts

Action Queue

Finally for more complex actions, especially actions that require parameters I suggest an action queue:


$actionQueue = new ActionQueue();

// ... 
$this->dispatcher->register('input.click', function(ClickSignal $signal) 
{
     if ($entity = $this->matchesSomeConditions($signal)) {
         $actionQueue->push(new SelectEntityAction($entity));
     }
});

// in the update loop
function update(Entities $entities)
{
    while($action = $actionQueue->pop()) {
        if ($actionQueue instanceof SelectEntityAction) {
            // .. do whatever is needed
        }
    }
}
mario-deluna commented 1 year ago

@borisstock First version:

https://github.com/phpgl/visu/commit/1c11d25363e8070c3c74357493c5b85ff53ce6a2

und

https://github.com/phpgl/php-towerdefense/commit/b120f30600cddc38110eecf8e0c8543cbb0b4103

A key map can be defined over the container:

input.actions.level_editor.selected: VISU\OS\InputActionMap()
     - importArrayMap({
         place: '#click',
         rotate_left: '@Key::COMMA',
         rotate_right: '@Key::PERIOD',
         scale_up: '@Key::K',
         scale_down: '@Key::L',
         delete: '@Key::BACKSPACE',
         copy: '@Key::C',

System can then use the input context like so:

if ($inputContext->actions->isButtonDown('rotate_left')) {
    $transform->orientation->rotate(0.01, new Vec3(0, 1, 0));
} else if ($inputContext->actions->isButtonDown('rotate_right')) {
    $transform->orientation->rotate(-0.01, new Vec3(0, 1, 0));
}

if ($inputContext->actions->isButtonDown('scale_up')) {
    $transform->scale += 0.1;
} else if ($inputContext->actions->isButtonDown('scale_down')) {
    $transform->scale -= 0.1;
}

if ($inputContext->actions->didButtonRelease('copy')) {
    // ...
}
mario-deluna commented 1 year ago

Combination of:

Should cover most cases for input handling for now.