akien-mga / dynadungeons

Bomberman clone using Godot Engine - Not actively developed since 2015.
GNU General Public License v3.0
217 stars 37 forks source link

Gameover screen #16

Open akien-mga opened 9 years ago

akien-mga commented 9 years ago

Should show and congratulate the winner, or a draw screen if it's there's no winner. Clicking it should send back to the main menu (at least until we implement multi-round games).

ghost commented 9 years ago

or a draw screen if it's there's no winner

Would this mean that a round timer needs to be implemented? Or is it solely for both players dying at the same time / via the same bomb?

ObaniGemini commented 9 years ago

I think both solutions could be implemented. Also, maybe should we use two layers for the screen : one with the background and one with the text (if there is a background)

ghost commented 8 years ago

Need some input here. Clicking is mentioned as the dismiss action in the OP, but I see that there's a ui_accept input that already exists and seems to fit the bill just as well.

Should I: a) Go with ui_accept as is (Keyboard only) b) Create a new input action, assign left click to it, and use that as the dismiss action (Mouse only) c) Assign left_click to ui_accept and then go with that (Keyboard and Mouse)

ghost commented 8 years ago

Just about finished this one by adding in a new process_deaths function, but can't for the life of me get around a small bug.

func process_deaths():
    var players = level.player_manager.get_children()
    var size = players.size()
    var alive = 0
    for player in players:
        if player.dead != true:
            alive = alive + 1
    if (alive == 0):
        gameover.get_node("Label").set_text("It's a draw!")
        gameover.show() # Does not accept input but other one does
    elif ((size - alive) == 1):
        var winner
        for player in players:
            if player.dead != true:
                gameover.get_node("Label").set_text("Player " + str(player.id) + " wins!")
        gameover.show()

For some reason the if (alive == 0): portion won't allow me to dismiss the gameover prompt (even when removing the elif below, in case it was interfering somehow), but the elif portion works fine.

Probably missing something obvious but just can't spot it. Any ideas?

akien-mga commented 8 years ago

Are you running this from _fixed_process in the player script? It will get run at each frame for each player, so the gameover prompt will be shown over and over and over as long as alive is null.

Since this code chunk does not need anything from the current player, it should be moved in another script, maybe level.gd, or wherever it fits best.

ghost commented 8 years ago

Yes, that's right, running it from _fixed_process. Then the code I added in previously chimes in so that the gameover prompt can be dismissed:

func process_gameover():
    if gameover.is_visible() and Input.is_action_pressed("ui_accept"):
        get_tree().change_scene_to(global.menu_scene)

I can dismiss the prompt fine when the elif portion runs (code from my previous comment) but not when the if portion above it runs.

Thanks for your response, though I'm still a bit confused. Do you know why the elif portion isn't affected? I would have expected it to react in the same way (gameover prompt being shown over and over) because as the difference between size and alive is 1 for multiple frames.

And yes, can move the code into level.gd. Had only left it in player.gd because the original snippet dealing with the winner was there. Will shift it over once I get it working properly.

akien-mga commented 8 years ago

I'm not exactly sure why the elif runs only once when the if runs ad libitum, but at any rate it shows that using _fixed_process to show UI elements is not a good idea. _fixed_process should be reserved to gameplay elements that actually need to be refreshed at each frame, else it's a useless loss of resource - I haven't seen your full changes yet but it looks like it will process the gameover stuff at each frame for the whole game when it only needs to be processed when a player dies, at it is done in the current implementation IIRC.

Basically, you just need to catch the "Hey I'm dead!" event from a player, and send it over to whichever node will have the code to handle it - level.gd sounds like a good match. For example:

A style comment: better use if !player.dead than if player.dead != true :)

ghost commented 8 years ago

Thanks heaps, will give it a shot :)