【暑假記憶】消暑神器,我用CSS復刻了一個遊戲機
theme: qklhk-chocolate highlight: atelier-dune-light
“我正在參加「初夏創意投稿大賽」詳情請看:初夏創意投稿大賽”
夏日回憶
我小時候,家裡的庭院有一棵枝繁葉茂的樹,那時候家裡沒有空調,夏天會在樹蔭下鋪個席子,或是午睡,或是看書。後來,家裡給我買了一臺掌上游戲機,那個時候還挺奢侈的。於是,暑假大部分時間都是在俄羅斯方塊的旋轉、移動中度過的。
我用CSS復刻了一個遊戲機
記憶中的遊戲機已經模糊了,於是我搜索了一下游戲機的圖片。尤其卡通圖片,圓乎乎的真可愛。遊戲機的主體和螢幕是矩形的,按鍵是圓形或者圓角矩形。有趣又比較好實現。
所以我便用CSS復刻了一個遊戲機。
碼上掘金
“碼上掘金”可以線上進行程式碼效果的即時預覽、演示,非常方便。下面是遊戲機的預覽。 https://code.juejin.cn/pen/7101709588033961991
UI展示
機體
- 遊戲機的主體是一個矩形,帶有邊框和弧度;
- 為了呈現立體感,通過box-shadow遊戲機主體設定了向外的陰影;
css
js
.player {
width: 280px;
height: 460px;
background: #ffc600;
border: 6px solid #5a1f12;
border-radius: 15px 15px 45px 15px;
position: relative;
box-shadow: 30px 20px 10px 10px #9e988b;
}
html
```js
```
聽筒
掌上游戲機在玩遊戲的時候,會有音效,所以我設計了一個聽筒。
- 聽筒是一個平面圓角矩形,通過設定border-radius的值可以實現兩邊的圓角;
css
js
.head {
width: 100%;
height: 26px;
position: absolute;
top: 0;
left: 0;
border-bottom: 5px solid #5a1f12;
}
.head::before {
content: '';
width: 6px;
height: 26px;
background: #5a1f12;
position: absolute;
top: 0;
left: 20px;
}
.head::after {
content: '';
width: 6px;
height: 26px;
background: #5a1f12;
position: absolute;
top: 0;
right: 20px;
}
.receiver {
width: 50px;
height: 8px;
background: #eba260;
border: 4px solid #5a1f12;
border-radius: 8px;
position: absolute;
top: 5px;
left: 35px;
}
html
```js
```
螢幕
螢幕除了邊框之外,顯示部分由兩個內容構成,開機前和開機後,兩個不共存。
開機前
- 開機前展示綠色的螢幕和反光效果,我小時的遊戲機螢幕是淺綠色的,這個我還有點印象;
- 反光效果,主要是為了增加趣味性和表現螢幕的光亮感。我將反光效果設計為一個白條從螢幕上方移動到下方,這個效果通過animation實現;
css
js
.screen {
width: 220px;
height: 170px;
background: #9c6766;
border: 5px solid #5a1f12;
border-radius: 10px 10px 30px 10px;
position: absolute;
top: 40px;
left: 50%;
margin-left: -115px;
}
.monitor {
width: 180px;
height: 120px;
background: #d5eabd;
border: 5px solid #5a1f12;
margin: 20px auto;
position: relative;
overflow: hidden;
}
.monitor .light {
width: 20px;
height: 220px;
background: #e2f0d8;
position: absolute;
top: -33px;
left: -23px;
transform: rotate(44deg);
animation: monitorlight 3s infinite;
}
@keyframes monitorlight {
50% {
left: 80%;
}
51% {
left: 80%;
opacity: 1;
}
61% {
left: 80%;
opacity: 0.3;
}
71% {
left: 80%;
opacity: 1;
}
81% {
left: 80%;
opacity: 0.3;
}
91% {
left: 80%;
opacity: 1;
}
100% {
left: 80%;
opacity: 1;
}
}
html
```js
```
開機後
- 開機後展示俄羅斯方塊的介面,包括左側的遊戲區域和右側的遊戲記錄兩個部分;
- 遊戲區域目前僅實現展示遊戲名稱的功能;
css
js
.screen .game {
width: 190px;
height: 150px;
background: #d5eabd;
border-radius: 10px 10px 30px 10px;
margin: 10px auto;
display: none;
}
.game .left {
float: left;
width: 52%;
height: 128px;
border: 1px solid #333;
margin: 10px 0 0 10px;
position: relative;
}
.game .game-name {
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
color: #000;
line-height: 1;
background: rgba(158, 174, 134, 0.8);
justify-content: center;
display: none;
}
.game .game-name .name-box {
animation: 1.5s linear gamename forwards;
font-size: 15px;
padding: 54px 0 0 10px;
}
@keyframes gamename {
30% {
opacity: 0.3;
}
60% {
opacity: 1;
}
90% {
opacity: 0.3;
}
91% {
opacity: 1;
}
100% {
opacity: 1;
}
}
.game .left-content {
position: absolute;
top: 10px;
left: 8px;
}
.game .left-box .integral-block.b {
border: 2px solid #333;
}
.game .left-box .integral-block.b::after {
background: #333;
}
.game .right {
float: right;
width: 30%;
font-size: 12px;
font-weight: 300;
text-align: left;
line-height: 1.5;
padding: 10px;
color: #000;
}
.game .integral-num {
font-size: 13px;
font-weight: 500;
text-align: right;
}
.game .integral-graph {
position: relative;
}
.game .integral-box {
position: relative;
height: 14px;
width: 40px;
}
.game .integral-box .integral-block {
border: 2px solid #333;
}
.game .integral-box .integral-block::after {
background: #333;
}
.game .integral-block {
display: block;
width: 6px;
height: 6px;
padding: 1px;
border: 2px solid #9eae86;
margin: 0 2px 2px 0;
float: left;
}
.game .integral-block::after {
content: '';
display: block;
width: 6px;
height: 6px;
background: #9eae86;
overflow: hidden;
}
.game .integral-box1 {
top: 4px;
left: 13px;
}
.game .integral-box2 {
top: 7px;
left: 27px;
}
html
```js
; ```
分割線
- 分割線為了更好區分螢幕和按鍵兩個區域;
- 包括左右兩個橫向和中間六個點;
css
js
.dividing {
width: 100%;
height: 24px;
display: flex;
justify-content: space-between;
align-items: center;
position: absolute;
top: 220px;
left: 0;
}
.dleft {
width: 50px;
height: 5px;
background: #5a1f12;
margin-left: 30px;
border-radius: 5px;
}
.dcenter {
display: flex;
}
.dspot {
width: 3px;
height: 5px;
background: #5a1f12;
margin-right: 3px;
border-radius: 3px;
}
.dright {
width: 80px;
height: 5px;
background: #5a1f12;
margin-right: 30px;
border-radius: 5px;
}
html
```js
; ```
按鍵
- 上下左右操作按鍵,由圓和十字圖形組成,十字圖形通過橫向和豎向的矩形組成,為了增加立體感,十字的矩形添加了外部的陰影;
- 開始按鍵,右側傾斜的圓角矩形上側的紅色圓點為開始按鍵,點選之後,螢幕點亮並展示內容,同時開始按鍵不可重複點選,停止按鍵可以點選;
- 停止按鍵右側傾斜的圓角矩形下側的紅色圓點為開始按鍵,點選之後,螢幕關閉展示綠色螢幕,同時停止按鍵不可重複點選,開始按鍵可以點選;
- 聲音按鍵,底部兩個圓角矩形為聲音按鍵;
css
js
.push-direction {
width: 80px;
height: 80px;
background: #ee9731;
border: 4px solid #5a1f12;
border-radius: 50%;
position: absolute;
top: 260px;
left: 15px;
}
.push-direction::before {
content: '';
width: 54px;
height: 20px;
background: #7b4a45;
position: absolute;
top: 30px;
left: 13px;
box-shadow: 0 -3px 0 0 #fff;
border-radius: 5px;
}
.push-direction::after {
content: '';
width: 20px;
height: 54px;
background: #7b4a45;
position: absolute;
top: 13px;
right: 30px;
box-shadow: 0 -3px 0 0 #fff;
border-radius: 5px;
}
.push-control {
width: 36px;
height: 80px;
background: #eb9430;
border: 4px solid #5a1f12;
border-radius: 40px;
position: absolute;
top: 260px;
right: 35px;
transform: rotate(55deg);
}
.push-control .begin,
.push-control .stop {
width: 26px;
height: 26px;
line-height: 26px;
text-align: center;
color: #fff;
background: #ff4822;
position: absolute;
left: 6px;
box-shadow: inset 0 3px 0 0 #fff;
border-radius: 50%;
font-size: 13px;
cursor: pointer;
}
.push-control .begin {
top: 10px;
}
.push-control .stop {
top: 45px;
}
.push-sound {
width: 16px;
height: 50px;
background: #864949;
position: absolute;
top: 350px;
border: 2px solid #5a1f12;
border-radius: 16px;
box-shadow: inset 3px 0 0 0 #fff;
transform: rotate(60deg);
}
.push-sound::before {
content: '';
width: 24px;
height: 4px;
background: #5a1f12;
position: absolute;
bottom: 21px;
left: 12px;
border-radius: 4px;
transform: rotate(-90deg);
}
.push-sound-top {
left: 80px;
}
.push-sound-bottom {
left: 140px;
}
html
```js
```
js
```js var leftBox = document.getElementsByClassName('left-box'); var pushBegin = document.getElementById('pushBegin'); var pushStop = document.getElementById('pushStop'); var monitor = document.getElementById('monitor'); var game = document.getElementById('game'); var gameName = document.getElementById('gameName');
// 螢幕展示方法 function show() { monitor.style.display = 'none'; game.style.display = 'block'; // 設定開始按鈕不可以點選 pushBegin.disabled = false; // 設定關閉按鈕可以點選 pushStop.disabled = true; setTimeout(function () { for (var i = 0; i < leftBox.length; i++) { var block = leftBox[i].getElementsByClassName('integral-block'); for (var j = 0; j < block.length; j++) { block[j].classList.add('b'); } } }, 800); setTimeout(function () { gameName.style.display = 'block'; }, 1500); }
// 螢幕停止方法 function stop() { monitor.style.display = 'block'; game.style.display = 'none'; // 設定開始按鈕可以點選 pushBegin.disabled = true; // 設定關閉按鈕不可以點選 pushStop.disabled = false; for (var i = 0; i < leftBox.length; i++) { var block = leftBox[i].getElementsByClassName('integral-block'); for (var j = 0; j < block.length; j++) { block[j].classList.remove('b'); } } } pushBegin.onclick = show; pushStop.onclick = stop; ```
總結
這次用CSS實現兒時的遊戲機,帶給我很多啟發,一大批卡通形象匯聚到了我的大腦中,等我有時間慢慢實現。
創作的過程真的很有意思,程式碼成了我的畫筆,作為一個不擅長繪畫但是喜歡卡通的人,程式碼幫助我實現了想實現的畫作。(^▽^)
不過,還有兩個功能待實現。第一個是按行點亮方塊的功能,另一個是俄羅斯方塊遊戲的開發。前面這個最近在探索中。後面的功能,演算法是我的短板,也希望未來能補足。
- await-to-js 原始碼分析,體驗一把捕獲異常的優雅
- CSS偽類的第三集,原來偽類也可組CP
- 從:is()說起,開啟CSS偽類第二集
- 一組純CSS開發的聊天背景圖,幫助避免發錯訊息的尷尬
- 「CSS特效」我的發呆專屬,反覆解鎖手機螢幕
- 「技術分享」以Antd為例,快速打通UI元件開發的任督二脈
- 「功能實現」我封裝了一個表單元件,感覺離財富自由又近了一步
- 「經驗總結」高效開發,老程式碼可以這樣動
- 前端開發提效小技巧之業務功能篇
- 人生有忙忙碌碌,也有詩和遠方 | 2022年中總結
- 【端午節】新奇體驗,我用react實現網頁遊戲的全過程(包括規則設計)
- 【暑假記憶】消暑神器,我用CSS復刻了一個遊戲機
- 突圍?我願稱之為向上的攀登者
- 【孟夏之遇】望孟夏之短夜兮,螢星相伴
- 【技術學習】SVG-邊學邊做
- 【TS實踐】自己動手豐衣足食的TS專案開發
- 【碼上掘金】通過FileReader讀取Excel檔案內容
- 【Taro開發】四月芳菲,Taro觀賞指南
- 【Node.js】青梅煮酒,聊聊zlib壓縮
- 【知識點】關於iframe跨域通訊