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).