fisholith's Forum Posts

  • The replace feature, (as far as I know), has loosely two modes.

    If there's only one object available to replace:

    Pops up an object browser, and whatever you choose will replace the original object.

    If there are two or more objects that can be replaced:

    Pops up an object browser showing the objects that can be replaced, and whatever you choose will be designated as the object type to be replaced.

    Then you will be presented with another object browser, and whatever you choose will replace the object designated on the previous step.

  • Hey Ashley,

    Thanks for the reply. I figured that might be the case. It makes sense that it would be set up to work just on the 100% parallax layers, as that's going to be pretty much all the practical cases.

    As for setting all layers to 50% parallax, I agree that that would be pointless, I was just using it as a simple example of paired layers with matching parallax.

    I actually happened to be faced with a special case that is related to that example, but a little more complicated, in which I would have several layers that would have variable parallax rates, but the parallax rates would always all be the same value across all the layers, or at least all the layers for which collision detection matters.

    Reason being, I figured out a way to scroll layers completely independently of each other, which I've been interested in for a while, but the method involves keeping the scroll coordinates fixed and adjusting the parallax scales of each layer instead. The parallax scales for each layer become the individual scroll coordinates for that layer. It works, but I was worried that the weird parallax values would break the collision optimization, and it sounds like they would. In this case the game world layers would all have the same parallax scales, and would stay lined up, but they wouldn't always be set to 100%.

    The main reason I've been interested in scrolling layers independently is that I'd like to be able to have a "game" world that scrolls normally, and an overlay-able "menu" system that can scroll from page-to-page independently of the game world. Currently there's no way that I know of to decouple the scrolling of the menu layers from the scrolling of the game world layers.

    I'm aware that it's technically possible to make a system that kind of approximates the en-mass coordinate shifting that layers can do, but it seems a bit tricky to make it play well across multiple object types, and with anything else that effects coordinates, like behaviors, or for that matter Particle object particles, which don't move with the source object.

    I've seen some other threads talking about independently scrolling layers, and it sounds like it's not currently planned. For what it's worth, I think it would be a cool feature, but I can also definitely understand why it might not be a priority.

    In any case, thanks again for the info.

  • Thanks for the reply jobel,

    Yeah, I don't plan to have misaligned layers with collisions between them, I agree that could get ugly.

    What I mean is if I have, for instance, just one layer, and it's parallax is set to 50%, will that disable optimized collision detection for everything on that layer?

    And the slightly more complex scenario is, if I have two layers both set to 50% parallax, so both layers are still always in alignment at all times, will the 50% setting disable optimized collision detection for everything on both layers?

    I'm just not quite sure what situations cause C2 to forgo optimized collision detection. I think it might only use the optimization for layers at 100% parallax, and will brute-force anything else. That might kind of make sense, as there may be only one data structure handling spatial binning, instead of one data structure for each parallax configuration found in the layout.

  • I gather that C2 does some kind of spatial binning based on the project's window dimensions to optimize collision detection.

    If I set all layers to use a 50% X and Y parallax rate, all layers will still always be in alignment, but will this disable optimized collision detection across all layers?

    That is, will layers use optimized collision detection between each other if they line up, or only if they are at exactly 100% X and Y parallax rate?

  • Hey again tunepunk,

    As blackhornet and Magistross mentioned, recursion is likely not what you want for this situation.

    I gave my example in terms of the opacity scenario you mentioned only for illustrative purposes, I wouldn't recommend actually using recursion to handle opacity.

    My fault, I misunderstood.

    I understood you were interested in having a function act in a self-contained manner over time, but I didn't realize you were interested specifically in controlling opacity.

    As Magistross mentions, with too much recursion you can run out of call stack space. This is what I meant in my first post when I mentioned the "Maximum call stack size exceeded" error.

    Triggering smooth transitions

    To trigger a smooth change over time, you can use an extra instance variable to store the desired target value, (such as "100" for opacity), and then every tick, move the actual opacity value towards that target value by an increment, (such as 2).

    So if you have a sprite that starts with 0 opacity, and the target is set to 0 as well, the sprite stays at 0 opacity.

    If you then set the target value to 100, the sprite's opacity will start counting up to 100, at a rate of 2 per tick.

    As Blackhornet mentioned you can use families to make it easier to get this behavior to work across a variety of similar objects.

    Layers, Sprites, & Families

    A single family will only work on a set of objects that all belong to the same plugin type, such as Sprite.

    To get a family that affects sprites to affect layers, you can create a sprite object called "layerTool" (or whatever you want) and put a layerTool object on each layer you wish to control. Set the "Visibility" of the layerTool objects to 0 and then create events for them that set their corresponding layers to match their opacity every tick.

    Now you should be able to control layer opacity with the same family events that control sprite opacity.

  • If you're using the physics behavior, you can apply a torque to the arrow to make it straighten out towards the direction it's moving.

    This torque should be greater the faster the arrow is moving. So, if it's sitting on the ground, no torque. If it's flying fast, lots of torque.

    You can use the "Apply torque towards angle" action to get this effect.

    It would look something like the following:

    Apply torque towards angle:

    • Torque: 0.001 * arrow_speed
    • Angle: arrow_movement_angle

    (The "0.001" just scales the amount of torque used to correct the arrow angle. You can experiment with it.)

    Of course there are no "arrow_speed" or "arrow_movement_angle" values by those names, so you'll need to calculate that information, but fortunately that's not too hard.

    We can get the speed by finding the length of the Physics behavior's velocity vector. We get the angle by finding the angle of the velocity vector.

    Apply torque towards angle:

    • Torque: 0.001 * distance( 0 , 0 , arrow.Physics.VelocityX , arrow.Physics.VelocityY )
    • Angle: angle( 0 , 0 , arrow.Physics.VelocityX , arrow.Physics.VelocityY )

    This should make arrows fly head first, but will still allow them to topple end-over-end if they bounce off of something and lose most of their speed.

    This is not a perfect simulation of arrow flight, as it doesn't account for linear off-axis forces resulting from the separate center of gravity, and center of pressure, but for it's simplicity it is pretty close.

    I actually just uploaded an update of a game I made that uses this exact method for handling arrow flight.

    ArcherOpteryx: http://gamejolt.com/games/archeropteryx/45519

    (note: Firefox runs it a little slow, but every other browser, and the desktop version run fine.)

    Hope that helps out <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

  • Thanks for the replies all.

    I thought that might be the case.

    I have a possible, limited case solution, but I haven't tried it yet.

    I might be able to make a shader that will multi-sample a large image, and give roughly the same effect as C2's native multi-sampling.

    The drawbacks are that the image would have to fit in frame at it's large size as any part of it off screen can't be sampled I believe. That means that it's size orientation and position would all need to be handled by shader. That said, it could conceivably give multi-sampled results in a "point sampled" project, so it could be handy if it works out the way I think it might.

  • Is there a way to change between Point & Linear sampling at runtime?

    Or is there a way to start some layouts in Point mode and others in linear mode?

    Just curious if there's any way to change between the two modes in a single project.

  • One option, though it can get tricky, is to have the function conditionally call itself after a short delay.

    On "fade_in":

    --- IF opacity < 100:

    --- --- Add 1 to opacity.

    --- --- Wait 0.5 seconds.

    --- --- Call function "fade_in"

    When the function is first called, it will do nothing if the opacity is 100, but if opacity is less than 100, it will increase the opacity by 1, and queue itself to be called again in half a second.

    This situation, where a function calls itself, is called a "recursive" function call, or just "recursion".

    This can be a really handy way of doing things, but just as you need to be careful with loops, to avoid infinite loop bugs, you also need to be careful with recursive function calls, to avoid infinite recursion. If you get an infinite recursion problem, you'll usually get an error message mentioning something along the lines of "Maximum call stack size exceeded".

    This isn't the only way to get functions to act repeatedly over time, but it is one that can be pretty useful in the right situations.

    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 glitchyghost,

    I think what may be happening is that the bullets are always being set to spread relative to the angle "0", but specifically the angle "0" relative to the world, instead of relative to the player.

    Angle 0 always points to the right.

    0 = Right

    90 = Down

    180 = Left

    270 = Up

    360 = Right

    The second issue is that using the Mirror action on a sprite will change the orientation of it's image, but if I recall correctly, it won't change the sprite object's actual angle.

    So you could try splitting the spread event into two events.

    If player is NOT Mirrored: random( -playerProjectile.spreadFactor , playerProjectile.spreadfactor )

    If player is Mirrored: 180 + random( -playerProjectile.spreadFactor , playerProjectile.spreadfactor )

    When the player is Mirrored, you can add 180 to the angle so the bullets fire to the left, plus or minus a random spread factor.

    Hope that helps out.

  • Hey, Sup with that?

    Thanks for the reply. Unfortunately an effect isn't quite what I'm looking for, as effect's to my knowledge, can only affect imagery that is rendered within the screen boundary.

    On an unrelated note, there's something kind of surreal about having "Sup with that?" recommend "Somebody".

  • I'm about to reprogram all the scrolling in my game to allow for arbitrary independent scrolling of individual layers.

    The workaround I came up with is kind of ugly and unintuitive to work with, so before I start I figured I'd ask if there's any built in C2 feature, or plugin, that already does this, that I might be overlooking.

    I've looked around the system object and manual for a while now, and to my knowledge the only layer parallax related thing you can adjust at runtime is the layer's parallax percentage.

    The workaround I came up with is to set the global scroll position to (-100, -100), never move it, and then I can set the scroll position of individual layers independently by setting their scroll percentage to the number of pixels I want to offset them by X and Y.

    It's ugly, and it makes the code harder to understand at a glance, but it does work. From there I can recreate the basic global scrolling behavior C2 normally does, but with the benefit that, for the few layers I need to scroll in slightly more specialized ways, I can use any formula or logic I want.

    Any suggestions are welcome.

  • Hey Radulepy,

    If I understand, it sounds like you might be interested in how to get 8 direction movement, but properly transformed for an isometric perspective; such that if a player holds the left and down keys, their character will walk at an appropriately shallow diagonal, rather than a perfect 45 degree diagonal.

    Model world / Display world

    One approach is to have two worlds.

    A "Model" world, which is invisible to the player.

    And a "Display" world, which is what the player sees.

    (Prepare to see those colors a lot. Sorry in advance...)

    The key is that the Model world is a flat 2D straight-top-down representation of your game world. And the Display world is the isometric view of your game world.

    We build the 2D Model world first.

    We then make a "renderer" (using events) which looks at all the objects in the Model world, and creates their Display world versions, positioning them to create an isometric view.

    All of the game logic, (character movement, collisions, projectiles), will be handled in the Model world where movement and collisions are simple, as everything can be done with the standard 2D features already built in to Construct 2.

    For each 2D object in the Model world, our renderer will create an isometric version, and use some math to convert its 2D world coords to isometric world coords.

    Example

    As a practical example, let's say there's a playable character with the "8 Direction" Behavior in our Model world. When the player presses the Move-Right key for one second, and then the Move-Down key for one second, the Model character moves rightward in the Model world, from pixel-coord (0,0) to (100,0), and then moves downwards to (100,100).

    Remember though, the Model world is invisible to the player.

    So the renderer takes that Model character and makes an isometric Display version of the character move rightward from pixel-coord (0,0) to (100,0), and then downward to (100,50).

    Notice that the Model character is at (100,100) but the isometric character is at (100,50). Converting from 2D Model coords to isometric Display coords is one of the jobs the renderer will do.

    In this case we are just dividing the Y coord by 2, and leaving the X coord alone.

    Essentially, to create the Display world, we are just squishing the Y axis of the Model world to half it's normal height.

    Thus, in the Model world, a 400 x 400 pixel patch of dirt in a field of grass, would be represented as a 400 x 200 pixel patch in the Display world.

    So far so good, but what we just created is sometimes called an "Oblique" perspective, which is not quite the same as the more traditional "isometric" perspective.

    Oblique vs Isometric

    Imagine a camera pointing straight down at a treasure map, on the map the compass rose's North to South axis is oriented vertically in the camera view.

    If we lower the camera's elevation angle from 90 degrees (straight down), to 30 degrees (shallow downward diagonal), we get the oblique view described above.

    In this oblique perspective, a cube shaped building would have its southern edge (not a corner) closest to the camera.

    To get a traditional isometric projection, we'd also then need to rotate the map 45 degrees, so that the camera is looking diagonally across the compass rose, such that (for example) the rose's North-West to South-East axis is oriented vertically in the camera view.

    In this isometric perspective, a cube shaped building would have its south-eastern corner closest to the camera.

    The math for converting from the Model world's 2D coords to the Display world's isometric coords is a bit trickier than the simpler oblique view, but still just some trigonometry.

    Edit view (Model) vs Runtime view (Display)

    So one problem you may have noticed is that with this Model-world/Display-world approach, when building your levels, you'll be editing the Model world, not the Display world.

    Editing the Model world means arranging a bunch of 2D placeholder rectangles in the Construct layout editor, knowing that the "renderer" will turn it into a nice isometric view that you can't see while editing.

    There is a workaround though, which can allow you to build your world directly using the isometric assets. Essentially, you would have to make a reverse-renderer, which will take an the isometric assets and their coordinates, and convert that to a Model world. After that the game would run normally off the Model.

    If you're familiar with the concept of a Model-View-Controller, that's loosely what you would have with this Display-to-Model-to-Display setup.

    Depth sorting

    Finally, there's the issue of making sure things in the Display world are depth sorted correctly, so that a distant object doesn't overlap a nearer object.

    I recently talked about this in another post on isometric depth sorting.

    Again, this is not the only way to handle isometric worlds (and movement in them), but it's an approach I think might work well with Construct 2 specifically.

    I hope that helps out.

  • Hey oceldot,

    I haven't worked with the path finding system very much, but one thing that might work is forcing the path to recalculate when you change posture.

    This way, if you stand up, the solid will reappear, the path finder will be forced to recalculate a path to the last destination given, and the path will no longer be valid.

    If you try this method out, for obvious reasons, it's important to make sure that the path is getting recalculated only after the solid reappears. Behaviors and event sheets can sometimes execute their effects in an order you aren't expecting. IF this becomes an issue, you can place the path recalculation action after a wait( 0 ) action, to delay the recalculation to the end of the frame.

  • Hey otaconnor,

    I'm not sure if there's an elegant solution to this issue with the default Physics behavior, but there's a 3rd party physics plugin, based on the Chipmunk physics engine, that specifically has the ability to separate objects into different "collision layers" which won't interact with each other.

    You can find it at the post linked below.