fisholith's Recent Forum Activity

  • Happy to help.

    I also noticed that my final version of the example disappeared somehow.

    The image I added is from the final version, but the download link is to an earlier version. I could not find a saved copy of the final version so I rebuilt the last few parts, added in the glideSpeed variable along with quite a bit of commentary on it, and it should now match the posted image, and support deleting blocks with middle-click.

    (also edited my first post to use the v2 example)

    Array Glide Reorder - v2

  • Ah, good catch with the missing glideSpeed,

    I was going to add it in so it would be easy to change the X and Y lerp speed in one place.

    Also, sorry if my reply being directed at you seemed strange. I accidentally referred to your name when I started typing up the post, instead of the OP's name. I edited the starting line to include czar.

    Though, I did take a look at your example capx, and it was cool.

    I like that the reordering is specific to a zone you can drag blocks in and out of, and so ordering is restricted to just that area. It seems like a really practical way to approach a UI element, as I can see how with multiple zones you could drag blocks between them, for things like inventory or card decks.

  • Hey czar and allan,

    (edit: derp, I meant to copy the OP's name.)

    One approach is to add a second private variable to the Block that smoothes out changes in the index variable. Then use that smoothed value to position the Blocks instead of the actual index.

    So in the example I linked below, each block has two private variables, index and indexAnim.

    Where index is the block's sequence in the row of blocks,

    and indexAnim is a variable updated every tick to glide towards the value currently in index.

    So if index changes from 0 to 1, then indexAnim will smoothly transition over several ticks from 0 to 1.

    An easy way to set up indexAnim to do this smooth attraction to the value in index is with the following event.

    Every tick: Set indexAnim to: lerp( indexAnim , index , 0.1 )

    This means that every tick, the indexAnim value will move towards the index value by an amount of 0.1 (10%) of the distance currently between them.

    Example capx

    Here's a commented example capx.

    Array Glide Reorder - v2

    Controls

    Left-click drag blocks.

    Right-click to create new blocks.

    Middle click to destroy blocks.

    Mousewheel to change cell width.

  • Hi Blamitall,

    If I understand correctly, I think you might want the following:

    Set Block1.Y to:

    Block2.Y - ( (Block2.Height /2) + (Block1.Height/2) )

    This adds the radius of B1 and B2, and then subtracts that whole value from the B2.Y.

    Place & move method

    Another handy approach in this kind of situation might be, to use two actions:

    1. B1: "Set position to another object", use B2 as the target object.

    2. B1: "Move at angle" a distance of ( ( B1.h / 2 ) + ( B2.h / 2 ) ), at angle -90.

    This approach separates out the relative offset, which can help make the code a little easier to understand/edit at a glance.

    It's not quite as efficient as setting the cords directly, but the slight difference in efficiency will likely only be noticeable if you do it 10,000 times a tick.

    So this method isn't strictly better or worse, it just has different pros and cons.

  • Hey spacedoubt,

    So, if I understand correctly, I believe the short answer would be this:

    snapX = ( round( mouse.y / 32 ) % 2 = 0 ) ? ( round( mouse.x / 128 ) * 128 ) : ( ( round( ( mouse.x + 64 ) / 128 ) * 128 ) - 64 )

    snapY = round( mouse.y / 32 ) * 32

    That said, I've also included an explanation of this solution below:

    The math

    What it sounds like you want to do is snap to a diamond shaped grid; basically a rectangular grid with every odd row shifted half a cell length.

    Let's start by thinking of the rectangular un-shifted version of the grid.

    From your capx, it looks like you want a horizontal snap distance of 128, and a vertical snap distance of 32. Now 32 might sound too small, but remember that as soon as we shift every odd row, it will suddenly look like the vertical snap distance is 64, because the vertical separation between tiles will appear to skip a row. But it really isn't skipping a row, and it really isn't 64, it's still 32.

    Unshifted
    #---#---#---#
    #---#---#---#
    #---#---#---#
    #---#---#---#
    
    Shifted
    #---#---#---#
    ..#---#---#---#
    #---#---#---#
    ..#---#---#---#[/code:315nwg0m]
    Now if we shift every odd row by half a cell width, we'll have a diamond grid that will snap 128 x 64 pixel tiles.
    
    [b]Vertical snap[/b]
    So lets start with the vertical snapping since it will be the same regardless of the row.
    We need to snap to steps of 32 pixels.
    
    tileY = round( mouse.y / 32 ) * 32
    
    We are squeezing the 32 pixel tile size down to the size of integers, then using round() to chop off the decimal part, then expanding the rounded result back to the 32 pixel tile size.
    
    [b]Horizontal snap[/b]
    Next lets do the horizontal snapping, but for simplicity, our first version here will not account for the shifting on odd rows.
    It's basically the same as the vertical snapping, but with bigger steps.
    
    tileY = round( mouse.x / 128 ) * 128
    
    Same deal, we squeeze, round, and expand back to normal.
    Now that formula works fine for the even rows, but what about the shifted odd rows?
    Well lets make a similar, but slightly adjusted version of the formula for the odd rows.
    We want to shift the tiles over by half the horizontal step width of 128. So we'll shift by 64.
    
    tileY = ( round( ( mouse.x + 64 ) / 128 ) * 128 ) - 64
    
    So it's basically exactly the same as the even-row formula, except we add a 64 offset to the input "mouse.x", and we subtract it back off after we end.
    Why? Well remember that the heart of our snapping system is the round() function. When we shift everything by half a step width (64), and then divide by an entire step width (128), as far as the round() is concerned we are shifting by "0.5"; and since round() will snap to the nearest integer, it will be snapping exactly halfway between the spots we'd get from the even-row formula. 
    
    But wait, even though we shifted the input, round() is still just snapping to integers, so shouldn't it just expand back to the same snap points that the even-row formula gave us? Yes, it would [b][i]except[/i][/b], remember that we also un-offset the result by half a step width, which is the "- 64" at the very end.
    
    [b]Picking Even or Odd formula[/b]
    Okay, so we have two formulas, but now we have to choose one or the other depending on the row.
    We'll need a formula that tells us if we're on an odd or even row.
    
    round( mouse.y / 32 ) % 2
    
    We squeeze the Y coord from counting pixels down to counting rows by dividing, then use round() to chop off the decimal fluff, leaving us with the integer row number. We then mod the row number by 2, meaning we'll get "0" if the row is even, and "1" if the row is odd. 
    
    Now we just need to say, IF ( row is even ) THEN ( even formula ) ELSE (odd formula).
    You could do this with events, and that would be just fine, but there is a slightly more compact way to handle the IF / THEN / ELSE case, and it's called the "ternary" operator, sometimes called the one-line-IF-statement.
    
    The ternary operator looks like this when used:
    
    ( name = "world" ) [b]?[/b] ( "hello world" ) [b]:[/b] ( "hello person who is suspiciously not world" )
    
    and means this:
    
    [b]IF [/b]( name = "world" ) [b]THEN[/b] ( "hello world" ) [b]ELSE[/b] ( "hello person who is suspiciously not world" )
    
    [i](Note: The "ternary" operator is named for the fact that it takes three arguments, where most operators (like "+" and "-") take only two.)[/i]
    This is exactly what we want to do. 
    We just need to plug in the parts we want to use.
    
    [b]IF [/b]( round( mouse.y / 32 ) % 2 = 0 )
    [b]THEN [/b]( round( mouse.x / 128 ) * 128 )
    [b]ELSE [/b]( ( round( ( mouse.x + 64 ) / 128 ) * 128 ) - 64 )
    
    Using the ternary operator we get this:
    
    ( round( mouse.y / 32 ) % 2 = 0 )   [b]?[/b]   ( round( mouse.x / 128 ) * 128 )   [b]:[/b]   ( ( round( ( mouse.x + 64 ) / 128 ) * 128 ) - 64 )
    
    [b]Final X &Y formulas[/b]
    snapX = ( round( mouse.y / 32 ) % 2 = 0 )   ?   ( round( mouse.x / 128 ) * 128 )   :   ( ( round( ( mouse.x + 64 ) / 128 ) * 128 ) - 64 )
    snapY = round( mouse.y / 32 ) * 32
    
    [b]Modulo operator[/b]
    The JavaScript Modulo operator (%) is ... tricky, to put it diplomatically.
    
    Unlike the more common operators like plus and minus, there's actually no universal standard definition for exactly how modulo is supposed to work, and so there are a few very subtly different versions of it. The version that JavaScript uses (and by extension Construct 2) is one of the weird ones, which does not behave uniformly for positive and negative numbers. 
    There's a nice visual comparison of the mod variations on the [url=http://en.wikipedia.org/wiki/Modulo_operation]modulus wiki page[/url].
    
    This is especially a problem when writing snapping formulas that make use of JS's modulo, as it means the snapping behavior will likewise not behave consistently across positive and negative input coordinates. If you are absolutely certain that you will never feed in a negative value then it's safe-ish to use the JS modulo, though if you inadvertently change that later in a project without realizing it, you may introduce some very subtle bugs as a result of its weird behavior. I personally never use it for anything. I instead use an alternate version of the mod function described below.
    
    There is a version of the modulo operator that does behave uniformly, and that's the "floored division" version.
    Here is the formula for the "floored division" modulo.
    
    [b]mod([/b] val [b],[/b] div [b])[/b] ... = ... val - ( floor( val / div ) * div )
    
    So if you just used substitution to modify the original even-odd-detector formula we made, we'd go from this,
    ( round( mouse.y / 32 ) % 2 = 0 )
    to this,
    ( ( round( mouse.y / 32 ) - ( floor( round( mouse.y / 32 ) / 2 ) * 2 ) ) = 0 )
    
    Not very pretty, but it will work. it would be nicer to be able to simply use a floored division mod function like any other function.
    Well, you can use C2's Function object to create a custom "floored division" style mod function.
    I actually explained how to do this a while back in another post if you're interested, in the subsection [url=https://www.scirra.com/forum/detecting-360-degree-rotation_p883148?#p883148]Getting "floored division" mod into C2[/url] (towards the end of the post).
    
    Hope that helps out.
  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Hey frodoe7,

    Another similar method is to use multiple sprites stacked together.

    Suppose you have a tank in your game, and you want to be able to change the color of the body, the treads, and the turret separately.

    One way to do this is to create a sprite for the body, a sprite for the treads, and a sprite for the turret, and for each one include color variations. The variations can either be in frames as Tetriser suggested, or in their own separate animations within the sprite.

    You can then use the "Pin" behavior to keep all the sprites together.

    This approach can be especially handy if you want to allow for a lot of variations, as the number of color combinations is the product (multiplicative total) of the number of color variations in each sprite.

    So if the tank has 8 colors for each sprite (body, treads, and turret), then the total number of color arrangements is 8 * 8 * 8, which is 512 combinations. It adds (multiplies) up fast.

  • Bundle of 25 themes

    I just put together a bundle of all the themes I've created with my theme editor so far.

    There are 25 themes, about 20 unique themes, with a few of them accompanied by additional variations.

    There are previews of all of them below. For each theme preview, there are two images, showing the base colors and the selection colors.

    This bundle includes a few updates and redesigns of some of my previously posted themes.

    So, I recommend that if you have any of my previous themes installed, delete them before installing this bundle.

    All my themes have filenames beginning with "fi_", which should make them easy to find and remove.

    As always, all feedback and suggestions are welcome.

    Download

    C2 themes - Fisholith bundle v1.zip

    Where to install them

    On Win7, xml theme files are placed in this path:

    "Program Files\Construct 2\themes"

    You don't have to restart C2 to test new themes, but you do have to close event sheets and reopen them to see the theme change take full effect.

    Theme previews

    fi_AmigaWB

    fi_Autumn

    fi_Clean

    fi_CleanGallium

    fi_Felt

    fi_Flat

    fi_Gallium

    fi_Hydrogen

    fi_Hydrogen_selC2

    fi_Marble

    fi_NeonPhoenix

    fi_NightSky

    fi_RedTail

    fi_RedTail_selPink

    fi_Sandy

    fi_ScirraSite

    fi_ScirraSite_selOrange

    fi_SeaNav

    fi_SedonaCandyShop

    fi_SlateAzure

    fi_SlateIndigo

    fi_SlateNixie

    fi_SlateNixie_OliveAccent

    fi_SlateNixie_VioletAccent

    fi_SpruceWoods

  • Bundle of 25 themes

    I just put together a bundle of all the themes I've created with my theme editor so far.

    There are 25 themes, about 20 unique themes, with a few of them accompanied by additional variations.

    There are previews of all of them below. For each theme preview, there are two images, showing the base colors and the selection colors.

    This bundle includes a few updates and redesigns of some of my previously posted themes.

    So, I recommend that if you have any of my previous themes installed, delete them before installing this bundle.

    All my themes have filenames beginning with "fi_", which should make them easy to find and remove.

    As always, all feedback and suggestions are welcome.

    Download

    (See first post for latest release. Newer bundle now included in download.)

    Where to install them

    On Win7, xml theme files are placed in this path:

    "Program Files\Construct 2\themes"

    You don't have to restart C2 to test new themes, but you do have to close event sheets and reopen them to see the theme change take full effect.

    Theme previews

    Click any image to see a full-sized version.

    fi_AmigaWB

    fi_Autumn

    fi_Clean

    fi_CleanGallium

    fi_Felt

    fi_Flat

    fi_Gallium

    fi_Hydrogen

    fi_Hydrogen_selC2

    fi_Marble

    fi_NeonPhoenix

    fi_NightSky

    fi_RedTail

    fi_RedTail_selPink

    fi_Sandy

    fi_ScirraSite

    fi_ScirraSite_selOrange

    fi_SeaNav

    fi_SedonaCandyShop

    fi_SlateAzure

    fi_SlateIndigo

    fi_SlateNixie

    fi_SlateNixie_OliveAccent

    fi_SlateNixie_VioletAccent

    fi_SpruceWoods

  • Hey TabloidA,

    Happy to hear the scaling system seems to be helping out.

    Looks like the preview image saving system may need some additional math, to work correctly with a scaled screen, but I think I can figure that out.

    Oh, did you get a chance to try out the console command "showDisplayStats"? I'd be curious what the editor thinks the DPR and window dimensions are. If there's a DPR of 1.5, that may be the culprit. Though if it's 1.0, then something else is going on.

    Also, very cool looking theme you put together. I look forward to trying it out.

  • Awesome, good to hear

    Sorry for taking a while to reply to your last few posts.

    I actually did end up implementing the click to select feature using the method I described back in my looooong post.

    There is an invisible image (idMap) sitting over the preview with different colors representing different elements. When you click on an element, you're really sampling a color from that idMap, and the color is just a shade of red wherein the value of the red is an ID number. Every element has an associated ID number, and so you just use the ID to look up the corresponding element. This means that I can control exactly which element is selected for any pixel clicked. This is handy because some elements, like boarders, would be really hard to click on, if you had to click exactly on them, as they're 1 pixel wide lines. So I can artificially fatten the clickable ID zones for boarders in the idMap image, to make them easier to click. Likewise for text, I can just use solid bounding boxes for their ID zones, so you don't have to worry about clicking inside an "o" or something.

    Going back to your prior post,

    I hadn't actually considered making the color picker it's own plugin, but that could definitely be handy.

    I did build a color utility plugin though, to simplify a lot of the math and conversions I didn't want to be doing over and over in events. A color utility/math plugin was something that I'd been interested in making for quite a while, and this was as good a time as any to finally start on that. :)

    My most recent game-jam game, Down Ward, has a customizable palette system, and I almost started working on a color math plugin for that, but it was probably for the best that I ended up waiting until I was working on a project that revolved entirely around color, before settling on an approach to designing the plugin. (There should probably be another period in there somewhere, but I'm too tired to figure out where to put it, so I'm just going to leave some extras here ...)

    An infinite scrolling strip probably is the best way to get it small, while preserving the all-hues-pickable characteristic I was interested in. Another possibility might be to show the entire hue strip square when clicking and dragging, but then only show the current band when un-clicked.

    Anyway, thanks as always for the feedback. :)

  • Hey Kraplanta,

    Themes are custom color palettes, that can re-skin event sheet colors, expression editor colors, and layout colors.

    Though they mainly tend to be targeted at just event sheet colors, from what I've seen.

    Applying a theme

    There are some themes that come with Construct other than the basic white-ish theme.

    You can try out one of the other themes by doing the following:

    • Start Construct 2.
    • From the main menu choose File > Preferences, then choose the "Colors" tab.
    • From the "Choose theme" drop-menu, pick a theme to try. (I think C2 comes with 4.)
    • Click the "Load selected theme" button, to apply the colors.
    • Click the "Ok" button to close the preferences window.
    • Finally, any event sheets you had open will need to be closed and reopened for the new theme to take full effect. (Otherwise you'll usually have all the fill colors from the new theme, and all the edge colors from the prior theme, and it looks weird.)

    Installing a theme

    On Win7, any xml theme files you download should be placed in this path:

    "Program Files\Construct 2\themes"

    Remember, you don't have to restart C2 to test new themes, but you do have to close event sheets and reopen them to see the theme change take full effect.

    Were you interested in trying or making a theme?

  • Update - Release 3

    New features:

    * Click directly on the live preview area to select an element for editing. (Middle click to toggle selection view now.)

    * Undo-Redo system with 1000 states.

    * Move swatch selection with arrow keys. (So you can keep the mouse over the color picker while changing swatches.)

    * Gradient tool, lets you make a gradient between any two colors for use as a custom color picker.

    * Custom color swatches, for temporarily storing relevant colors separately from the theme swatch list.

    * Fullscreen mode.

    * Buttons and edit box use dark colors to better fit the overall UI scheme, and reduce unnecessary contrast.

    * Other UI details refined: e.g. Each group of buttons now have a unified highlight color.

    * Added faint white grid lines to pickers for visibility in dark regions.

    * Added a console to aid with diagnostics when troubleshooting, and to provide special features accessed via commands.

    * Fix: Preview image no longer saves with gray flecks at the corners.

    Downloads

    (see first post for latest release)

    (update: "C2 themes - Fisholith bundle v1" is now included.)

    (click to enlarge)

    Gradient picker

    Right click on the left or right side of the gradient to set the current color as an edge-color for the gradient.

    Likewise while performing any color picking action you can hold "<" or ">" keys or "A" or "S" keys to set the left and right gradient colors. By any color picking action I mean anything action that sets the color of a swatch, so a left-click in a color picker or a right-click anywhere on the screen will both work. (e.g. If you right click a color in the preview area while holding the "A" key, it will be set as the left edge color for the gradient.)

    Console

    Open the console with the F5 key.

    Enter a command name, followed by a comma and arguments if any.

    Commands are listed below.

    showDisplayStats

    Shows info about the monitor and Device Pixel Ratio (DPR).

    scroll

    Toggles free camera scrolling over the UI for monitor accessibility issues. Use {U,H,J,K} keys to move camera.

    scale , <scaleFactor>

    Scales the entire UI by the given scale factor.

    e.g. "scale , 2" will scale the UI up by 2x.

    unscale , <inverseScaleFactor>

    Scales the entire UI by 1 divided by the given scale factor.

    This is handy if you know your computer is scaling up by a factor, and you want to undo that scaling.

    e.g. "unscale , 2" will scale the UI down by 1/2x or 0.5x.

    e.g. "unscale , 1.5" will scale the UI back to normal if your computer is already scaling it up by 1.5x.

    UI Scaling (edit)

    Hey TabloidA, I added some features specifically to try to solve the screen scaling issue you're having with your monitor.

    Use F5 to open the console, and type "showDisplayStats" (without quotes) and hit enter. (You may need to click back in the text field before hitting enter, it's finicky about focus sometimes.)

    Anyway, you should get a popup showing some display stats. If you can tell me the value given for Device Pixel Ratio, that might help determine if DPR is related somehow.

    After that, you can try the command "unscale , 1.5" (without quotes), to see if that shrinks the program from the mysterious 1.5x overscale back to the correct size.

    If all else fails, for the time being the "scroll" command might help, as it allows you to scroll your view around the interface.

fisholith's avatar

fisholith

Member since 8 Aug, 2009

Twitter
fisholith has 1 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