Pulstar's Recent Forum Activity

  • The solution should work for any number of nodes. Although the execution time should be proportional to the square of the number of nodes.

    I think what is happening is the pontifex function not firing. Either because node booleans were not reset to false after new lanes were generated or because the conditions for it firing did not work. I did a few dozen runs of this and did not encouter the issue eith the version i attached to my previous post. Unless that is an old file.

    Send me the link to your capx via PM. I wil check what the issue is in 10 hours when I get home.

  • I solved the disconnected isles issues. Red lanes are lanes created by the gap-bridging logic I created:

    Basically I added another boolean to nodes, which is only set to true after the connect function is fired for nodes connected via lanes to the initiating node. So if the number of nodes that are checked and the number of nodes that are connected is the same, but it is not equal to the number of total nodes, it means that unconnected nodes exist. Then I launch a "Pontifex" function that finds connected-unconnected node-pairs that have the least distance between their nodes. It retrieves two such pairs, creates lanes between them and lanes between the second least distant unconnected node, relative to the connected node of the pair. So 4 lanes per gap with two choke-points per gap. The overlap function may delete a lane or two, but it is guaranteed to create at least one lane per every gap (two for most).

    It then goes back before the connection checking functions and runs them again. Once it finds that checked nodes=connected nodes=total nodes it stop running the generation logic.

    https://www.dropbox.com/s/d1qsk715wkmtz ... .capx?dl=1

  • A second question, how do I make this static once it's generated?

    For example, in a run of the game I would need to generate 10 of these on the start of the game and I would need access to these during the game.

    They already are static, so long as you do not run the generation events again or change layouts in game. Any loss of nodes on layout changes can be avoided by adding persistent behaviour to all randomly generated objects. You just need to remember that when you switch back to a layout all initial objects (stuff you place/see in the editor) will also be placed. So you need to check carefully if everything is where it should be and no new objects appear. Or worse, so you don't delete already existing nodes when deleting initial objects.

    Alternatively, since you just need it for a map where you just pick it once every 5-15 minutes and do nothing else, you can have the sector branching map a separate layer above the fully random node map. Hide that layer when it is unneeded (FTL does this with the star map I think). However that approach has a different problem. You need to add some conditions to all clickable objects/nodes so that nothing happens when the branching map is visible or invisible. On clicked/touched events for invisible sprites to register.

    Personally, as my current project is using lots and lots of window/screen for procedurally generated spaceships. I add a boolean to all button objects, if say ship weapons or ship cargo screens are visible (ship window button is set to true) I do not allow selecting a different ship to work as the ships are on a layer behind the window screens so you could click-through them.

    If you go with the layer approach, I also recommend naming your layers and always using the string/text name in events (not the layer number), as adding deleting any layers of your project changes the layer number order and it becomes a chore changing all the numbers to the current ones and keeping track of them.

  • Oh nice!

    Would there be an easy way to limit the space between nodes? For example it would be nice to not have nodes close together.

    I guess you could just offset them if the distance of a line is too short?

    I managed to overcome that and get rid off lanes overlapping each other in the middle of space, see below capx. I have the events check if the distance to the closest node other than itself is less than 70 pixels. Then I have it offset the node and check again if any nodes are closer than 70 pixels to each other. Once no nodes are found I have it stop checking and moving nodes. There is a second way of avoiding the problem, it involves generating nodes inside grid sections and not allowing more than one node to be generated within a grid section. That requires different random node generation logic though. I may show how to do that later on.

    Now I am stuck at checking if there is a path from start to exit. I have a function that marks all nodes connected to start, I know how to connect any "islands" if start is not connected to them. Problem is determining when the functions I did encountered a dead end as there are multiple instance of the connect function running in parallel.

    https://www.dropbox.com/s/d0ltq4t9b6c1k ... .capx?dl=1

    Regarding copying the FTL select sector map, you do two loops, one within the other. One is for the X axis the other for the Y axis. Next you generate nodes like this:

    condition: mod(loopindex("x")/2)=1 action: set offset=100

    condition: mod(loopindex("x")/2)=0 action: set offset=0

    loopindex("x")*200,loopindex("y")*200+offset

    I would show an example if I had the time, it is quite late and I am unfortunately rather busy tomorrow. Really want to solve that "node is connected" problem though.

  • Do a for loop("x") for 1 to number of bricks in a row, within another for loop("y") for 1 to number of rows. I suggest setting the origin of the brick sprites to the lower-left corner, unless you want to offset the math I wrote below.

    Under the bottom level loop("x") add a condition "compare two values" Random(0,100)>20 (that's 80% odds, adjust as you see fit), and do the following actions:

    System actions>create object at layer 0 (or whichever you wish) x = (brick.width*loopindex("x"))+left boundary, y=(brick.height*loopindex("y"))+upper boundary.

    EDIT:

    Changing the left boundary and upper boundary as well as the number of rows and number of bricks per row will make the bricks appear only in a specific part of an area/grid. Upper boundary and left boundary can be variables (randomly set at that), ditto for number of rows or number of bricks per row.

    Ok, maybe leave the origin as top-left and start from for 0 to (desired row total number-1), bottom-left origin is counter-intuitive:

  • Something similar can be done with overlapping, but when I set current value of variable+1, it just goes razor fast up without limiting to the increment of 1.

    This is because it adds 1 every tick/frame while the apple is on the cup. I do not know if you just want it to be 1 for on cup, 0 if not on cup or if you want 1 to be subtracted/added every second. In the case of the latter, change add/subtract "1" to "1*dt", that will add one per second regardless of framerate.

    You have three options if you just want 1 or 0 for on cup:

    1) Instead of add to/subtract from variable use "set value" action.

    2) Add a "trigger once while true" condition to the overlap event.

    3) Don't use a global variable, add a boolean variable to the apple object called OnCup and set it to true/false if it is overlapping/not overlapping.

  • Is there any way to make objects from families share variable types, but give them each individual amounts OF that variable?

    Let's say I have 3 bullet types in the family "PlayerShots". I want each to do an individual amount of damage, but I don't want to have to make each enemy have 3 different reactions to said bullets, but instead just subtract their health by the variable in each individual bullet's damage amount.

    Yes, set the variable on playershots then edit all the members of playershots individually in the editor on the object list, changing the default value of the damage variable for them. Newly spawned instances of all those objects should correctly use the same default values as other bullets of that type.

  • So you want to make a FTL-like random star map with lanes?

    Turns out this is actually rather difficult. Difficult but not impossible. Took me ~3 hours to figure it out and I have some experience with doing random generation in construct. The solution involves a fair deal of loops, functions and some array operations. Not sure if there are simpler ways to do this.

    First of all you need your lanes to know to what they connect, I added A and B variables which store the ID of nodes which the lane connects. Connecting them in a sensible manner is the tricky part.

    Basic idea was: generate nodes, after nodes are generated create lanes to 3 nearest other nodes, after all lanes are generated you delete duplicate lanes. To find the 3 nearest node you need an event sequence that for each node stores the distance to all nodes (including itself) in y=0 and the node ID at y=1 in an array's x element. Then you sort the array by axis X, go through elements 1 to number of lanes and create lanes to them.

    Hardest part was deleting duplicate lanes actually. Took me an hour before I figured it out, the solution was surprisingly simple and short.

    Linked capx with my solution below, right click-release generates new node set. Please bear in mind that it has 2 problems which you will have to figure out yourself.

    https://www.dropbox.com/s/z9hlr5i169lnc ... .capx?dl=1

    1) It is possible to generate node "isles" that are fully disconnected from other isles, the smaller the numbers of MaxLanes the more likely this is to occur. Wonder how the FTL guy solved this. He probably wrote code that checks if there is a path between the starting and ending node and created one if needed, that's the efficient solution. The lazy brute-force solution is to check if there is a path and if not generate the whole nodemap again.

    2) Sometimes nodes overlap, this should not be too hard to fix. I would do a function for that after all nodes are generated but before you start generating lanes, that offsets overlapping nodes.

    Also, compared to the image you attached, it has overlapping lanes. But that could be fixed some clever overlap checks, you would put lane in a family, check if the family object overlaps a lane object, mark for deletion (similar logic to removing duplicates).

  • my code seems logical but does not works. (Logic internal function..."for each instance" ?)

    your solution works very well.

    .

    No problem. However you have to realize that your events set the every random seconds condition every engine tick (so every frame). Enemy_go=1 was true every tick.

    The event would set it once and then overwrite it in the next frame up to 60 times a second, as a new for each loop runs every tick. Also once it finished the for each enemy loop it should no longer track the every random seconds, as the tracking exists only within the for each loop and ceases to exist once the loop finishes. That is why I wrote that I was surprised that it even worked for one enemy at all.

    As timer behaviour exist outside of events (just like other object properties and variables) it works in such cases.

  • You need to edit the family and add a family instance variable called life, this will automatically be added for all family members. Then you can click on enemy A, enemy B and enemy C individually to change the default instance variable value of life for them.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Hello (excuse my english), <img src="{SMILIES_PATH}/icon_redface.gif" alt=":oops:" title="Embarrassed">

    How do I jump enemy every radom second with "for each instance" function.

    I tried that but it is jumping all at once or just one jump.

    http://joueralamaitresse.com/test/enemy_jump_random.capx

    Help me please. <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    If I understood you correctly:

    Use timer behaviour (add it for the enemy object), set timer to random duration for each enemy. On timer expiration do jump and then set new timer with new random duration.

    I personally avoid putting every X seconds inside a for each object loop, because loops need to finish their actions within one tick/frame. Timer behaviour was made for such things (that need to be executed across multiple frames/ticks) and it works great.

    Please see attached capx (I decided to go with 1-3 seconds between jumps, also disabled your events for jumping):

    https://www.dropbox.com/s/e5igcja8182g9 ... .capx?dl=1

    Note: this will only work if no new enemies are created after layout start. If new enemies are created while it is running, you would also need to add an "on enemy create" event to set the timer for that new enemy.

Pulstar's avatar

Pulstar

Member since 10 Jan, 2016

None one is following Pulstar yet!

Trophy Case

  • 8-Year Club
  • Email Verified

Progress

9/44
How to earn trophies