fisholith's Forum Posts

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

    I made my own modified version of the SDK template files, with some extra information comments, and a more graphical style of divider comments to break up and mark the different sections of code.

    I'm planning on making a tutorial to go along with my modified version of the SDK at some point, but I can upload a copy for you to take a look at now in case it might help. <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    https://dl.dropboxusercontent.com/u/382 ... mplate.zip

    You may alraedy know this, but the one really important step in creating a plugin is to make sure the "id" value you choose for the edittime.js file, matches two spots in the runtime.js file.

    In my SDK mod the places that must match are marked in both files with the following placeholder text:

    XXXXXXXXXXXXXXXX_MyPluginID_XXXXXXXXXXXXXXXX

    (Note the "ID" in the placeholder text.)

    edittime.js

    (Note the first placeholder is for the NAME, not the ID. Only the ID has to match between files.)

    //╔════════════════════════════════════════════════════════════════════════════╗
    //â•‘///////////////////////////////   Settings   ///////////////////////////////â•‘
    //╚════════════════════════════════════════════════════════════════════════════╝
    function GetPluginSettings()
    {
    	return {
    		"name":			"XXXXXXXXXXXXXXXX_MyPluginName_XXXXXXXXXXXXXXXX",
    		"id":			"XXXXXXXXXXXXXXXX_MyPluginID_XXXXXXXXXXXXXXXX",[/code:28nntpg6]
    		
    [b]runtime.js[/b]
    [i](You may need to scroll down a little to see both placeholder spots.)[/i]
    [code:28nntpg6]//╔════════════════════════════════════════════════════════════════════════════╗
    //â•‘/////////////////////////////   Plugin class   /////////////////////////////â•‘
    //╚════════════════════════════════════════════════════════════════════════════╝
    
    //----------------------------------------------------------------
    // *** CHANGE THE PLUGIN ID HERE *** - must match the "id" property in edittime.js
    //          vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    cr.plugins_.XXXXXXXXXXXXXXXX_MyPluginID_XXXXXXXXXXXXXXXX = function(runtime)
    {
    	this.runtime = runtime;
    };
    
    //----------------------------------------------------------------
    (function ()
    {
    	/////////////////////////////////////
    	// *** CHANGE THE PLUGIN ID HERE *** - must match the "id" property in edittime.js
    	//                            vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    	var pluginProto = cr.plugins_.XXXXXXXXXXXXXXXX_MyPluginID_XXXXXXXXXXXXXXXX.prototype;[/code:28nntpg6]
    
    [b]C2 plugin video tutorial - by John Velojet[/b]
    I found this nice walk-through for setting up a super simple plugin from start to finish. 
    [youtube video="ZlgJ4ts00C4"]
    [i](This is actually the first tutorial I use to make a working plugin, back when I started looking into making plugins.)[/i]
  • Okay, I've done some digging through the C2 js files, but I'm having trouble finding the point at which any image data is actually encountered.

    C2 snapshot code

    The Action in system.js calls "doCanvasSnapshot()"

    [system.js , line 1913]

    SysActs.prototype.SnapshotCanvas = function (format_, quality_)
    {
    	this.runtime.doCanvasSnapshot(format_ === 0 ? "image/png" : "image/jpeg", quality_ / 100);
    }; [/code:355ixjpx]
    
    "doCanvasSnapshot()" is called in system.js, and seems to be declared in preview.js ... maybe?
    I'm not especially familiar with the setup of the HTML5 canvas in C2, or in general. So I suspect there are probably some conventions I'm not recognizing.
    [preview.js , line 5043]
    [code:355ixjpx]Runtime.prototype.doCanvasSnapshot = function (format_, quality_)
    {
    	this.snapshotCanvas = [format_, quality_];
    	this.redraw = true;		// force redraw so snapshot is always taken
    }; [/code:355ixjpx]
    
    I found a spot in the tick code that seems to be involved with the snapshot process, and uses "this.snapshotCanvas" , but it seems like it's arranging for the snapshot data to be available to some other system somewhere, rather than handling image data itself.
    [preview.js , line 2346]
    [code:355ixjpx]// Snapshot the canvas if enabled
    if (this.snapshotCanvas)
    {
    	if (this.canvas && this.canvas.toDataURL)
    	{
    		this.snapshotData = this.canvas.toDataURL(this.snapshotCanvas[0], this.snapshotCanvas[1]);
    		
    		if (window["cr_onSnapshot"])
    			window["cr_onSnapshot"](this.snapshotData);
    		
    		this.trigger(cr.system_object.prototype.cnds.OnCanvasSnapshot, null);
    	}
    		
    	this.snapshotCanvas = null;
    } [/code:355ixjpx]
    
    The only other place I'm even seeing the word snapshot come up is in an assignment to an array named "window".
    I have no idea what's going on here. Is this some kind of variable function callback thing?
    [preview.js , line 6061]
    [code:355ixjpx]window["cr_getSnapshot"] = function (format_, quality_)
    {
    	var runtime = window["cr_getC2Runtime"]();
    	
    	if (runtime)
    		runtime.doCanvasSnapshot(format_, quality_);
    } [/code:355ixjpx]
    
    [b]My thoughts so far[/b]
    So I'm starting to suspect that the image data saved by the snapshot action is setup inside code much closer to the actual drawing of the main canvas, and the snapshot action just flags it to be saved to a variable for later use. I could be completely wrong though, as I'm not quite sure what I'm looking at.
    
    All that said, I'm not sure if I really need to get at the snapshot code in the first place. I was going to take a look at it just to get an idea of how to pick a color from the final rendered scene, though I don't know if that's the direction I should be going, or if there's a better way to get at the color data.
    
    Any suggestions are still welcome. I'm still not quite clear on how to access the canvas from within the SDK.
  • Thanks for the reply rexrainbow,

    I'm familiar with that aspect of the third party Canvas plugin. I meant the HTML5 canvas that C2 renders the game into. Apologies, I should have been more specific in my first post. I think (though I may be wrong) R0J0hound's code I linked to in the first post samples C2's main HTML5 canvas directly.

    I was also thinking that since C2 can store a screencap of the canvas that includes applied shaders, would it be better to try to use an approach related to that screencap mechanism to get the post shader colors?

    I've been trying to get a simple method for picking screen colors for a while and all the event-and-object approaches I've tried end up being kind of fiddly, especially when it comes to capturing post shader colors.

    [edit] Oh, hey R0J0hound, I think you just posted right before I did.

    I have to head out briefly, but I'll be able to reply shortly. Thanks for the info.

    [edit 2] Thanks for the info, and the suggestion R0J0hound, I'll take a look at the screencap action code.

  • I'm looking to create a color utility plugin, to provide a variety of color related expressions and conditions.

    The first expressions I want to add would form a color picker that will get a color at a specified pixel coord on C2's game canvas.

    [edit] (By "canvas", I mean C2's game window area, not the 3rd party "Canvas" plugin.)

    It would look something like this:

    pxR( x , y )

    pxG( x , y )

    pxB( x , y )

    Ideally the picker expressions would get the color as it appears on the screen. (i.e. After all webGL effects have been applied.)

    Does anyone know how best to do this from within the SDK?

    Thanks in advance for any advice or suggestions.

    Possibly related R0J0hound example code

    I saw in another post that R0J0hound posted some javascript that could be executed from within a C2 event sheet to retrieve color at a given pixel, and this looks like what I want to do.

    Granted, I'm not sure if this is the best way to do it from within the SDK, since I might be able to get access to the canvas directly, rather than looking it up in the DOM by element id.

    // This is a paraphrase of R0J0hound's original code found at the link above.
    var canvas = document.getElementById( 'c2canvas' );
    var ctx = canvas.getContext( '2d' );
    var pixel = ctx.getImageData( x , y , 1 , 1 );
    pixel.data[ 0 ];") [/code:2hd9dwhd](That said, I wasn't able to get this code to work from within C2. It seemed to work up until assigning the canvas context into "ctx", which as near as I can tell always assigned null/undefined, as I could never get any data out of it, or .toString() the object. So I'm probably doing something wrong.)
  • Hey alextro, <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    Just in case you're interested, a while back I found a really cool interactive demo of various path finding algorithms.

    https://qiao.github.io/PathFinding.js/visual/

    At the site listed above, I believe the "breadth-first-search" algorithm is equivalent to the "flood-fill-search" algorithm. (3rd in the list.)

    Construct 2's built in path-finding algorithm is A*, (which is pronounced "A Star"). (1st in the list.)

    One other special case path finding solution that can be handy is "Goal-Based" path-finding. This one is usually only good when you want to have a massive number of objects path their way to a single goal location.

    This is a video that does a nice job of explaining it.

    Subscribe to Construct videos now
  • No worries. And thanks for sharing your findings, SirPumpAction. Very helpful to know.

    ... also I love your avatar.

  • Interesting.

    So, from what I gather, "Use high-DPI display" forces the browser to ignore the "device-pixel-ratio" specified by the mobile device.

    For instance, the Galaxy s6 normally scales everything up by 4x (device-pixel-ratio of the s6) to make webpages readable, but with "Use high-DPI display" enabled, it will instead render everything at 1x scale, or more importantly, 1-to-1 pixel density with the display's native resolution.

    That kind of makes sense, as you were seeing the full screen view of your game rendered at exactly 1/4th the display resolution, and then scaled up by 4x (device-pixel-ratio of the s6) to fit the screen. By coincidence your game at 1x scale happened to also be exactly 1/4th the display's resolution, which perfectly hid what was going on. <img src="{SMILIES_PATH}/icon_e_biggrin.gif" alt=":D" title="Very Happy">

    The device-pixel-ratio is a fixed scaling factor determined by the device manufacturer, but is different for different devices. This scaling factor came about as a way to scale websites to a reliably readable size across different devices and display resolutions.

    The description for the "Use high-DPI display" property is as follows,

    "Use high resolution display where available. If disabled, renders in low-res and upscales."

    So when enabled it renders directly at native resolution.

    Back towards the end of 2013 Construct 2 "r148" was released, and the high-DPI option became a project default. In the release notes Ashley explained the following:

    [quote:1jf7k7iy]"This build broadens support for any device with a high-DPI display, including modern Android phones and tablets, Tizen and Blackberry 10 devices, and Amazon tablets. Graphics can render at considerably better quality with high-DPI support, and especially text which can appear much crisper and more readable.

    Since high-DPI displays have many more pixels, using this mode can reduce performance since there is more rendering work for the GPU. So we've kept it as an option, but renamed from "Use iOS retina display" to "Use high-DPI display". It's on by default and we highly recommend using it whenever possible, but in some cases you may need to turn it off for performance to be acceptable."

    https://www.scirra.com/construct2/releases/r148)

    As he points out, it's theoretically possible to see a performance gain from turning it off, but it's essentially required for correct rendering on devices that use a scaling factor (device-pixel-ratio), and it's also worth noting that the performance effect was negligible enough back in 2013 to make it enabled by default. So in 2016 you should be pretty safe leaving it enabled, especially since it fixes the blur problem.

    [ edit ]

    Here's an interesting article on "device-pixel-ratio":

    http://juiceboxinteractive.com/ideas/a- ... e-devices/

  • Awesome! Happy to help. <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    If you're interested, you can also get more 3rd-party shader Effects in the "Extending Construct 2" > "Effects" section of this forum.

    The "WebGL Effects List" thread keeps a list of the published 3rd-party Effects.

    And depending on how far into effects you want to get, you can also code your own shaders for C2.

    Shaders for C2 can be programmed in the GLSL language, in any text editor.

    There's a template effect file included in the Construct 2 SDK files, which you can get at the link below.

    SDK: https://www.scirra.com/manual/15/sdk

  • That's a good point. On a mobile device it would be ideal to render once at the pixel art resolution and then just scale up to full screen.

    When running the game on the Galaxy, are you running the game as an installed android app, or are you running it from within a browser like Chrome or Firefox?

    You might want to try running from a few different browsers on the Galaxy to see if there's a difference in the scaling behavior. It's possible that the bilinear blurring is a side effect of the environment the game is running in and not you're project settings, especially given that the games scales correctly on your desktop computer.

    It may be that, the method C2 uses to tell the target environment to use "point" interpolation scaling, doesn't work for all environments.

    Finally you said in your first post that "Fullscreen scaling" was set to Low quality, which would seem to make sense, given that you don't want any filtering, but you could try high quality, to see if that makes a difference on the Desktop and Galaxy versions.

    This one is a long shot, but mobile graphics hardware does some weird things in response to settings you would think would be consistent across platforms.

    I've vaguely recall seeing a very (very) few situations where a graphics property on low settings will defer to the discretion of the target hardware on how to handle things, while a high setting will force the hardware to do things a certain way. Mind you, I've never seen or heard of that kind of thing in C2, but mobile graphics hardware is weird that way. It seems to me like it was a floating point precision thing, so likely not related.

    For an interesting example of said weirdness, here's an article on floating point calculations that does a good job of showing the inconsistent internal computational spookiness of mobile GPUs. Note: I don't think the effect described in the article below is specifically related to your problem. I was just trying to remember some of the articles I'd come across that showcases some of the same kind of esoteric mobile GPU characteristics that can result in unexpected behavior.

    http://www.youi.tv/mobile-gpu-floating- ... variances/

    (Scroll down to see various devices render the same exact shader script in uniquely distorted and variably buggy ways.)

  • Hey again,

    I suspected that Crop wouldn't fit the game correctly by default, which is why I mentioned the "start of layout" event that might be needed to see the pixels close up, but that said, did Crop mode fix the blurry pixel problem?

    The reason I'm curious is because Crop mode is (as far as I know) C2's most open-ended full screen display mode, and with some effort (and events) you can pretty much make it behave like any of the other modes, but with more control.

    The main thing that Crop mode will give you is that the game will not be rendered to an intermediate texture and then stretched to fit the target display. I'm not sure, but I suspect that might be the cause of the blur you're encountering.

    The Galaxy s6 has a res of

    2560 x 1440

    The image of the title screen you posted is

    1280 x 720

    And that title screen is a 2x scale-up of the pixel art, meaning its un-scaled res is

    640 x 360

    Out of curiosity, could your list you PC's monitor resolution?

    And most importantly, what is the game's "Window Size" property set to? If it's 640 x 360 that might help shed some light on the issue.

    Anyway, given the above, that means the pixel art is being scaled up exactly 4x to fit the Galaxy's screen, (from 640 x 360 to 2560 x 1440). Also is the image you posted from the Galaxy's screen scaled back down 2x, because it's not the full 2560 x 1440 res. No problem if it is, just curious.

    It looks to me like the 4x scaling being done on the Galaxy is using bilinear filtering. If I take your sharp title screen into Photoshop, scale it down (via Nearest Neighbor) to its 1x scale and then scale that up by 4x (via bilinear) to simulate the Galaxy's scaling, my re-scaled version is virtually identical to your blurry comparison image. (Note: I also scale my version back down by 2x to match the 1280 x 720 res of you're 2nd comparison image.)

  • Hey SirPumpAction,

    I have yet to build any games for mobile devices, so I'm not sure all of the potential causes, but one possibility comes to mind.

    "Crop" mode

    It may be that the "Full screen in browser" mode is rendering to an intermediate texture and then scaling it to fit the mobile's screen.

    To work around this you could try setting "Full screen in browser" to "Crop".

    The "Crop" mode means that your game will not be auto-rescaled regardless of the monitor dimensions.

    You'll then have exact control over how the game is scaled up to fit a monitor, but as a side effect you'll have to be a little careful with how you place hud elements, as object positions that work on a 16:9 aspect ratio display, might get cut off on a 4:3 aspect display.

    You may also need to zoom the layout with events, by detecting the monitor dimensions and scaling up by the best integer fit.

    Even if you don't plan to ultimately use Crop mode, you might want to at least try it to see if that suppresses the blurry bilinear filter effect you're seeing in the second image.

    Importantly, if your game displays at a 1-to-1 pixel scale (looks super tiny and zoomed out) when running in Crop mode, then you may want to temporarily add in an "On start of layout" >> "Set layout scale" to 3 or 4, so you can see if the pixels are coming out sharp when scaled up.

    Pixel Rounding

    One other option you might want to enable is "Pixel Rounding", though that isn't likely to fix the blur unless your entire title screen has pixel coordinates that are exactly half way in between integer pixel coords, (e.g. 0.5 by 0.5).

    That said, "Pixel Rounding" will ensure that all game objects will be rendered as if their origin points are snapped to integer pixel coords, though the internal game logic will still treat them as floating point coords.

  • Hey shalmu,

    Apologies if I misunderstand your question, but it sounds like you're interested in applying a "multiply" blend mode to an object.

    HTML5 vs Shader Effects

    So there are two systems that can apply blend modes to an object, basic HTML5, and Shader Effects. I think you may be looking at just the basic HTML5 list of blend modes, which has modes like "Additive" and "XOR", but it doesn't have "Multiply". Fortunately the Shader Effects do have a "Multiply" blend mode you can apply to objects.

    Applying a shader effect

    With the object selected, in the properties panel, in the "Effects" section, there should be two properties listed, "Blend mode" and "Add / edit" (Effects).

    The "Blend mode" property sets the basic HTML5 blend mode for the object, and does not require a graphics card. Again, this is the list that has "Additive" and "XOR", but not "Multiply".

    Alternatively, the "Add / edit" (Effects) property lets you add multiple shader "Effects", which require a graphics card.

    A "shader" is a graphics effect, like a blend mode, or a distortion, or a blur, but importantly these effects are rendered by a graphics card instead of just the basic HTML5 engine.

    • If you click the blue "Effects" link, to the right of the "Add / edit" property, you should see the "Effects" window pop up. This window shows you the list of effects applied to your object. It will be empty to begin with, since we haven't added any effects yet.
    • At the top of this window, click the plus "+" button, and you should get a list of all the available shader Effects you can choose from.
    • If you scroll down to the "Blend" section, you'll see "Multiply".

    Shader effect & Mobile devices

    Mobile devices like tablets and phones might not support shaders, because they might not have a graphics card to render the shader effects. But nearly all computers should have no problem rendering shader effects. Just something to be aware of.

    Hope that helps.

  • Hey deropke2,

    I'm not entirely sure I recall all the limitations of the free version but I think the following setup might be an option...

    "ScrollTo" & "Pin" Behaviors

    If you create a sprite object (e.g. named "camTarget") and scroll the camera to it using the "ScrollTo" behavior, you can then move the camTarget object to move the camera.

    As an added bonus, you can pin other objects to camTarget and they will follow the screen around.

    This means you don't have to fiddle with typing in pixel offsets in events to position the hud items. You can just position hud items in the editor, wherever you want them to appear, relative to the camTarget object.

    The HUD items will keep their positions relative to camTarget, and camTarget will always be centered. You'll need to enable "Unbounded Scrolling" in the layout properties, to make sure the camera can stay centered on the camTarget even at the edges of the layout.

    Another benefit of this setup is that it requires almost no events, just 1 per pinned HUD element. Or if you use families, 1 per pinned object type. (e.g. Put all the HUD sprites in a fam, and pin the fam. Put all the HUD text in a fam, pin that fam. That's just 2 events.)

    Behavior/Event sequencing Problem

    There is one possible problem though. Behind the scenes, behaviors work like invisible events. The problem is that you can't (to my knowledge) control exactly when behaviors execute their event-like effects.

    This means that the position updates executed by ScrollTo and Pin, may occur always after or always before your actual events. (I forget which) And the danger there is that, if you try to stick the camTarget to your main character with an "every tick" event, you may find that the behaviors are updating the camera position before your custom events move your main character.

    That is, the behaviors move the camera to your character, THEN your custom events move your character somewhere else, THEN the frame is rendered and the camera is looking at where your character was.

    This means that your character will always be one frame ahead of the camera position which will look stuttery. One work around is to also use the Pin behavior to pin and un-pin the camTarget object to your main character, so that the entire camera movement system is handled through Behaviors. That should minimize the possibility for behavior/event sequencing problems.

    C2 online manual

    In case you're interested, you can read more about those behaviors in the C2 manual at the links below.

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

    Just wanted to add a small additional note...

    At the top of the screen cap I noticed the LstickRadius was being set via the distance formula.

    C2 has a built in distance function that will return the distance between two points.

    It can be found as an expression in the "System" object, in the "Math" section. Or you can just type "distance" in any expression area.

    In your case, you want the radius of the stick position. Which is the distance from the stick's centered position (0,0) to the stick's current position (axisX,axisY).

    So you can use the distance function like this:

    distance( 0 , 0 , axisX , axisY )

    Granted the above example is simplified for clarity.

    Using the actual expressions for retrieving the stick positions you'd write the following.

    distance( 0 , 0 , Gamepad.Axis(0,0) , Gamepad.Axis(0,1) )

    Finally, there is also an angle(x1,y1,x2,y2) function, and an anglediff(a1,a2) function among others which can come in handy as well.

    Below I added a link to a full list of all built-in math system expressions from the online C2 manual:

    The "Math" section is a ways down the page. The "Text" section is also worth checking out. <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    https://www.scirra.com/manual/126/system-expressions

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Hey heagon, <img src="{SMILIES_PATH}/icon_e_smile.gif" alt=":)" title="Smile">

    I believe this can be done.

    I think what you're looking for is "preview over local network".

    It's a little tricky to set up, but I got it working with an Android tablet.

    Here is an article explaining the setup process:

    https://www.scirra.com/tutorials/247/ho ... al-network