PaulPlay's Recent Forum Activity

  • I assume you are testing on mobile, where loader layouts are not supported? It still shows a quick screen for launching the engine though in your browser, the loader layout is just being shown while downloading files. This is normal actually, it just takes a few seconds max. to load up your first layout and while doing so shows the logo you have selected for this screen in the icons folder and you can also opt to show a different background image as well or rather display the project color

  • Hey everyone!

    I was making a web app that generates and formats text and stumbled upon the following issue:

    I could not make a button that lets the user copy the text and keep the formatting.

    When you use the built-in clipboard plugin and copy the text of a text field (using Object.Text), the formatting through BBCode is being copied as plain text. For example, This would not look cursive but rather just show the BBCode brackets with the i's inside of them.

    So I tried doing it with an html field, I set the HTML's content to the text field's BBCode-formatted text and it displays it nicely, however, when I copy the HTML.HTMLContent, the text doesn't copy with the right format and <em> elements are being shown instead of the text being cursive etc.

    In the end, I managed to find a solution to this problem which I wanted to share with you and it does not require any plugin, just a few lines of javascript code which you can simply include in the construct editor thanks to the built-in scripting feature.

    What you need to do beforehand, is to set the text of an html element to the formatted text that you want to copy and set the ID of the html element (in the construct inspector) to "result" (you can pick a different id, but you have to change it in the js code accordingly).

    So in the event sheet, I put the following script under my button press event:

    function copyToClip(str) {
     function listener(e) {
     e.clipboardData.setData("text/html", str);
     e.preventDefault();
     }
     document.addEventListener("copy", listener);
     document.execCommand("copy");
     document.removeEventListener("copy", listener);
    };
    copyToClip(document.getElementById('result').innerHTML);
  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • I‘m glad it helps :)

  • I still experience a lot of crashes on my relatively recent iPhone. Also, can confirm that ads don‘t pause the game and it also doesn’t pause when opening the app switcher. This is really unfortunate, as the game gets a lot less fps on my old galaxy s8 with 4gigs of ram but there are no other issues.

  • With the current vibration implementation through the Browser object, there is no way to set the duration / length of vibrations on ios (the value will be ignored).

    I made this plugin which adds the cordova-plugin-taptic-engine by Eddy Verbruggen to the build service and comes with multiple actions that let the user add various types of vibration to their games. The actions represent the vibration types for the taptic engine introduced by Apple and explained here: developer.apple.com/design/human-interface-guidelines/patterns/playing-haptics

    I have filed a feature request for this before, but unfortunately the devs do not seem to have the time to implement it (which is totally understandable, but I think this is quite important). Therefore, I figured I would try to implement this by myself and surprisingly it worked. I used the C3IDE for making this plugin and it is really amazing. Big thanks to piranha305.

    Here is the link: construct.net/en/make-games/addons/923/taptic-engine-vibrations-c3

  • I want to make the iphone-x style homebutton transparent like in most mobile games and require 2 swipes (one for waking up the homebutton and one to actually perform the action). I've read online that in unity you can make this work by enabling a simple toggle ("defer system gestures on edges") however, in construct 3 there is no such option.

    I've stumbled upon this cordova plugin online but I have no idea how to implement that. Any help is appreciated.

  • Yeah so far it works well :) Yes, it is quite specific... because most buttons in my game use different animations etc. and I only want 1 event per button because otherwise the code becomes more cluttered and it's hard for me to get an overview. If you just have simple tap buttons that don't react to the touch / lift off of the finger then it is way simpler. (or if you are fine with long touches not registering)

    Overall I think it would be very cool if you could fine tune the parameters of the built in "on tap (object)" event.

  • Thanks for that solution. This sorta works but has a few issues compared to mine ;) First of all, if one finger is on a button, and the other one taps somewhere else, the animation gets reset. I combat this issue in my game by checking if the touch with a specific index ends (as explained at the end of my post).

    Second, we would now need a place to execute the actions of the button. Usually, that happens when you lift up your finger, so we would need a combination of "on any touch end" + "is in touch" and then check if the sprite is currently playing the "intouch" animation.

    Now, because your buttons all got the same animation (a sprite change) you can use a group for that. However, in my game buttons shrink (that's done with the tween behavior or an animation), so that is harder to track. It would work with an instance variable (a boolean) though.

    Another issue is that if you place your finger on the button, then move it away slightly and then back on the button, the action would not trigger because the button animation would have already reset.

    So your solution would work as well if we modified it a bit but it would need at least 2 events per button which is not ideal.

  • On tap does not trigger on long touches.

    The main issue is that the buttons in my game (and many other games) play an animation when they are initially being tapped and play a second animation once they are released.

    Now, you could just seperate these 2 things into different events - 1 for the action of the button (which triggers on tap object) and one for the button animation, which triggers on touched object and on any touch end (+ a second condition to check whether the button was pressed before). However, this eliminates long touches and the buttons feel very unresponsive. If you hold something for longer or move your finger just slightly, the tap does not register.

    The issue with the „On touch end“ event in combination with the „is touching object“ event is that the finger can start touching the screen somewhere else and move to the button and then release & activate it. This is very unnatural. Yes, you could store wether the button had been touched with a variable and then check on the second event with the „is touching object“ condition wether it was also initially touched, but that requires way more code than my solution. In addition to that, you would need another event to make this work, one for playing the initial animation once the object has been touched and one for playing the second / the „back“ animation once the touch has ended & the player was touching the button in the first place - otherwise it would play all button anomations at the same time. You can’t just put this revert animation under the „on touch end“ + „is touching object“ event because then the button would stay small in my case if you would touch the button and then move your finger away from it because then there is nothing that reverts it back.

    So yes, you could make this work, but it would require 3 events for every button and a lot of complicated logic on top of that.

  • You can also modify the function to always return 1 if a controller is being used, this way, you can have controller + touch input in the same button event with an or function and the code still gets executed.

    Also, I added an update for this solution (in the main post) because it had a flaw. If you touched a button and held, then tapped somewhere else, the button would revert to its initial state because the „On any touch end“ event would trigger (and wouldn’t do the action)

    This isn’t a huge deal but the new solution is far more elegant because it mitigates this issue :)

  • Hey everyone,

    making a great and responsive touch button that plays an animation when you first touch it and triggers the action once you release the button in construct 3 is not easy.

    See, when you use "on tap object" a touch of a button does not register if you hold the button for longer.

    If you want to make a button, that plays an animation (e.g becomes smaller) when you first touch it, and play another animation (e.g become big again) and then triggers and action once the touch has ended, there theoretically is a simple option:

    1) You play the first button animation when you touch the object "on object touched"

    2) You wait for a signal that you call something like "Wait for signal: TouchEnd"

    3) You use a seperate event "on any touch end" and trigger the signal "TouchEnd"

    4) The code that comes after the "Wait for Signal: TouchEnd" will be executed

    However, this approach is flawed. See, when you touch the button, then move your finger away from it and release, the action still happens. This means, once your finger is on the button (might be an accidental touch), there is no way to cancel the action.

    For a long time I used "On tap object" for all sensitive actions and this 2nd approach for everything else, but now I have found a great way to check if the finger was released / the touch ended on a certain object.

    Here is how it works:

    First, you add an event "on any touch end" that casts the signal "TouchEnd". Also, we add 2 global variables, TouchEndX and TouchEndY. We set these as seperate actions to Touch.X and Touch.Y respectively - If you have parallax or scrolling layers, you need to use Touch.XAt(TouchIndex,"NameOfUILayer") and the same for Touch.Y. This way, we store the last touch of the player.

    Second, we add a new function that takes the parameter "ObjectUID" -> this will be set to the Object.UID of the object that has the touch action later.

    The function also returns a number. 1 representing a valid touch, 0 meaning that the user has cancelled the touch.

    Now, you need to create a family that consists of all buttons in your game (in my game it is called "Buttons"), that are supposed to use this approach.

    The function, in its first event, now gets 2 conditions. One is called "Pick instance with UID ObjectUID" with ObjectUID being the variable we just assigned to the function. This ensures that only the object the player has clicked on is being used in this expression. The second condition is one of type "compare 2 values". We compare the first value:

    ---

    Compare:

    (Buttons.bboxright>TouchEndX)+(Buttons.bboxleft<TouchEndX)+(Buttons.BBoxBottom>TouchEndY)+(Buttons.BBoxTop<TouchEndY)

    to:

    4

    What I‘m doing too (as you can see in the last screenshot) is to add 35 to the dimensions of the button in this expression so that if the user is moving his finger only slightly away from the button, it still counts as a touch.

    ---

    So what this do? It checks, whether the last touch of the player was in the boundaries of the hitbox of the object / button that he has just touched. If one of these 4 conditions is true, it adds "1" to the expression, therefore the total should be 4.

    If this condition is true, the function should return "1". If the condition is false (add an "else" event here), it should return 0.

    Now let's have a look at the button:

    The parent event is a simple "On touched object" event.

    The (only) subevent consists of your 1st animation, then the "Wait for signal: TouchEnd" action, and after that, the actions that should be executed regardless if the touch ended on the object (so, the 2nd animation to revert the 1st one as well as a sound effect, maybe).

    Now, we add a subevent of this subevent, which checks wether the function we created returns 1. When calling it, we have to specify its parameter (ObjectUID) which is the button.UID (the button of the event). Only if this condition is true, we execute the code of the button. This way, the animation of the button works independently from the action action and as compared to the animation only triggers when the touch ends on the object.

    Note, that this basically eliminates multi - touch for all buttons that use this system. On any touch end, the signal will trigger and all buttons will return to their initial state (with the 2nd animation playing / reverting). However, only the one where the last touch has started (because we only have 2 variables) will cause a button to activate, assuming the touch has also ended on this exact button.

    If you want to improve this with Multitouch, we would need a more complex system, where an object stores the X and Y values of the last touch and the ID of the touch would be taken into account.

    - - - - -

    Update (improvement):

    If you want to make sure that the „on any touch end“ event will only store the position of the finger that touched the button in the first place (otherwise, if you press and hold a button and simultaneously tap somewhere else, it will trigger the event „on any touch end“ and the button will revert back to its initial state without executing the action) there is an easy way to add that to the existing code.

    1) Add a Global variable called „TouchIndex“

    2) Change the „on any touch end“ event to an „on nth touch end“ event and set the number of it to the variable (TouchIndex)

    3) Add a new event „on touched object“ with the object being the Buttons family. Add an action „set value“ to the event and set the value of „TouchIndex“ to touch.TouchIndex . If you have many overlapping buttons, you may want to add another condition, something like „Buttons opacity = 100“ or „Buttons is visible“. If you have many layers that you make visible or invisible, consider also making them inactive when they are transparent.

    -> this means, that only when the user ends a touch that initially started on a button, it will cast the signal „TouchEnd“ and store the position of where it ended.

    In my case, I also got a condition to check whether a controller is being used, but this is how it looks like now:

    Again, if you are using Parallax, you need to use TouchXAt() and TouchYAt() (and your UI layer in the brackets) instead of TouchX and TouchY.

  • I wanted to share this virtual joystick for mobile games that I've been working on with everyone who needs a good virtual joystick for their game. I have seen videos on virtual joysticks on youtube, however, they usually just use the drag and drop behaviour with the stick. The issue with this is, that you really have to tap on the stick and drag it, you can't just touch everywhere on the joystick and the stick will move to that location - so that's what I've done in my solution.

    You can download the example C3P to implement it in your own game!

PaulPlay's avatar

PaulPlay

Member since 22 May, 2021

Twitter
PaulPlay has 2 followers

Trophy Case

  • 3-Year Club
  • Jupiter Mission Supports Gordon's mission to Jupiter
  • Regular Visitor Visited Construct.net 7 days in a row
  • RTFM Read the fabulous manual
  • x4
    Great Comment One of your comments gets 3 upvotes
  • Email Verified

Progress

8/44
How to earn trophies