Overriding the d-pad with custom events

In Pulp the A and B buttons can be scripted to behave as you like, but the d-pad always makes the player move.

I've already battled with changing the default movement on a few different occassions, and I know I am certainly not the first! In those situations I ended up with a specific implementation for the behaviour I wanted, but I thought it would be fun (and maybe even useful) to go one step further and try to make a generic framework for overriding d-pad input in Pulp. This is probably overkill for a lot of use cases, but it may be helpful nonetheless!

My goal was to try and make something as idiomatic to Pulpscript as possible. If pressing the A button triggers the confirm event, and pressing the B triggers the cancel event, it would make sense for pressing a direction on the d-pad to trigger its own specific event. Otherwise I wanted an implementation that was as transparent as possible, not limiting use of Pulpscript if at all possible.

Example Project

Here is what I have come up with:

Overriding Dpad Input Demo.zip (4.9 KB)

The code is heavily commented (hopefully) for clarity, but I'm very happy to answer any questions about it. I'm also very open to any suggested improvements, I'm certain to be missing some tricks!

For this example I re-implemented standard directional movement, with an item that inverts input for a short duration, but you might make the d-pad buttons do just about anything you like.

The Code

This is all in the example project, but it's nice to share in the forum right? This is just the actual code that is needed for overriding d-pad input, and I've removed all of my comments for brevity.

The game script:

on start do
  config.autoAct = 0
  px = event.px
  py = event.py
  room = "room"
end

on loop do
  skip_detect_dpad_input = 0
  frame_player_update_count = 0
end

The player script:

on update do
  frame_player_update_count++
  
  if room!=event.room then
    room = event.room
    px = event.px
    py = event.py
  end
  
  call "detectDpadInput"
  if dpad_input==1 then
    undoing_move = 1
    goto px,py
    done
  end
  
  if undoing_move==1 then
    undoing_move = 0
    call "processDpadInput"
    done
  end
  
  px = event.px
  py = event.py
end

on detectDpadInput do
  dpad_input = 0
  if skip_detect_dpad_input==1 then
    done
  end
  
  if frame_player_update_count==1 then
    if event.dx<0 then
      abs_dx = 0
      abs_dx -= event.dx
    else
      abs_dx = event.dx
    end
    if event.dy<0 then
      abs_dy = 0
      abs_dy -= event.dy
    else
      abs_dy = event.dy
    end
    abs_dxdy = abs_dx
    abs_dxdy += abs_dy
    if abs_dxdy==1 then
      dpad_input = 1
      call "determineDpadInput"
    end
  end
end

on determineDpadInput do
  dpad_up = 0
  dpad_down = 0
  dpad_left = 0
  dpad_right = 0
  
  if event.dy==1 then
    dpad_down = 1
  elseif event.dy==-1 then
    dpad_up = 1
  elseif event.dx==1 then
    dpad_right = 1
  elseif event.dx==-1 then
    dpad_left = 1
  end
end

on processDpadInput do
  if dpad_up==1 then
    call "dpadUp"
  elseif dpad_down==1 then
    call "dpadDown"
  elseif dpad_left==1 then
    call "dpadLeft"
  elseif dpad_right==1 then
    call "dpadRight"
  end
end

on dpadUp do

end

on dpadDown do

end

on dpadLeft do

end

on dpadRight do

end

Usage

With the above code in place, scripting behaviour for d-pad input should be as easy as using the player events for each direction button! The events that get triggered are:

  • dpadUp
  • dpadDown
  • dpadLeft
  • dpadRight

You should be free to write any valid Pulpscript in these events. While in the example project I have re-implemented standard movement, you could just as easily have pressing up on the d-pad do something like call say and make a dialogue box appear.

Constraints

Despite wanting to make the implementation as transparent as possible I ended up with a few constraints that must be adhered to:

  • The collect event must be overriden on all item tiles. In the example project I implement a new pickup event as a replacement for collect.

  • Exits cannot be used. In the example project I show how item tiles can be used as exits, but various alternative approaches are possible.

  • If goto is called in a frame without d-pad input, and is targeting a tile adjacent to the player's current position, this may incorrectly get interpreted as d-pad input to be processed. In this specific situation the variable skip_detect_dpad_input should be set to 1 before calling goto.

And possibly more, but hopefully not! Remember that all variables are global in Pulpscript so you must make sure your own don't clash (or change those used in the code).


Hopefully this is of interest to someone. I'm certainly interested in hearing of other ways people have solved this problem, and I am especially interested if anyone has a better solution for detecting d-pad input! :playdate_happy:

4 Likes

amazing

i was literally thinking today during a walk : "i wonder what it would take to make a mirror room - where the movements were opposite or different ? -- hmmm... maybe the d-pad can behave differently? i wonderrrrrr..."

very cool / great demo.

Wish I had this the other day when I was trying to override the d-pad, with mixed success.

Glad this is of relevance!

If I were wanting regular movement in most places and inverted/different movement in just one or a few rooms, I think I would take the simpler approach of changing the behaviour only in those rooms.

Either with an if event.room=="room name" then in the player's update event followed by the relevant code, or a neat way of inverting movement in a room would be to contain the behaviour inside an item tile - its collect event could use event.dx and event.dy to check the solidness of the tile in the opposite direction from which the player moved onto it and then move the player to that tile if non-solid or to the tile they came from otherwise.

I'm sure there are other ways too, all more contained and less overbearing than always overriding d-pad input like here!

I think I would only champion the approach in this example project if I never wanted the default movement behaviour and always wanted the d-pad to be used for something else.

1 Like

Could this be used in a way to create a platformer style game within Pulp? By adding "gravity" and creating platforms that the player can interact with, it seems possible. Obviously the tiling scale would effect the performance, but it could be an interesting limitation.

It could! In fact, although I implemented it differently (as I was only worried about preventing vertical movement with the d-pad), I made a platformer in Pulp and shared it in this post.