R0J0hound's Forum Posts

  • Construct supports JavaScript, typescript and events. No other languages are supported beyond that.

    You’d need to add support yourself or get someone else to do that. In theory you could compile the python interpreter into wasm to use via JavaScript, then add some kind of layer to call things from construct’s js api with python. But even doing all that would result in limits with what you can do. Aka you wouldn’t be able to run arbitrary python since within the web browser there are limits on things you can do or access. Generally working with supported languages are the easier way to go.

    On the bright side any programming concepts you learn often transfer to other programming languages. Or you can go down the python rabbit trail.

  • You probably will run into a snag in that c3 and threejs each have their own rendering contexts and you can’t share the same texture between contexts. What you’d end up needing to do is copy the texture to memory from one context and load that into the other context. Memory wise you’ll be loading the texture twice and speed wise transferring images to and from vram is rather slow. So you likely will want to do that selectively.

    Generally most of the time when integrating a different renderer with construct they each would have their own unique context so the above is pretty unavoidable. In theory you could have two different renderers operate with the same context to be able to share resources. But in practice it’s not really feasible since the renderers with conflict with each other a lot so you’d need to juggle rendering state.

  • I need to stop posting text versions of events I guess. Here's what I posted implemented in events. Does that work?

    dropbox.com/scl/fi/7skmhfwidcf0ygdqucsp3/oval_to_oval.capx

  • When I write so called pseudocode it usually can be written in the exact same way with events. However, it's probably not clear to most which is ok, but I am not around a computer often enough to whip up an example instead. Anyways, here is an example showing the idea since what I wrote is pretty exact. Only typos were 20 instead of 33 with the volume calculation and "duration" instead of "playbackTime".

    It has only one sound file, in which there are two sounds a gunshot and a monkey. I just wrote down the start and end time of both files.

    Then in the events to play a sound we get a unique tag, play the sound, and seek to the start time. I then add the tag and end time to an array so we can keep track of each sound to stop later.

    To avoid audio clipping from stacking sounds getting too loud I calculate a volume from the number of sounds playing. 1 sound: 100%, 2 sounds: 50%, 3: 33% and so on... The rest of the formula is convert percentage to decibels. It does avoid the clipping, but with a high number of sounds it does make things a bit quiet.

    An alternate idea to handle the clipping could to be to add an analyzer effect to the tags, sum up the peak levels of all the playing sounds, and ease the volume down if it gets too high. Might be a bit heavy though.

    dropbox.com/scl/fi/7574tn2yq9k3wimj8ywek/sub_sounds.capx

    It shows the number of playing sounds at any time.

    Anyways, its just an idea and an array works fine for this purpose.

  • In the loop you need to update shoottag. It should be array.at(i). As is it’s just stopping the shoottag of the last sound you started.

    Edit:

    That only partially matches the pseudocode i sent. I’ll have to screenshot the events later i suppose if it’s not clear.

  • Why not have a unique tag per sound you play? Like have a global variable ID and when you play a sound set the tag to “shoot”&ID then add one to the ID variable. To keep track of all those tags you could add them to an array, and remove them as they finish.

    I’m unfamiliar with playing multiple different sounds from the same file but I assume it involves having a start and stop time to each sound in the file.

    So roughly the idea would be this. Array.width would be the number of sounds playing.

    global number id=0
    Global text tag=“”
    Start of layout
    — set array size to (0,2,1)
    
    Keyboard: On space pressed
    — set tag to “shoot”&id
    — add 1 to id
    — array: push tag to front
    — audio: play sound with tag tag
    — audio: seek tag to startTime
    — array: set at (0,1) to endtime
    
    Global number vol=0
    Global number I=0
    
    Every tick:
    — set vol to 33*log10(1/array.width)
    — set i to 0
    
    While
    I<array.width
    — set tag to array.at(i)
    — audio: set volume of tag:tag to vol
    — compare: audio.duration(tag)>=array.at(i,1)
    — — audio: stop tag
    — — array: remove index i
    — else
    — — add 1 to i
  • Your example disappeared. It should be reversible, but it’s been a bit so let’s redo it from scratch.

    To setup you’d have four objects: oval0, cur0 on layer0, and oval1 and cur1 on layer1. It shouldn’t matter the scale,rotation or rotation of the objects, layer or layout.

    Now let’s suppose you want the mouse position on an oval on one layer to be mapped to an oval on another. We can do that with four set position actions.

    Cur0: set position to mouse(0).x, mouse(0).y
    
    Cur1: set position to cur0.x-oval0.x, cur0.y-oval0.y
    
    Cur1: set position to (self.x*cos(oval0.angle)+self.y*sin(oval0.angle))/oval0.width*oval1.width, (self.x*cos(oval0.angle+90)+self.y*sin(oval0.angle+90))/oval0.height*oval1.height
    
    Cur1: set position to oval1.x+self.x*cos(oval1.angle)+self.y*cos(oval1.angle+90), oval1.y+self.x*sin(oval1.angle)+self.y*sin(oval1.angle+90)

    It should work mapping from any layer to any other layer. The idea here is we get the xy relative from one oval and then calculate the xy relative to another.

  • I mean chess is kind of like any other game. It’s made up of many simpler steps which can be broken up into even simpler steps.

    Generally I think you’d start with how you want to move the pieces. I find moving them with drag and drop sounds pretty intuitive. When you drop you’d snap it to the nearest square. To make it abide by rules you can instead mark all possible moves of that piece and only let you drop on those spots. Just need to be able to look at squares around the piece and see if they are empty or occupied.

    Consider a pawn. One move would be moving up one if the space is free, or move up two if there two spaces ahead are empty. Then for attacks it can go diagonal left or right if there’s an enemy in those squares. It’s pretty straightforward, you just break it down for each piece’s moves.

    The way you implement that can vary a lot. Since it’s a 8x8 grid an array works well but you’d also need to maintain a visual version of that. Using a tilemap mixes array with a visual but you are limited to positions at grid positions. Finally just using sprites for everything gives more position options but you’d have to deal with collisions or picking to inspect squares. Plus you will have to deal with the case of picking two instances of the same type at once I suppose. Anyways, you have options and there are pros and cons of each.

    To see if the king is in check one thing you could do is loop over all the enemy pieces and mark the squares they can attack. If your king is on any of those it’s in check. You can use that to limit where the king moves to so it’s not in check too. But to check if moving another piece will put the king in check you’d just have run the test after the move. And undo it if need be.

    For ai it’s useful to be able to make copies of the game board and try out different moves. So that can add another level of complexity. And as far as how you’d make the ai work it could be as simple as picking random pieces and moves or something more clever and involved. It’s a broad topic and seems involved to make one that isn’t easy to beat.

    Could be educational to try to implement tic-tac-toe, checkers or fox and geese first to get the feel of making a game like chess.

    Beginners tend to write logic like that in a long way. It can be correct but can be tedious to write and refactor. The more you do the more you can use shortcuts like loops, functions and such to reuse code so things aren’t so repetitive.

    Anyways. Interesting idea if you want to make alternate rules. But since it’s intended as a sub game I’d try to find ways to cut as many corners as possible to reduce the time you’d spend on it.

    EDIT:

    Every approach will be a bit different but here is one wip idea how to go about it with a few pieces implemented.

    dropbox.com/scl/fi/260ne0mq2ponctl8rmm6g/chess_wip.capx

    Here's another old one from 2014. It's always interesting to see different approaches. Here it looks like I used arrays more and got it to detect if the kings were in check, but I don't find it very readable.

    dropbox.com/scl/fi/wzw1iy1ng75ijdl26pfl3/chess.capx

  • Here's a demonstration of the hybrid approach. Basically it sets the animation from the angle of motion unless moving diagonally. When moving diagonally it keeps using the direction of whichever arrow key was pressed first. There are likely other ways to implement the idea.

    dropbox.com/scl/fi/tnk06c4xrpkfms75w3b7y/topdown_control_and_animation.capx

  • A hybrid approach may be what he’s after. Use angle of motion in most cases, but when moving at a 45 favor the direction pressed first. That or I’m completely misreading what he’s after.

    Global number jx=0
    Global number jy=0
    Global text keys=“”
    
    On left pressed
    — add -1 to jx
    — add “L” to keys
    
    On left released
    — add 1 to jx
    — set Keyes to replace(keys, “L”, “”)
    
    On right pressed
    — add 1 to jx
    — add “R” to keys
    
    On right released
    — add -1 to jx
    — set Keyes to replace(keys, “R”, “”)
    
    …etc for other keys 
    
    Compare: abs(jx)+abs(jy) = 0
    — set anim to “idle”
    
    Else
    Compare: abs(jx)+abs(jy) = 1
    — set anim to tokenat(“right,down,left,up”, (angle(0,0,jx,jy)+360)%360/90,”,”)
    
    Else
    — set anim to tokenat(“right,down,left,up”, find(“RDLU”,left(keys,1)),”,”)

    Or maybe there’s a simpler way.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Here's an example of the idea above. Opted to use the next tree's x position and size as inputs, and made the hidden layer have three nodes. Seems to generally converge on a decent ai player by 10 generations. Jumping so it just misses the back corner seems to be the way to go.

    dropbox.com/scl/fi/jhhtxm6eunyqaqsm46qsv/neuralNetwork.capx

    I'm not sure if this is valuable to anyone but myself, but I can see possibly using it for other games.

    I found smaller NNs converge faster and it helps to have repeatable levels, at least at first. After mastering a premade level you can throw random generation at it. I also found that giving it simpler goals first helps as well. I'm probably only scratching the surface, as there are a lot of other ideas that come to mind.

  • That plug-in looks to be for a specific kind of neural network. You provide inputs and use some training data with the output to tune the weights with the back propagation action.

    For what you want the “deep” basically means taking the pixels of the game screen and using that as an input. Likely applying some convolution to reduce the amount of data first. You may be better off just feeding the NN with inputs directly to simplify things. Probably the x positions of the next three obstacles or something. The output would be whether to jump or not.

    For the “reenforcement learning” that would basically mean running the game multiple times with random weights, then taking the ones that performed the best and run copies of that with slight differences with the weights and repeat. Over time it would converge on a better solution.

    Anyways that’s what I gather from reading on it. Looks to be a vast subject and there is a lot of ideas you can implement.

    Anyways, as a simple example, you could have the x of the two next platforms be the input, and have a hidden layer of two nodes, and an output of one node of whether to jump or not.

    Math wise you can calculate whether to jump with the NN like so.

    In0 = tree.x
    In1 = tree.x
    Hidden0 = 1/(1+exp(-(in0*w0+in1*w1+w2)))
    Hidden1 = 1/(1+exp(-(in0*w3+in1*w4+w5)))
    Jump = 1/(1+exp(-(hidden0*w6+hidden1*w7+w8)))

    You’d need to do some picking so the inputs would be the next two trees. Or if there isn’t any you could set the values to infinity or something.

    The w0 through w8 values is an array of 9 values that make up the brains of your NN. the values apparently are usually in the 0 to 1 range. Initially you’d just use random values and you’d choose one of them to tweak to do a mutation.

    By having the 9 weights in one array it’s easy to duplicate it to make variations. You could even store the distance as instance variables.

    Game loop would be to take one of the arrays, duplicate it and tweak some values of the duplicates. Then run the game with each of them until the player dies and log the distance. Once they are all done keep the best, remove the others and repeat.

    There are likely other improvements but that’s the limit of my knowledge at the moment. It’s likely easier to do better or more advanced things by understanding neural networks better.

    This guy has good videos explaining stuff like that. But you may want written docs at some point.

    m.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw

  • When moving diagonally the x/y speed is slower but the total speed is equal to the max speed which is what most games want. Otherwise you’d actually be moving faster on a diagonal.

    Anyways, I guess one solution would be to give your object two 8direction behaviors. Set one the up and down and the other to left and right and you’ll be set.

    You could even skip the behaviors altogether and just do some events like:

    Key left is down
    — sprite: move self.speed*dt pixels at angle 180
    Key right is down
    — sprite: move self.speed*dt pixels at angle 0
    …etc for up and down

    As to the animation issue, I suppose you could solve that by somehow keeping track of the order the keys were pressed. I’m thinking you could do it with an array that you’d add the key to the end of when you press a key, and you remove the key from the array when you release it. Then you’d just play the animation of the key in index 0 of the array. It’s simple enough you can get away with implementing it with a text variable instead if you wanted like so:

    global text keys=“”
    
    On left pressed
    — add “L” to keys
    
    On left released
    — set keys to replace(keys, “L”, “”)
    
    On right pressed
    — add “R” to keys
    
    On right released
    — set keys to replace(keys, “R”, “”)
    
    Compare: left(keys,1) = “R”
    — set animation to “right”
    
    Compare: left(keys,1) = “L”
    — set animation to “left”

    That should get the idea across. Adding up and down can be added too with minimal effort.

  • Found him. Must be on vacation?

  • Enums are just numbers under the hood but I can see the value of ensuring that only a certain set of values are used. You could use a function to set the values with events and do the checks there if you really wanted to.

    As for using array.asJson, if you look at the manual you can access the array object directly from JavaScript instead of having to pass the json back and forth.

    Personally the hoops needed to jump between programming languages is annoying enough that I try to avoid it completely. Events only in construct and if I want to use JavaScript I just don’t use construct at all.

    The exception is for performance. Same algorithm in events vs js can be x10 faster in js in some cases. So I’ve done that sometimes. I personally think there’s no reason events can’t be made to perform nigh as fast as JavaScript with some internals reworking. But I’d rather not worry about something I have no control over.