6464 }
6565 </ script >
6666
67- < a id ="tutorial-menu " href ="index.html "> menu</ a >
68- < a id ="tutorial-full " href ="# " target ="_blank "> view full source</ a >
67+ < a id ="tutorial-menu " style =" display: none " href ="index.html "> menu</ a >
68+ < a id ="tutorial-full " href ="# " style =" display: none " target ="_blank "> source</ a >
6969 < a id ="tutorial-save " href ="# " onclick ="save(); return false; "> < div style ="margin-top: 3px "> run</ div > </ a >
70- < a id ="tutorial-prev " href ="# " style ="display: none " onclick ="tutorialLoadPreviousStep(); return false; "> < div style ="margin-top: 3px "> prev step</ div > </ a >
71- < a id ="tutorial-next " href ="# " style ="display: none " onclick ="tutorialLoadNextStep(); return false; "> < div style ="margin-top: 3px "> next step</ div > </ a >
70+ < a id ="tutorial-prev " href ="# " style ="display: none " onclick ="tutorialLoadPreviousStep(); return false; "> < div style ="margin-top: 3px "> < - step </ div > </ a >
71+ < a id ="tutorial-next " href ="# " style ="display: none " onclick ="tutorialLoadNextStep(); return false; "> < div style ="margin-top: 3px "> step - > </ div > </ a >
7272 < div id ="editor-container ">
7373 < div id ="editor "> </ div >
7474 </ div >
@@ -274,6 +274,13 @@ <h1>Tutorials</h1>
274274 text . match ( / i t e m t y p e / ) ;
275275 }
276276
277+ function removeLeadingWhiteSpace ( code ) {
278+ var leadingWhiteSpace = code . split ( '\n' ) . filter ( l => l . trim ( ) . length != 0 ) [ 0 ] . match ( / ^ [ ] * / ) [ 0 ] || ""
279+ var code = leadingWhiteSpace + code . trim ( )
280+ code = code . split ( '\n' ) . map ( l => l . replace ( new RegExp ( '^' + leadingWhiteSpace + '' ) , '' ) ) . join ( '\n' )
281+ return code
282+ }
283+
277284 function parseTutorialHtmlAndStart ( htmlTutorial ) {
278285 window . tutorial = { steps : { } , totalSteps : 0 } ;
279286
@@ -287,8 +294,7 @@ <h1>Tutorials</h1>
287294 var textElement = e . querySelector ( "[itemscope='itemscope'][itemtype='tutorial-text']" ) ;
288295 var codeElement = e . querySelector ( "[itemscope='itemscope'][itemtype='tutorial-code']" ) ;
289296 var leadingWhiteSpace = codeElement . innerText . split ( '\n' ) . filter ( l => l . trim ( ) . length != 0 ) [ 0 ] . match ( / ^ [ ] * / ) [ 0 ] || "" ;
290- var code = leadingWhiteSpace + codeElement . innerText . trim ( ) ;
291- code = code . split ( '\n' ) . map ( l => l . replace ( new RegExp ( '^' + leadingWhiteSpace + '' ) , '' ) ) . join ( '\n' ) ;
297+ var code = removeLeadingWhiteSpace ( codeElement . innerText )
292298 tutorial . steps [ stepNumber ] = { text : textElement , code : code } ;
293299 tutorial . totalSteps += 1 ;
294300 } ) ;
@@ -302,14 +308,24 @@ <h1>Tutorials</h1>
302308 }
303309
304310 function tutorialRetrieve ( ) {
305- if ( tutorialUrl ( ) . length == 0 ) { return ; }
311+ if ( tutorialUrl ( ) . length == 0 ) {
312+ editor . setValue ( "" + removeLeadingWhiteSpace ( document . getElementById ( "bouncing-dvd" ) . innerText ) ) ;
313+ setTimeout ( ( ) => {
314+ editor . gotoLine ( 0 ) ;
315+ editor . focus ( )
316+ } , 100 )
317+
318+ return ;
319+ }
306320
307321 document . getElementById ( "tutorial" ) . innerHTML = "<div>loading tutorial....</div>" ;
308322
309323 reqwest ( {
310324 url : tutorialUrl ( ) ,
311325 crossOrigin : true ,
312326 success : function ( resp ) {
327+ document . getElementById ( "tutorial-full" ) . style . display = "inline"
328+ document . getElementById ( "tutorial-menu" ) . style . display = "inline"
313329 document . getElementById ( "tutorial-full" ) . setAttribute ( "href" , tutorialUrl ( ) . replace ( / r a w $ / , '' ) ) ;
314330 var script = document . createElement ( "script" ) ;
315331 script . id = "retrieved-tutorial" ;
@@ -339,5 +355,146 @@ <h1>DragonRuby Game Toolkit Sandbox</h1>
339355 </ body >
340356 </ html >
341357 </ script >
358+ < script type ="text/template " id ="bouncing-dvd ">
359+ # Bouncing DVD example
360+ def tick args
361+ # initialize the defaults for the game
362+ defaults args
363+
364+ # render the game
365+ render args
366+
367+ # check for user input
368+ input args
369+
370+ # run simulation
371+ calc args
372+ end
373+
374+ def defaults args
375+ # colors for random selection
376+ args . state . colors = [ :red ,
377+ :orange ,
378+ :green ,
379+ :blue ,
380+ :indigo ,
381+ :violet ]
382+
383+ # size of the box
384+ args . state . box . size = 10
385+
386+ # movement speed
387+ args . state . box . speed = 0.1
388+
389+ # start the box center x
390+ args . state . box . x ||= args . grid . w . half -
391+ args . state . box . size . half
392+
393+ # start the box center y
394+ args . state . box . y ||= args . grid . h . half -
395+ args . state . box . size . half
396+
397+ # pick a random direction of movement for x
398+ args . state . box . dx ||= [ 1 , - 1 ] . sample
399+
400+ # pick a random direction of movement for y
401+ args . state . box . dy ||= [ 1 , - 1 ] . sample
402+
403+ # state variable that is consulted before moving the box
404+ args . state . box . status ||= :moving
405+
406+ # set the color of the box to a random one
407+ set_box_color args if ! args . state . box . color
408+ end
409+
410+ def render args
411+ # render the box sprite
412+ args . outputs . sprites << {
413+ x : args . state . box . x . round ( 0 ) ,
414+ y : args . state . box . y . round ( 0 ) ,
415+ w : args . state . box . size ,
416+ h : args . state . box . size ,
417+ path : "sprites/square/#{args.state.box.color}.png"
418+ }
419+
420+ # render title and box location
421+ args . outputs . labels << {
422+ x : 5 , y : 5. from_top ,
423+ text : "Bouncing DVD" ,
424+ size_enum : - 8 , a : 80
425+ }
426+
427+ args . outputs . labels << {
428+ x : 5 , y : 12. from_top ,
429+ text : "x: #{args.state.box.x.to_sf}" ,
430+ size_enum : - 8 , a : 80
431+ }
432+
433+ args . outputs . labels << {
434+ x : 5 , y : 19. from_top ,
435+ text : "y: #{args.state.box.y.to_sf}" ,
436+ size_enum : - 8 , a : 80
437+ }
438+ end
439+
440+ def input args
441+ # exit this function if space isn 't pressed
442+ return unless args . inputs . keyboard . key_down . space
443+
444+ # toggle the box state
445+ if args . state . box . status == :moving
446+ args . state . box . status = :stopped
447+ else
448+ args . state . box . status = :moving
449+ end
450+ end
451+
452+ def calc args
453+ # do not move the box if the box status isn 't :moving
454+ return unless args . state . box . status == :moving
455+
456+ # move the box in the x direction by the speed
457+ args . state . box . x += args . state . box . dx * args . state . box . speed
458+
459+ # move the box in the y direction by the speed
460+ args . state . box . y += args . state . box . dy * args . state . box . speed
461+
462+ # collision logic : determine if the box is outside the
463+ # bounds of the 1280 x720 canvas if it is , then change
464+ # the direction of the box and color
465+ if ( args . state . box . x +
466+ args . state . box . size ) > args . grid . w
467+ # right side of the canvas check
468+ args . state . box . x = args . grid . w - args . state . box . size
469+ args . state . box . dx = - 1
470+ set_box_color args
471+ elsif args . state . box . x < 0
472+ # left side of the canvas check
473+ args . state . box . x = 0
474+ args . state . box . dx = 1
475+ set_box_color args
476+ end
477+
478+ if ( args . state . box . y +
479+ args . state . box . size ) > args . grid . h
480+ # top of the canvas check
481+ args . state . box . y = args . grid . h - args . state . box . size
482+ args . state . box . dy = - 1
483+ set_box_color args
484+ elsif args . state . box . y < 0
485+ # bottom of the canvas check
486+ args . state . box . y = 0
487+ args . state . box . dy = 1
488+ set_box_color args
489+ end
490+ end
491+
492+ # helper method for setting the box 's color
493+ def set_box_color args
494+ # to something other than its current color
495+ args . state . box . color = ( args . state . colors -
496+ [ args . state . box . color ] ) . sample
497+ end
498+ </ script >
342499 </ body >
343500</ html >
0 commit comments