nimos100's Forum Posts

  • I would suggest that you read about families and how they work as fast as possible, as it will make things a lot easier for you.

    Anyway for the issues:

    [quote:10n5zsiz]I've tried to handle multiple instances using the "For Each Enemy" condition as the first one listed for each event where multiple instances of the Enemy Object will be referenced to, but this results in a rather long error pop-up in the Chrome Browser (the one I am using to test this in)

    The only work-around I have found so far is to limit the number of IIDs that can ever spawn at any time and then list each one off. If there were a shorter way of dealing with this, I am all open to ideas.

    I assume that the limit you refer to is 4? exactly why it gives you an error I don't know. However your program as it is currently made wont work with more than your limit, as you have "hard coded" checks into it that uses specific IIDs, so the moment an enemy spawn that are outside this range your game wont react to it. That's why I suggested that you look at families.

    In general using IIDs for anything is rarely needed, at least in my experience, in fact I have never found anything where I would use them. The UID for objects on the other hand are very useful as these are unique for each object. So to solve this problem would require you to remake everything that have to do with the enemies unfortunately.

    [quote:10n5zsiz]2) Sounds are not fading in and out correctly. I have tried to use an approach where the script seeks out the closest instance of Enemy and then determines its proximity to the Player sprite. I then set it up so when the player walks into range of any Enemy instance, the peaceful music fades out and the Action_Intro starts to play with its volume initially being an inaudible dB and gradually getting louder as the player gets closer to the target.

    The reason this doesn't work is because your are calculating it based on the "Enemy_ghost" and that one is offscreen. To fix it you have to add the following:

    [quote:10n5zsiz]I am secretly expecting that I've gone and made things far more complicated than they have to do and that Construct 2 is designed to automate a lot of the things I've tried to micromanage but I just am not sure how to access these things so they function as intended.

    That is completely correct

  • I downloaded the version that Lordshiva made and don't see any problem, it works fine. Have you tried to preview it in Nodewebkit instead?

  • Thanks for the reply.

    The problem is/was that as i increased the cell size the precision went with it as well, so units would not go to the correct coordinate but just somewhere near it, and that looked weird as the scale of objects are not that big, it needs to be somewhat precise.

    The idea or hope was that somehow it was possible to make the path finding calculate based on the speed and direction of the object, where the actually path finding would start. So even if it changed cell it wouldn't have reached the point from where the changes would take place. But as it did the new path found from that location would take over. But as i said i knew it was a long shot, and not even sure that A* is capable or used for such type of prediction movement.

    But anyway i remade how it works so it doesn't rely on path finding in those cases anymore and it works as it should now.

    However it uses a every tick movement system now, and since there might be a lot of units presents on the map at the same time, i was wondering if there are any performance hit from doing it that way compared to for instant using one of the other movement behaviours or will it be the same in the end?

    The movement is pretty simple a unit have a direction and move "unit_speed * dt" in that direction, so its not more complicated than that. But read somewhere in another post that someone said to stay away from every ticks. Which i agree with in most cases as its not needed, but in this case i need that or one of the behaviours, but would prefer not to discover later on that doing it with every tick will serious limit the amount of units (Im not talking 1000s, but around 30-50 max) which ofc is not a lot, but as the rest of the units are calculated offscreen there might be 1000-1500 in total, so no need to make it worse than it need to be

  • Global variables are not linked to a specific group, in that case they will turn into local variables, and are only available to that group.

    I don't think there are any logical or good way to do it. Due to several reason, it would be very inconvenient to work with variables that way, and it will complicate things for you unnecessarily.

    Want i would suggest and a way that i personally think is a good way to organise things, as im not a huge fan of global variables in general, as you tend to end up with a very long list and after a while its very hard to maintain an overview of what variables does what and where they are used, so i use them only for very few things. Instead i would suggest you to make a small sprite or a series of them, what you prefer and depending on how many weapons you have, but just a size of 16x16 and place it outside the layout and you use this/these for storing your weapon settings.

    So if you give it a name like "Weapon settings" whenever you need to get a value or setting for a weapon you know that these are found in that sprite. And you don't have to worry about loosing control of them, as these are only used for weapons. So when you look through your "Add action/Add event" things will be a lot more organized. And if you ever need to change any settings you can just update the values in that sprite.

    I normally use several of these types of sprites, for "Names", "Weapons", "System settings", "Enemy settings" etc. and since they are so small in size they will have near to no impact on performance and they allow you to use Booleans. And if you need them to be global you just set the sprite global value to true.

    However just be sure that whenever you need a value that you get it from the sprite, and not just make a "Set weapon damage = 2" etc as that would give you wrong data at some point. However that also means that its very easy to update your whole project in one go, if you decide at some point that a certain weapon should do more damage.

  • Unfortunately such solution for my game wouldn't work, as it would increase the number of objects to something that would hurt performance quite a bit i think. Or it just wouldn't be able to calculate it fast enough to avoid stopping the ships anyway i think.

    Also it is ofc difficult to know as i haven't explained what and how im gonna use it But when the player switches back the path finding takes over again. But as it need to recalculate the path the ship, they some times stops for a short while before moving, and it just seems weird.

    But if i could make it so the ships continued moving as the new path was found the problem would be solved. I do however get some better results by disable and enable the path finding, but its a bit buggy at the moment.

    But you suggestion gave me another idea that i might try to solve it

  • Anyone using the path finding behaviour know if its possible to make it work without stopping the objects as it changes path?

    Normally when you tell something to go a certain path and its moving and then changes to a new path the object stops, rotate and then moves again.

    What im looking for is to make an object take a smooth path to the new location, so it takes the speed and direction of the object into account as its generating the new path.

    Know its a long shot but maybe someone found a solution or workaround.

    Cheers

  • Can you post a screenshot of your code? As i know the one i linked works so cant really help without knowing what you did

  • This is a very simple example of how to do it, but should aim you in the correct direction:

  • nimos100

    This is very impressive, I think you have the largest gameplay made out of C2. 5049 events was in June, so how many events do you have now? How long have you been working on this?

    Well...hmmm

    At the moment its on 5657, but I haven't actually worked on it for a long time. So whether I will continue with it or not im not sure of. As with most projects as you probably know yourself, when you get more and more experience working with C2. You notice things that are made in very bad ways. But due to the way you original designed it, it can be very difficult to redesign. And also new features are released with C2 that at the moment could have help you create a better design. For instant I was working on the tactical combat part of the game, and was having serious problems with the path finding behaviour as it had a lot of limits to it and actually didn't work very well for something like this I think. So I had to make a lot of workarounds that was really messy, and most likely filled with bugs etc. But now you have so you can regenerate obstacles etc around certain objects. Which would really have made a huge difference.

    So if I should continue on it, I would most likely just reuse the graphic and create a new one from scratch instead, I learned so much from doing it, especially because you cant avoid running into problems and also working on a huge project like that, really make you see and learn where problems occur when having to organize something like that. And I really would hope that C2 had better tools for that, as it really falls short when it comes to such size programs I think. As you can imagine how it is to find a specific function between 5600 events even if you have good organisation, is not easy

    So a simple feature like being able to Ctrl+Left click a function call to jump to the function it self, would be a gift from God

    But understand that they prefer adding stuff that benefit the masses, as the majority of people probably doesn't create game with so many events.

    But anyway at the moment im working on a strategy space game kind of like X-3 the old ones, where you have to survive in the universe, by building up a company with space stations to produce varies goods/resources that can be traded with other stations, mine for ores, buy or build space ships, and engage in hopefully huge battles. So its more like a choose what you would like to do kind of game, so if you prefer to be a pirate or having a huge trading empire or maybe just conquer the universe you can do that.....well at least that's the general idea

  • [quote:2igy93jr]Hey thanks for the detailed reply.

    I tried to make what you told, but I couldnt implement this line: set s_sword_icon.sword_cost to (array_swords.X[s_sword_slot.slot_number])

    Right now when you buy a sword the sword icon changes from red to green, which is good.

    But I still need to figure out how to display other swords using just 1 sprite.

    Here is my capx: shop_test.capx

    You can just add several frames (Images) to the bought and notbought animations. And as the player switch through the shop you just change the animation frame. From what i can see you don't have a functionality to do this yet. But what you can do is something like this:

    However in your case it wont work. Because your program is running wild and you keep making s_sword_icons.

    You need to add some condition to prevent that, this event will eventually kill your game and computer as it is running endlessly and keep making sprites:

    After running for a few secs:

    I would suggest that before you continue with your game, take a look at functions. Learning those and getting used to using them all the time, will be a huge benefit.

    I wrote this example some time ago for another post of how to use functions, which explain it very basically, maybe that can be helpful, otherwise ill check the manual:

    [quote:2igy93jr]Since I just made a very simple example of a function and how to call it in another post. Ill add it here as well, as functions are actually very easy to use, the moment you get them.

    1. Add function plugin

    You first have to add the function object to your project. You find it in the list where you also add mouse, keyboard etc.

    2. Create a function

    Once the plugin is added it will be available for your whole project. To create one you add it like you would any other event. And you have 2 options to choose from:

    "On function"

    "Compare parameter"

    For now you only need "On function" and this can be compared to adding an "On mouse click" event, but instead of "On mouse click" already being added for you, you can decide what it should be called, and when to trigger it, which is done by calling it.

    So after you select the "On function" you will be able to give it a name.

    "Name" is just a reference so C2 know which function you are calling whenever you do a function call. So you can make it whatever you like.

    In the above example I want the function to give me the license plate of a car. So giving it a name of "Get car license plate" describe what the function does so I can remember it. But in theory I could have called it "Moon rising" and still make it return the license plate of a car.

    3. What a function does

    Now that you have added a function it will be empty and not very useful. To make it useful you want it to do something for you. And you can see a function like a machine you put something into it, and it does something and then it might throw something out.

    In the above example I throw in a car, and I want the function to give me the license plate of that particular car.

    Input = Car

    Output = license plate

    4. Calling a function

    A call to a function is an action, so like you would set the text of an text object, you will make the function call as an action.

    When you press "Add action" you can again select function, but this time you will have two other options "Call function" and "Set return value". Since we need to call a function you just select "Call function"

    And again It ask you for a name. Now this name need to be the name of the function you want to call. So in this case "Get car license plate". This will make C2 aware that this is the function it should look for.

    5. Parameters

    In this window you can also add parameters. Which would be the input, so in our case we want to throw in a car, since we want the license plate of a car. We need to tell the function which car we want the license plate from.

    So if you press "Add parameter" there will be added a field called "Parameter 0" These names are locked, so you can't change them. But you need to be aware of the order in which you add them. But for now since we only need 1 it doesn't matter.

    Since we want a specific license plate of a car, we need something that is unique for a car. So the UID of the car objects works very well, as its unique for any object. So we throw that into the parameter 0.

    6. Make the function do something

    So now the function call is ready and will do what it is suppose to, however since our function is empty it doesn't do anything.

    So the first thing we have to do, since a function isn't that clever even though we have already thrown it a "Car object" it still doesn't know what that parameter is for. So to make sure it knows, we add:

    "Car pick instance with UID function.param(0)"

    Since we stored the UID in parameter 0, we can also use it to select a car which match this UID. Now the function know what car we are talking about.

    7. Return value

    The same way as we added the function call, we now add an action of "Set return value", when you add it you get the possibility to set a Value. This is what will be returned when the function is done, doing what I does. In our case we want it to simply return the license plate of a car.

    Since we have already told it what car we want the license plate of. We can simply set the return value to "Car.license_plate"

    8. Using the return value

    Now that it have returned the license plate we want to use it for something. So what we can do is to check the return value and then act on it.

    In this case we want to check if the returned license plate is "12345678" and if that's the case then do something.

    That is the basic of using functions and in this example we returned a license plate, however its perfectly fine to not have a function return anything.

    When C2 reads your code and it gets to a function call, it actually jumps into that function, and will not continue reading your code, until it gets back from the function. So you could actually add everything that are in the function instead of the function call, and it would be exactly the same.

  • [quote:2q7muwr1]Yes that is in fact what I am trying to achieve. I am however having trouble with the tilemap obj. When I load a sheet of sprites to it and set the cell size and position all I get is a empty sprite in my workspace. I can not figure out what is not working as no matter what image I load every sprite object I place in the level is blank. I have made sure that initial visibility is true and that the tiles are the right size and place. the manual does not really go into troubleshooting this.

    I cant open your Capx as you are using some plugins that i don't. So i can only look at the images that you posted, so this might not be as useful. But from the last screen shot it seems like you might have misunderstood the tilemap object and how it works.

    The tilemap is an image/object that is able to tile images based on certain settings. So you can save resources when using the same graphic elements over and over again. This is done by choosing an area that the tilemap should cover, lets say 1000x1000, which would be the size of the tilemap object.

    In the tilemap you in theory can have as many graphical elements ("sprites") as you want, and you use these to fill the tilemap it self, in this case the 1000x1000 size tilemap. The amount of tiles you can have in the tilemap is based on the size of each individual tile. Which you set in the "Tile height" and "Tile width", so for simplicity lets say both of these are 10.

    That would mean that our tilemap can hold 100 tiles in X and 100 tiles in Y. And likewise if these were set to be 100, it could hold 10 in X and 10 in Y.

    Looking at your screenshot you have the tilemap size set to 74,106, which doesn't really make sense as this is a very small tilemap with weird dimensions. And looking at the "Tile width" and "Tile height" you have these at 100 and 150. Which are actually larger than the tilemap itself, and therefore its blank as it doesn't have room to place any tiles in. And i assume that you use these values as its the size of the character sprites?

    But as i said i can only see the screenshots so might not be true for your actual program.

    So i would suggest either redesigning the way you present the characters if you want to use a tilemap. Maybe make it so the whole screen is filled with characters and when the player clicks one it could open up the stats for that character or something.

    Like you see it in League of legends, if you know that:

    You can still keep the dimensions that you have, just a good idea is to make sure the size of the tilemap fits this, so if you want 10 character in X direction and 15 in Y direction, make the tilemap size 1000x2250.

    Otherwise i would redesign the way you choose character to not using a tilemap at all, but maybe just use 1 sprite and make some buttons to flip through them.

    [quote:2q7muwr1]If I read your example correctly you are suggesting that I create a function for each character with which sprite to chose and all. However when I will scale this up that is a lot of data for the engine to chew though and I am looking for a way to automate this proses as it is just a menu and I can not budget too many resources to it.

    This wont use any resources as its a function so it will only do something when you call it. Otherwise it will just be there doing nothing.

    Since you already have characters sprites for each character, you could use these to hold the data for them, like name, health etc. And instead of using an array, you simply load each available character when you need them. And when a character is unlocked you can save it to the disk/server if these are dynamically generated during the game.

    If these are characters that you create before hand i would probably just add them to the game it self, and just check whether they have been unlocked or not when you need to show them, or maybe make it so they are loaded from the server/disk instead when needed.

  • nimos100

    yeah I don't know about this, seems heavy handed when you can probably just rearrange how you do things; initialize all the relative objects within the same event umbrella. Because we aren't really talking about anything other than initialization or rather, things that happen only once. Otherwise a reoccurring event will catch up with no noticeable problem.

    Not saying your object handler won't work, it's just maybe not very practical? I don't really know, I'd have to see a situation where you couldn't keep created object references together.

    I agree its not practical in any way, its merely a solution to the wait problem And it will work in any situation where you would normally solve the problem with a wait. But maybe I misunderstood your situation.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I fought with the same problem as you and came up with a solution for not having to use waits, whether it will work in your case I don't know. But this is from that post (Its a bit long ):

    "-- First post --"

    Think I might have found a solution to do it without using waits. However it does requires an extra check every tick. But if it works I think its worth it

    The Idea is to use an object handler, that can handle all newly created objects.

    You can make it with a list or array whatever you prefer. However you still need to organize the way you create objects according to the normal rules.

    In my case it uses a list, the idea is that these objects that rely on other objects that might not be created yet during the cycle, are added to this list. And then you apply whatever extensions to them that you want. And its actually quite simple to make.

    In my game the handler looks like this:

    Which in this case is the Quest_master_object that give me the problem. As its the one that rely on a Quest_step, which is a sub quest that are part of the master quest. To this Quest_step there is a dungeon attached. Which again is used to generate a random Quest description.

    To use the object handler all you have to do, is tell it what action you want it to do, in form of a Boolean, and then add the UID to the list. And then hook it up to a function, or whatever you prefer.

    And you can just add as many conditions and objects to the object handler as needed. I think the benefit comes when you have to do something several times during one tick. For instant in my case I actually have to repeat it 5 times, but having to wait each time is first of all not something I like, but also seems to create problems, as sometimes the descriptions got mixed, some steps weren't made etc.

    Anyway haven't tested it fully, but the initial tests seems to work very well, and now at least this problem is solved "

    "-- Second post --"

    [quote:2psokaom]Nice work. Looks pretty slick.

    I was reading up on the thread that explains why picking works this way now, and I'm actually confused.

    In the thread, it is explained that the object doesn't exist to same-level events until the next top level event. Then how come pick by UID works on our tests?

    Agree that it gets confusing, because its logic that you have created the object, so surely it must be there, but it actually ain't as explained by Ashley in that post.

    A solution also from that post is:

    [quote:2psokaom]The workaround is to try to do everything in the same event - nest the other events beneath the creating event if possible, so everything is moved up in to the green area.

    Which are the reason that you can create an object and right afterwards set its variables.

    Create object

    Set Object name = "Whatever"

    That also means that you can pick UID of the object if its in a sub level of the create function.

    But if you do it like this:

    level 1: Create object

    --------------Do something

    Level 1: Pick Object with UID of the newly created object shouldn't work.

    You have to reach a top level. (Now this post is from version r102, so its pretty old, but don't think a lot if any have changed.)

    However the common way of dealing with this problem as you most likely know is to throw in a Wait of 0, 0.1 or 0.01 or whatever as it will then go through to the next tick and force it to reach a top level or what to say and then it works. Im not really sure how solid this actually is, it seems to work well with simple stuff, but if it gets a bit complex it seems to not really work well.

    For instant if you have an event:

    Repeat 10 times

    ------- Call function("Spawn enemy")

    Function Spawn enemy

    Create enemy()

    Call function ("initialize enemy")

    Function Initialize enemy

    Call function ("Create enemy weapon")

    Function Create enemy weapon

    Create Enemy_weapon

    Then suddenly things starts to go wrong as I see it.

    Because now there are actually two objects that doesn't exist yet, The Enemy and the Weapon that you want it to use. So if you throw in a Wait different places to solve it, It might work. However at the very start we are actually repeating this 10 times, to create 10 enemies which will then create 10 different weapons, so suddenly you might have 20 objects that actually doesn't exist, and then it seems to go wrong. Whether that's completely true im not 100% sure about, but it seems that a function doesn't count as a top level, which I find to be logic if its the case, but I haven't seen anything saying that it ain't which is why im not certain.

    As I mentioned in my last post, I had to repeat it 5 times, but I did something similar with 50 objects using a wait, and it looked like it was working fine, however as I went through the objects in the debugger I could see that suddenly some of the objects would have "NaN" in some of the variables. Which didn't make sense as 95-98% of them had no problems and all different possibilities for this variable was used, but for some reason some of them just failed, and my guess it that since I repeated it several times, it might have screwed up with the wait somehow. So the only thing I did, was to move the function call to the Object handler, didn't change any code and none of them had any problems after that, same goes for several other mistakes that was happening. So I moved those as well and now all of them gets initialized correctly, without having to use wait, which I think in itself is a huge benefit.

    "--- end ---"

    Also if this doesn't work, maybe you can use the "Wait for signal" which weren't available when the above was discussed, but you might be able to make it so it will not do anything to these objects you create before all of them are made, in that case you "Signal" it to continue.

    R0J0hound - a nice visual explanation! So does Wait 0 sort of make the Function act like a top level event?

    No, wait doesn't make anything a top level, it just forces C2 to go "around" so to speak, it will look like it might make a function a top level. But in fact it could be anything else and most likely Is something else. And also as mentioned it the last part of my "Second post" you will most likely end up with things that seems to work but at some point it will probably give you weird problems, that are not easy to fix, as you "loose" control when using wait 0, 0.1 etc., At least that's my experience and why I never use them.

  • Sounds like you are using individual sprites, so depending on the size of your grid any event that works with these sprites will need to check each of them, so if you have a large grid it will eventually kill performance as you add more and more events and actions to your game.

    Depending on your game and what these tiles are used for, you might consider switching to using a tilemap object instead, and just use 2 different images. 1 which is grey and the other that looks blurry. And then you just switch the frame whenever you mouse is over one of them. Think that would make you able to do it pretty much without any performance drop and with a much larger grid than you can have with sprites.

  • You need to check the angle between your object and the mouse click. Here is an example of 4 directional movement:

    On mouse left click (Trigger)

    Next you need the four directions, Since the angle is calculated from 0 to 180 degree when going clockwise and 0 to -180 degree when going counter clockwise you have to add 360 to those in the counter clockwise direction to get the correct angle.

    So you will need 4 sub events, one for each direction and these you check with a between values.

    Up (Since this is going counter clockwise we add 360)

    Condition:

    255 <= 360 + angle(Object.x, Object.Y, Mouse.X, Mouse.Y) <= 315

    Action:

    Object.Angle = 270 (So whenever you click above the object in a cone shape it will set the angle of the object to 270)

    Down (Since this is clockwise we don't need to add anything)

    Condition:

    45 <= angle(Object.x, Object.Y, Mouse.X, Mouse.Y) <= 134

    Action:

    Object.Angle = 90 (So whenever you click below the object it points down)

    Left (As it changes from positive to negative as it goes pass 180 you need two conditions and an OR)

    Condition:

    180 <= 360 + angle(Object.x, Object.Y, Mouse.X, Mouse.Y) <= 224

    OR

    135 <= angle(Object.x, Object.Y, Mouse.X, Mouse.Y) <= 180

    Action:

    Object.Angle = 180

    Right (Exactly the same as for left except now it changes as it goes pass 0)

    Condition:

    0 <= angle(Object.x, Object.Y, Mouse.X, Mouse.Y) <= 44

    OR

    315 <= 360 + angle(Object.x, Object.Y, Mouse.X, Mouse.Y) <= 360

    Action:

    Object.Angle = 0