I have currently the following (stripped down to the minimum to show what I am trying to achieve):
A StoryInit passage where I do my initialization:
<<set $room = 0>> /* current room */
<<set $action = -1>> /* no previous action */
<<set $exitNames = ['north','east','south','west']>>
<<set $roomExits = []>> /* -1 : no exit */
<<set $roomExits.push([-1,1,3,-1])>>
<<set $roomExits.push([-1,-1,2,0])>>
<<set $roomExits.push([1,-1,-1,3])>>
<<set $roomExits.push([0,2,-1,-1])>>
<<set $roomNames = ['room 0','room 1','room 2','room 3']>>
A PassageHeader passage containing the canvas element:
<canvas id="mycanvas" width="100" height="100" style="border: 1px solid red;"></canvas>
A Room passage where I want to display the passage text (a room description and how the player got there etc):
<<if $action >= 0>>You go $exitNames[$action].
<</if>>You are in $roomNames[$room].
A PassageFooter passage containing the navigation buttons:
<<if $roomExits[$room][0] >= 0>>
<<button $exitNames[0] Room>>
<<set $room = $roomExits[$room][0]>>
<<set $action = 0>>
<<=setup.setRoom($room)>>
<</button>>
<</if>>
: // the above repeated for the directions 1..3
<<done>><<= requestAnimationFrame(setup.draw)>><</done>>
And finally I added my JavaScript functions in the Story Javascript page:
let rcx = [1/4,3/4,3/4,1/4];
let rcy = [1/4,1/4,3/4,3/4];
let room = 0; // state.active.variables.room
setup.setRoom = function(r) {
room = r;
}
setup.drawCell = function(t,w,h,i) {
const cx = rcx[i];
const cy = rcy[i];
const lx = (cx-1/8)*w;
const ly = (cy-1/8)*h;
const dx = 1/4*w;
const dy = 1/4*h;
if (room == i) {
t.fillStyle = 'red';
} else {
t.fillStyle = 'white';
}
t.fillRect(lx,ly,dx,dy);
t.strokeStyle = 'white';
t.strokeRect(lx,ly,dx,dy);
}
setup.draw = function (timestamp) {
const c = document.getElementById("mycanvas");
const t = c.getContext("2d");
const w = c.width;
const h = c.height;
t.clearRect(0,0,w,h);
t.beginPath();
t.moveTo(rcx[3]*w,rcy[3]*h);
for (let i = 0; i < 4; i++) {
t.lineTo(rcx[i]*w,rcy[i]*h);
}
t.strokeStyle = 'white';
t.stroke();
for (let i = 0; i < 4; i++) {
setup.drawCell(t,w,h,i);
}
requestAnimationFrame(setup.draw);
}
Then when I run the story I get this:
Navigation works (i.e. clicking east, gets me to room 1 and the canvas now shows room1 (top right square) highlighted). But I run into the following challenges:
- According to the sugarcube docs I should be able to refer to a story variable (e.g.
$room) by using state.active.variables.room but this gives me an error. I use a setRoom function for now, but I want the canvas to stay in sync with the story directly (now if the player navigates back to an earlier room by using the history buttons in the sidebar, the canvas does not get updated because setRoom is never called).
- When the passage does not fit on the screen, I can scroll but then I either lose the map at the top or the navigation buttons at the bottom. I would prefer the scrolling part to only apply to the passage text (the
room passage).