Yann's Forum Posts

  • demo

    capx

  • structure.Timer.CurrentTime("03")
  • nemo

    Yeah, well, I actually wanted a virtual joystick that would appear where you first touch (:

    Kinda relative stick

    I indeed made another version with fixed buttons so I can just do a "on object touched" and capture the TouchID without having to check the touch.X value.

    But with a relative stick, I need first to check if it's on the left or right of the screen to know if it's the left or right stick.

  • jayderyu

    Ah yeah indeed

    I could have done

    Touch.XForID(Touch.TouchID)

    But still, I wonder why the Touch.TouchID and Touch.TouchIndex correspond to the last touch, but Touch.X is kinda forced to always be the first finger's position.

    To me, it would make more sense to put in the instanceProto.onPointerStart function

    this.trigger_x = touchx
    this.trigger_y = touchy

    And us those for the Exps.prototype.X and Exps.prototype.Y functions

  • Hi,

    Another suggestion (:

    Here is the situation: I had to implement some virtual joystick system for smartphones.

    The idea was to have two joysticks, a left one to move a character, and a right one to aim and shoot.

    And here is how it seemed natural to proceed:

    Global number rightID = -1
    Global number leftID = -1
    + on touch start
       + leftID = -1
       + Touch.X < scrollx
          -> set leftID to Touch.TouchID
       + rightID = -1
       + Touch.X >= scrollx
          -> set rightID to Touch.TouchID
    + on touch end
       + Touch.ID = leftID
          -> set leftID to -1
       + Touch.ID = rightID
          -> set rightID to -1

    Then I can track the position of the left and right finger

    The only issue is that the Touch.X expression (as well as the Touch.Y) will always give you the position of the first touch

    Here is the proof in the js code:

    Exps.prototype.X = function (ret, id, layerparam)
    {
       ....
       ret.set_float(layer.canvasToLayer(this.touches[0].x, this.touches[0].y, true));
       ...
    }

    The work around I used was to get the last touch using the touch index like this:

    + on touch start
       + leftID = -1
       + Touch.XAt(Touch.TouchCount-1) < scrollx
          -> set leftID to Touch.TouchID

    So my suggestion would be to:

    • either make Touch.X return the position associated with the trigger it's used in, and fall back to the first touch outside of a trigger context (that's already the case with TouchID and TouchIndex I believe)
    • or create a Touch.LastTouchX expression

    (I prefer the first solution (: )

  • Ashley

    alright thanks (:

  • Link to .capx file (required!):

    9-patch-cocoonjs.capx

    CocoonJS export:

    9patch-cocoonjs.zip

    Steps to reproduce:

    1. insert a 9patch object

    2. set edges and fill to tile

    3. export for cocoonjs

    Observed result:

    black patches, and if some layer are used it can appear transparent as well

    Expected result:

    the same as in edit time and desktop export

    Browsers affected:

    cocconjs launcher

    compiled apk

    Operating system & service pack:

    Sony XPERIA with Android version 4.1.2

    Construct 2 version:

    138.2

  • Magistross: that's what Ash asked in the spec. But here is what I think:

    if you use an off-DOM canvas (what you call buffering which is rather caching I think), you will have to use an extra bit of memory for that, and then you still have to draw the resulting big image.

    So the question is: what is faster? drawing many little small images, or a big one?

    I don't have the answer to that, that's probably a good test to run on jsperf (maybe if I have time and motivation when I'm back home...)

    Also how much place the big off-DOM canvas will take in memory can be a big problem.

    And all that is really hypothetically intersting for canvas2D. In webGL, drawing textured polygons should be pretty super fast and way more interesting than rendering a big fat texture that would sit in your memory.

    So yeah, the simple answer is that it's a trade off between memory and cpu use. Here Ash prefered lowering memory use.

  • Little explanation about how the spritefont plugin works:

    First when the plugin gets loaded, it creates a list of all the clipping coordinates for all the characters.

    Then on the first draw, or each time the text changes or each time the object's width changes, the plugin will calculate the word wrapping (splits the text in lines according to wrapping method, size of the object, etc)

    Then it will draw each letter the same way a sprite is drawn (taking care of horizontal and vertical alignement for you):

    - in canvas2D mode, using the context.drawImage() function

    - in webGL mode by building quads that c2 uses to pass to the default rendering shader along with the texture.

    What you have to keep in mind is that each time the text needs to be drawn on the canvas, whether it's webGL or canvas2D, each letter will have to be redrawn.

    It means, that will happen each time your text moves, each time the text is modified and, I think, each time any object gets on top or underneath your text.

    So if you have a constantly scrolling game (like bit trip runner), your spritefont text will be redrawn each tick.

    Drawing a lot of characters one by one can end up being quite expensive in canvas2D. In WebGL you can just think that one character costs 2 triangles (think 3D rendering) so you'll probably have 200 triangles for a 100 character text. Which should be ok in most devices... I think.

    Also, any characters not in your character set will be drawn as a nothing, it will just offset the next character's drawing, creating a space.

    So basically, i'm saying that spaces should more or less cost nothing (unless you put a space in your character set... which you shouldn't do (:

  • 'm going to have a lot of these sprites in my game at once, so it'd be nice if I didn't have to compute distance between all of them each tick. I thought the overlaps on offset was perfect, but I guess not?

    I'm honestly not sure that overlap is less expensive than distance checking.

    To check the distance between two points, the formula is (and it's what c2 use):

    distance(xa,ya,xb,yb) = sqrt((xa-xb)^2 + (ya-yb)^2)

    basically you have 4 multiplications, 1 addition and one square root operation.

    The square root operation is known to be a bit slow

    Now for an overlap check, depending on the complexity of the shapes and the fact that they are rotated or not, it can be easy, or less easy.

    But the basic "quad is overlapping quad" function more or less check if one is contained inside the other, and then if not, it checks if there's an interesection between each segments.

    The operations used are fairly simple but it something of the order of

    "number of vertices of object A TIMES number of vertices of object B"

    So it can get pretty iffy.

    Now, the only thing that is a bit unknown here is the speed of a square root operation. But you know, you don't even have to use a square root, you can yourself check if:

    (xa-xb)^2 + (ya-yb)^2 <  someDistance^2

    Then you have your cheap distance check.

  • If you want some thing more complex, like having any shape constrained inside any other shape, it becomes more complex.

    It would be slightly easier if we had access to the position of the collision polygon's vertices.

    Then we could do some math ourself to check if one of the point of the dragged object is outside of the constraining shape.

    Then it would be a matter of keeping in memory the previous position of the object and interpolating between this position and the position the object would be if there were no constraint by running a loop to approximate the position the shape should be to stay within the constraints.

    Using multiple objects to build the constraining area would be a possible solution but, to me, it would look quite messy to set up.

  • something like that?

    squareConstraint.capx

  • Ashodin

    usually if you want to know the format of the JSON used by a plugin, you just have to do

    on start of layout
       -> add data in object
       -> add data in object
       -> add data in object
       -> download JSON

    you'll get a file with something like what I posted (but in one line)

    it works with the array, dictionary and my polygon plugin.

  • Magistross

    Indeed... But very bad Idea :D

    In Canvas 2D, the spritefont plugin would draw each tile one by one (almost as bad as using tonnes of sprite directly)

    Whereas you usually want to use context.createPattern() to make something tile (that's what the tiledbg plugin uses)

    In WebGL the spritefont plugin would draw a quad for each repetition (faster than canvas2D, but still).

    Whereas you would probably just wrap a texture on a big quad.

    Knowing that the major bottleneck in html5 is the rendering... bad idea =)

    And in both cases, using createPattern (canvas2D) or a big texture (WebGL) you would avoid seaming issues.

    Personnally, I made a quick test on JSBin and animating a tiled bg using image frames should be possible.

    http://jsbin.com/aqowin/2 (tested with canvas2D)

    I'm not sure though how much strains it puts on performances. But any cases, redrawing big chunks of screen (and tilebg are more likely to be big objects) is expansive.

    I'm not entirely sure why tiled background aren't animatable, but I would bet on the "big todolist" syndrom =)

    And well... you can always emulate animated tiledbg by using many objects and alternating their visibility. (I did that once)

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • hmmm I'm not sure what you exactly want, but if you can somehow generate a word list using php/python/java

    You just have to follow this structure:

    {
       "c2dictionary":true,
       "data":{
          "key1":"value1",
          "key2":"value2",
          "key3":"value3"
       }
    }

    It's rather straightforward, you have a "c2dictionary" key which is just for c2 to check that it's supposed to be a JSON for a dictionary object, and a "data" key which holds the list of key/value pairs.

    Now if you have to do it by hand, it's still easier to build such list using a text editor than to create all the "add key" action in construct.

    Now to use such thing, you just have to put that in a file, import it in the file folder of your project tree (in the project panel)

    And then using the AJAX plugin, you request the file, and "on request completed" you load the AJAX.LastData value into a dictionary object.