Mobile touch gestures - swipeleft & swiperight

(Sugarcube 2.31.1 Tweego)

I’m trying to create a simple swipe left/right event on my game - like Tinder or Reigns. How can I get one of these examples working in my Twine game?

Note - I’m using the amazing event macro from Chapel’s Custom Macro Collection (v2.5.2), which is working great for keyup events and suchlike, but I don’t think that touch gestures are supported.

I’ve also tried running an event handler like the following, which is successfully detecting mouse and keyboard effects:

<<script>>
(function () {
	$(document).on('keyup', function (ev) {
		/* the ev variable contains a keyup event object.
		 * ev.key contains the key value of the key that was released.
		 */
		/* the following shows an alert when the 'a' is released. */
		if (ev.key === 'a') {
			UI.alert("the 'a' key was released.");
		}
	});
}());;
<</script>>

Probably the same way.

<<script>>
(function () {
	$(document).on("swipe", function(){
		/* do stuff */
	});
}());
<</script>>

According the docs, swipe is left or right, swipeleft is just left, and swiperight is just right.

1 Like

SugarCube includes jQuery, but not jQuery Mobile. If you want to use jQuery Mobile in Twine, you’ll need to download it from that second link, and then put the jquery.mobile-1.4.5.min.js and jquery.mobile-1.4.5.min.css files in the same directory as your Twine HTML file.

[EDIT: See my post below, where I discover you actually need jQuery Mobile v1.5.0 instead!]

Then, at the top of your JavaScript section, you’ll need to import those files like this:

if (window.hasOwnProperty("storyFormat") || document.location.href.toLowerCase().includes("/temp/")) {
	// Change this to the path where the HTML file is
	// located if you want to run this from inside Twine.
	setup.Path = "C:/Games/MyGame/";  // Running inside Twine application
} else {
	setup.Path = "";  // Running in a browser
}
setup.SoundPath = setup.Path + "sounds/";
setup.ImagePath = setup.Path + "images/";

setup.JSLoaded = false;
var lockID = LoadScreen.lock();  // Lock loading screen
importStyles(setup.Path + "jquery.mobile-1.4.5.min.css");  // Your CSS files go here
importScripts(setup.Path + "jquery.mobile-1.4.5.min.js")  // Your JavaScript files go here
	.then(function() {
		setup.JSLoaded = true;
		// Reload current passage since imported scripts can function now.
		Engine.play(passage(), true);
		LoadScreen.unlock(lockID);  // Unlock loading screen
	}).catch(function(error) {
		alert(error);
	}
);

You’ll need to change "C:/Games/MyGame/" to the directory path of the game’s HTML on the machine you’re developing on (make sure you use slashes / in the file path). You can also modify the sound and image paths as needed so it will work properly on your machine. Also, you may need to change /temp/ if that’s not the default temporary directory that Twine uses on your computer.

Once you’ve done that, then the jQuery Mobile stuff will work in Twine, though only after the JavaScript has finished loading. You can check setup.JSLoaded to determine whether the JavaScript has loaded yet or not.

Now, to implement those jQuery Mobile samples you linked to in your post, but within only a single passage, then you’d want to put something like this at the end of the passage where you were doing that:

<<script>>
$(document).one(":passagerender", function (event) {
	$(event.content).find("#elementid").on("tap", function (event) {
		$(this).hide();
	});
});
<</script>>

And that would hide the element with id="elementid" that you’d have somewhere in that passage when the user taps on it.

If you want to write some jQuery Mobile code which works on the whole document, then you’d modify part of the JavaScript I gave you earlier, something like this:

importScripts(setup.Path + "jquery.mobile-1.4.5.min.js")  // Your JavaScript files go here
	.then(function() {
		setup.JSLoaded = true;
		$("p").on("tap", function() {
			// Whatever code you want to trigger when a <p> element is "tapped" on goes here.
		});
		// Reload current passage since imported scripts can function now.
		Engine.play(passage(), true);
		LoadScreen.unlock(lockID);  // Unlock loading screen
	}).catch(function(error) {
		alert(error);
	}
);

Or, if you want to trigger some jQuery Mobile code on some elements within every passage which has those elements, then you’d add something like this to your JavaScript section:

$(document).on(":passagerender", function (event) {
	if (setup.JSLoaded) {
		$(event.content).find(".elementclass").on("tap", function (event) {
			$(this).hide();
		});
	}
});

And that would make it so that any HTML elements with class="elementclass" would be hidden when tapped on.

Take a look at the jQuery documentation (which I linked to above) if you need help understanding how to select different items or the like.
 

If you want that to work in every passage, then you should just put that in your JavaScript section like this:

$(document).on('keyup', function (ev) {
	/* the ev variable contains a keyup event object.
	 * ev.key contains the key value of the key that was released.
	 */
	/* the following shows an alert when the 'a' is released. */
	if (ev.key === 'a') {
		UI.alert("the 'a' key was released.");
	}
});

The reason why is that, if you put your code into a passage, and then the player loaded a save from after that passage, then that code wouldn’t trigger. This method prevents that problem.

Also, you wouldn’t want to put your code anywhere where it would repeatedly trigger (such as a PassageFooter special passage), since then it would stack up “keyup” events every time you went to a new passage, which would cause your game to play slower and slower as time went on. Thus putting it in the JavaScript section is the best solution.

Please let me know if you have any additional questions.

Hope that helps! :slight_smile:

1 Like

Thank you so much for your detailed advice - this is helping me find my way around the code and learn more too.

I’ve run into a problem at the beginning. After downloading the jquery mobile css and js files, placing them in the right directory, and using your script to load them, I get the following:

error

Immediately afterwards, once the Start passage begins, it appears that setup.JSLoaded is true. I’m hesitant to continue until I can chase down this error!

Compiling with Tweego, in case that makes any difference.

I took a look, and apparently the version of jQuery that SugarCube uses is too new to work with jQuery Mobile v1.4.5. :stuck_out_tongue:

You’ll have to download jQuery Mobile 1.5.0-rc1 from the “minified” and “theme” links, and then use those files, instead of the v1.4.5 ones. Don’t forget to update the JavaScript to use the jQuery Mobile v1.5.0 filenames as well.

You’ll also need to make some styling changes in your Stylesheet section to override some of the changes that the CSS file makes. Alternately, if you’re only using the events and not any of the jQuery Mobile custom elements, you might just want to comment out (i.e. put a // in front of that line) or remove the line that loads the CSS file.

Anyways, that should get you working. :slight_smile:

1 Like

Amazing - thank you so much! Loading up now no problem, time to get swiping :slight_smile:

(Just a note to make sure you didn’t miss my edits in my previous post. Never treat my posts as complete until they’ve been untouched for 15 minutes or more. :wink: :stuck_out_tongue: )

2 Likes

Don’t worry, I’m still only halfway through reading it!

1 Like