R0J0hound's Forum Posts

  • I thought it was generated and run at the start of the game. It might still happen when the first script is run though, I'm not sure.

  • If the python files are outside the exe you can just ship the pyc fies generated instead of the py ones. The slowdown is from Construct generating the script to bind objects with python, then of course python also parsing and running it. I don't think it can be improved since the length of the script is proportionate to the number of objects. Unfortunately it can only be made when the game runs, and can't be pre-compiled.

  • 99Instances2Go

    I can't visualize the idea. It seems kind of non-intuitive. I'd have to see it in action.

  • ye7yakh

    I only use pc, but there must be some subtle scaling going on. Maybe try setting "full screen scaling" to "low quality", or using point sampling.

  • I found a pc to test webgl on, and it seems that you can't get both a webgl and 2d context on the same canvas. That explains why my code doesn't work.

    You can still save the entire canvas. Ex:

    var canvas = document.getElementById( 'c2canvas' );

    canvas.toDataURL("image/png")

    or

    canvas.toDataURL("image/jpeg", 0.75)

    That is all the runtime is doing, except it waits till after everything is drawn for that frame.

    From a plugin you can get the canvas with:

    this.runtime.canvas

    instead of

    document.getElementById( 'c2canvas' );

    So the process to get the color of a pixel that also works with webgl would be

    var img = new Image();
    var self = this;
    
    img.onload = function ()
    {
    	var canvas = document.createElement('canvas');
    	canvas.width = img.width;
    	canvas.height = img.height;
    	var ctx = canvas.getContext('2d');
    	ctx.drawImage(img,0,0);
    	var pixel = ctx.getImageData( x , y , 1 , 1 );
    	
    	// save the value in the plugin and call a trigger to use the color in your program
    	self.redvalue=pixel.data[ 0 ];
    	self.runtime.trigger(cr.plugins_.Sprite.prototype.cnds.OnURLLoaded, self);
    }
    
    img["crossOrigin"] = "anonymous";
    img.src = this.runtime.canvas.toDataURL("image/png")[/code:15nrlz3e]
    It's referenced from the loadUrl sprite action.
    
    Basically load toDataUrl to a image.  This is asynchronous so we need a callback when it finishes.  When it's done loading we can then create a canvas, draw the image to it and retrieve a pixel with a 2d context.  Then we save the pixel to a variable we can access from an expression and call a event sheet trigger.
    
    Whew, that's not exactly straightforward.  When webgl is off a pixel can be retrieved in place with the code in your op.
    
    Now to go the webgl route instead there's a nifty readpixels function so supposedly it's as simple as this:
    [url=https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/readPixels]https://developer.mozilla.org/en-US/doc ... readPixels[/url]
    [code:15nrlz3e]var canvas=document.getElementById('c2canvas');
    var gl=canvas.c2runtime.gl;
    var pixel = new Uint8Array(4);
    gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pixel);
    pixel[0];[/code:15nrlz3e]
    which works only on frame 1 it seems. I don't know why, and my google fu hasn't been helped me yet.  But that could be a start.
    
    Edit:
    Here's the proper solution:
    [url=https://asalga.wordpress.com/2011/08/01/using-webgl-readpixels-turn-on-preservedrawingbuffer/]https://asalga.wordpress.com/2011/08/01 ... ingbuffer/[/url]
    But that requires modifying the runtime in preview.js.
  • Ashely

    I'd agree there about it being more like a programming language, which doesn't necessarily make it harder for a beginner. It's kind of more event sheet inspired at this point.

    The "filter" condition would act just like the "pick by comparison" condition of c2, it could be called "pick" as well but for now I'm leaving it for now. The idea for "sol" is it would be a more advanced feature to allow some additional control. Without it things would operate the same as most of C2's events already do.

  • ye7yakh

    The colors must be slightly different at those spots.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Prominent

    In that case "else" would still work since it's just logic based. Aka the else will be true if the previous event block fails. It just doesn't do any picking. The "split filter" condition is supposed to address the else like picking, but I may yet axe it from the design since it's kind of akward. I'm shooting for simple and intuitive with everything.

  • fisholith

    That should work with webgl off i'm pretty sure. Even with webgl on I think it should work. For reference you could look at the snapshot canvas action, which basically uses the same approach i think. i can''t test webgl currently.

    From a plugin you should be able to access the canvas from the runtime variable i think. There is a way to grab a pixel with just webgl which I tried to use with the paster plugin when webgl was working for me but it proved unreliable.

  • Here I present an idea for a ground up re-design of Construct's event system. This is purely for the logic portion and doesn't cover engine features. It's not entirely fleshed out and there are details I'm probably forgetting. The purpose is purely for fun, and may never see the light of day.

    conditions

    First off conditions are greatly simplified.

    Here are the system conditions:

    * "if" which is basically the same as system->compare

    * "else" this will differ from C2's else in that it doesn't pick, it's only if the previous event block was false.

    * "loop" which will cover all looping: and will look like "loop: var i=0 to 10", "loop: var i=sprite.count",...etc. More on what "var" is later.

    * "split filter" my solution to else. It's like "filter" below but the unpicked instances will be put in another type. Example "split filter: sprite, sol other: sprite.x>0", after which "sprite" will be all the instances below 0 and "other" will be all the instances above zero.

    Object conditions will be:

    * "filter" which is the catch all picking. For example "sprite: filter sprite.x=2" will replace "sprite: pick by x=2". It still follows the rule if nothing is picked then the following conditions in the block don't run.

    "sort" the idea with this one is is an object type is a list of objects and can be sorted. The closest in C2 already is the for each ordered. One example use would be "sprite: sort sprite.y" which would sort the object list from low to high instead of it's current order.

    actions

    Actions as well will be simplified. Basically for values, instead of "sprite: set x to 10" it would be "sprite.x=10". More on other kinds of actions later.

    variables

    Next up are variables definitions. The big thing here is you can put them anywhere you need them. A list of possible places:

    * in between event blocks, like C2 already does

    * inside event blocks

    * in the actions column.

    * special cases: var in "loop", and sol in "split filter".

    Next we have two kinds of variables:

    * "var" this is basically the same as C2's variables. aka. number and text. However this can be extended to array, object, dictionary, etc...

    * "sol" this defines a new type on the fly, which will replace families and make picking two seperate instances simpler. From the point it's defined it acts like any other object type.

    Family example:

    sol family=sprite, sprite2, sprite3
    
    +----------------------------+
    | family: filter family.x<10 | family.x = family.x+1
    +----------------------------+[/code:3j88tc5m]
    
    General picking example:
    [code:3j88tc5m]+----------------------------+
    | sol other= sprite          | sprite.x=200
    | sprite: filter sprite.x=10 | other.x = 11
    | other: filter other.x=11   |
    +----------------------------+[/code:3j88tc5m]
    
    [b]expressions[/b]
    Referencing seperate instances with expressions will be improved.
    You can still do the familiar pattern for an action: "sptite.x = sprite.x+1" which will add 1 to the x of every picked instance.
    You can also use "sprite[0].x" which is about the same as c2's "sprite(0).x" but will reference the first picked instance of sprite instead of just the first instance. You can also do stuff like this:
    x of first picked sprite: "sprite[0].x"  
    x of last picked sprite: "sprite[-1].x"
    It even applies to the action:
    [code:3j88tc5m]+----------------------------+
    | sprite: filter sprite.x<10 | sprite[0].x = 11
    |                            | sprite[-1].x = 22
    +----------------------------+[/code:3j88tc5m]
    Also objects can be assigned to variables.
    [code:3j88tc5m]+----------------------------+
    | start of layout            | sprite.child = sprite2
    +----------------------------+
    +----------------------------+
    | sprite: filter sprite.x<10 | sprite.child.y = 11
    +----------------------------+[/code:3j88tc5m]
    Another reason for this is to make create an expression if you don't want to affect the sol:
    [code:3j88tc5m]+----------------------------+
    | start of layout            | var new = create("sprite")
    |                            | new.x =33
    +----------------------------+[/code:3j88tc5m]
    Of course you can use create as normal as well which only picks that new sprite. At this time of design the same top level picking as with C2 is used.
    [code:3j88tc5m]+----------------------------+
    | start of layout            | create("sprite")
    |                            | sprite.x =33
    +----------------------------+[/code:3j88tc5m]
    
    [b]Functions[/b]
    This is the most significant re-design.  The goal is to make functions be able to be used perfectly as a condition, action or expression.
    
    First off parameters are named and can be object types.
    
    [code:3j88tc5m]+-----------------------------+
    | on function "turn" (ot, deg)| ot.angle = ot.angle+deg
    +-----------------------------+
    +-----------------------------+
    | start of layout             | call turn (sprite, 90)
    |                             | call turn (sprite2, 45)
    +-----------------------------+[/code:3j88tc5m]
    
    Next the return action will actually exit the function instead of just setting the return value.
    [code:3j88tc5m]+-----------------------------+
    | on function "dist" (a, b)   | return distance(a.x,a.y,b.x,b.y)
    +-----------------------------+
    +-----------------------------+
    | start of layout             | sprite.width=call.dist(sprite1, sprite2)
    +-----------------------------+[/code:3j88tc5m]
    
    Next in order for a function to modify a sol, returnSol is used instead.  This allows it to be used as a condition.  ReturnSol can have multiple values.
    
    [code:3j88tc5m]+-------------------------------------+
    | on function "indist" (a, x,y,dist)  | returnSol a
    | a: filter distance(a.x,a.y,x,y)<dist|
    +-------------------------------------+
    +-------------------------------------+
    | call "in dist"(sprite, 0,0,100)     | sprite.angle = sprite.angle+1
    +-------------------------------------+[/code:3j88tc5m]
    
    The synatax of calling sould simplified somehow.  Above are just a few ideas.
    
    Anyways that's a rough overview.  I'll have to prototype it in order to flesh out a few of the details.
  • The idea isn't super difficult but i guess explaining it with text and implementing it is tricky.

    1. we first need to know if the player is colliding with a tilemap. This is dead simple with one event.

    2. we need to know what tiles the player is overlapping. This example here does that:

    viewtopic.php?f=147&t=123332&p=877612&hilit=overlapping+tiles#p877612

    3. So now we have a list of tiles overlapping the player. Here's a collection of ideas that search gives to get a rough collision point between two objects:

    how-do-i-get-coordinates-of-span-class-posthilit-collision-span_p983039?#p983039

    Guess one idea would be to get an average of all the tiles and use that.

    Here's an idea to take the example from two and only use the part of the tile that's overlapping:

    https://dl.dropboxusercontent.com/u/542 ... oint2.capx

    works well if the sprite is only slightly overlapping the tiles

  • [quote:2qlqyoaa]one question though, how do I actually pick by UID? I can add System.Object With UID(Function.Param(0)) Exists", but that doesn't seem right.

    The array object has a pick by uid condition.

  • That's a handy idea.

  • That's still acceptable in my opinion. There's probably some more details about it in ashley's blog or something. What it comes to is if you need to measure a timeframe that matches the real clock, use wallclocktime.

  • Good point, could be interesting if changes in the code could reflect in the editor.

    That's not really possible since you can do things in js/c that don't translate directly to events.

    The modular idea sounds good but it'll have to wait to see how it works. For construct this is tricky because events are all over the place, so it's hard to handle all cases.