You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
aney.co.uk/blog/p1-basic-drawing-and-intera...

98 lines
4.6 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="description" content="">
<meta name="author" content="Nathan (Aney) Steel">
<meta name="theme-color" content="white">
<meta name="theme-color" content="green">
<link rel="stylesheet" type="text/css" href="/main.css">
<link rel="icon" type="image/png" href="/images/favicon.svg">
<title>Project 1: Basic Drawing and Interaction</title>
</head>
<body>
<header>
<a href="#main" class="vh">Jump directly to main content</a>
<h1 style="font-size: 2.4rem">Project 1: Basic Drawing and Interaction</h1>
<input id="burger-toggle" type="checkbox"/>
<label class="burger-container" for="burger-toggle"><div class="burger"></div><span class="sr">Burger menu</span></label>
<hr/>
<nav>
<a href="/">home</a>
<a href="/about.html">about</a>
<a href="/projects.html">projects</a>
<a href="/blog/">blog</a>
<a href="/sitemap.html">misc</a>
<a href="/support.html">support</a>
</nav>
<hr/>
</header>
<main id="main">
<p>Switching away from the server-side stuff after getting the stack setup, I've opted to the basic game 'drawn', and 'playable', if you can call it those.</p>
<h2>Drawing</h2>
<p>Since I'm using JS and HTML canvas I need to draw each shape onto the canvas setting each individual shapes co-ordinates and size. This sounds simple, but the more shapes you draw, and the more you don't want them to overlap, or to add zoomed in/out shapes it gets much more complicated than you'd think. This is a prime example of why a solid grasp on basic mathematics is good for developers.</p>
<h3>Shape class</h3>
<p>Repeating the setting of context data, and the drawing of each shape became tedious and took a big chunk of my code-base after not long, so I decided to simplify by creating a Path2D extended class.</p>
<pre class="pre--small"><code>class Shape extends Path2D{
constructor(params){
super();
this.shape = params.shape || 'rectangle';
this.name = params.name;
this.x = params.x || 0;
this.y = params.y || 0;
this.width = params.width || 0;
this.height = params.height || 0;
this.fillStyle = params.fillStyle || "#FFFFFF";
}
draw(){
context.fillStyle = this.fillStyle;
if(this.shape == 'circle'){
context.beginPath();
context.arc(this.x, this.y, this.width/2, 0, 2 * Math.PI);
context.fill();
context.closePath();
}else if(this.shape == 'semi'){
context.beginPath();
context.arc(this.x, this.y, this.width/2, Math.PI, 0);
context.fill();
context.closePath();
}else if (this.shape == 'rectangle'){
context.fillRect(this.x, this.y, this.width, this.height);
}
context.fillStyle = defaultFillStyle; // Reset back to default
}
}</code></pre>
<p>Pretty simple, I pass the shape I want to draw, x,y co-ordinates, width and height, and the fill. Not included above, but the class also accepts, and draws the shape stroke.</p>
<p>I then call the draw method of the new Shape, and it sorts everything for me.</p>
<h2>Interaction with Event Handlers</h2>
<p>Next up, for the game to be a game and not just some visual media, we need to be able to interact with it.</p>
<p>Basic interaction is simple enough, I threw in a 'click' EventListener, then take the event/click's X/Y position and subtract the canvas's offset from the HTML body (to have 0,0 set to the top-left of the canvas, and not the HTML page).</p>
<p>This new X/Y, which I will just call X/Y is then compared to the X/Y locations of each shape. If the event X/Y occurs in a location greater (or equal) than the shape X/Y, and less than (or equal) Shape X/Y plus the shape Width/Height I then do whatever action I require.</p>
<p>This is another thing I've simplified by creating a function:</p>
<pre class="pre--small"><code>function clickableCheck(x,y,shape){
if(
y > shape.y && y < shape.y + shape.height
&& x > shape.x && x < shape.x + shape.width)
{
return true;
}
return false;
}</code></pre>
<p>The function above is even simpler too, as all you need to do to check for a click, is pass a Shape object, created by the Shape class earlier in this post!</p>
<p>Fun Fact! Shape here, is actually called clickable in my code-base, but I've changed it to make more sense without context.</p>
</main>
<footer>
<hr/>
<p>Written by <a href="https://aney.co.uk" target="_blank" rel="noopener">@aney</a> with <a href="https://danluu.com/web-bloat/" target="_blank" rel="noopener">web bloat</a> in mind | <a href="https://github.com/Aney/website" target="_blank" rel="noopener">Source Code</a></p>
</footer>
</body>
</html>