fisholith's Recent Forum Activity

  • Hey, emoaeden.

    I have to start by seconding chrisinfinger's sentiment. Very cool looking game.

    I can't be sure, but the problem you're running into might have two parts.

    Firstly, while you are checking each power line segment, you may not be checking them in an order that propagates power the way you want.

    Secondly, determining connectivity, or a lack of connectivity, may not be possible by making a single top-to-bottom left-to-right pass over all the tiles.

    Tile checking order:

    To illustrate what I mean through the power of ASCII art,

    Suppose we have a power plant (represented by "#"), and a chain of power line segments (represented by 0 or 1 depending on powered state.)

    From here on, I'll call the power plant a "plant" and each power line segment a "seg".

    Plant on left, with five powered segs.

    #11111

    Now I may be interpreting the capx events wrong, but it looks like there's a nested XY loop that checks every cell, starting from the top-left, moving top to bottom in columns, and moving left to right from column to column. As the loop runs, for each cell, if that cell is powered, then power is propagated to the cardinally adjacent cells.

    I think this may mean that power will propagate asymmetrically, moving much faster from top to bottom than from bottom to top.

    Consider the following 1-dimentional example in which we loop through segs from left to right. The act of running a loop, until all loop iterations are complete, I will refer to as a single "pass".

    Start: #00000 (6 tiles so we will do 6 steps inside each pass.)

    ---- Pass 1:

    index 0: #10000

    index 1: #11000

    index 2: #11100

    index 3: #11110

    index 4: #11111

    index 5: #11111

    ---- Done in 1 pass.

    Now, consider a case where the plant is on the right instead of the left. Note that the loop still steps from left to right:

    Start: 00000# (6 tiles so we will do 6 steps inside each pass.)

    ---- Pass 1:

    index 0: 00000#

    index 1: 00000#

    index 2: 00000#

    index 3: 00000#

    index 4: 00000#

    index 5: 00001#

    ---- Pass 2:

    index 0: 00001#

    index 1: 00001#

    index 2: 00001#

    index 3: 00001#

    index 4: 00011#

    index 5: 00011#

    ---- Pass 3:

    index 0: 00011#

    index 1: 00011#

    index 2: 00011#

    index 3: 00111#

    index 4: 00111#

    index 5: 00111#

    ...

    ---- Pass 4:

    ...

    ---- Pass 5:

    ...

    index 5: 11111#

    Done in 5 passes.

    So it takes much longer to propagate power against the direction the loop is stepping. In the above cases, if you do a pass every 5 seconds, then it will take 5 seconds to propagate power from left-to-right, and it will take 25 seconds to propagate power right-to-left, over the same distance. If the power line was 20 segments long then it would still take 5 seconds to propagate moving right, and 100 seconds to propagate moving left.

    This might be part of the strange behavior you're seeing.

    Connectivity checking issue:

    So the other issue is determining connectivity.

    The problem here is that I don't think you can determine connectivity in a single top-to-bottom left-to-right pass. In the example above, when the power is advancing against the loop stepping direction, a single pass only advances powered status by a single tile, and it takes multiple subsequent passes to complete the propagation. (Again, a pass is not a single loop step, it's the processing of all tiles once.)

    In theory, every time a seg was destroyed, you could set every tile to un-powered, and then immediately run a number of full passes equal to the number of power line segs in the game, and while that would mark all power lines correctly when it finally completed, it would be prohibitively time consuming.

    Assuming I'm thinking about this right, (and I may not be) below is an example of why we can't solve connectivity in a single pass.

    Suppose you destroy a seg in the middle of a chain of powered segs,

    going from this

    #11111

    to this

    #_1111 (with the underscore "_" representing the bulldozed seg.)

    You now have 4 isolated segs in a chain, all marked as being powered.

    The problem is, when making a pass over all the tiles, how do you know if a seg should be un-powered?

    That is, suppose you're in the loop, stepping through tiles,

    index 0: #_1111

    index 1: #_1111

    index 2: #_1111 (we arrive at the left end of the isolated chain)

    and you come to the left end seg of that chain of 4 segs. It's marked as powered. How would you be able to tell if it shouldn't be? Well, it's not connected to a plant, but it *is* connected to another powered seg. Inside the loop, you can't tell whether the chain is powered from the other end, so you can't tell whether it should be powered or un-powered.

    That is, you could be dealing with this case,

    index 2: #_1111#

    With a plant on the right-hand end that seg could have a legitimate reason for being powered. There's no way to know inside the loop, because we can only check the neighboring segs.

    As an interesting aside, Minecraft has a very similar problem. Leaf blocks are "powered" by log blocks. A leaf block is only immune to decay if it was connected to a log block, or if it is connected through a chain of leaf blocks to a log block. In this sense it is exactly what you're trying to solve, but in a 3D grid instead of a 2D grid. Verifying that a leaf block is connected to a log block through a chain of leaf blocks involves path finding through neighboring leaf blocks to see if a path exists. Minecraft also has a max radius from log blocks (4), beyond which it doesn't bother doing any path finding, and instead a too-distant leaf block is simply doomed to decay.

    Connectivity checking - possible solution:

    In order to quickly determine connectivity, you might be able to use a "backtracking" algorithm.

    It would work kind of like this:

    Set all segs to un-powered.

    For each power plant:

    Start walking along a chain of segs coming out of it, marking each segment "powered" as you go.

    Every time you come to a branch (e.g. T-intersection) you put the "hub" tile's coords on a stack. Now you pick one of its un-powered branching tiles and start walking along that chain.

    If you reach a dead end, then pop the last "hub" tile off the stack (if one exists) and jump ("backtrack") directly back to that tile, and continue walking along the next un-powered branch. (Note: If it doesn't have an un-powered branch then treat it just like a dead end.)

    Eventually you'll have hit every dead end, and followed every branch, and there will be nothing left to pop off the stack.

    If you check every power plant, this way, when you're done, the only power line segs that will be un-powered will be those with no connectivity to a plant.

    If two power plants are connected to each other by a chain of segs, then the first power plant check will leave all those segs marked "powered" so the second power plant check will end instantly in a dead end, which is good, because you don't have to re-check any segs.

    Okay, sorry for the lengthy post. The more I started thinking about it the more I realized it's a pretty interesting problem.

    Hope that helps at all.

  • Hey bscarl88,

    I have a thought on how you might be able to get this effect.

    It sounds like what you want is to have a solid shape trail behind the blade, kind of the way a silk flag would follow a flagpole, if you were to sweep the pole from side to side. Though, with one difference, the "flag" shape should only stretch from "where the blade is now" to "where the blade was last frame". Such that when the blade is not moving you won't see the flag shape.

    We will need the following objects:

    • An extra blade object, to keep track of "where the real blade was last frame". I'll call this extra blade the "lag blade". The lag blade is just a helper object and will be invisible during play. -
    • A sprite object that is just a 2x2 or 4x4 white square, with its hotspot on the center left edge. We can stretch this object horizontally to draw lines from point to point, which we'll need to do later. I'll call this stretchable line object a "Strip" object.

    Setting up the lag blade:

    Starting simple, we need to make the lag blade follow the movement of the real blade, but the lag blade has to lag one frame behind the real blade. So where ever you created the events that move the real blade, pick a spot right before those events, and add an event to set the lag blade to the real blades position and angle. This way the lag blade is positioned, and THEN the real blade is moved to its new location, at which point the lag blade is doing its job of being one frame behind the real blade.

    Drawing the "flag" shape - overview:

    Now that we have a real blade and a lag blade, we can stretch a "flag" between them. The flag will be made of several of our strip objects.

    Starting simple, lets imagine that we place one strip object at the tip of the real blade. Then we angle the strip object to look at the tip of the lag blade. Then we stretch the strip object out until it touches the tip of the lag blade. Now the strip has one end (the hotspot end) on the real blade's tip, and the other end on the lag blade's tip. This creates the top edge of the flag shape. (In practice, this positioning will be done through events, not by hand.)

    Now let's add in another strip object. This new strip will do exactly the same thing we just did, but instead of connecting the real tip to the lag tip, we connect the real hilt to the lag hilt. and that creates the bottom of the flag shape.

    We can add another strip and connect the middle of the real blade to the middle of the lag blade in the same way.

    Using this process we can create several more strips to "fill" in the rest of the flag.

    Drawing the "flag" shape - example:

    A practical way to set this up with events would be to, create 20 or 30 strips, and then use a loop to position them correctly. You'll want enough strips so that they overlap, and there are no gaps left between them, otherwise you'll get a Venetian blinds look. (Then again that could be kind of cool, but I'll assume we want a solid shape.)

    To position the strips you'll need the coordinates along a line from the tip to the hilt of the real blade, and you'll also need the coordinates along a line from the tip to the hilt of the lag blade.

    To simplify getting these coords, you can create an image point at the tip of the real blade, and an identical image point at the tip of the lag blade. Inside the loop that positions each strip, you can use the "lerp()" function to interpolate from the tip coord to the hilt coord of the real and lag blades respectively. That is, on the first loop step, you'll start at the tip of both blades. As you go through successive loop steps, you'll step from the tip towards the hilt on both blades. On the last loop step you'll reach the hilt coord on both blades.

    This will give you the flag shape, dynamically drawn every frame based on the movement of the blade. This essentially simulates the rotoscoping process that was actually done for the light saber trail effect in the Star Wars films.

    This brings up an interesting point though. A theatrically shot film is 24 frames per second, and you're game will likely run at 60 fps. So a single frame in Star Wars is 2.5 times longer than a single frame of your game. This in turn means that the 24-fps "flag" effect will be 2.5 times physically longer than a 60-fps "flag" effect for an object moving at the same speed. So to really get the light saber effect, you may need to make the flag longer than a single frame, and I'll explain how to do this later.

    Polishing the effect:

    So we have the flag effect, and it's the correct shape, but it's also solid white, which may not be what you're looking for. (Or maybe it is, but I'll assume it's not, just in case.)

    • Semi-transparency: It might be nice to make it semi-transparent, like 50% opacity or something. But we can't just set the strip objects to be transparent because they may overlap each other a little bit and so you could end up with a pinstripe look along the flag shape. What you can do instead is create a layer for the flag shape, place all the strip objects on that layer, and turn the layer's opacity down to 50%. -
    • Longer trail: Making the flag trail for more than a single frame can also be done. The simple, albeit un-optimized way, would be to *create* strips inside the loop, instead of just positioning existing strips. This means you can fade out and destroy strips at whatever speed you want. But the overhead of creating a bunch of objects every frame could get ugly on slower devices. A cleaner way to get longer trails would be to pick, in advance, the number of frames you want the trail to last, say 3, and then create 3 groups of strips, one for each frame. Give the strip object type an instance variable "frameGroup", and use it to give each group of strip objects a number, 0, 1, 2. Inside the loop that positions the strip objects, first pick only the strips that belong to group 0, then on the next frame pick only group 1, etc. When you get to the last group, you just wrap back to group 0. Each frame, only the most outdated strips will get updated.

    As a side note, Construct Classic provided a way to lattice deform sprites, which would solve your problem far more simply, but it is not a feature that has been added into C2 yet, at least not to my knowledge. In C2 it might be possible to simulate lattice deformation via shader effects, though getting the deformed result to line up with specific coords could be tricky.

    Sorry for rambling a bit.

    Hope that helps.

  • I had a thought for a possible feature.

    In the "Edit" dialog for event group settings, there could be an "Allow deactivation" checkbox.

    This might eliminate the need for every event group to have a unique name.

    What it might solve:

    Currently, any group can be disabled with the System > "Set Group Active" action.

    The "Set Group Active" action takes a group's name as a parameter.

    This means that every group in the entire project must have a unique name. (even across separate event sheets)

    Group deactivation is a cool feature, but when I create a group, 99% of the time it's just for organization purposes, and will never be deactivated. Unfortunately, there's no way to tell C2 that I will never want to disable the vast majority of groups, and so C2 still requires me to give every one of them a unique name.

    Now that I'm working on larger projects, I'm starting to append a namespace prefix (based on the event sheet name) to the groups I create to prevent group name collisions between event sheets. As a side effect, group names are getting longer and more visually cluttered.

    How it could work:

    If we add an "Allow deactivation" checkbox into the group settings, then individual groups can opt out of needing a unique name. Or since the majority of groups will never need to be deactivated, the default could be that groups must opt *in* to needing a unique name.

    Again, I like the group deactivation feature, but I usually only use groups for organization. Even according to the Scirra manual, "Groups of events are mainly for organizing events."

    Anyway, just a thought.

  • Problem Description

    For the Dictionary object, there's a possible typo in its event-block condition text.

    When the Dictionary object's, condition "Compare current value" is added to an event, the resulting condition in the event block reads "Current key = " instead of "Current value = "

    Attach a Capx

    [attachment=0:2po313ua][/attachment:2po313ua]

    Description of Capx

    This capx shows two examples of the Dictionary condition text typo.

    (See the event sheet. It includes comments.)

    Steps to Reproduce Bug

    • 1. Open a new project.
    • 2. Add a Dictionary object.
    • 3. In the event editor, create a new event, and as the condition, choose the Dictionary's "Compare current value" condition.
    • 4. In the condition parameters dialog, leave the settings as they are ("equal to" and "0") and click the "Done" button.
    • 5. In the newly created event block, notice the wording of the text in the compare current value condition. It says s "Current key = 0" instead of "Current value = 0"

    Visual Walk-through:

    Another example where the confusing nature of the typo might be a little clearer.

    Observed Result

    When the Dictionary object's, condition "Compare current value" is added to an event, the resulting condition in the event block reads "Current key = "

    Expected Result

    Perhaps it should instead read "Current value = "

    Affected Browsers

    • Chrome: n/a (the bug is only visible at edit time, within the C2 application.)
    • FireFox: n/a
    • Internet Explorer: n/a

    Operating System and Service Pack

    Win 7 Pro - SP1

    Construct 2 Version ID

    Release 178 (64-bit)

    Built at 19:13:26 on Aug 19 2014

    Identified as "Stable update r178" in release notes.

  • Thanks jayderyu,

    I'm actually familiar with the built-in iterator for the Dictionary. I'm not having a problem with the functionality. I just think I might have spotted a typo in the text describing the functionality.

    I've included some images below.

    You can also check for yourself by opening a new project, adding a Dictionary, and then adding the Dictionary's "Compare current value" condition to any event. The typo seems to be in the event block text for that condition.

    Walk-through:

    Another example where the confusing nature of the typo might be a little clearer.

  • Hi all,

    Is there a simple way to copy a family from one project to another?

    In the Project panel it doesn't look like you can drag families between projects, and since families don't have a physical presence on the layout there's nothing physical to copy.

    If I save the source and destination projects as project folders (instead of single files), would it be possible to move some kind of family file between projects without causing corruption?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I just noticed a possible problem with the Dictionary object's block text.

    When I add the condition "Compare current value", the resulting condition in the event block reads "Current key = ..." instead of "Current value = ..."

    That is, it says it's comparing a key, when it's really comparing a value.

    Does this happen for anyone else?

  • No problem, hope it works out.

  • How would I launch Node-Webkit, with a command line switch enabled, on OSX and or Linux?

    (I hope it's okay to ask this here.)

    My situation

    I have a game exported with Node-Webkit.

    If I launch Node-Webkit with the switch "--disable-threaded-compositing", the game runs perfectly.

    If I launch Node-Webkit without it, the game is essentially unplayable, with huge lag, and intermittent 1 to 10 second freezing.

    The .bat solution for Windows

    In Windows, I can make a "launchThyStuff.bat" file containing the line "gameName.exe --disable-threaded-compositing"

    How would I do the equivalent for OSX and Linux?

    Do I edit the exported files, by adding "--disable-threaded-compositing" somewhere?

    Do I create a special .bat-like file for OSX/Linux?

    I'm just not familiar enough with this kind of stuff when it comes to those operating systems, so any advice is very much appreciated.

  • Hey, trueicecold

    I did find one way that works but it's a little derpy.

    I tried a few things, so I can also tell you what doesn't work.

    Local variable - (does work, but kind of inelegant)

    Take the set of events you want to break out of, and put them under a blank event, just to carve out a local scope for your set of events.

    At the top of the event set, create a local variable like "b_break" = 0, and add the condition " b_break == 0" to each of the events in your event set. Now, if you set b_break to 1 anywhere in your event set, all the following events will be skipped.

    Stop loop - (doesn't work)

    Take the set of events you want to break out of, and put them under a For Loop that runs for 1 loop. Then use System > Stop loop. Unfortunately, all the remaining events will complete regardless of where you try to stop the loop. So, "stop loop" just prevents the next loop from running.

    Deactivate group - (doesn't work)

    Deactivating a group from inside the group has a very similar effect as stop loop. The rest of the events in the group will continue to execute as normal after the group has been deactivated. However, after deactivating the group, the "Group is active?" condition will test as false even if you're doing the test from within the now deactivated group.

  • No problem. Glad I could help.

  • Hey mariogamer,

    The layout size and window size are two separate things. (You may know this already so sorry if I'm misinterpreting the question.)

    The window size might have to change to fit different devices, but the layout size probably doesn't.

    If I recall, The layout size is only really relevant for behaviors like "destroy if outside layout", and for convenience while placing objects to make up your game world. As long as the layout is big enough for you to work comfortably, then you should be okay.

    For instance, I tend to set the layout size to be pretty large, and most of the time I don't use all of it. The only thing an end user will see is the part of the layout that shows up in the game's window.

    One of the other features of layout size that might be important, is that if you scroll your view around in your game, the game window will stop at the edge of the layout by default. You can free up the window to scroll off the edge of the layout by clicking the layout in the project panel, and in the layout's properties, you can enable "Unbounded scrolling".

fisholith's avatar

fisholith

Member since 8 Aug, 2009

Twitter
fisholith has 2 followers

Connect with fisholith

Trophy Case

  • 15-Year Club
  • Forum Contributor Made 100 posts in the forums
  • Regular Visitor Visited Construct.net 7 days in a row
  • RTFM Read the fabulous manual
  • Email Verified

Progress

19/44
How to earn trophies