Pulstar's Recent Forum Activity

  • If you really really need to track the bullets movement every frame one solution would be as follows. Don't use a bullet sprite for checking for collision. Use a sprite acting as a ray. Invisible ray if you wish, for collisions visibility is irrelevant. You can still have the actual bullet spawned and visible, only the logic of the game will not care what happens to it. Although personally if it is moving 333 pixels per frame as I just calculated, I would not bother with the bullet itself as nobody will see it anyway. I have a project on a similar scale and I just show bullet trails and assume the travel time is instant (so hitscan basically), then again I do not need actual bullet movement as everything is turn based and dicerolls pre-determine the hit/miss before the bulletrail is created.

    Anyway, here is a solution to your problem, capx at the bottom:

    Spawn a ray object when a bullet is fired. For a ray you need a sprite with an origin at x=0 and y equal to the middle of its height. On spawning, set its angle to the firing direction.

    First you calculate how much the bullet would move during the frame. Then you draw a ray from the beginning of its path (its x and y positions) in the current frame to its end. This is done by calculating how much distance the bullet will travel this frame (dt*speed per second in pixels) and setting the ray's width to that distance. That way you will have a sprite covering the whole path travelled by the bullet during the frame (basically what a regular bullet sprite would skip over and not collide).

    Next you check for collisions using the "object is overlapping another object" condition, you pick the instance of the object the ray collided with that is closest to the frame origin point. Do whatever hit logic you want with it (damage dealt, destroy sprites etc.). Destroy the ray and bullet unless you wish to make a Quake railgun or something.

    If there are no collisions, you set the ray's position to its end. That is x=x+(width*cos(angle)) and y=y+(width*sin(angle)).

    https://www.dropbox.com/s/mt21w5foq4v2o ... .capx?dl=1

  • Conditions:

    compare variable: score>0

    compare two values: score%5=0

    Actions:

    Create object

    Explanation: the "%" sign is for modulo, or the remainder after division. If the score is a multiple of by 5 this operation will return 0. You also need a second condition so that this action does not run when score is equal to 0 as 0%5 will also give 0.

  • If you just want to darken the unseen surface you can create the fog of war out of a tilemap on top of your surface tilemap. All you need is a whole black tile with less than 100% opacity set in your graphics program of choice before saving it. That is the easy part. This could also be done with just sprites but believe me, using a tilemap is much faster, especially if the map is big.

    Making things only show their last "seen" state is trickier. If it's just units you need a "dummy" ghost sprite. Basically when a unit is being set to invisible due to being in a hidden area, it would spawn a ghost sprite at it's position and with it's angle. This would be destroyed the moment the tile is revealed.

    To be honest the hardest thing with FOW is making efficient FOW reveal events. The higher the map size (in tiles not pixels) and the higher the unit count the bigger the performance hit will be, there basically is no simple solution here that is also efficient. With small unit numbers, small maps and simple map reveal mechanics (show all tiles in vision range, so no line of sight blocked by obstacles etc.) you might not notice anything. However anything more ambitious and it will become apparent there is slowdown.

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I start with planning key gameplay mechanics and technical features and their scope. Next I do a prototype for the technically riskiest concepts (basically things I never tried doing before). If it works, it goes further ahead, if not the concept is shelved, the scope is changed or otherwise the project evolves.

    Next when I start going into specific systems I look into their interdependency first and prioritize the ones on which others are dependent. For example, I could not implement combat mechanics before inventory mechanics worked. So I worked on a rudimentary inventory system first, design it so that it can easily be expanded if I miss something without scrapping the whole thing. That happened a lot to me in the past.

    For art I am a big fan of programmers art. For two reasons, one is that art is a timesink and time is the biggest constraint in a solo hobbyist project, it is best not to commit too much of it if you are not certain that. The other is that I am more of a technical/designer person than an artist, in the end once the technical part is done I will most likely hire a proper artist to redo most of the art. Making decent looking GUI is probably the best I can do.

  • I made an example showing how to filter/search for recipes by ingredient(s) used:

    https://www.dropbox.com/s/eo2ym6av6bqnm ... .capx?dl=1

    It should also show the XPath query used for filtering only the recipes containing the given selected components. There's also some extra attributes that could also be used in the searching but I was too lazy to do any GUI for them or implement the functionality.

    It also shows the quantity of the recipe output and the quantity of the component inputs. XML code is below (its also in the capx)

    Recipes:

    <?xml version="1.0"?>
    <recipes>
    <recipe name="Hammer" qty="1" lvl="3" type="weapon">
    	<component qty="2">Wood</component>
    	<component qty="1">Iron Bar</component>
    </recipe>
    <recipe name="Healing Salve" qty="3" lvl="1" type="consumable">
    	<component qty="2">Leaf</component>
    	<component qty="1">Wood</component>
    	<component qty="1">Medicinal Herb</component>
    </recipe>
    <recipe name="Staff of Bashing" qty="1" lvl="1" type="weapon">
    	<component qty="3">Wood</component>
    </recipe>
    <recipe name="Leaf Skirt" qty="1" lvl="2" type="armor">
    	<component qty="10">Leaf</component>
    	<component qty="2">Leather</component>
    </recipe>
    <recipe name="Short Sword" qty="1" lvl="5" type="weapon">
    	<component qty="7">Iron Bar</component>
    	<component qty="2">Leather</component>
    </recipe>
    </recipes>[/code:3atbg7v1]
    
    Items:
    
    [code:3atbg7v1]<?xml version="1.0"?>
    
    <items>
    <item type="armor" sprite="0" MaxStack="1">Leaf Skirt</item>
    <item type="weapon" sprite="0" MaxStack="1">Staff of Bashing</item>
    <item type="weapon" sprite="1" MaxStack="1">Hammer</item>
    <item type="weapon" sprite="2" MaxStack="1">Short Sword</item>
    <item type="component" sprite="0" MaxStack="99">Leaf</item>
    <item type="component" sprite="1" MaxStack="99">Iron Bar</item>
    <item type="component" sprite="2" MaxStack="99">Wood</item>
    <item type="component" sprite="3" MaxStack="99">Leather</item>
    <item type="component" sprite="4" MaxStack="99">Medicinal Herb</item>
    <item type="consumable" sprite="0" MaxStack="99">Healing Salve</item>
    
    </items>[/code:3atbg7v1]
  • So am I right on organizing them? If a Hammer has ingredients of wood and iron then I would have three separate XML files.

    One for wood, one for iron and one with craftable items (hammer, basket, hat)?

    If user searches hammer then it will show wood and iron.

    If user searches wood then hammer will show up.

    If user searches wood and iron then I can compare and still bring up hammer since it is in both?

    If I search leaf and wood then hammer would not show up because hammer isn't under leaf.

    I assume I would compare the the leaf and wood XML and remove the ones that don't match.

    I am not sure how to do that. Would I somehow use an array to compare?

    Would this be the best way?

    As I wrote in my post above, have ALL recipes in one XML file. Have them as parent nodes of their <ingredient> nodes. Then all you would need is an XPath query saying return all recipe nodes where the ingredient child is wood OR iron. If you had an XPath query searching for recipes using wood OR leaf, the hammer would show up on the list. No need to eliminate anything yourself, Xpath would return only nodes containing either of the ingredients. That would be it.

    Well, the issue would be constructing an XPath query string dynamically based on inputs to the "search list recipes with specified properties" function. That requires some planning on what you want the player to able to search for.

  • Also need to know how to hide a few from search for restrictions.

    Such as level or if recipe isn't unlocked yet.

    An example Capx would be great, but an explanation would work as well.

    I am thinking I will need a XML/JSON for the craft that has the recipe and a XML/JSON for each ingredient that has the names of the crafts the ingredient is in.

    Would I do Category the same? How would I show the recipe list in alphabetical order?

    While XML has a higher learning curve and is more of a pain to modify (I wrote an excel macro just to convert tables into the desired XML text output), it would be faster and easier to implement all the other functionality you want for this with XML. The reason for that is XPath queries. For JSON I think you would need to setup custom logic to get query-like functionality which you need for the recipe system features you desire (hiding unavailable recipes). Depending on what you need and how you organize the data, it can be more of a hassle but maybe that's just my ignorant opinion. I always used XML for these kinds of game databases (mostly for items, but not only).

    If you are already familiar with XML and XPath queries I would suggest XML as it will result in less stuff to debug within C2. Issue with it is human-readability, preparing the file itself and getting the XPath queries right.

    If I would be doing a system such as yours (actually I will need to do one, but probably after I get the skill trees fully working and combat turn logic working). I would do it as below:

    1) All recipes are stored within one XML file database. Every recipe is a single <recipe> element. The <recipe> element should have an attribute called "Output" and "OutputQuanity", these would define the item created and the quantity of the item created. You can also have additional attributes such as "Type", "ClassNeeded", "LevelNeeded" so that you can narrow down and filter the recipe list via XPath easily.

    Under each <recipe> element you would have <ingredient> child element. These <ingredient> elements should have an attribute called "QuantityNeeded". That would define how much of the ingredient would be needed to create one output batch of items.

    2) Now the hard part. What is an ingredient and how to check for it? There are two approaches here I can think of. The easy one is "each ingredient is a unique item", think WoW crafting. Then you just need to check the relevant inventory object (probably an array) with the player's items for the item named as the ingredient. If you are getting crafting materials directly from the natural source or resource nodes (mining copper veins, chopping trees for wood etc.). In this case the ingredients themselves would be listed with all the other items in an item XML object.

    The hard approach is what Fallout 4 did (yes, that game actually managed to not take the easy route with some RPG-ish mechanics, shocking I know), have ingredients not exist only as items, but as properties of other items. Say a telephone is made out of some copper and plastic. So basically allow breaking down junk items into components. This system is more realistic and depending on the theme of the game (in Fallout 4's case, a post-apocalyptic world of jury-rigging and salvage prospecting) may fit better. In this case your item system would need to be amended with data on what and how can be broken down into what. Also you would might want to add some logic to allow automatic breaking down of junk items when crafting a specific recipe, but that would also require additional logic to identify what can be broken down.

    3) Regardless of a picked approach at the end you need to show the available recipes via the games GUI, as a list. You will need an array. What I would do is fill this array using an xml object and the "for each node" condition, after entering an xpath query. So on a list refresh the array would have its width set to 0, next the query would be entered (you can build this dynamically out of function parameters with some text string appending) and the array would be filled by entering a new array X element for each node of the XML file returned by the XPath query. The main issue here really is setting up the XPath queries correctly. XPath is quite powerful but it is easy to make a mistake and get a broken query that does nothing, especially when building the XPath query dynamically based on function paremeters.

    4) Finally once the use selects one of the listed recipes (or for all visible recipes), you will need to use the XPath to the particular recipe (or for each recipe), get its components and check if they are in the required quantity in the player's inventory.

  • There are a couple of ways. But I think the best one would be to have just one generic message object(s). I imagine you would want a speech bubble or box or something and on top of it a spritefont or regular text object that from this point on I will simply call a label. Alternatively if you use sprite fonts and have one with outlines (to make it more readable against differently coloured backgrounds) you would need the label alone (typical floating text like in lucas arts adventure games of old).

    Now these objects (label and message box) should be invisible at layout start. What you would do is move these to the desired position (above the sign or player, I recommend using an image point for this) on collision, changing the text to the desired message and then making both objects visible.

    The message itself should be stored in each sign object as text variable. That way when the collision event with the sign happens, it would pick the right text (so long as the player does not overlap or collide with multiple signs simultaneously).

    All you would need to do now is to create an event as below:

    Conditions:

    On Player collision with Sign

    Actions:

    Move Label to sign image point (1)

    Set Label text to Sign.text

    Set Label visible

    Of course now you also need a way to make the message invisible either when the player stops colliding with it or after a given time (possibly both). For the former a simple inverted "player overlaps sign" event would be enough, as it would trigger when the player is not overlapping the sign. For the latter a timer and/or fade behaviour can be used (but then you need to remember to set opactity to 100% in addition to making the Label object visible when moving the sign).

  • you need to use sprites not the tilemap

    I am sorry but that is not correct:

    https://www.dropbox.com/s/bfwr6zs8mmzaf ... .capx?dl=1

    Shoot at a cactus. Press the button to generate a new map when out of cacti to shoot. The collision polygon is a bit too small on them so it mail fail occasionally, that can be changed in the tilemap tools in the C2 editor.

    That is one way to do it with just one tilemap, although for best performance I recommend using two tilemaps. One without collisions for most of the grapics and the other with collision for just the destroyable tiles. This is because only empty tiles do not have collision masks (it is not possible to disable collisions for specific tiles), therefore like in the example I linked to above, the "on collision" event will trigger every tick. If you would disable the second condition of the on collision event in my example which checks what tile the projectile collided with, the bullet would erase the tile on which the player is standing.

    I use something similar for LOS with walls, walls are a separate tilemap from the surface and have collisions plus solid behaviour.

    • Post link icon

    At the end of the day, working with an easier game engine made me waste more time. I came to realize that having a better notion of coding and also using better tools was the solution.

    That's my humble two cents

    This is my conclusion as well. Once I am done with my current project, apart from maybe a quick prototype, I am not investing more time into using Construct. I learned a lot, definitely got my money's worth out of the purchase (not in actual money but you get the idea). It was not a complete waste of time definitely, but it was a detour so to speak. What Jayjay and the others wrote is not very encouraging if one has ambitions beyond the web for a construct-based project.

    We will see where C3 heads off to, but my general feeling is it only has a future as an educational product.

  • Make a local variable in the consumption event, call it roll. Set it to random(0,100) in the ammo consumption event in the first sub-event.

    Have the chance of no ammo consumption as a variable of the player object, let's say it is called chance_of_no_ammo_consumption.

    In the ammo consumption event, add a subevent after the one where you set roll, compare variable roll great or equal to player.chance_of_no_ammo_consumption.

    As an action if that condition is met, add ammo consumption. If the roll is higher than the chance of ammo consumption, ammo will be consumed. If you roll a value lower than the ammo consumption chance, nothing will happen (so no ammo consumed).

  • For this explanation I assume the array is named array and the parameter through which you pass it is parameter 0.

    How do I pass an array as a parameter ?

    Enter the parameter you want as "array.uid" (without quotes) when calling the function. Of course make sure that only the specific array you want is picked in the sub-event from which you call the function.

    Then in the "on function" event just use an array pick by UID condition as the second condition, enter "function.param(0)" as the UID by which you want to pick. Alternatively if you use your own variable you use to identify arrays, you can just pass that and pick an instance that has the right value.

    How do I pass an array as a return value ?

    Just use array.UID again, similar to above.

    How do I have a local array in an event ?

    You can't set an array as local to an event, this is one of the drawbacks of construct 2. There are some workarounds though. One I use is that I have a global dummy array. In the every event/function/whatever/ it is used it first gets cleared, resized. Then I use it as I wish. So far this has not came back to bite me, but knowing how unpredictable loops sometimes are in construct (the "for"/"for each" loops seem to run iterations in parallel rather than sequentially) I only use it in while and repeat loops only or events without loops.

    Another is to create the array in the event to use it and destroy it in the end. But this one is not as simple as you might think, because in the tick/frame in which an object is created it cannot be picked events apart from the pick by UID event. A workaround for this is to have a function that creates and object and returns its UID.

    The an alternative for one dimensional arrays is to use a local string variable and build a coma "," or semicolon ";" or pipe "|" string where each value is an array element. Then use the tokenat and tokencount expressions to retrieve the element. That is truly local but it has its own limitations.

    Same for dictionaries and XML trees...

    They also cannot be set to local. I would suggest trying to do something similar as I wrote for arrays.

    And how do I count occurrences of an element in an array ?

    I assume you meant occurrences of a particular element value (how many time the array contains "foo" for example). This one is simple. Just use a "for each element" array condition. Then add a subevent to the event containing the "for each element" checking the value at "array.CurX" if it matches the desired value. In that subevent add 1 to a local variable tracking occurrences.

Pulstar's avatar

Pulstar

Member since 10 Jan, 2016

None one is following Pulstar yet!

Trophy Case

  • 9-Year Club
  • Email Verified

Progress

10/44
How to earn trophies