Lunarovich's Forum Posts

  • And here is my LightMask/TintMask example, made specially for this friendly forum...

    EDIT: This example has a single layer dark mask (whit light hole punched in), light tint mask (cycle) and sine opacity and size behavior, used to simulate the light flicker.

  • Here is another nice light tinting screenshot...

  • Thanks! Actually, yes, you can tint your light...

    However, since original LightMask is in a "destination out" blend mode, you'll have to make another mask (I call it originally TintMask ) and synchronize its position, angle, etc. with the LightMask. You put your TintMask on top of all objects in the target level.

    I am using the sine behavior for the opacity and size on the LightMask in order to give some flicker to it. Naturally, you do not see it on the picture, but the effect is just great

  • Thanks for sharing your capx. Sadly, a node-webkit does not work...

    On the other hand, I've tested my solution, and it works in a node-webkit This C2 is such a fine tool... Look what I've got with different tint settings...

    p.s. Sorry, cannot send capx... I'm working on a commercial project... But the explanation / mini tutorial above should help. If anyone is in doubt, I can explain further, if need be...

  • ADDENDUM 1

    As Ashley points out, "Prefer to add the shader effect to a whole layer, then put any objects you want to have that effect on that layer. This means the overhead of processing a shader only happens once." Thus, I control the tint and brightness of other layers independently (per layer basis) using the Tint effect applied on a layer.

    Unlike the Tint mask, Tint affects only the tinted object/layer (and does not affect background objects/layers). As a further optimization, be sure to keep the option "Force own texture" of non masked layers (simply tinted layers) off.

    ADDENDUM 2

    Anyway, Ashley, it would be very useful, for situations like this, to have a plugin which composits/blends chosen images/sprites in real-time (per tick basis) and gives them readily available as a single image/sprite object. Thus, we could elminate the overhead of using the transitory invisible layer (as is the case with Paster plugin) and would have a more elegant overall solution.

  • I actually managed to solve the problem myself. Here is the result

    As you can see, the sky is bright (not masked by foreground layers) and the background layers are not affected by the foreground layer light system.

    I achieved this using Paster plugin. Bascially, you use an invisible layer to render a tint mask image which you paste, using a Paster plugin, on the target layer (the layer which you want to mask).

    A more detailed version:

    1)

    • I created an invisible layer called "NightMask".
    • I placed a "Night" black rectangular sprite over the layer.
    • I placed "LightMask" (images with alpha transparency) with the blend mode "destination out" over the black rectangular sprite "Night". This has punched the holes in the "Night" sprite. These holes will act as lights.

    2)

    • I created a Paster object on the target foreground layer - a layer which has to be darkened completely (without affecting the luminosity/brightness of other layers) and partially lit by the lights. I added a Tint Mask effect to the Paster object.
    • I checked the Force own texture option on the target layer. In that way we ensure that the Tint Mask effect affects only the target layer.
    • I pasted in Paster all objects from the "NightMask" invisible layer. That has created a dark tint mask with alpha transparency holes punched in it.

    Hope someone will find this explanation helpful...

  • Hello, I would like to achieve something like this (Starbound):

    On the image above a foreground layer mask masks only non-transparent parts of the single (foreground) layer. Every other layer is unaffected by the darkness of the foreground layer mask. Lights "punch" holes in this mask using, I suppose, a "destination out" blend type.

    Now, I know how to make a whole layer partially non-transparent or fully opaqu and punch wholes in order to see lower layers (layers beneath it). This is demonstrated in C2 Lighting example. However, this is NOT something I want, since a sky layer should not be affected by the foreground dark mask.

    Is it possible to achieve this in C2 and what would be the best way to do it?

  • Hello, thanks on your answer.

    However, my question does not concern strictly the routine part of uploading a project to the cloud. I was rather asking for the best way to use a source control and collaboration system in regards to C2 projects in general.

    Therefore, I rephrased the topic title to correspond better to my original intent.

  • Hello, I want to develop a project together with a friend, so we are looking for an effective source control and collaboration system. So far, we have tried Github, but only with a moderate success.

    We have set up Git to ignore uistate files. This works good, since uistate files determine non essential aspects of a C2 project - the visual organization of sheets, layouts, etc. in the editor. Since we only want to work on separate sheets and separate layouts, this works good. Namely, working on different sheets/layouts does changeuistate files. However, since they are ignored, there is no need for the conflict resolution.

    On the other hand, adding a new sheet or layout changes autmatically caproj xml file - a project's master file. Unfortunately, we cannot setup the git to ignore this file, since it is a project essential file. It informs the C2 about existing layouts and sheets in the project.

    So, I would like to ask if anyone has set up a successful, working source control collaborative C2 project, whether it be on Github or on some other platform. If yes, how did you go about it?

  • Thank you monitz87. I think I finally got it now. This sentence,

    "Actions run only once per event, but they run across all objects of that action's 'object type' that were picked by the event conditions."

    was a a crucial part of your explanation.

  • Thank you Ashley for you answer. I am sorry to respond this late, but I did not see your response before (it landed as a first post on the second page, so I somehow did not registered it).

    Well, the mouse condition is irrelevant in this example. It is what follows that I find puzzling for users. At least for me, since i did not understand it and had problems even after reading relevant manual pages and the official blog text about gotchas. Take a look at the following example, please

    The set opacity action works fine (as expected), that is, for each worker. On the other hand, the function does not get executed for each worker. The function in question simply sets the opacity of worker identified with the UID to 50. It is a simple wrapper function for the build-in set opacity action. And yet, it gets executed only once, for the first instance of the worker object. As I see it, it is so, because a function is a single instance object. Every function objects gets picked and since there is only one function object, function gets executed only once.

    I agree that it is a consistent Construct 2 behavior. However, I think that it is not properly documented behavior. Or at least, it should be pointed to as a gotcha. Maybe it is something obvious to you why you should put system condition "for each" in front of function calls and it is redundant to do it before build-in actions. However, I highly doubt that it is for other users which did not participate in the development of C2.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I have just tested the picking for arrays and it works in the same way (that is, as for functions). Here, the striked out solution does not give the intended results, while the "for each" works towards the intended goal:

    So, the C2 is consistent in the way it treats single instance object types. However, I find the lack of explanation of this behavior quite a bit misleading for the newcomers. At least, I was confused until now, and I spent at least 50 hours or more debugging the system which I did not understand inspite the fact I have read every relevant page of the manual. Despite the effort, I was still using the striked out manner, without realizing that the action gets executed only once for the first picked instance of the object stated in the condition.

    Ashley, I think that manual page on how events/picking works has to be augmented with the explanation of the picking of single instance object types, like functions, arrays or system objects.

  • Thanks! This is quite explanatory! A small question, just in order to test my understanding: In the last script image, function "rotate" will be called only once and with first sprite instance's (according to IID) UID?

  • Thank you for this precious link. I think I got it. This is the relevant passage for understanding why function runs only once without a for each condition:

    [quote:3epnghcy]So when should for-each loops be used? Only when what the engine is already doing is not enough. This is usually when you want all the event's actions to run once per instance, rather than just the actions relating to that object. Often this is to get system conditions and actions to run for each instance, which are normally only checked or run once (since there is only ever one system object). For example, if the above event included a system action to subtract from a variable, adding the for-each loop does then change the behavior of the event. Without the explicit loop, the system action only subtracts from the variable once when the event is run, regardless of how many Monster instances were picked by the conditions; with the explicit loop, it also runs the system action once per picked Monster instance, meaning the amount subtracted is proportional to the number of Monsters that are hunting. This can certainly be useful, but the cases when it is truly necessary seem to be less frequent than many users think. Often what the engine does already is enough.

    Ok. In order to explain, I'll make an analogy between the system object and the function object. There is only one instance of the function object of a certain function type (analoguos with: "there is only ever one system object"). Now, when I pick instances of the object in the normal event, the picking is done through the use of the implicit for each loop:

    [quote:3epnghcy]Going back to How Events Work, conditions are tested for each instance, and then actions are run for each instance that met the event's conditions.

    In my case, for each worker that is overlapping the selection box, set worker's opacity to 50. Since all workers which are overlapping the selection box are remembered by the event during the condition testing, an event's action to set worker's opacity to 50 can run for each single worker which satisfies the condition.

    Now, let's go to the function which gets called when the same condition is satisfied. As in the previous case, event's condition filters all instances of worker object type which overlap the selection box. However, no singular instance of the function object type is picked, since actions do not pick anything. Since there is only one instance/object of the function object type, this one gets called only once when the condition is satisfied (= when there is at least one worker overlapping the selection box). That is analoguos to the system actions:

    [quote:3epnghcy]Without the explicit loop, the system action only subtracts from the variable once when the event is run, regardless of how many Monster instances were picked by the conditions;

    So, please do suggest corrections if I got something wrong.

  • Hello! I am trying to implement a sprite mirroring in conjunction with the pathfinding behavior. If I try to pick instances with the system condition like this

    sprites only get mirrored but do not revert to their unmirrored state.

    However, if I use a normal/object picking, everything works as expected. Here is the script

    The problem is that I do not want to revert to every tick hack in order to synchronize the custom instance variable with behavior defined variable. It is not an elegant solution and it wastes CPU and memory.

    A side question: is there a way to test for the value of behavior defined instance variable - eg. MovingAngle of pathfinding behavior - directly in the object's condition? Currently, I can only see a way to test custom instance variables with "Compare instance variable" condition.