EngoEngine / engo

Engo is an open-source 2D game engine written in Go.
https://engoengine.github.io
MIT License
1.75k stars 136 forks source link

Click handling #59

Closed EtienneBruines closed 8 years ago

EtienneBruines commented 8 years ago

How should clicks be handled according to the ECS?

In javascript/html, there's some kind of propagation: the foremost element is clicked, then passed along to any other element that may have been involved ; and each time the element has the ability to stop the propagation.

In ECS, I would assume there is some kind of System that monitors whether or not something gets clicked?

Any best-practices here? Anything I misunderstood? (I imagine the "buttons" in the "main menu" I'm creating, to be some kind of clickable)


Current status

paked commented 8 years ago

AFAIK there is no "Clicking Idiom" in ECS. @matiwinnetou correct me if I am wrong.

Clicking is something we desperately need though, I am a big fan of the propagation model from javascript/html though.

Would you mind if I took this PR?

EtienneBruines commented 8 years ago

Be my guest. :+1:

paked commented 8 years ago

@EtienneBruines what are your thoughts on implementing this handler at the World level?

EtienneBruines commented 8 years ago

A ClickSystem, together with ClickComponents.

If an Entity has a ClickComponent, the ClickSystem will use the SpaceComponent and Mouse values to see if it's being clicked, and if so, either set some value at ClickComponent to CLICKED, or perhaps dispatch some Message?

Misread your message. At the World level... hmm. They'd have to register some kind of OnClick event, but who should do that? Systems could do that, I guess.

Or just dispatch a Message, and then everyone can Listen for those messages if he/she pleases?

paked commented 8 years ago

@EtienneBruines I think implementing this as a System is a good idea. Although, if we do this we may as well remodel the way key input works as well.

I believe going with the messaging model for this would serve us best.

EtienneBruines commented 8 years ago

Well, with keys the state is kinda important: just clicked, holded, released, etc. And combinations of keys.

A click is simply a click.

paked commented 8 years ago

@EtienneBruines state can actually be important for clicks too.

Imagine a button: You want to act when the button has been released!

Imagine a shooting game: You want to act when the button is first pressed, and perhaps when it is continuously held down.

Either way however, this is irrelevant (for both clicks and key presses). Data can be transferred within a message which could be used to contain the state.

For example

engi.Mailbox.Listen("ScoreMessage", func(message engi.Message) {
    scoreMessage, isScore := message.(ScoreMessage)
    if !isScore {
        return
    }

    sc.scoreLock.Lock()
    if scoreMessage.Player != 1 {
        sc.PlayerOneScore += 1
    } else {
        sc.PlayerTwoScore += 1
    }

    log.Println("The score is now", sc.PlayerOneScore, "vs", sc.PlayerTwoScore)

    sc.upToDate = false
    sc.scoreLock.Unlock()
})
EtienneBruines commented 8 years ago

Good point. Messages are kinda cheap anyway, so we could do that, yes.

paked commented 8 years ago

Thoughts @matiwinnetou?

EtienneBruines commented 8 years ago

(We should also note that this should indeed also cover things like hover)

EtienneBruines commented 8 years ago

Have you already started working on this, or can I create something with a ClickSystem and ClickComponent, which has some states (i.e. Clicked, Hovered, Focused, etc.)?

(I'm making a little game, and am in need of this; don't want to rush you, but also don't want to wait if you don't have time for it anyway; again: I do not mean this in a negative way, whatsoever. :smile: )

paked commented 8 years ago

@EtienneBruines feel free to take this.

EtienneBruines commented 8 years ago

Tricky; currently at "how to handle zooming", and "how to handle scrolling to the sides".

The very basics work.

paked commented 8 years ago

:+1:

On Fri, Nov 27, 2015 at 8:20 AM Etienne Bruines notifications@github.com wrote:

Tricky; currently at "how to handle zooming", and "how to handle scrolling to the sides".

The very basics work.

— Reply to this email directly or view it on GitHub https://github.com/paked/engi/issues/59#issuecomment-159995290.

EtienneBruines commented 8 years ago

Current status:

TODO

faide commented 8 years ago

Etienne, Paked,

I am using the current head from paked/engi and I am using the MouseSystem and MouseComponent to handle clicks on a HUD entity of mine.

At the moment I note that the mouse component does not give me access to the "Mouse Released" event. If I try to use the mc.Clicked against my entity I receive a lot of events (I assume this is normal because my poor fingers are not quick enough to compete against 120fps...) and I'd like to receive only one because each click will launch actions and cost resources. I can (and did) implement some kind of filter based on timing but I find it brittle and error prone.

I would like to make the "mouse released inside your entity" available through the MouseComponent as mc.Released. I don't see the big picture yet so it is possible this event does not make a lot of sense and a better solution already exists... please just let me know if this is the case.

What do you think of it? If you are interested I'll propose a PR.

BTW I added to this issue instead of opening a new one because of the "click system" focus of my question

paked commented 8 years ago

@faide If you want to take a crack at this, I'd be happy to review the pull request!

faide commented 8 years ago

@paked I did first run here: #146

paked commented 8 years ago

Correct me if I'm wrong, but #146 fixed this.