Advertisement

Best way to implement (simple) events/triggers in my platformer game

Started by November 17, 2013 07:41 PM
2 comments, last by ApochPiQ 11 years, 3 months ago

Sorry, I'm not good at being brief. You can probably get a good enough idea of what I need by only reading half of this but if you read the whole thing you'll really understand my specific situation and be able to give me very relevant advice. I really appreciate any help I receive as I want to get started coding this soon and I want to employ the help of this community to make better design decisions than I would if I were doing this completely alone.

I'm working on the editor for an android/ios/pc game I'm making(with libgdx),

(side question: when making a game that has a level editor I usually start by making the editor first and then copy the project and building the actual game off of the editor codebase after the editor is already working, is this a good approach? I like having the game playable/testable from inside the editor so most the gameplay code is already there).

It's just a 2d heavily physics-based platformer with an interesting main concept/gameplay but technically it's nothing to complicated. The least trivial part of the code is the part this thread is about, the whole event/trigger system. I'll give some examples to explain what I mean by event/trigger system in my game:

The player is running along the obstacle course of a map that exists in my game and steps on a floor platform that looks slightly different from all the other ones around it, this triggers a laser to spawn behind the player, it stands vertically on the platform and starts moving towards the player at a steady speed. After 10 seconds, or when the laser reaches a predefined point, it despawns.

Another example would be the player is running along the same level and everything is going fine but he comes into contact with an invisible 'trigger object'(which is just a rectangular object with no graphic that I placed on the level solely to trigger an event when the player unknowingly 'collides' with it) that is placed directly below a platform with a huge boulder on it. When the player hits the transparent rectangle it starts a 1.5 second timer and when that timer runs out the platform above crumbles causing the boulder to fall down potentially crushing the player.

I am just looking for the best way to implement this kind of system. I want it to be flexible because I like to be able to try out many different ideas once my game is completed enough to prototype a bunch of different ideas, but I do know for the most part what kinds of things I want these events to do: enable/disable an object, set a movepath(a set of points, in order, with a set speed, which any game object(platform/obstacle/whatever) will follow in order when it's set to that movepath, apply a force to an object(I'm using box2d for physics so that'll be easy), and anything else I think of(any general ideas anyone?). An event should have one or multiple of these 'actions' and the ability to happen instantly when triggered, after a preset time interval, or after an animation ends(e.g for the crumbling platform it'd wait a second, play the animation, then at the end of animation despawn the platform).

My current plan:

I will have an 'event editor' window(probably just a JFrame with swing components) that I can open from my main editor window. the event editor will list all the events for that level. Each event will consist of a list of 'actions.'

First you create a new event, then click add action. select the action type(enable, disable, apply force, set movepath, etc) and depending on the action type it'll display different options/properties. E.g for set movepath it might give you the options target object, movepath#

(movepaths will be part of the object they belong to, objects can have multiple movepaths and only 1 active at a time), repeating/looping. Each action will also have properties for general things like delay time. you can add as many actions as you want to an event.

The whole event will also have some options such as the trigger. You can select the trigger from a list of 'triggers' you created in the editor. To create a trigger you can select an object in the editor(e.g the invisible rectangle or the strange platform) and in the objects properties window(also a JFrame that you can open from the main editor window) click create collision trigger and then type in a name for it so it's easy to find later when assigning it to an event(hmm, maybe for collision trigger I'll also have an option to select the object it needs to collide with to trigger a collision, so events can be triggered by objects touching other objects instead of just the player touching an object). So far collisions are the only triggers I've thought of, but I just had the idea of having an 'event trigger' action so I can chain events together, I don't know if that would be useful though or if I might as well just add more actions to the first event instead of having it trigger a second event with more actions. If anyone has any fun ideas for things that might trigger an event in a typical platformer let me know.

If i go with this idea(right now that's what I'm planning on doing, although i fear it won't be flexible enough) I'll implement it by having 'Action,' 'Event,' and 'Trigger' objects:

Game objects that trigger events have 'Trigger' objects. When player touches one of these gameobjects the object will call activate() on all it's trigger objects. A trigger object has a list of events and its activate() method just calls start() on all these events.

The start() method of an event will add itself to the 'activeEvents' arraylist which is located in the same class as my main gameloop. the gameloop calls the update() method on all events in the activeEvents arrayList. Event.update() first takes deltaTime as a parameter and adds that time to the 'runningTime' variable of the event class. Then the update method loops through the 'unactivatedActions' arraylist in the event class and if runningTime is greater than the delay time for that action it'll call that actions activate() method and move it from unactivatedActions to the activatedActions array. once the unactivatedActions arraylist is empty it calls the finish() method on the event, this method removes the Event from the activeEvents array in the gameloop class, switches the activatedActions and unactivatedActions arrays back, and does whatever else I'll need to do when an event finishes.

The level file will save all this information('l'll probably save levels as JSON, but if anyone wants to make an argument for XML or something else please do so). a level file will consist of a list of GameObjects listed by ID and their properties, trigger id's+properties, event id's+properties, and Action Id's+properties. the json for a gameobject will store the location of the physics body file in my assets folder(I use some physics body editor which stores a box2d body and it's corresponding .png graphic), location, rotation speed, density/restitution/friction values, a list of movepaths(each movepath being a list of points, each point being a location, movespeed, and pauseTime), and a list of triggers id's. triggers will be stored by there id and consist of a list of the id's of the events it triggers. events will be stored by id and consist of a list of action id's. actions will be stored by id and store the delay time followed by the action type and a list of properties that pertain to that action type(e.g movepath# for movePath Actions).

Loading a level will work like this,

load all objects first and store the trigger id's in the objects. Then load all the triggers, events, and actions into arrays where the array index corresponds to the id's. then loop through each object and for each object loop through all the trigger id's, for each trigger id copy the trigger object from the trigger array we just created to the objects trigger array, and as soon as a trigger is added loop through all it's event id's, grab those events from the event array i just loaded from the file and add those to the event array in the trigger class, for each event added loop through the events action id's and copy all the correct actions from the action array I just created to the action array inside the event.

Hmmmmm.. or I could just load all the objects and store the trigger id's in the objects. and load all the triggers/events/actions into separate arrays that are held in my game class and just use the id's to do everything. So the object only has a list of trigger id's that point to indices in the main Trigger array, and the Trigger objects in the Trigger array just have int id's pointing to Events from the main event array and so on, and just code my logic to work off the id's and Trigger/Event/Action arrays instead of having the triggers belong to objects, events belong to triggers, and actions belong to events. Can someone help me figure out the pros and cons of each of these methods I really don't understand. Or point out flaws in my ideas/suggest better ideas for me. ANYTHING that will help me design my game/code better

Thanks Gamedev

This sounds fine. I'm not sure what your actual question is?

I say go for it, and if it turns out it doesn't do something you wanted, revisit it then. Stressing too much about it will just get in the way of finishing your game.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Advertisement

Thanks, I do tend to stress over things like that too much lately and it interferes with my progress. I'm just go for it like you said and start doing it according to the plan I described above. I think the reason I tend to stress over that stuff too much is because in the past I would always work on projects that were too ambitious and I wouldn't be able to get more than halfway done without my code being such a horrible mess that I was afraid to look at it, and now I'm afraid of falling into the same pattern. I'm trying to identify why I always ended up in that situation and figure out how to avoid it this time.

The fact that I'm better at programming now and this project is much less ambitious relative to my skill level is probably going to make a big difference. Also I'm trying not to rush in the beginning like I usually do just so I can get to the point where my game is playable ASAP, I'm just taking it one part at a time and trying to follow good practices and be consistent in my conventions/design. And I'm planning things out more thoroughly beforehand(perhaps I'm overdoing that part though?). If anyone has any suggestions to help with getting to the finish line without my codebase becoming unmaintainable/umanagable that'd be very helpful(aside from all the typical things people always say that I've probably already thought of or heard several times).

hmmm I really didn't have a very clear question there, I suppose what I'm doing is just looking for reassurance that my plan makes sense. I've never designed or programmed anything as complex as this, not that this is very complex or anything, and I feel like I'm just stabbing around in the dark when I try and come up with solutions for these kinds of problems. So it's nice to get a little reassurance to make me feel more confident in my design before I spend hours and hours implementing it. Also I wanted to get any advice or specific tips to improve my design because I want to stretch my ability as far as possible on this project and do as good as I possibly can so that I can make a bigger leap forward in terms of learning(I think of each bigger project I do as a little leap forward in my programming skill, if it isn't I feel like I wasted my time).

I have to learn to slow down my mind a little bit so I can make more sense and stay on topic better when I post on forums

Here's some advice that took me a long time to learn:

Code is not set in concrete.

If you find code that you're working on to be messy or hard to understand, don't be afraid to rewrite it or clean it up. Deleting code is not a sin. Look into the set of techniques commonly referred to as "refactoring" for some practical ideas on how you can do this. If you're constantly making sure your code is solid and maintainable in small increments, it's never going to cause a project to completely fail. It essentially becomes a non-issue because you deal with the complexity in tiny changes and improvements instead of waiting for it to collapse under its own weight.


Another thing you might find useful is the idea of write one to throw away. This is decent advice for relatively inexperienced programmers, because it takes a ton of practice to reach a point where thinking about a design up-front is actually productive. You don't know what you don't know, so write a quick prototype and learn all the things you didn't realize were going to come up (good and bad). Don't obsess over planning for every contingency. Even expert programmers fail to think of possibilities all the time.

Instead, start out and get some momentum. It doesn't matter if you're heading in the "wrong" direction if you follow the first rule, and constantly course-correct and improve your work when it needs it. You'll find that over time you learn to keep thing separated so that if one part of your code is bad you can just redo it without impacting the whole project, and so on.

The best way to learn is experience. Planning ahead is just a way to deprive yourself of the experience you need in order to learn.

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

This topic is closed to new replies.

Advertisement