314 lines
9.8 KiB
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 '<'</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>
|