Fengist's Forum Posts

  • Yea, placements... that is a science unto itself. While most games are satisfied to let Construct's automatic placement handle things, I end up putting gobs of elements on a layout that I want to size and scale based on how large the browser is. I have a whole huge function that I run whenever the browser is resized or a layout is loaded that manually puts every element on that layout exactly where I want it based on the viewport height and width. The reason I took a moment to reply now is because I'm taking a break from trying to line up a chat HTMLElement properly.

    As for mobile, I have no idea if it would work or not. I'm working on a laptop/desktop based game so I have no need to test it on anything other than Safari. I would assume that it should as HTMLElement is just JS. If there's any way to open a browser console on an Apple device, look for JS errors.

  • Actually, I needed a good excuse to get the news added into my current project so, your need for information and my need to get it done coincided. Writing the tutorial was just me vocalizing and testing how I planned to make it work.

    Hope you understand it.

  • MySQL might be overkill but that depends on your plans.

    If this is going to be a triva game for a few select people or it's an educational thing, the CSV will work great.

    If you plan on this being a commercially viable product, I don't suggest the CSV.

    1. Always assume your code will get hacked into.
    2. The URL to a CSV file will be exposed somewhere in the code most likely.
    3. Someone WILL directly access that CSV and do what they will with all of your data.

    While AJAX calls to scripts that load data from a MySQL are a pain in the arse, require skills in coding and still aren't completely fool proof, it does add a mostly secure layer between your customers and your data.

  • Here, as simple as I can make it:

    construct.net/en/tutorials/adding-html-news-construct-2226

  • I can give you a couple of examples. One is my main menu and the other is for the skill tree you see above. I'll try to explain the menu as it's a LOT simpler. The skill tree gets pretty complex. Here goes. Let me know if I don't make sense here.

    The first thing you have to realize is that HTMLElement is designed to work with chunks of HTML and not full web pages. It doesn't surprise me that an iframe in the middle of it produced unexpected results. It doesn't expect to see <head><body><script> tags and the like. It's kinda an iframe all to itself but it doesn't need all the trappings of a full web page.

    Here's the codepen for my main menu. One thing to consider is this HTML is static. I put it in the element's text and don't change it. It changes itself.

    codepen.io/Fengist/pen/LoWwGq

    On the left in the HTML block you'll see two chunks of HTML. The first thing to realize is that the second isn't displayed and it is the HTML I actually have in my HTMLElement. The first chunk is what the HTML looks like after I'm done with it inside C3. I put it there so you can see how it actually looks and can play with it.

    In the second chunk you'll see odd things like {{Menu1}} and {{Menu2}}. These represent instance variables on the HTMLELement. I created instance variables that exactly match what's in those brackets, i.e. Menu1, Menu2, etc. and I left them as empty strings.

    On the start of the first layout where the menu is visible I call a function called ClearMenu like this:

    -> Functions: Call ClearMenu (selectedMenu: 1)

    The function looks like this:

    * On function 'ClearMenu'

    * Parameter 'selectedMenu' (Number)

    -> HTMLElement: Set Menu1 to ""

    -> HTMLElement: Set Menu2 to ""

    ----+ System: selectedMenu = 1

    -----> HTMLElement: Set Menu1 to "><a class=""active"""

    -----> HTMLElement: Set Menu2 to " el-on:onclick=""menuFunction(2);""><a "

    ----+ System: selectedMenu = 2

    -----> HTMLElement: Set Menu2 to "><a class='active'"

    -----> HTMLElement: Set Menu1 to " el-on:onclick=""menuFunction(1);""><a "

    In this example I'm only working with Menu1 and Menu2 to make it brief. What this function does is first sets all of the instance variables to an empty string. This resets the HTML back to it's original state with the {{Menu1}},{{Menu2}}... etc. Then, depending on the value of the parameter passed (1 in this case.) It sets the instance variable to:

    ><a class=""active

    It sets all of the other instance variables to:

    el-on:onclick=""menuFunction(2);""><a

    With the 2 being the parameter I'm passing to menuFunction. Others would be 3, 4, etc. You can see that in the codepen.

    When HTMLElement looks at the text, it replaces {{Menu1}} with whatever the value of instance variable Menu1 is.

    So, the HTML for Menu1 changes from this:

    <li {{Menu1}}>Dashboard</a></li>

    to this:

    <li><a class="active">Dashboard</a></li>

    And all I did was change the instance variables.

    What this does, and you can see this in the codepen, is adds in the class="active" tag. In my CSS I have that so that the background changes color to indicate that it's the one selected.

    The other lines get changed from (for example) this:

    <li {{Menu2}}>Skills</a></li>

    to this:

    <li el-on:onclick="menuFunction(2);"><a>Skills</a></li>

    That el-on:onclick is a special code used by HTMLElement to perform an on-click event. In this case, when you click on that list item, it will call a function in Construct. Here, it calls menuFunction and passes 2 as the parameter. That function looks like this:

    * On function 'menuFunction'

    * Parameter 'MenuRequested' (Number)

    ----+ System: MenuRequested = 1

    -----> System: Go to Layout 1

    ----+ System: MenuRequested = 2

    -----> System: Go to Skills Layout

    (shortened for brevity)

    When that function is called, it simply tells Construct to open a specific layout. In this case, the parameter is 2 so it opens the Skills Layout.

    In the On Start of Layout for the Skills Layout I call this again:

    -> Functions: Call ClearMenu (selectedMenu: 2)

    Which resets the instance variables back to empty strings, replaces {{Menu2}} with the 'active' tag and all of the others get replaced with the el-on:onclick tag.

    When this all comes together, it creates an HTML menu system inside Construct. When a user clicks on a list item, it opens a different layout, highlights the selected menu item, disables it from being clicked on (you don't want them loading the same layout over and over again) and resets the others so that they can be clicked on.

    I hope that explains it.

    The skill tree is much more complex. You can find it here:

    codepen.io/Fengist/pen/oOjgBw

    The huge difference between the two is that the skill tree HTML is built by a PHP script and sent to the client as a JSON. The HTML you see on the left is the output of that PHP script. Each of those list items is built from several MySQL tables. Because users can 'train' skills, this has to be a dynamic list as things like skill in training and the users level in a skill have to be timely. Using the el-on:onclick code along with some creative HTML, users can click on a 'learn' button inside the HTML and it calls a function that fires off an AJAX to update the database to record which skill the user is learning. It then, updates the HTML and sends it back to the client. If you'll notice, one of those progress bars is 'pulsing' to indicate which skill is currently in training. It also fires other functions to highlight specific list items to indicate which is selected. For that, rather than 80 odd instance variables like in the menu, I do a simple string 'replace' to set one class to the 'active'. And it does other things. If a list item is clicked, it fires off an AJAX call that returns a description of the skill, the time it will take to train and training prerequisites and loads that HTML response into yet another HTMLElement.

    I've only been working with this plugin for a few weeks and there are still a lot of things I haven't experimented with, like all of the 'EVENT' settings at the bottom of the properties. I believe, the author originally put those in to do the things I'm already doing with the HTML el-on code. He added in that el-on after he had all those settings and it replaced many of those. But if you look, you can even set up events to change the HTML based on keyboard events, mouse events and even HTML form events (like you can call a function when a form submit button is clicked!).

    The beauty of this plugin is that you can include all of the power of HTML, CSS and JS onto a Construct form or, you can just have chunks. Rather than reloading entire web pages when a user clicks on an item (as you would with straight HTML), you just reload or change what's in the HTMLElement.

    I know this is a tldr but you asked for it. Hope this helps.

  • Function parameters are an easy way to perform the same calculation using different inputs.

    For example:

    Assume I have a function that adds parameter+13 and returns the answer.

    I can call that function and pass say 8 as a parameter and have it return 21. If I pass 85 as a parameter, it returns 98.

    Here's an example of how I use a function with a parameter to switch layouts.

    * On function 'menuFunction'

    * Parameter 'MenuRequested' (Number)

    ----+ System: MenuRequested = 1

    -----> System: Go to Layout 1

    ----+ System: MenuRequested = 2

    -----> System: Go to Skills Layout

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Ok, so here's how I'm having to do this...

    My AJAX call gets a JSON as a response and when the AJAX succeeds I tell it to parse that JSON file.

    Because I see no JSON.onParsed event, I'm having to check every single cycle to see if a JSON.hasKey exists, whether it does or not. If the JSON.hasKey succeeds as a result of the JSON being successfully parsed, it then proceeds to fire every single cycle of the event sheet because the key DOES exist. So this means, that when the .hasKey is triggered as true, I'm having to immediately delete that key from the JSON so that .hasKey doesn't keep firing. And even then, every single cycle of the even sheet, it's still checking to see if that key exists, which IMHO, is a waste of CPU cycles.

    Now I could set it to trigger once while true but that means, if I do an AJAX call for the same JSON later with different data in the key, it won't fire.

    Please tell me I'm missing the .onParsed event.

    Tagged:

  • Firebase is one way to do it. There's a discussion about it here:

    construct.net/en/forum/construct-3/how-do-i-8/firebase-construct-135443

    The way I'm doing it is more complex but I have full control over how it works. I use MySQL on a web server, PHP to query the database and send results back to the client as JSON and AJAX calls to the PHP files to transfer the information back and forth.

    Either way, you're going to have a lot to learn.

  • No problem. The HTMLElement can be quite confusing as it uses some rather unconventional methods to achieve what it does. It took me a good while to figure it out from his examples. I've figured out how to use most of it and the power it has and the unique abilities it gives C3 is pretty amazing. If you have any questions, just ask.

  • It appears I misread the OP.

    It depends on your game but if it's a shooter type game with PVP or cooperative play you'll need both if you want it to succeed.

    A game without players needs bots. A game with just bots, needs players.

  • And a quick suggestion.

    I use codepen.io to test out what I'm going to be doing in the HTMLElement. On that site, I can play around with the HTML, the CSS and any JS (which the CSS Injector also handles) and make it look and function exactly as I want.

    Oh, and to confirm how you're doing it does work, that skill tree in the second image, that's generated on-the-fly from several MySQL tables. I use an AJAX call to a PHP file which builds the HTML and sends it back to the client in a JSON. I then save the HTML as a global variable. This allows me to do some cool stuff as I can do a 'replace' on the HTML variable to search for specific codes I included to make instant changes. Then, I set the HTMLElement.text to that variable.

    If done right, HTMLElement will even respond to clicks on the HTML and call functions in C3.

    Take the time to learn it, you'll love it for doing news.

  • Previously I used the text box to accomplish this and it was a challenge. I'm going to be adding in news to my app and I'll use the HTMLElement.

    To set up the HTMLElement, the text property under HTML holds your news. If you use HTML, check the box "Text like HTML".

    To get the scrolling you'll have to make changes to the 'inline style' properties.

    Make sure the word-break is set to what you want. Break-word will wrap the text based on spaces in your sentences.

    overflow-x will add in a horizontal scroll bar. Set it to hidden if you don't want a horizontal scroll.

    overflow-y will add in the vertical scroll bar. Set it to auto or scroll. If set to scroll, a vertical bar will always appear. If set to auto, the vertical bar will only appear when the text is larger than the box.

    You should get something that looks like this:

    The author of the HTMLElement also created a CSS injector that makes it real easy to add in your own css styles:

    construct.net/en/make-games/addons/166/inject-css

    If you play around with CSS much, you can come up with something like this which is also the HTMLElement:

  • They added an expression: unixtime

    Maybe make a feature suggestion for the rest of the date api?

    That should be built into a language like JS. Instead, what I'm discovering is that in JS you either have to include some huge library or write your own.

    I haven't checked the expression and I may. All I wanted to do was convert a unix time (in the future) to a date time string. I feel like landing on the moon would have been an easier task.

    But... I guess I expect to much from a programming language.

  • Well, I ended up just doing this.

    function timeConverter(UNIX_timestamp){
     var a = new Date(UNIX_timestamp);
     var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
     var year = a.getFullYear();
     var month = months[a.getMonth()];
     var date = a.getDate();
     var hour = a.getHours();
     var min = a.getMinutes() < 10 ? '0' + a.getMinutes() : a.getMinutes(); 
     var sec = a.getSeconds() < 10 ? '0' + a.getSeconds() : a.getSeconds()
     var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ;
     return time;
    }

    Good reason for me not to invest a lot of time into learning JS. When the base code doesn't even have basic date/time conversions then it's still not a real language.

    Proof?

    Date.now() - gives the Unix timestamp in UTC.

    Date() - gives the date string in LOCAL time.

    Seriously? What logic came up with that?