Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Click Anywhere to Continue

So, this question's probably been asked before, but Google is doing me no favors today.

In Sugarcube 2.0, is there a means to click anywhere on a passage to continue to the next passage? In my specific case, I'd need it to only trigger after all the text is displayed in my passage, as I use TheMadExile's delayed text code.

Delayed Text Javascript
/*
	Define up a setting to control the rate of inter-passage
	text fade-in.
*/
Setting.addList('textDelay', {
	label   : 'Choose how long it takes for text to appear.',
	list    : ['No delay', '1s', '2s', '3s'],
	default : '3s'
});

/*
	Set up a postrender task to handle fading in each text
	section based upon a player selected delay.
*/
postrender['delayed-text'] = function (content) {
	// Find all elements containing the `delayed` class.
	var $elems = $(content).find('.delayed');

	// Text appearance delay (in milliseconds).
	var delay;
	switch (settings.textDelay) {
	case '1s':
		delay = 1000;
		break;
	case '2s':
		delay = 2000;
		break;
	case '3s':
		delay = 3000;
		break;
	default:
		delay = 0;
		break;
	}
	
	if (delay > 0) {
		$elems.each(function (i, el) {
			$(this)
				.delay(delay * (i + 1))
				.fadeIn(1000); // 1 second fade-in
		});
	}
	else {
		$elems.removeClass('delayed');
	}
};

CSS
/*
	Set sections containing the `delayed` class to be hidden
	initially.
*/
.delayed {
	display: none;
}



In passage:
@


The idea would be to replace the 'next' with being able to click anywhere. The reason I'm seeking this solution is because it's a 400k game, and there's a loooot of passages with Next or Continue or End.

I'd like to just slap an animated arrow at the end of the delayed text, and have it so you could click the screen to continue. This would be more visually appealing and immersive, replicating the feel of many VNs I've played.

Comments

  • edited March 2017
    You can do this by making your story autoclick any link on the screen that is within a particular span.

    In javascript passage write:
    $("#passages").bind("mousedown", function(event){
    	$("#passages")
    	.find('.next')
    	.trigger("click");
    })
    

    In passage write:
    <span class="next">[[Next|SomePassage]]</span>
    
    If you want to make the link invisible but still can be autoclicked, in css write
    .next a {
    display: none;
    }
    
  • Hi Claretta! Thanks for the swift reply.

    Gave that one a shot and clicking anywhere but directly on the link results in nothing happening. I created a seperate test story with nothing but the code provided, and still no dice.
  • edited March 2017
    Whoops I got it wrong, sorry. I cut and pasted something from my story that was a different context.

    Write this in javascript instead:
    $(document).on("mousedown", function (event) {
    	$(".next")
    	.find('a')
    	.trigger("click");
    });
    




  • edited March 2017
    Cool, when I click it now moves to the next passage.

    Only problem is, it doesn't wait until the link is revealed by the delayed text effect, no matter where you put the span class and link. I presume it's because the Javascript seeks out all instances of 'next' when you mousedown, and whether the link has been displayed or not is irrelevant, since it hasn't been explicitly told this is important.

    The reason I'm trying to wait until the full passage has displayed before the 'Click Anywere' part kicks in is because if they click prematurely and/or think it's finished displaying, they may miss out on vital text telling them something. Because it's half RPG, half VN, I can't really include a back option without causing several other issues.

    That said, if there's not a way to make that work, I may have to weigh up which is the lesser of two evils, since clicking anywhere to proceed is a very neat feature.
  • edited March 2017
    You can just delay the loading of the link.

    At the end of the passage just write SugarCube 2's equivalent of

    <<silently>><<timedcontinue 4s>><span class="next">link</span><</silently>>

    I don't know what timedcontinue is in sugarcube 2.
  • Claretta wrote: »
    You can just delay the loading of the link.

    At the end of the passage just write SugarCube 2's equivalent of

    <<silently>><<timedcontinue 4s>><span class="next">link</span><</silently>>

    I don't know what timedcontinue is in sugarcube 2.

    It's just <<timed>> in sugarcube 2.
  • edited March 2017
    Wouldn't that backfire as a solution if the timed text was set to instant, and you had to sit around waiting before you could click for 4 seconds?

    @.delayed; is.
  • <<timed>> accepts variables. I don't know about <<timedContinue>>. If it does though, just have your settings system also assign a variable and pass that value to the macro.
  • edited March 2017
    Chapel wrote: »
    <<timed>> accepts variables. I don't know about <<timedContinue>>. If it does though, just have your settings system also assign a variable and pass that value to the macro.

    @.delayed in a passage delays the text.

    @.delayed is used in any given passage.

    @.delayed - one for each paragraph. So if each delayed holds back text for 3 seconds, that's 3 x 7 = 21 secs.

    @.delayed, so that's 3 x 5 = 15 seconds.

    I mean, technically you could do this math for every single passage and then set it at the top. E.g. A quick eyeball of a passage tells me there's 5 instances of Delayed, so I manually write in 5 x (whatever the user set delay is) = whatever the timed delay needs to be. That would make it match up. But what you've got then is a situation in which you're doing a math equation for every passage you write, a calculation you've got to maintain and update for each passage, highly subject to human error.

    @.delayed once in a passage, the solution would work just fine.

    I apologize if it sounds like I'm shooting down freely and helpfully given suggestions. That's really not my intent!
  • edited March 2017
    @.delayed and use the length of the resulting array to multiply your timed value.

    Something like:
    @.delayed/g);
    
        if (delayArray != null) {
            State.variables.clickTimer = delayArray.length * delay;
        } else {
            State.variables.clickTimer = delay;
        }
    <</script>>
    

    You'll need to initialize the story variable $clickTimer in your StoryInit special passage. Then you can just plug in <<timed $clickTimer>>...<</timed>> where you need it.
    DairynGM wrote: »
    I apologize if it sounds like I'm shooting down freely and helpfully given suggestions. That's really not my intent!

    You're fine, just a minor miscommunication, I think.

    As an aside, maybe moving an automatic continue that isn't based on the text delay time to somewhere on the keyboard, like the spacebar, would be a good idea as a sort of shortcut. Much lower chance of accidentally skipping through if it's placed there.

    Also, with the code used above, it might be possible to accidentally skip scenes while clicking around in the ui-bar menus and such, which could be problematic.
  • Been trying to implement that code, and coming up against an error where the timed <<$clicktimer>> is.
    Error: <<timed>>: invalid time value syntax: "NaN" in <<timed>>

    Looking at the timed macro, it seems to use a "<<timed 10s>>" kind of thing rather than a straight number. Not sure if that's the problem, but it could be.

    As you said, I'm thinking that a key binding might be better at this point. It wouldn't need to interact with the delayed text, and if I separate any important item gain / stat loss etc events to separate passages or make it stand out at the top, I can migitate the risk of things being missed.

    Small chance of clicking too early, but probably the lesser of evils. And I've got thousands of passages to do, so I should probably stop worrying about the UX and more about actually getting the game's shell done.

    Anyway, I did this- my first attempt at actually trying to mess with Javascript instead of just mooch it off other people.

    Javascript:
    $(document).on("keydown", function (event) {
    	if (event.which === 32) {
    		$(".next")
    	.find('a')
    	.trigger("click");
    }
    });
    

    CSS
    .next a {
    display: none;
    }
    

    A Passage
    Some Text
    
    <span class="next">[[Next|A Second Passage]]</span>
    
  • edited March 2017
    I think a widget is the best solution honestly.
    <<widget "timedlength">><<if $option1>><<timed 1s>><<elseif $option2>><<timed 2s>><</if>><</widget>>
    

    and so on. You could make a widget which is gradiated enough to deal with many instances.

    Then you'd have each passage use a limited vocabulary of option 1, option 2 etc and then just put the widget in front of the link each time.

    Eg in passage
    <<set $option1>>This takes one second. <<silently>><<timedlength>><span class="next">[[next]]</span><</silently>>
    


    All you'd then have to do is put the correct <<set>> macro at the start of each text line.

    DairynGM wrote: »

    Anyway, I did this- my first attempt at actually trying to mess with Javascript instead of just mooch it off other people.

    Javascript:
    $(document).on("keydown", function (event) {
    	if (event.which === 32) {
    		$(".next")
    	.find('a')
    	.trigger("click");
    }
    });
    

    That's basically what my story does. The code I gave was originally written in my story for a key bind.

  • I edited my post about a hundred times but I'm happy with it now, in case you read it before. I use widgets to handle this. If statements are simple and easy to code, and widgets saves you having to recode every passage.


  • DairynGM wrote: »
    Been trying to implement that code, and coming up against an error where the timed <<$clicktimer>> is.
    Error: <<timed>>: invalid time value syntax: "NaN" in <<timed>>

    Looking at the timed macro, it seems to use a "<<timed 10s>>" kind of thing rather than a straight number. Not sure if that's the problem, but it could be.

    Looking at my code, I made a handful of mistakes, and this is one of them. I'll have an update later today.
  • edited March 2017
    After lightly skimming this thread—I haven't had time to really dig into it—I have few comments.


    1. @Chapel Try the following, which leverages DairynGM's textDelay setting and uses a temporary variable:
    @\.delayed/g);
    
    State.temporary.clickDelay = (matches ? matches.length * delay : delay) + 's';
    <</script>>
    


    2. The following:
    $(".next").find('a')
    
    Is much better written as:
    $('.next a')
    
    There's no point here in selecting one set of elements, simply to search through it for another set. Simply select the correct set to begin with.


    There's also no point in using a class for something which, by its very nature, must be unique on the page. I'd recommend making next an ID.


    3. @DairynGM I'm going to assume you're using some kind of UI. Laboring under that assumption, you are likely going to have issues with the suggestions so far as clicking on the UI will also trigger the next passage link even though that was probably not the player's intention.
  • After lightly skimming this thread—I haven't had time to really dig into it—I have few comments.


    1. @Chapel Try the following, which leverages DairynGM's textDelay setting and uses a temporary variable:
    @\.delayed/g);
    
    State.temporary.clickDelay = (matches ? matches.length * delay : delay) + 's';
    <</script>>
    
    Thanks, that was pretty much both problems I was going to address.
  • edited March 2017
    Awesome! Thanks for the feedback guys, I'll try implementing these later today.

    @TheMadExile Does the inbuilt Sugarcube sidebar count? By default, I've got it tucked away and semi-transparent, with the ability to click it back and forth. There's a few things in that menu so far. Character Info / Stats, the Quest Journal, and the Inventory.

    This could be a problem, but I'd have to see how it works in practice. Scenes where choices are made would by default not have the screen-click enabled, only the ones where 'Next' is pretty much the only option.

    I was planning to build UI elements as mentioned a week or so back in a thread, but these would be more informative than interactive elements. E.g. A box to the top right corner which displays in-game time, so you don't have to open the tucked away sidebar to see what time it is.

    I guess I'll put together a test and see what the UX is like, and if it's an acceptable tradeoff.

    I've already replaced the Next with an clickable animated arrow and included the Spacebar to skip ahead. It's such a small change, but it makes the whole thing feel a lot more smooth and user friendly.
  • edited March 2017
    Thanks for the code efficiency tips, TheMadExile.

    I didn't really make any real suggestions to avoid the ui problem because it depends on the ui you use and how you want to fix it.

    My options screen is in its own unique passage, not an overlay, so I avoid it like that. I also use key binds only. My clicks are limited to elements currently hovered over.

    The other way, though a bit more clunky, is to put the link within an <<if>> statement and have the ui activate a variable that sets the if to false.
Sign In or Register to comment.