I love games and as a developer it has always been my goal to create my own game at some point. Tic Tac Toe…honestly not a super fun game. But here’s the deal: as a developer, it’s easy to get ahead of yourself and come up with grand projects that you either don’t have time for or are too big and overwhelming to accomplish. My advice to beginner developers: start small. Choosing something simple allows you to focus on the concepts you want to learn, accomplish it in a short amount of time, and have something fun to share with others when you are done. It also can lead to those bigger projects that you originally wanted to make. In this case, my next step for this project is to set up SignalR so people can play against each other. And after that, I can make other board games or card games. Then after that, move beyond to something more advanced like an RPG or shooter. But the point is, you have to start somewhere. It makes it easier when your goals are realistic but can evolve and grow into bigger things.
The Project
CSS Grid makes creating layouts extremely easy, and while it might not be the ideal choice for creating a game, it allowed me to have some fun while learning about it. I also had a few challenges that allowed me to dive into some new solutions I have never used before.
Before I get into that, here is the link to the game. You can play with someone sharing a phone or desktop.
Challenge 1: Responsive Design with Aspect Ratio
I have seen examples with CSS Grid without media queries and I was hoping I could do the same for Tic Tac Toe while keeping it responsive. Yet, when it came time to maintaining the square while scaling up or down, it was a bit more challenging than I imagined. Looking for alternatives to media queries, I found something that would help.
Viewport Units
Of course, the first step for looking for solutions was Stackoverflow. This led me to some code that used viewwidths (vw). 1vw is equal to 1% of the width of the viewport (browser) and 1vh is 1% of the height of the viewport. So in the examples, the code I ended up with looked something like this:
grid-template: repeat(3, 30vw) / repeat (3, 30vw);
At first appearance, this seemed to solve the entire issue. Unfortunately, it didn’t do anything on vertical scaling and it also caused some problems with a wider monitor because its based off width. This lead me to vmin.
1 vmin is equal to 1% of the smallest viewwidth or viewheight. So for example, on a phone the width is smaller than the height, so vmin would go off of vw and if it was desktop, 1vmin would be equal to 1vh because the smaller side is the height. It took me a bit to wrap my head around it too, but this ended up working great for this project because it would always scale to the smallest size.
I still ended up using media queries in the end for some of the fonts, but I kept the viewports for the grid because they work out well. It isn’t perfect for vertical scaling- there is still overflow when vertically adjusting the browser, but with some more time on it using vmins, it could be improved.
Note: compatibility for viewport units is pretty good, but not perfect. Here is a browser list for reference.
Mobile Devices and Hover
After deployment, one of the first things I always do is open up the app on my phone. There is something satisfying about seeing your work in your hands. Yet, this is also where it can cause some disappointment. During development, I’m always working to make my designs responsive and verify this with resizing the browser or an emulator. But even with all of that, you can still end up with some surprises.
In this case, I have hover effect over the grid. On the desktop, it makes it easy to see where you will be marking your spot. This is not critical to the game, but it does provide a nice touch to the desktop users. For mobile, it caused an unintended side effect. When the user would touch the screen, it would apply the hover effect to the square, which highlighted it. Some might have let this go, it wasn’t the end of the world. Being a perfectionist though, I had to figure out how to get rid of it.
The Javascript Fix
if (!!('ontouchstart' in window)) {
//logic for mobile devices
} else {
//non-mobile
}
The ontouchstart is a javascript event that occurs with touch screens. One thing that you probably notice is the double bang (!!). It took me some headscratching as well on that, but this will take an object with falsey values (null, undefined, 0) and convert them to a boolean value of true/false. More on that here.
I did not go crazy testing this with tablets or different browsers because this app is really just a test project, but I will have to explore this more in the future.
Next Steps:
As mentioned above, I’m already looking into evolving this project into its next phase of converting to a web app and using SignalR for real time gameplay that will hopefully be a good foundation for future games. In the meantime, I’m just going to start small, and take it one step at a time 🙂