Доброго времени суток, уважаемые хаброжители.
На днях у меня появилась идея написать Game Boy, на чистом CSS.
После того как Game Boy был реализован, прибывая на codepen, поступали разные интересные предложения, о том, как бы оживить его.
По мере того как Game Boy приобретал своих сторонников, я решил опубликовать статью: «Как я написал Game Boy » и подключил эмулятор.
Рабочая версия Дубасим: в старый добрый «Mario».
Среда для разработки Sublime text и webkit браузер.
Работа оказалась абсолютно не сложная, скорее увлекательная.

Полагаю, вы хорошо знакомы с CSS, Javascript, HTML5, и вам не составит труда разобраться в моей писанине.
В HTML разметке присутствуют комментарии к дивам.
1. HTML, Javascript
В представленном ниже коде, я не буду упоминать про резет, либо нармолайз цсс.
Так же я опустил префиксы, чтобы сэкономить время.
2. CSS
Надеюсь, вам было интересно.
На днях у меня появилась идея написать Game Boy, на чистом CSS.
После того как Game Boy был реализован, прибывая на codepen, поступали разные интересные предложения, о том, как бы оживить его.
По мере того как Game Boy приобретал своих сторонников, я решил опубликовать статью: «Как я написал Game Boy » и подключил эмулятор.
Рабочая версия Дубасим: в старый добрый «Mario».
Среда для разработки Sublime text и webkit браузер.
Работа оказалась абсолютно не сложная, скорее увлекательная.

Полагаю, вы хорошо знакомы с CSS, Javascript, HTML5, и вам не составит труда разобраться в моей писанине.
В HTML разметке присутствуют комментарии к дивам.
1. HTML, Javascript
<body>
<div class="wrapper"> Тело геймбоя, я поместил под элементом враппер, мозила и експлорер, почему-то игнорируют градиентный бекгаунд у элемента body (если в родителе есть потомок с абсолютным позиционированием.) Решение проблемы я не нашел, по сему пришлось сделать вот такую мутку .
<p>by ANTON ESSENTIAL</p>
</div>
<div class="gameboy"> Тело геймбоя
<hr class="l-1">
<hr class="l-2">
<hr class="l-3">
<hr class="l-4">
<hr class="l-5">
<hr class="l-6">
<hr class="l-7">
<hr class="l-8">
<p>dot matrix with stereo sound</p>
<div class="reflex">
<div class="display-2"></div> Дисплей
<canvas id="LCD" width='147' height='134'></canvas> Дисплей
<div class="display"></div> Див с эффектом (эффект пластика на дисплеей)
<span class="diod"></span> Диод
</div>
<ul class="buttons"> <b>Кнопки (А.B)</b>
<li></li>
<li></li>
</ul>
<ul class="buttons-2"><b> Кнопки (Start, Select)</b>
<li class='start' onclick='gb_Run();'></li>
<li class='pause' disabled onclick='gb_Pause();'></li>
</ul>
<ul class="speacker"> Динамик
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<div class="stick"> Стик
<ul class="left">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="right">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="top">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="bottom">
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
</ul>
<ul class="circle">
<li></li>
</ul>
</div>
</div>
<select id="CARTRIDGE" row='1' onchange='gb_Insert_Cartridge(this.value,true);'> Селектор образов (картриджы)
<option value="Super-Mario-Land.gb">Super-Mario-Land</option>
<option value="mc-mrder.gb">PD mc-mrder</option>
<option value="20y.gb">PD 20y</option>
<option value="wario_walking.gb">PD wario_walking</option>
</select><br>
<input id='BR' type="button" value='Run' onfocus='this.blur();' onclick='gb_Run();'> Управление
<input id='BP' type="button" value='Pause' onfocus='this.blur();' disabled onclick='gb_Pause();'>
<input id='BS' type="button" value='Step' onfocus='this.blur();' onclick='gb_Step();'>
<input id="BS" type="button" value="Reset" onfocus="this.blur();" onclick="gb_Insert_Cartridge($('CARTRIDGE').value,true);"/>
<input id='BX' type="button" value='Size x2' onfocus='this.blur();' onclick='gb_Resize_LCD();'>
<div id="DEBUGGER"></div>
<script type='text/javascript' src='js/cssrefresh.js'></script>
<script type='text/javascript' src='js/jquery-1.10.2.min.js'></script>
<script type='application/x-javascript' src='js/toolbox.js'></script>
<script type='application/x-javascript' src='js/scrollbar.js'></script>
<script type='application/x-javascript' src='js/jsgb.cpu.js'></script>
<script type='application/x-javascript' src='js/jsgb.memory.js'></script>
<script type='application/x-javascript' src='js/jsgb.rom.js'></script>
<script type='application/x-javascript' src='js/jsgb.interrupts.js'></script>
<script type='application/x-javascript' src='js/jsgb.input.js'></script>
<script type='application/x-javascript' src='js/jsgb.lcd.js'></script>
<script type='application/x-javascript' src='js/jsgb.timers.js'></script>
<script type='application/x-javascript' src='js/jsgb.debugger.js'></script>
<script type='application/x-javascript' src='js/jsgb.gameboy.js'></script>
<script type='application/x-javascript'> Ресайз дисплея
var gbSeconds = 0;
var gbFrames = 0;
function gb_Resize_LCD() {
if($('BX').value=='Size x2') {
$('BX').value='Size x3';
$('LCD').style.width='320px';
$('LCD').style.heght='288px';
}
else if($('BX').value=='Size x3') {
$('BX').value='Size x1';
$('LCD').style.width='480px';
$('LCD').style.heght='432px';
}
else {
$('BX').value='Size x2';
$('LCD').style.width='147px';
$('LCD').style.heght='134px';
}
}
function gb_Show_Fps() {
gbFrames+=gbFPS;
gbSeconds++;
$('STATUS').innerHTML =
'Running: '+gbFPS+' '+
'fps - Averenge: '+(gbFrames/gbSeconds).toFixed(2)+' - '+
'Bank switches/s: '+gbBankSwitchCount;
gbFPS=0;
gbBankSwitchCount=0;
}
function gb_Toggle_Debugger(show) {
$('DEBUGGER').style.heght=(show)?'auto':'0px';
}
window.onload = function(){
gb_Insert_Cartridge($('CARTRIDGE').value, false);
gb_Toggle_Debugger($('TOGGLE_DEBUGGER').checked);
}
</script>
<script> По событию клик, появляется канвас [дисплей]
jQuery(function($) {
$('.start').click(function(){
$('#LCD').fadeIn(1);
});
});
</script>
</body>
</html>
В представленном ниже коде, я не буду упоминать про резет, либо нармолайз цсс.
Так же я опустил префиксы, чтобы сэкономить время.
2. CSS
body {
background: rgb(32, 32, 32);
}
.wrapper {
position: relative;
top: 50px;
width: 100%;
height: 645px;
background-image: linear-gradient(-32deg,#e41717, #72075c 78%);
-webkit-filter: blur(2px);
}
.gameboy {
position: absolute;
top: 150px;
left: 200px;
width: 265px;
height: 433px;
border: 2px solid rgb(153, 153, 153);
border-radius: 10px 10px 77px 10px;
background-image: -webkit-linear-gradient(#adb6b3, #bec2c1 50%);
box-shadow: -5px 6px 20px rgba(0, 0, 0, 0.46),
-21px 17px 65px rgba(0, 0, 0, 0.46),
inset 3px 0 10px #616465,
inset -3px 0 4px #8e918e,
inset -7px 0 7px #dfdfdf,
inset 1px 0px 3px #66696a,
inset 0 3px 7px #919496,
inset 0 4px 10px white;
}
.wrapper p {
position: relative;
top: 511px;
left: 534px;
display: inline-block;
color: white;
font-weight: bold;
font-size: 26px;
font-family: "Arial"
}
.gameboy p {
position: absolute;
top: 45px;
left: 85px;
z-index: 2;
color: rgba(255, 255, 255, 0.63);
text-transform: uppercase;
font-size: 7px;
font-family: "Arial"
}
.reflex {
position: relative;
top: 36px;
left: 15px;
overflow: hidden;
width: 232px;
height: 177px;
border-top: 1px solid #3d4844;
border-right: 1px solid #3d4844;
border-bottom: 1px solid #1d2120;
border-left: 2px solid rgba(29, 33, 32, 0.57);
border-radius: 10px 10px 53px 10px;
background: #485055;
box-shadow: inset 0 1px 1px #aab3b0,
0 1px 0 #5b5e63,
0 2px 0 #ebebeb,
1px 0 2px #d3d3d3,
-1px 0 2px #cfcfcf,
inset -1px 0 2px rgba(255, 255, 255, 0.44);
}
.display {
position: absolute;
z-index: 3;
width: 232px;
height: 177px;
border-radius: 10px 10px 53px 10px;
background-image: -webkit-linear-gradient(46deg, rgba(72, 80,85, 0), rgba(143, 151, 156, 0.58)80%);
}
.display-2 {
position: absolute;
top: 21px;
left: 43px;
z-index: 2;
width: 147px;
height: 134px;
border-top: 1px solid #394b21;
border-right: 1px solid #36472f;
background: #5f953d;
box-shadow: inset -2px 5px 10px #2a421a;
opacity: .5;
}
#LCD {
display: none;
position: absolute;
top: 21px;
left: 43px;
}
.l-1 {
position: absolute;
top: 11px;
width: 265px;
height: 3px;
border: none;
border-radius: 50px;
background-image: -webkit-linear-gradient(#87928d, #a9b2af 90%);
opacity: .6;
}
.l-2 {
position: absolute;
top: -8px;
left: 20px;
width: 3px;
height: 19px;
border: none;
border-radius: 5px 5px 0 0;
background-image: -webkit-linear-gradient(#a9b2af, #87908d 90%);
opacity: .6;
}
.l-3 {
position: absolute;
top: -8px;
right: 20px;
width: 3px;
height: 19px;
border: none;
border-radius: 5px 5px 0 0;
background-image: -webkit-linear-gradient(#a9b2af, #87908d 90%);
opacity: .6;
}
.l-4 {
position: absolute;
top: 36px;
left: 26px;
z-index: 2;
width: 51px;
height: 3px;
border: none;
background: #543363;
}
.l-5 {
position: absolute;
top: 42px;
left: 26px;
z-index: 2;
width: 51px;
height: 3px;
border: none;
background: #30345a;
}
.l-6 {
position: absolute;
top: 36px;
left: 217px;
z-index: 2;
width: 20px;
height: 3px;
border: none;
background: #543363;
}
.l-7 {
position: absolute;
top: 42px;
left: 217px;
z-index: 2;
width: 20px;
height: 3px;
border: none;
background: #30345a;
}
.l-8 {
position: absolute;
display: none;
}
.diod {
position: absolute;
top: 61px;
left: 12px;
display: block;
width: 9px;
height: 9px;
border: 1px solid #ac774d;
border-radius: 50px;
background: #e4b443;
box-shadow: 0 0 5px #ac774d,
-1px 1px 1px rgba(83, 53, 41, 0.99),
inset 0 1px 2px #fcb251;
-webkit-animation:light linear 3s infinite;
}
.buttons {
position: absolute;
top: 242px;
left: 179px;
padding: 6px;
border-radius: 50px;
box-shadow: 1px 1px 5px rgba(255, 255, 255, 0.21),
-1px 1px 0px #babdbc,
inset 0 12px 22px rgba(0, 0, 0, 0.12);
-webkit-transform: rotate(64deg);
}
.buttons li {
width: 30px;
height: 30px;
border: 1px solid rgba(68, 32, 54, 1);
border-radius: 100%;
background-image: linear-gradient(6deg,rgba(133, 50, 108, 0.61),#6d1851 89%);
box-shadow: inset 1px 2px 4px #a87493,
-1px -1px 2px #000,
3px 6px 7px rgba(125, 136, 134, 0.79);
}
.buttons li:first-child {
margin-bottom: 17px;
}
.buttons-2 {
position: absolute;
top: 348px;
left: 103px;
-webkit-transform: rotate(64deg);
}
.buttons-2 li {
position: absolute;
width: 9px;
height: 34px;
border-radius: 50px;
background-image: linear-gradient(269deg, #6f7875, #9b9b9b 71%);
box-shadow: 1px 1px 1px rgba(226, 226, 226, 0.97),
-1px -1px 2px #767a79,
inset 1px 1px 1px #a3aca9;
}
.buttons-2 li:last-child {
position: absolute;
bottom: 7px;
left: 20px;
}
.speacker {
position: absolute;
top: 344px;
left: 174px;
-webkit-transform: rotate(64deg);
}
.speacker li {
margin-bottom: 8px;
width: 42px;
height: 6px;
border-radius: 10px;
box-shadow: 1px 1px 1px rgba(255, 255, 255, 0.7),
inset 2px 1px 3px #5b5a53,
inset 1px -1px black;
}
.stick {
position: absolute;
top: 252px;
left: 14px;
width: 93px;
height: 93px;
border-radius: 50%;
box-shadow: inset -7px 10px 22px #c7cbca,
inset 7px -10px 22px #b8b8b8;
}
.top {
position: absolute;
top: 15px;
left: 34px;
width: 24px;
height: 21px;
border-radius: 2px 2px 0 0;
background-image: linear-gradient(90deg,#282c2b, #9b9b9b 119%);
box-shadow: 1px -1px 1px rgb(53, 53, 53),
-4px 3px 7px rgba(96, 96, 98, 0.64);
}
.top li {
margin: 2px;
width: 20px;
height: 2px;
border-radius: 2px;
background: #353837;
box-shadow: inset 0 -1px 1px #494c4b;
}
.left {
position: absolute;
top: 36px;
left: 56px;
width: 24px;
height: 22px;
border-radius: 2px 2px 0 0;
background-image: linear-gradient(303deg,#282c2b, #9b9b9b 111%);
box-shadow: 1px -1px 1px rgb(53, 53, 53);
-webkit-transform: rotate(90deg);
}
.left li {
margin: 2px;
width: 20px;
height: 2px;
border-radius: 2px;
background: #353837;
box-shadow: inset 0 -1px 1px #494c4b;
}
.bottom {
position: absolute;
top: 58px;
left: 34px;
width: 24px;
height: 21px;
border-radius: 0 0 2px 2px;
background-image: linear-gradient(55deg,#131716, #6a706f 147%);
box-shadow: -5px 0px 6px #606362;
}
.bottom li {
margin: 2px;
width: 20px;
height: 2px;
border-radius: 2px;
background: #050908;
box-shadow: inset 0 -1px 1px #343839;
}
.right {
position: absolute;
top: 36px;
left: 12px;
width: 24px;
height: 22px;
border-radius: 0 0 2px 2px;
background-image: linear-gradient(290deg,#131716, #6a706f 173%);
box-shadow: 2px 3px 7px rgb(53, 53, 53);
-webkit-transform: rotate(90deg);
}
.right li {
margin: 2px;
width: 20px;
height: 2px;
border-radius: 2px;
background: #050908;
box-shadow: inset 0 -1px 1px #433839;
}
.circle {
position: absolute;
top: 36px;
left: 35px;
z-index: 5;
width: 22px;
height: 22px;
background-image: linear-gradient(-134deg, #656666, #2e3231 60%);
}
.circle li {
position: absolute;
top: 2px;
left: 2px;
width: 16px;
height: 16px;
border: 1px solid rgba(39, 42, 41, 0.91);
border-radius: 16px;
background: #4b4e4d;
box-shadow: inset 2px -1px 8px #868787,
inset 3px -1px 10px black;
}
@-webkit-keyframes light {
0% {
box-shadow: 0 0 0 #ffa300;
}
50% {
box-shadow: 0 0 24px #ffa300;
}
100% {
box-shadow: 0 0 0 #ffa300;
}
}
#DEBUGGER {
visibility: hidden;
}
.start:hover,
.pause:hover {
cursor: pointer;
}
input, select {
position: relative;
top: 100px;
}
Надеюсь, вам было интересно.