Create Word Search

Hello, we want to create a word search in html. Is it possible with hype?

Thanks in advance

What do you mean by ‘Word Search’? Can you provide an example?

If you’re thinking of a search engine field to find something in your Hype document, I recommend checking out some of these threads to see some ways of going about this: http://forums.tumult.com/search?q=search%20engine

Sorry, I was thinking about something like the attached screenshot. People has to find some words in the box.

Thanks

Hype may be able to help with some of the layout and handling actions, but you will still need a decent amount of custom javascript for letter randomization, highlighting, and determining correctness.

I saw this code for word search, is it possible to apply this to Tumult Hype?

https://codeguppy.com/code.html?t=word_search

Are you looking to embed that particular word search, or make a new one from scratch?

If you're looking to embed it, this should be possible, but it isn't immediately clear from the site since it looks like they are using some sort of library to abstract over typical javascript/HTML conventions (seems like p5.js, but I'm not sure if they've done more to it). If you find general instructions they have on how to export or embed in standard .html documents, then we can provide guidance on how to add those to a .hype document.

I probably wouldn't use Hype to program this from scratch, at least not if you want the words/puzzle randomized.

  • one way or another, you'll need to write a decent amount of code for the solving aspects
  • the puzzle is a square grid, which is very easy to make programmatically. While this is also easy to make in Hype and I usually like doing the visual aspects in a visual tool (especially if it is an irregular shape), the reality is if you're coding anyways this isn't much to do.
  • The puzzle is solved by a drag action that spans multiple grid cells, and this isn't something that can be setup with Hype's event UIs, you'd still need code if you want this effect

Thank you so much for responding.

I was hoping that I can use this particular word search (it's okay if it's not randomized). Is creating a new one better?

I don't really know much about coding, but I think everything is made in the code. Is it possible to alter the code of that so I can use my own buttons for the background and letter buttons? The most important function for me in this is the drag action to solve a word.

I cheated a little bit. I asked ChatGPT to give me a clue on the missing code that would draw the canvas for this puzzle game.

It confirmed what @Jonathan said about p5, and gave me the p5 functions to draw the canvas and do the setup using p5. Also the p5 library is linked in the head .

All the code goes in the head file.

This code (from ChatGPT ) is added to the existing code.

 function setup() {
       var myCanvas =  createCanvas(cols * squareSize + matrixX + 10, rows * squareSize + matrixY + 10);
 
        }

        function draw() {
            loop();
        }

I have not played with p5 for a few years, so forgot it was a simple as that. :person_shrugging:

Also note p5 complains about the loop var in the existing code, it is already in use, so it is renamed in our code to loop_


 function draw() {
            loop_();
        }

Now the issue is that p5 will place the puzzle in a canvas some where in the body of the html.
A simple google find how to put a p5 canvas in a div, gives us the answer to direct the canvas to an Hype element. Therefore allowing you to place it inside a hype rect and have some sort of control over the layout.

The Hype rect has an id of myDiv

and the change to the code is:

 function setup() {
       var myCanvas =  createCanvas(cols * squareSize + matrixX + 10, rows * squareSize + matrixY + 10);

    myCanvas.parent("myDiv");
        }

Also added a function to jump to new scene when complete.

p5.hype.zip (28.5 KB)


You probably can find other tidbits from


5 Likes

Thank you so much it really is working on Hype now. But I've encountered a problem when I tried to add it to my activity. I don't know how to customize, plus when I try to drag the letters the mouse action is not centered.

Here a sample of my project.
Word Search.zip (163.3 KB)

This is due to the scaling you have set on the scene.
The canvas does not follow it so the mouse pointer registers in the wrong place. Apart from turning off scaling I am not sure how to fix it in this case.

I did get it to kind of work correctly by adjusting its cell calculation which is related to the pointer events but not good enough I’m afraid.

But that may be one way of solving it, by adjusting the registration of the mouse pointer event x,y position.

It does look like this may be a common problem with canvases but I did not find any simple fixes.
Which does not mean there is not one.. just in the time I investigated, I did not find it.

It may be worth asking the question on the original site to see how they deal with responsive layout

Also you seemed to have changed the code in a way that the words do not show correctly. Putting the original code back fixed that!

1 Like

*EDIT: >> There are two answer here.. I realised that the canvas behaved once outside of he Groups responsive layout property inheritance, and started to write the first answer *

The first one solves the mouse clicking issue but you get a ok'ish responsive behaviour with the new code that tries to manage that for the canvas.

*The second Answer is an improved version that still keeps the canvas rect outside of the group but as I was writing the first answer here, I realised I could probably get the responsive part much better.. *
read on..

end edit<<


Had another play with this and got it working as well as I could with your setup.

1, I took the canvas div out of the group with the responsive scaling on it.
This allows the canvas pointer registration to be in the correct place.

2, To give the canvas some sort of responsive scaling,
I added a function autoresizeCanvas()

This function loads an on resize listener for the browser window.
It will try and scale the canvas to something that looks ok and matches the rest of the scene.
I limited it to adjusting the width.

It is called after in the draw() function to run after the canvas comes into existence.

function autoresizeCanvas(){
      const canvas = document.getElementById('defaultCanvas0');
 
      window.onresize = (event) => {
      
     canvas.style.width = (window.innerWidth  / widthScale ) + 'px';
     
       };

widthScale is define in the head file.

Also in the head file there is some css that will set the height to auto.

<style>
	
	 #defaultCanvas0  {
	 height :auto!important;
	}
	</style>

3,
I change the line

var myCanvas = createCanvas(cols * squareSize + matrixX + 10, rows * squareSize + matrixY + 10);

to

var myCanvas = createCanvas(window.innerWidth /widthScale , window.innerHeight / 1.5);

This allows us to set the background and initial size of the canvas better.

Word Search_mhV1.hypetemplate.zip (180.0 KB)

--

Now with more time we probably could get it scaling better. maybe by match the width height of another hidden element inside the group....


WAIT!!

Actually as I write that last bit hmmm.....

This actually works. A bit of a farthing around due to p5 being p5!.

Any way , the better way is to put a duplicate sized rect with its own id inside the group.

We can then use the duplicate rects transforms width/hight and top values to set the canvas in the real rects properties.

In the code we hard code the the initial size of the canvas, using the parent rects sizes.

const parentElWidth  = 664
const parentElHeight  = 626

We then change the size to match the dup rect ( just to makes sure it matches correctly, we can't do this before hand as it does not exist yet. And thensetup for auto resize

      function draw() {

            loop_();
            initSizeCanvas() // sets initial size
            autoResizeCanvasOnWidowResize() //- Set resize on window size change
           
        }
 
 
 
 function initSizeCanvas(){
      const canvas = document.getElementById('defaultCanvas0');
   		var matcherElement = document.querySelector('#matcher')
    
     let rect =  matcherElement.getBoundingClientRect();
    
     canvas.style.width = (rect.width ) + 'px';
     canvas.style.height = (rect.height ) + 'px';
     canvas.style.top = (rect.top ) + 'px';
     
	
      
      }

The autoResizeCanvasOnWidowResize(). just calls the same initSizeCanvas() within a window.onresize

Word Search_mhV2.zip (180.3 KB)

Oh and both example fix the mouse issue . v2 is the better solution I think.

3 Likes

Hi Mark!
You made the crossword game (Word Search_mhV2.zip) work just fine in Hype!
There is that function enter() in the final part of the Head HTML's inline javascript (lines 391 through 407) that is meant to fire up on game completion.
I have noticed that it doesn't work inside Hype for whatever reason.
I have a question: would it be possible to implement a Hype-compatible function that could work on game completion? For example to start a specified Hype Timeline e.g. hypeDocument.startTimelineNamed('instruction');?

Hi Mate,
Merry Christmas.

I never used that function. There is a couple of lines in the Validation() code that I actually converted to do just that though.

If you create a scene MyScene, that code will go to that scene at completion.

 if (found.length === words.length)
    {
        //showScene("Congrats");
        HYPE.documents[window.hypedoc].showSceneNamed('MyScene',HYPE.documents[window.hypedoc].kSceneTransitionInstant);
    }

The code can be easily changed to start timeline.

1 Like

Hooray, this is working!
Thank you @MarkHunte for pointing out that part of the code. Now I see it (lines 145 through 160 of the Head HTML's inline JS). Happy Holidays!

1 Like

Wow this really worked!! Thank you so much!! This a big life saver <3

PS.
I just encountered a new error, when I'm coming from a different scene the Word Search doesn't appear. Is it because of the p5?

You will need to explain more..

just had a play.

If you mean you are starting of on another scene before you go to the p5 one. then;
The answer is yes mostly because the p5 has likely shot is bolt already in the head and a bit of the by-document is not known to the p5 if you did not also load the bit of code that declared it for external usage.

So I have taken a different tack, which should solve both issues.
We will try and set things up so that the p5 scope is only run as an instance and is set up only when the right scene loads.

With an instance ,we can load the setup in an on scene load.

This also allows us to directly use the hypeDocument runtime directly
But being its a p5 instance also means if we leave that scene and come back to it, the canvas with the words will be still setup and show any selections as we left it.
It will also then create another canvas each time on the same scene.

After some playing around with the p5 API to reset everything and not getting that working, I tried to just remove the original canvas if we have run once already. That worked and it will redraw a new one.
(p5 is always redrawing) effectively resetting every thing.
We set a var with true of false to know if we have run once or more.

This all seems to work well. But note I am not a P5 pro and am hacking my way to solutions. Instances may not be needed to do this but that's where I landed first with working results. The same goes with how I reset.

Word Search_mhV3.hype.zip (203.4 KB)


If you actually want the canvas to keep its selections etc.

Then change the lines

if (p5loadedOnce){
 		
 			//we reset on scene loading again
 		document.getElementById('defaultCanvas0').remove();
 		 
 
 }

to

if (p5loadedOnce){
 		
//we dont make any changes after  scene loading again
 		return 
 
 }

--

With the latter code change to leave the canvas un reset, You can use a button if you want to have a manual reset and call to a script that will run this code if you want.

 document.getElementById('defaultCanvas0').remove();
	p5loadedOnce = false
	hypeDocument.functions().loadCanvas(hypeDocument, element, event)

Word Search_mhV3 keep setup.hype.zip (205.3 KB)

An add-on to the above.

This has been quickly thrown together and just got it as an unrefined working example.

This one allows for multiple puzzle grids.
You have to map each of them out in their own matrix.

In this example I have made two.
Scene names are used in the matrix etc var names so the must be done as I have shown.

There is a random char generator to add a char to any blank char in a matrix. Did that to save time when making them.

This version does not save changes on return to scene. The p5 just did this once I had more than one canvas and honestly CNBA to figure that out..


Word Search_mhV4Multi_v2.hype.zip (288.6 KB)

--

Here Also is a 2d word Matrix generator.

Simply enter your words. And hit the Get Matrix button.

The array of arrays will be fed to the console, clipboard and in the below rect for you to copy.

v2 ( added an importer, so you can import existing matrix text and edit it )

2d word Matrix generator..hype.zip (36.4 KB)

IMPORTED AND EDITED MATRIX


And finally thinking about it, the code used in the mratrix generator could probably be used with some of the code in the p5 to create the game without p5.

Again if I have time I may come back to this..

--

Progress Report:

I honestly did not think I would get this done.
I have been playing with the idea for a few days when I had a bit of time.
I had everything pretty much working. All done in vanilla JS.

Using a Table instead of a canvas.
Dragging across a Tables cells.
Highlighting cells.
Finding words and so on.

To be honest I did not refer much to the p5 code. More the behaviour of the puzzle game.
On reflection, that decision I think that was the best thing I could have done.
And made it quicker than I thought would be to figure things out with my own logic.

The last stumbling block was while the mouse was still down reversing the drag back over already selected cells. The cells needed to be un highlighted. That was again in the ars... to figure out.

I in the end used the help of ChatGPT (3.5) for that last bit.
Oh my word. wasted a lot of frustrated time with that.
But it did in the end push me in the right direction even though it failed badly on the code.
And it did give me the idea to use sets instead of arrays. which work much better.

--

Here is a video showing the behaviours of my working model.
I will need to migrate it to one of the above examples before I post it but wanted to give a progress report.

3 Likes