fisholith's Forum Posts

  • Hey cmbbar,

    I think the two main things you're probably looking for are global variables, and the "Persist" behavior.

    (Those links go to the corresponding C2 manual pages.)

    Global variables keep their values between layouts.

    The Persist behavior, saves and preserves the state of objects between layouts, such that when you go back to a layout, the persistent objects will be wherever you left them last, instead of resetting to their starting positions.

  • Hey p0tayters,

    Below are a few things that came to mind.

    David Silverman - Match 3 in Construct 2 (from scratch)

    RexRainbow - Match 3 demo

    RexRainbow - Plugins Website

    RexRainbow has built a ton of plugins for C2, and several are tailored to board & tile game mechanics.

    My best wishes for your gaming grandmother.

    You sound like an awesome grandkid.

  • Hey DiVeR, <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    I believe a family can only have one kind of object (plugin) in it.

    e.g. Only Sprite objects, or only Text objects, or only Tilemap objects.

    The icon of the family is borrowed from the object (plugin) type it currently contains.

    Manual > Families: https://www.scirra.com/manual/142/families

    • "All the object types in a family must be from the same plugin ..."

    The problem you're having might be that you're trying to add a Tilemap object into a family already dedicated to Sprite objects.

  • Hey ChefSeth,

    I'm not sure I quite understand what aspects of the code are currently not working.

    The first thing I notice that might be an issue is that in your last two events, there is no icon for either the PlatformCollision object, or the PlatformCollision2 object. I don't know if that's indicative of a problem, but it might shed some light on what's going on.

    In particular, in the "Set animation" actions, it looks like there's no way to visually tell which object is being acted on. I assume they should be PlatformCollision and then PlatformCollision2, but if they're not, that might be causing a problem.

    It looks like every object in the Segments family has a private var named "collision", just out of curiosity, what does it do, and what would cause it to be greater than 900?

  • Hey JasonS,

    One possible approach might be to separate the problem of path finding from the problem of overlap prevention.

    Instead of having the Soldier be the object doing the path finding, make your current path finding object invisible, and make a new soldier object to follow the path finding object. Then give that Follower object the physics behavior, with a constant force pulling it towards its personal Pathfinder. By default, Physics objects won't overlap each other, and will instead slide past each other, or bunch up like gumballs in a jar.

    But what if there's a physics traffic jam, and one of the physics Followers can't keep up with its Pathfinder object? After all, if a Pathfinder goes around a corner while the Follower is stuck, even if the Follower later gets un-stuck the Follower may not be able to reach the Pathfinder by moving straight at it, via a physics force. We need to make sure a Follower never gets left behind.

    Basically each Pathfinder should be a mini Dr. Alan Grant. :)

    To prevent Followers from getting left behind, you can pause the Pathfinder if it gets too far from the Follower. "Too far" in this case might mean 1 or 2 soldier widths. Ideally the soldier (Follower) will nearly always be just behind, and almost touching its Pathfinder.

  • No problem, glad to help. :D

  • Hey imothep85,

    ... imothep ... imothep ... imothep ...

    One possible method:

    Assuming the sprite objects are already set up to move forwards, (e.g. they have "Bullet" behavior or something), you can set their angle each tick to make them approach a target on a spiral path.

    Every tick:

    • Set the sprite angle to face the target position.
    • Rotate the sprite 20 degrees clockwise.

    Note: Rotating 0 degrees would make the sprite move straight at the target, 90 degrees is circling the target, and anything between 0 and 90 will spiral towards the target.

    The above method results in spirals that get curlier as you get closer to the target. If you want more uniform curvature as the sprites approach, you can set that rotation offset to be dependent on the distance between the sprite and the target. So, when the sprite is far from the target, the rotation offset is large (e.g. 45 degrees), and as the sprite gets close to the target the rotation offset gets smaller (e.g. 10 degrees).

    Proportional - (with upper limit)

    Rotate the sprite min( 80 , 80 * ( distance( Sprite.X , Sprite.Y , Target.X , Target.Y ) / 400 ) )

    Here we scale the rotation offset by the distance to the target, with 400 pixels being the distance where the scaling value equals 1.0 (or 100%). We are scaling the number 80 to act as the rotation offset, and we are capping the maximum rotation offset at 80 as well. We cap the offset so that it doesn't reach or exceed 90 degrees which would cause the sprite to start spiraling away from the target.

    Making the cap number smaller will make the maximum turning radius softer. (It should be between 0 and up to but not including 90.)

    Making the base rotation offset smaller will make the approach turning radius softer. (It should be between 0 and up to but not including 90.)

    Making the distance scale larger will make the curves softer.

    ArcTangent

    Rotate the sprite atan( distance( Sprite.X , Sprite.Y , Target.X , Target.Y ) / 400 )

    This is a slightly simpler expression to write and it doesn't require an artificial cap value, because no matter how big the distance gets, the arc-tangent will never return 90 degrees or more. The 400 in this case is the distance at which the arc-tangent will return 45 degrees.

    Making the distance scale larger will make the curves softer.

  • I may be misunderstanding what you mean, but I believe all instances of objects in a layout have a unique integer ID assigned on creation by Construct. That automatically assigned integer ID is what I was referring to when I mentioned the "UID".

    The object type (e.g. "helmet") is different from the UID.

    Each helmet should have it's own totally unique ID number.

    UID explained in the manual: https://www.scirra.com/manual/130/common-features

    Example

    If you spawn three helmet objects in your game, their UIDs might be automatically assigned as 61, 62, and 63, respectively.

    If the player collides with one of the helmets, you can ask Construct which UID that specific helmet has.

    ...Event: Player collides with helmet. Action: set variable itemTouchedLast to helmet's UID.

    Let's assume the player touched the helmet with the UID of "62".

    You can now refer to that specific helmet in other events by using the UID to pick it.

    Suppose we want to place a selection box image on the last item the player touched.

    ...Event: Every Tick. Pick helmet by UID ( itemTouchedLast ). Action: Move selectionBoxSprite to position of helmet.

    This event will pick the helmet with the UID of "62", and it will then run the action only on helmet 62.

  • Try Construct 3

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

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

    I don't have the plugins needed to open the project, so I'm not sure quite how things are set up, but I have some thoughts that might work.

    Boolean marker

    You might be able to store an extra Boolean for each object, that indicates if it has already been assigned stats.

    When you get a new item, you can then use the Boolean to exclude all items that already have stats from the randomization process.

    Pick by UID

    Another possibility is to store the UID (unique ID integer) of the object the player just acquired, and then in the event that does the randomizing, add the condition "Pick by unique ID" and use the UID you just stored.

    You can usually find "Pick by unique ID" condition in the "Misc" section of the object's conditions.

  • Thanks R0J0hound and Ashley for the suggestions and info.

    Sounds good.

    I have gone ahead with building this plugin, and it seems to be working correctly so far.

    As it happens, the root object's properties are never removed or added to, as all the dynamic stuff happens inside a permanent property named "rootHash".

    So it sounds like that should work.

    I'm ultimately hoping to make a behavior version of it as well, so I can have per-instance dynamic data structures.

    Also, sorry R0J0hound, for some reason I thought I posted a "thanks" reply a day or so after your response. In any case I did take your advice, so thanks.

  • Hey all, :)

    I just started building a plugin that provides a hashtable for witch each key can be a number/string value, or it can reference a deeper hash table. Because each hashtable can have keys that link to other hashtables, you can have an arbitrarily deep tree of hashtables and data.

    My concern is that I just remembered something about object sealing in the runtime.

    Will sealing prevent this plugin from working?

    In my plugin's runtime, in the instance class's onCreate() function, I'm only creating one property to hold the root hash table, named "rootHash".

    All other modifications to the data structure from then on are done to rootHash, via C2 events/actions. That includes the addition of keys, and the creation of deeper hash tables.

    I'm trying to understand if that kind of modification is possible, or if sealing the object restricts what you can add to it, or restricts what you can add to sub-objects.

    I'm hoping that as long as I don't add more properties directly to the instance class (which I'm not) I should be okay.

  • Hey Freemium, <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    I'm not sure off hand if you're interested in info on animation in Construct 2's editor, or info on character animation in general, but hopefully some of what follows may help. <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    C2 Animations

    In Construct 2, when you double click a sprite to open the image editor, there are two other windows that open with it, the "Animation frames" window, and the "Animation" window. The Animation window shows a list of the animation sequences you've created for your sprite. Initially the list should only contain one animation named "Default", but you can Right-Click in the Animation window and (from the context menu) choose "Add animation".

    In the Animation window, if you click on an animation, you can edit its speed and other properties in the "Properties" panel.

    You can also Right-Click on an animation to rename it or duplicate it.

    So for a typical sprite character, you might want to make several animations for standing, walking, jumping, falling, attacking, and so forth.

    Then in the event editor, you can add actions to switch between animations.

    e.g. When the player holds the left or right move key, set the sprite's animation to "walking", and when left and right aren't being held, set animation to "standing".

    A little oversimplified, but same basic idea. <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    Sprite sheets for reference

    As for the more general side of character animation, it might help to take a look at sprite animation work from existing games.

    The Spriters-Resource is an open database of actual sprite animation sheets from a wide array of games from many systems. It's organized by game system, then by letter, and then often by character or asset type within the game.

    e.g.

    Super Mario World:

    http://www.spriters-resource.com/snes/smarioworld/

    Mario...

    Exploring sprite sheets

    A little off topic, you can find some interesting things by looking through various sprite sheets.

    For instance, In Super Mario Kart, some interesting optimizations can be seen in the sprite collections that make up a character.

    As you can see in the image above, there are 8 different distance levels for a character, and for farther distances, fewer angles are used.

    Likewise, you may notice that there are 12 angles for the close-up distances. If you look closely you'll see that 8 of those images represent the first 90 degree span, (facing away to facing sideways), and the last 4 represent the last 90 degree span, (facing sideways to facing the viewer). I would guess that there are half as many images representing angles facing towards the viewer, because in a race game, if a character is very close to you, they'll most likely be heading the same direction you are, and so they'll most often be facing away from the viewer.

    I think that's kinda neat. :D

  • Is there a good way to scroll layers in any direction, independently of each other?

    For instance, in Super Mario World, in some of the castles, there was a parallax background layer, a game layer, and a moving blocks layer that would sweep from side-to-side sinusoidally. That moving blocks layer's offset in the screen was not just a simple scaled version of the camera coordinates.

    In C2 I can't find an action that allows you to scroll individual layers to any location you want.

    Or if you think of the "camera" as being the thing that is scrolling, I can't find an action that allows you to offset a layer relative to its default starting point.

    Going back to the Mario Castle example, if you could specify layer offset via expression it might look like this:

    • layer_background.X = scrollx * 0.5
    • layer_game.X = scrollx
    • layer_movingBlocks.X = scrollx + ( sin( time ) * sweepDistance )

    The best workaround I've found so far is a bit of a jury rig.

    If, at the start of the layout, I set the "camera" scroll point to the coordinate ( scrollx-100 , scrolly-100 ), then the parallax rate of each layer is effectively that layer's offset in pixels. (I use "-100" instead of "-1" because the scroll rates are given in percentage form.)

    I hope I'm not missing something really obvious, but I can't find anything built-in to use in place of this workaround.

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

    For instance, if I create a family that handles advanced particle behavior, can I later copy it into another project?

    The only way I know of at the moment is to, in the new project, exactly replicate the family with all the instance variables, effects, and behaviors by hand, and then copy the relevant event code, first by copying top level event sheet variables into a new events sheet, and then copying all the other events over, so as to avoid the missing variables error message.

    Currently I save most of my projects as single files, but I'm curious if it might be possible to copy families and other objects between projects by just dragging and dropping files between project folder structures, or maybe copying blocks of xml or something.

    Any advice or suggestions much appreciated.

  • I don't know of any differences off hand.

    When you import a sound file into Construct2, at the bottom of the import window there is an "OGG/AAC encoding quality" option box. If, this time around, you used a different setting for the quality, you might be hearing a difference from that. If so, you can delete the music files out of C2's Sound or Music folder and re import with higher quality settings. For music I usually use the max audio quality 192-kbps unless I know for a fact that it will cause a problem.

    I did a blind test, playing a song either by C2's music system or the audio system at random, and I could not hear any difference, or predict which was which at all.

    I used 192-kbps for the import quality. I wrote the song I used to do the test, so hopefully if there was going to be a difference I would have noticed. Then again, if I can't find a difference when specifically looking for one, even if there is a difference in there somewhere, it's not likely to be that noticeable.