R0J0hound's Forum Posts

  • This was reported as a C2 bug and not a C3 one. Also I think tagging the devs in posts in the bugs section is kind of redundant.

    Anyways, what's happening is the textbox object, once selected, blocks most all input events from passing through it to anything else. So the keyboard state (which is stored in a array in the keyboard object) isn't updated when the spacebar key is released.

    I'm not the developer, but you can make the keyup events not be blocked from the textbox object as a self fix. It would make the key released triggers fire as you type stuff, but perhaps that's acceptable in your case.

    Anyways, set the textbox id property to something like "foo" and then using the browser object run this code:

    start of layout
    -- browser: execute js: "$(document.getElementById('foo')).off('keyup');"

    I don't think it would work in C3 unless jquery is used in the textbox object.

    Alternatively, I guess if you wanted more control you could just do your own textbox with events and filter keyboard events yourself. Last I checked the keyboard object wasn't quite up to snuff to get typed keys with case and such, so you could capture keys with a little js as well. I thought I had posted this before, but I guess not.

    ucf4f5901e4b2339617d497dd05f.dl.dropboxusercontent.com/cd/0/get/Ch5PitZZhvlm6Nv3myvjP_rSGzA6WKFpKfkqV-AJvBn0ZIwjbmSHr7x8q3tXqMikxxAwUJspu3lOc1ScCQuGst9u_B8ZjlZxKcyxRm12WjP4PVxRj34ADzAeUtug9hLZxco/file

    cheers

  • Array.asJSON, when parsed as javascript gives a dictionary with an entry with a 3d array. Do you really need to convert it?

    You could build your own array with text from the array before passing it.

    global text arrayText = ""
    every tick
    -- set arrayText to "["
    array: for each x
    -- add array.curvalue&"," to arrayText
    every tick
    -- add "]" to arrayText

    Then just pass arrayText when you call some js.

    You could also build a 1d array from it after passing it, or even just use it directly. I mean say you did:

    browser: execute js "myfunction("&array.asJSON&")"

    then in that function you'd access stuff like this:

    function myfunction(c2array)
    {
    	// access value at x=22
    	c2array.data[22][0][0];
    	// access value at x=3, y=2
    	c2array.data[3][2][0];
    	// access value at x=13, y=66, z=5
    	c2array.data[13][66][5];
    }

    Notice it's always a 3d array.

    If you want to convert the 3d array to a 3d one then just go for it. It's the standard type of thing to do when writing code.

  • Even a hidden html5 canvas will use video memory. Internally the browser is using the graphics card for basically any and all rendering.

  • Oh interesting, I didn't know "multiply" was one of the options now. It didn't used to be. I'm not sure if that would cause compatibility issues on some browsers.

    I hadn't thought of creating individual letters of different colors as needed and keeping them for later use. Probably works well when only using a limited amount of colors. If the user ended up trying to do gradual color transitions you may run out of video memory though.

    It's not bad to end a batch in c2's renderer. It does it all the time. All a batch does is it sends multiple quads using the same texture at the same time instead of separately. Besides you'd be doing your own batching of all the letters in your spritefont renderer. The only drawback is if multiple spritefont instances drawn right after each other then they could only be batched individually instead of together, but I say it doesn't matter too much.

    It seemed fun enough to try my hand at webgl again and try using my own shaders instead of working within the limits of c2's shaders and renderer. I must say webgl tutorials seem to add a lot of cruft to their code. It actually seemed fairly straightforward.

    Here I used the browser object to replace the drawGL of one instance to test stuff out. It uses it's own shader program and supplies it's own vertex,uv and color data. The only things I had to save and restore in the c2 renderer was the current shader program and arraybuffer it was using. Otherwise I tried to reuse as little as needed from the renderer, which amounted to just the view matrix.

    uc431d0c7caed3a8a31113f0c8f0.dl.dropboxusercontent.com/cd/0/get/Ch8t3GzRTJvrgR9GVsXVbb-jlFi1qJQrrELJHnSxajQET5VxKFvYZP3wZbEioYM-Eul9bxIWaVGmSfdM3DHf4S9jEhnTd4m-LW_DtABhiFWQo_dYnBYljHZWj3h5rS_e_nw/file

    Maybe that could be a useful example to use alongside a webgl tutorial.

  • We are still talking about spritefonts though, which is a quad per letter. Here the question was ways to do a different color per letter. I seem to recall c3 solved this with their updated spritefont object. This is mainly because c3's renderer adds a per quad color multiplier.

    You're probably thinking of geometry based. It's relatively simple to draw a bunch of quads. Although it's probably tedious to design or convert existing fonts over. You'd still want to use some custom webgl to do multiple quads faster and color them.

    Anyways here is a nice list of all the methods of doing text in webgl:

    stackoverflow.com/questions/25956272/better-quality-text-in-webgl

  • As I recall the Klik n Play example you got the graphics from used an actual user defined path to move around the track.

    The pathfinding behavior in construct is probably not well suited for this. Typically you'd define waypoints you'd want to pass through before telling to to find the path. You'd only do this again when the end of the path was reached.

    An example capx is always better than images, but it probably stops because the pathfinding behavior will slow to a stop when it hits the grid containing the destination location, so it may not collide with those sprites to pathfind again. Setting the cell size smaller could be an idea, but wouldn't be great for performance.

  • I'd say for simplicity don't mess with the internals of C2's renderer. It's designed to draw quad and point batches as well as using effects in a way that's best left handled by the editor.

    So If you want to draw in webgl you should be able to call glw.endBatches() or whatever it's called and then use any webgl you want. Just save all states you change and restore them when you're done. The creature2d plugin does this and performance seems to be decent.

    My guess is you'd replace the shader used by default with one that takes a color per quad as a parameter too, so it would multiply the texture with the per quad color to get multiple colors. I'd say first try it out in straight webgl outside of construct to get the concept down. Then you can do it in construct and see how much of the c2 renderer's webgl state you can reuse.

    For rendering it with a html5 canvas you could probably do it by using two canvas'. One you'd draw the text in white to, and the other you'd draw colored rectangles for each letter. Then as a final step you'd use a blend mode to combine the two to make colored text.

    If you're concerned about performance don't use a html5 canvas method when you plan on drawing with webgl. The main issue is the canvas will need to be copied to a webgl texture every frame it changes. This is why C2's text object is slower, as well as my own canvas plugin.

  • Shift+enter to add a new line in comments.

  • If it helps all the motion equations are defined by this equation:

    rate x time = distance

    vz is the rate that z is changing (the velocity)

    dt is the time is the duration of the frame

    so vz*dt is the amount that z changes in a frame

    In the same way we can apply gravity to the velocity, since gravity is an acceleration, which is the rate of change in velocity.

    So g*dt is the amount that dz changes in a frame.

    Or just simply:

    every tick:
    -- sprite: add g*dt to vz
    -- sprite: add self.vz*dt to z

    Next we need to decide what z value would be the ground. This is fairly arbitrary, you can pick any value. I initially used 1, then changed it to 100, mainly to simplify the math with the perspective scaling. We also need to decide what direction z goes, whether into the screen or out of it. It doesn't matter which, but it does affect the values you'd use for vz and g.

    Let's be simple and say z=0 is where the ground is. Let's also say that into the screen is positive z, and for our physics lets consider positive z as down.

    So if gravity is down then we can make g = 10. So the object will accelerate down into the screen.

    To make a nice arc instead of a freefall we'd make vz=-10 so it goes up first.

    Here's a nice diagram of our setup showing where the ground is, and the directions of gravity and the initial velocity:

    Next we can figure out when and how to bounce.

    Well it makes sense that a ball would bounce when it collides with the ground. So a collision would be when z=0? Yes, but the calculations can make the z move past 0. That would make a collision when the z is greater than or equal to 0. So viola we now can detect when the object is on the ground, aka this can be our condition.

    sprite: z>=0
    -- ...

    Here's a visual of the z position frame by frame and a possible example when a collision is detected:

    Notice the object can have moved past the ground before the collision is detected. Let's fix it by moving it to be on the ground.

    sprite: z>=0
    -- sprite: set z to 0

    Note: this pretty much does what I used the max() expression for in my op.

    Now that the object is safely resting on the ground, even when it tries to move past, we can now consider how to bounce.

    Bouncing is really simple, just reverse the direction of the velocity. We do that by making the velocity negative.

    sprite: set vz to -self.vz

    It will bounce to about the same height as it was dropped from. To make it bounce less we can just multiply the velocity by a number between 0 and 1 when we reverse it. Let's make each bounce go only half as high, so we'll use 0.5.

    sprite: set vz to -0.5*self.vz

    Sweet. So that would make the whole collision detection and bounce event this:

    sprite: z>=0
    -- sprite: set z to 0
    -- sprite: set vz to -0.5*self.vz

    All that takes care of the motion and bouncing, but it gives us no visuals. We want the sprite to scale as if it was getting closer or further from us as the z changes. So first lets look at how such scaling is done. A diagram is great for this:

    We see an eye, an object and the screen. The size of the object's shadow on the screen is the size we want to scale the object to to make it seem that close.

    Notice that the triangle from the eye to the object is a scaled version of the triangle from the eye to the screen. For those interested you can dirive the the equation for z scaling from this. I'll keep this simpler by just giving the equation:

    sprite: set scale to eyeDistance/(self.z + eyeDistance)

    In similar fashion you can move the xy position with something about the same for more effect.

    eyeDistance is the z distance from the eye to the screen. We just choose a value for this. 100 works well for our purposes, but we can change that to adjust the strength of the effect.

    Anyways here is the whole example:

    {Editor setup:}
    Sprite:
    z=0
    vz=-10
    
    {Events:}
    global number g = 10
    global number eyeDistance = 100
    
    every tick:
    -- sprite: add g*dt to vz
    -- sprite: add self.vz*dt to z
    
    sprite: z>=0
    -- sprite: set z to 0
    -- sprite: set vz to -0.5*self.vz
    
    every tick:
    -- sprite: set scale to eyeDistance/(self.z + eyeDistance)
  • No reason really. Adding a negative number is the same as subtraction. Plus it’s faster to change.

    I don’t have Twitter. Just here.

  • There are more elegant ways to handle it.

    Basically I started with z is the distance into the screen and 1/z is to get the scale.

    Basically z=0 is the eye location.

    Z=1 is the ground

    And z<0 is behind the eye and should be hidden otherwise things scale up again negatively.

    If we just had stuff going away from the camera it would work fine. The objects would get smaller. The problem is the objects are going up and only have 1 unit to move before being behind the camera. So I just scaled everything down.

    A better solution may be to use z=300 and the ground level, and make vz negative, and g positive.

    Then the scale would be:

    300/z

    Yeah that would look cleaner.

    Further reading would be “perspective transform” on Wikipedia or elsewhere. I’ll see if I can make a simpler example/better explanation later.

  • That was the line where z was added to.

    I also forgot to take into account z scaling. Edited the op with the changes.

    It uses (100-1)/(100-z) for the scale now. Change the 100s to adjust the amount of scaling. It may be ok to just use z directly like before. It all depends what is acceptable.

  • Probably something like the following. Only considering one product but it’s basically the same for multiple.

    Global number wallet=5000
    Global number applePrice=45
    Global number applesOwned=0
    Global number quantityToTrade=10
    
    Wallet < applePrice*quantityToTrade
    — disable buy button
    Else
    — enable buy button
    
    On buy button pressed
    — add quantityToTrade to applesOwned
    — subtract applePrice*quantityToTrade from wallet
    
    quantityToTrade > applesOwned
    — disable sell button
    Else
    — enable sell button
    
    On sell button pressed
    — subtract quantityToTrade from applesOwned
    — add quantityToTrade*applePrice to wallet
  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Intuitively the one doing more steps would be slower, but here it is negligible so it doesn’t matter.

  • There isn’t a way to make a path in the editor, but as one possible solution you could place a bunch of sprite instances along a path and use that.

    Create a sprite and call it “node.” Give it and instance variable called “order.”

    Now just make multiple instances of node and position them in the shape of the path you want. Then set the order variables for each instance. 1 for the start, 2 for the second and so on. This is so we can move along them in order.

    Next we need to setup the object that will move along the path. Create a sprite and call it “follower.” Give it some instance variables:

    pos=0 for it’s position on the path

    speed=10 for the speed along the path.

    Anyways on to the events to make follower to move back and forth along the nodes:

    Every tick

    — follower: add self.speed*dt to pos

    Follower: pos<0

    — follower: set pos to 0

    — follower: set speed to -self.speed

    Follower: pos>node.count-1

    — follower: set pos to node.count-1

    — follower: set speed to -self.speed

    Global number t=0

    Global number id1=0

    Global number id2=0

    For each node ordered by node.order ascending

    — follower: pos<=loopindex

    —— set id1 to node.iid

    — follower: pos>=loopindex

    —— set id2 to node.iid

    ——stop loop

    Every tick

    — set t to follower.pos-int(follower.pos)

    — follower: set x to lerp(node(id1).x, node(id2).x, t)

    — follower: set y to lerp(node(id1).y, node(id2).y, t)

    That will change the followers pos variable with the speed. If it goes off either end then the speed is reversed and the pos is limited to the end.

    Next we loop over the nodes to find the instance right before and right after the object’s current pos.

    Finally we use lerp to get an actual xy position between those nodes.

    Note:

    Speed is how fast the follower moves from node to node. So for consistent speed keep the nodes evenly spaced.

    The events were done with only one path and one follower in mind.

    Barring any typos the above should work.