4
\$\begingroup\$

I'm working on a side scrolling game that has a number of timed puzzle elements. As a simple example: I have a number of moving platforms that have been setup to transition in a pattern. Ideally I'd like to ensure that as the player first approaches them, they are in an ideal state -- whereby the player can witness the full transition and more experienced players (i.e: speedrunners) can complete the puzzle immediately without having to wait for the current transition to complete.

The issue here, in a nutshell, is that because these platforms begin transitioning at the start of the level, it's impossible to correctly calculate when the player is likely to stumble upon them.

I've done a fair bit of Googling but haven't managed to turn up any decent resources with regards to solving a problem like this. The obvious solution is to only begin updating the objects when the player (or more likely: the camera) first encounters them. But this becomes difficult when you consider more complicated situations.

It seems like potentially the easiest way of handling this is to have an invisible trigger volume that will tell any puzzle elements located inside of it that the player has 'arrived' upon first colliding with the player. But this would mean I'd have to logically group puzzle elements, which could become fairly messy in a hurry. Take, for instance, a puzzle that appears to the right of the screen. It may take the player a number of seconds to reach it. It would look strange if the elements involved were to remain stationary. But by the time the player arrives, it's likely things will be 'out of sync'.

I wanted to post here in the hopes that others know of, or have implemented, a decent solution to this problem?

\$\endgroup\$
1
\$\begingroup\$

Have you considered using a messaging system like the observer pattern, or the publish/subscribe pattern. You could create a trigger object, register any platform that needs to be notified with the trigger object. Then when the trigger goes off it informs all those that are listening that the event has happened. The nice thing is you can have as many or as few event listeners that you need and they do not have to be aware of each other. Just place the trigger somewhere before the player gets to the platforms. If the trigger is a non-drawing game object, the player will be completely unaware of it.

public class TriggerableGameObject extends GameObject {
    public void start() {
        // Override this in derived class.
        // Start action
    }
}


public class GameObjectTrigger extends GameObject{
    private ArrayList<TriggerableGameObject> gameObjectList;

    public void register(TriggerableGameObject gameObject) {
        gameObjectList.add(gameObject);
    }

    public void unregister(TriggerableGameObject gameObject) {
        gameObjectList.remove(gameObject);
    }

    public void notify() {
        for (TriggerableGameObject gameObject : gameObjectList) {
            gameObject.start();
        }     
    }

    public void onDraw() {
        // leave blank if you do not want the trigger to be visable
    }
}

Obviously I am making some assumptions about your class hierarchy, but I think you get the idea. This behavior would work well for what you are asking about, as well as animatiable floor switches and pressure plates. Also, implementing something like this would allow you to make a trigger control more than just a platform, for example: dropping block, swinging chains, flooding rooms, etc. Anything you derive from TriggerableGameObect can be registered with a GameObjectTrigger, (or more than one if you like).

\$\endgroup\$
1
\$\begingroup\$

If the concern is for speed running, you can measure how far the player is from the puzzle "entrance" by the time they first see a part of the puzzle, calculate how long it will take to reach the puzzle entrance at top speed, and rewind the puzzle state by that many seconds.

Most games just make periodic events happen often enough that you're unlikely to miss one by too long. If you're making a game for speedrunners, you should allow for some creativity when navigating sections anyway.

\$\endgroup\$
0
\$\begingroup\$

In the past I did something exactly like what you said, Group the Puzzles elements, and trigger then on player distance, this ensures that they are in the same state no matter what time it took to reach there, after that its the player responsibility to move fast toward it or to wait, this will make speed runners have pretty much the same puzzle once they reach there, only varying based on their performance to reach the goal.

Clarifying the distance concept, the easier way ( I am assuming its 2D) its just to check the max BoundingRect of all the puzzle elements, if the player ViewArea intersects that of the puzzle + some offset, start the puzzle mechanics. This works quite well to tell the truth.

The only draw back is the time needed to setup the puzzles.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.