my_blog/public/tech_demos/demos/svg_pong.html

314 lines
9.8 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>chmod777's SVG Pong</title>
<meta name="description" content="">
<meta name="author" content="chmod777">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta property="og:type" context="website">
<meta property="og:title" context="chmod777's SVG Pong">
<meta property="og:description" context="">
<meta property="og:url" context="http://tilde.club/~chmod777/tech_demos/demos/svg_pong.html">
<meta property="og:image" context="http://tilde.club/~chmod777/favicon.svg">
<meta property="og:local" context="en-US">
<meta property="og:site_name" context="tilde.club">
<meta property="twitter:card" context="summary">
<meta property="twitter:title" context="chmod777's SVG Pong">
<meta property="twitter:description" context="">
<meta property="twitter:url" context="http://tilde.club/~chmod777/tech_demos/demos/svg_pong.html">
<meta property="twitter:image" context="http://tilde.club/~chmod777/favicon.svg">
<link rel="canonical" href="http://tilde.club/~chmod777/tech_demos/demos/svg_pong.html">
<link rel="stylesheet" href="/css/styles.css">
<script src="/assets/js/main.js"></script>
</head>
<body class="dark-theme" onload="first_load()">
<header>
<h1 id="title">chmod777's SVG Pong</h1>
<a href="#page-content">skip to page content</a>
<p>There is a version of this site available as a <a href="gemini://tilde.club/~chmod777">gemini capsule</a>. It may or may not be up to date.</p>
<nav>
<ul class="link-list">
<li><a href="/">home</a></li>
<li><a href="/blog/blog.html">blog</a></li>
<li><a href="/projects/projects.html">projects</a></li>
<li><a href="/tech_demos/tech_demos.html">tech demos</a></li>
</ul>
</nav>
</header>
<form>
<fieldset>
<legend aria-describedby="about-accessibility-options">Accessibility Options</legend>
<p id="about-accessibility-options">accessibility options requires javascript</p>
<script>
const id = "about-accessibility-options";
const element = document.getElementById(id);
element.innerHTML = element.innerHTML.concat(" (javascript enabled)");
</script>
<label id="color-theme-label" for="color-theme">color theme</label>
<select id="color-theme" name="color-theme">
<option value="dark-theme">dark (default)</option>
<option value="classic-theme">classic</option>
<!--
<option value="high-contrast-theme">high contrast</option>
-->
</select>
<label id="fonts-label" for="fonts">fonts</label>
<select id="fonts" name="fonts">
<option value="default-font">browser default (default)</option>
<option value="monospace-font">monospace</option>
<!--
<option value="comic-sans-font">Comic Sans</option>
-->
</select>
<input type="button" value="apply settings" onclick="apply_accessibility_options()">
</fieldset>
</form>
<main id="page-content">
<asside id="about-pong">
<header>
<h2>The Game of Pong</h2>
</header>
<section>
</section>
<footer>
</footer>
</asside>
<div id="main-content">
<article>
<header>
<h2>About This Project</h2>
<p>About three years ago(2018) I created this little project. I have
recently brushed away most of the bugs so here is my Pong clone which uses
Scalable Vector Graphics(SVG).</p>
<p>Some resources related to SVGs.</p>
<ul>
<li><a href="https://www.wikipedia.org/svg">Wikipedia article</a></li>
<li><a href="https://mdn/">Mozilla documentation</a></li>
</ul>
</header>
<h3>Just Why</h3>
<p>The main reason for this project was to learn about SVG and SVG
animations. Before starting this I had never used an SVG in my own
websites. My only interactions with them is seeing them used on other
websites and the one time I opened up InkScape. Back in the days when I
cared about fancy websites I was envious of the cool animations some
folks had and wanted them for myself.</p>
<p>The other thing that motivated me to create a game was seeing the 13k game
jam. A jam that only accepts games whos entire contents fit in 13kb
including all their assets. I had only heard about it after it was already
over that year but that wasn't going to stop me from creating a tiny
game.</p>
<p>Why Pong?</p>
<p>Pong is second only to Tetris and I had never really played it. Plus I thought I
could actually finnish the project if it was a clone of a simple game.</p>
<h3>Was it a Success?</h3>
<p>Partially. I did create a game that used an SVG image instead of an
HTMLCanvas. I learned how to manipulate the elements with the transform
attribute from JavaScript, as well as us an animateMotion tag to move the
ball along a path.</p>
<p>As a bonus the game was 9kb when compressed when I had "finnished it".
That included the svg, html, and transpiled typescript.</p>
<p>However the game wasn't finnished when I stopped working on it three years
ago but I feel I achieved my goal. Or rather the pong game took me as far
as it could on my SVG adventure. Or at least that's what I thought back
then...</p>
<h3>The Revitalized SVG Pong</h3>
<p>What you see below is the new and improved SVG Pong, with far fewer bugs,
a cleaner(TM) codebase, and better preformace.</p>
<p>I revisted this project because I thought it would be fun. That really is
the main reason. And guess what. It was fun. I got to track down weird
bugs related to collisions and missing state. The project truely was just
slapped together over a weekend and it showed.</p>
<p>Try to have fun against the restless AI.</p>
<p>If you like SVGs checkout some of my <a href="/projects/project/creative_commons_icons.html">SVG icons</a> I made for a now defunct project.</p>
<footer>
</footer>
</article>
<p>fps: <span id="fps"></span></p>
<svg viewBox="0 0 532 276" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Pong</title>
<desc>Two paddles, a ball, vertical dashed line in the center, and two numbers for player scores.</desc>
<defs>
<linearGradient id="pong-gradient" x1="0%" y1="0%" x2="100%" y2="0%">
<stop id="pong-gradiant-begin" offset="0%" />
<stop id="pong-gradiant-end" offset="100%" />
</linearGradient>
</defs>
<rect id="pong-boarder" width="100%" height="100%" />
<svg x="10" y="10" width="512" height="256" >
<rect id="pong-board" width="100%" height="100%" />
<path id="pong-ball-path" d="M256 128" />
<path id="pong-collision-path" d="M256 128" />
<line id="pong-center-line" x1="256" y1="0" x2="256" y2="256" />
<rect id="pong-player-paddle" width="2" height="28" transform="translate(0, 114)"/>
<rect id="pong-ai-paddle" width="2" height="28" transform="translate(510, 114)"/>
<text id="pong-player-score" class="pong-score" x="85.33" y="64">0</text>
<text id="pong-ai-score" class="pong-score" x="426.66" y="64">0</text>
<circle id="pong-ball" r="3">
<animateMotion id="pong-ball-animation" dur="1.0s" repeatCount="indefinite">
<mpath xlink:href="#pong-ball-path"/>
</animateMotion>
</circle>
</svg>
<style>
#pong-gradiant-begin {
stop-color:blue;
stop-opacity:1;
}
#pong-gradiant-end {
stop-color:red;
stop-opacity:1;
}
#pong-boarder {
fill:url(#pong-gradient);
}
#pong-board {
fill:black;
}
#pong-ball-path {
stroke:blue;
}
#pong-collision-path {
stroke:red;
stroke-dasharray:1;
}
#pong-center-line {
stroke:white;
stroke-dasharray:5;
stroke-width:2;
}
#pong-ai-paddle,#pong-player-paddle,.pong-score {
fill:white;
}
.pong-score {
font-family:'Courier New',Courier,monospace;font-size:2em;
}
#pong-ball {
fill:white;
}
</style>
</svg>
<form>
<fieldset>
<legend>Controlls</legend>
<summary>Each button has a keyboard shortcut.</summary>
<br>
<div>
<label id="pong-reset-label" for="pong-reset">New Game shortcut 'N'</label>
<input id="pong-reset" name="pong-reset" type="button" value="New Game">
<label id="pong-serve-label" for="pong-serve">Serve shortcut 'S'</label>
<input id="pong-serve" name="pong-serve" type="button" value="Serve">
<label id="pong-paddle-up-label" for="pong-paddle-up">Paddle Up shortcut '&#x3c'</label>
<input id="pong-paddle-up" name="pong-paddle-up" type="button" value="Paddle Up">
<label id="pong-paddle-stop-label" for="pong-paddle-stop"></label>
<input id="pong-paddle-stop" name="pong-paddle-stop" type="button" value="Paddle Stop">
<label id="pong-paddle-down-label" for="pong-paddle-down">Paddle Down shortcut '>'</label>
<input id="pong-paddle-down" name="pong-paddle-down" type="button" value="Paddle Down">
</div>
</fieldset>
</form>
<form>
<fieldset>
<legend>Game Settings</legend>
<summary></summary>
<div>
<label for="ai-difficulty">AI Difficulty</label>
<select id="ai-difficulty" name="ai-difficulty">
<option value="easy">easy</option>
<option value="normal">normal</option>
<option value="hard">hard</option>
</select>
<label for="paddle-speed">Paddle Speed</label>
<input type="slider" id="paddle-speed" name="paddle-speed">
<label for="ball-speed">Ball Speed</label>
<input type="slider" id="ball-speed" name="ball-speed">
</div>
<input type="button" value="Apply Settings(starts a new game)">
</fieldset>
</form>
<table>
<summary>Game Summary</summary>
<tr>
<td>Difficulty</td>
<th>Won</th>
<th>Lost</th>
<th>Tied</th>
<th>Incomplete</th>
<th>Longest Volley</th>
</tr>
<tr>
<th>Easy</th>
</tr>
<tr>
<th>Normal</th>
</tr>
<tr>
<th>Hard</th>
</tr>
</table>
<table>
<summary>Latest Games</summary>
<tr>
<th>Difficulty</th>
<th>Won/Lost/Tied/Incomplete</th>
<th>Player Score</th>
<th>AI Score</th>
<th>Longest Volley</th>
</tr>
</table>
</div>
</main>
<footer>
<a class="link-padding" href="#">jump to top</a>
<br>
<br>
<a class="link-padding" id="page-source" target="_blank" href="https://tildegit.org/chmod777/my_blog">page source (tildegit in new tab)</a>
</footer>
</body>
</html>