iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 20
4
IoT

IoT沒那麼難!新手用JavaScript入門做自己的玩具~系列 第 21

[Day 20]-用JS控制Arduino吧!小財神啊!你看見那個鐵人在惡搞iT邦熊俠嗎?Johnny Five 之 光敏電阻- 小遊戲(?)應用篇

  • 分享至 

  • xImage
  •  

IoT沒那麼難!新手用 JavaScript 入門做自己的玩具!(iT邦幫忙鐵人賽系列書)

★本系列文章已集結成冊,和系列文不同的是:

  • 本書使用大量的圖解來說明LED系列、多種感測器等原理。
  • 補足系列文程式碼的解說,增加逐行程式碼的詳細解說!
  • 全彩的書籍,用圖解的方式,讓讀者來理解Johnny-Five各種API的功能與效果,讓你不會只讀文字看到想睡覺而學不起來。

歡迎大家做出自己想要的玩具,為了樂趣而學習,讓學習變成你的樂趣!ヽ(・×・´)ゞ
讓Arduino也能用JavaScript創造出屬於自己的作品!

★購書連結-天瓏網路書局:
https://www.tenlong.com.tw/products/9789864345328

《IoT沒那麼難!新手用 JavaScript 入門做自己的玩具!(iT邦幫忙鐵人賽系列書)》
博客來、金石堂、momo、誠品、PChome、讀冊,均有販售喔!─=≡Σ((( つ•̀ω•́)つ
ISBN:9789864345328

上篇 本來想做中二的小夜燈的 ......
但我看到光敏電阻的輸出數值後,突然覺得好像可以做更有(ㄨˊ)趣(ㄩㄥˋ)的東西XDDD

下音樂~
登登楞登~登登~ (多拉A夢的音效)

『 Flappy iT-Bear 』 (☝ ՞ਊ ՞)☝

小財神不要打我

謎之音:這蝦.....餃朋友啦XD
本魯:我果然是很無聊的魯宅啊~科科~

不過做出來有莫名的成就感,現在就跟著我一起浪費才能吧~ヽ(・×・´)ゞ

故事是這樣開始的.......

寫完光敏電阻後,心裡覺得有點空虛....
就這麼剛好每天都會在 iT 邦幫忙鐵人賽看到,有個野生的小熊(?)在那邊上上下下的動...

突然靈光一閃 (✪ω✪)
如果用光敏電阻的連續數值,應該可以做的像 Flappy Bird 一樣的遊戲吧XDD

於是....就是決定是你啦!(ΦωΦ)

身為一個開發者,要抓熊是很簡單的
把 Dev Tool 打開後一個 Move 小熊就被我 Download 下來了 (  ̄ 3 ̄)y▂ξ

身為一個開發者擁有好奇心是 hen 正常
抓完熊後,順便看一下這網頁裡面有什麼東西~

本魯心裡OS:
這個網頁做(ㄙㄨˋ)的(ㄘㄞˊ)不(ㄏㄣˇ)錯(ㄉㄨㄛ)耶~
嗯~這山 這草 這場景都不錯耶~我全都要了 ლ(╹◡╹ლ)

怎麼玩?想法是這樣的~

我的想法是熊俠會像 flappy bird 的動作機制。

flappy bird需要點擊才會飛一下,


(flappy bird 遊戲方法)

熊俠則是光照一下才會飛一下,如果沒有光照就飛不起來~

知道要怎麼遊戲後,來設計場景舞台!

那先從網頁解構來看~

現在我們有草、小熊、背景,
就可以做出小熊從草叢飛起來的假象XD
利用 CSS 的 Z 軸 順序,依序把場景物件給定位好~

快速的切好後,網頁長這樣子 ↓↓↓


沒有廣告費的工商時間:

想更快速的切好版嗎?每天20分鐘內讓你學到大絕招!
趕快訂閱 Amos老師 的(a.k.a CSSCoke)
金魚都能懂的這個網頁畫面怎麼切 - 金魚都能懂了你還怕學不會嗎 系列
讓你切版比我快!


接下來要進入程式啦~(๑•̀ㅂ•́)و✧

後端部分

昨天一樣,我們取光敏電阻的數值加上用 Socket.io 傳給前端接收;
唯一要改的是偵測的頻率可以改快一點,我就設0.25秒輸出一次數值好了~

小熊的動作就由前端來處理 d( ・∀・)b

  photoresistor = new five.Sensor({
    pin: 'A0',
    freq: 250, // 頻率改快
  });

後端程式碼

var io = require('socket.io');
var express = require('express');
var five = require('johnny-five');

var board = new five.Board();
var app = express();

app.use(express.static('www'));
var server = app.listen(3000, function() {
  console.log('connected!');
});

var sio = io(server);

board.on('ready', function() {
  photoresistor = new five.Sensor({
    pin: 'A0',
    freq: 250, // 改成0.25秒輸出一次數值
  });

  sio.on('connection', function(socket) {
    photoresistor.on('data', function() {
      // 取得數值
      pVal = this.value;
   
      // 透過socket傳給Clinet端(前端)
      socket.emit('startData', {
        pVal: pVal,
      });
    });
  });
});

前端部分

先說讓小熊看起來像飛起來的關鍵是
CSS 的 position 定位,待會會講到~
先了解一下HTML的架構。

HTML

<body>
  <div class="bg">
    <div class="top"></div>
    <div class="bear"><img src="img/bear-fly.svg" alt="" /></div>
    <div class="footer"><img src="img/footerbg.png" alt="" /></div>
    <div class="bell">
      <p>訂閱下去 - IoT沒那麼難!新手用JavaScript入門做自己的玩具~</p>
    </div>
  </div>
  <script src="/socket.io/socket.io.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  <script src="index.js"></script>
</body>

最外層的 <div class="bg"> 為父層,
絕對定位position:relative在網頁的左上角 {top:0; left:0;} 的地方;

<div class="bg">
<!-- 先設定好絕對定位 position:relative; 讓小熊之後以相對定位來使用-->
  <div class="top"></div>
  <div class="bear"><img src="img/bear-fly.svg" alt="" /></div>
  <div class="footer"><img src="img/footerbg.png" alt="" /></div>
  <div class="bell">
    <p>訂閱下去 - IoT沒那麼難!新手用JavaScript入門做自己的玩具~</p>
  </div>
</div>

再由子層<div> → top、bear、footer
相對定位position: absolute;在 父層<div class="bg"> 上。

<!-- 定位點依附著 <div class="bg"> -->
  <div class="top"></div>
  <div class="bear"><img src="img/bear-fly.svg" alt="" /></div>
  <div class="footer"><img src="img/footerbg.png" alt="" /></div>

CSS Style

.bg {
  position: relative;
  width: 100vw;
  height: 100%;
  top: 0;
  left: 0;
}
.top {
  position: absolute;
  width: 100%;
  height: 100vh;
  top: 0;
  left: 0;
  background: url('img/background.jpg');
  background-repeat: no-repeat;
  background-origin: border-box;
  background-position: center;
  background-size: cover;
}
.bear {
  position: absolute;
  width: 100px;
  height: auto;
  /* top: 0; */
  left: 50%;
  transition-duration: 0.5s;
}
.footer {
  position: absolute;
  width: 100vw;
  height: auto;
  top: 70%;
  left: 0%;
}

把 top、bear、footer 依照相對位置 position: absolute; 定位後

小熊要上下動像超人一樣飛行,
我們利用 改變 CSS 的 top 數值 讓小熊上下動作~

Demo
改變 CSS 的 top 數值,也就是改變熊的 Y 軸定位。

謎之音:可是小熊看起來 頓ㄉㄟ 頓ㄉㄟ 的欸......
本魯:這是另外一個關鍵點啦~

CSS有一個屬性叫 transition-duration -「轉場動畫時間」

MDN:CSS - transition-duration
https://developer.mozilla.org/zh-TW/docs/Web/CSS/transition-duration

我們改變小熊的 top 數值時,沒有設定轉場延遲看起來畫面會鈍鈍的!
藉由設定 transition-duration 的時間來延遲轉場動畫,這樣動作看起來會比較順暢~


解決完小熊的飛行動作後,做到這邊也差不多半成品啦~ ( ´Д´)y━・~
接下來是前端 JavaScript 的部分 (ง๑ •̀_•́)ง

JavaScript

var socket = io.connect();

socket.on('startData', function(data) {
  // 當socket開始連線時,接收資料
  tempData = data.pVal;
  // 把接收到的值變成百分比
  topPosition = tempData / 10;
  // 有時候數值會超過100,可處理可不處理
  if (topPosition >= 100) {
    topPosition = 100;
  }
  // 調用jQuery的.css()函式來改變熊的垂直定位
  $('.bear').css('top', '' + topPosition + '%');
});

程式碼比 CSS 還要簡單 XD

現在我們把光敏電阻的數值當成熊的 CSS top 定位數值,
隨著光照的強度而改變數值,熊的top定位點也跟著改變,
就能隨之呈現 flappy bird 的動作啦~

昨天結尾的實驗,
已知光敏電阻的數值大約在 1000 ~ 100 之間,
前端接收到的 Value 除上 10 轉換成百分比即可。

  // 原始數值
  tempData = data.pVal;
  // 把接收到的值變成百分比
  topPosition = tempData / 10;
  // 有時候數值會超過100,可處理可不處理
  if (topPosition >= 100) {
    topPosition = 100;
  }

最後一步啦~(ง๑ •̀_•́)ง

為了讓熊固定出現在視窗裡飛,且動的幅度大一點~
CSS的top數值,單位我們採用百分比單位 %
百分比是彈性的數值,會因為視窗的大小而計算改變,剛好符合需求。

最後只要用 jQuery 的 .css() 函式一直呼叫改變熊的垂直定位數值就可以囉~ヽ(・×・´)ゞ

//第一個參數填CSS屬性名稱(propertyName),第二個參數填上數值(value)
$('.bear').css('top', '' + topPosition + '%');

補充連結:

jquery - .css()
https://api.jquery.com/css/#css-propertyName-value

這樣就完成啦! (*´∀´)~♥
超簡單又無用的小玩具XD


寫完了然後呢?

因為有時間的關係又是 IoT 組,想說做一些 Sensor 和網頁連動的東西,所以就沒有繼續寫一些遊戲裡的障礙物物件了....

如果有空再繼續寫JS,讓熊俠IoT遊戲像 flappy bird 遊戲水一樣碰到水管就Game Over,我們可以把水管換成寫鐵人文的時間啦、寫鐵人賽時會出現的立志句子啦~那就更好玩了XD

想像力就是超能力

邦友-挖洗菜呱的鐵人文
每日挖個坑,用坑填起耍廢聊天室!」系列

看到邦友用 Socket 讓多名 User 一起連線聊天,
啟發我甚至可以製作各種 Sersor 的闖關遊戲~
利用 Socket 讓多名 User 連線一起玩抽 Sensor 闖不同的關卡,是不是一種商機呢?

(才不會勒~(寫文寫到腦洞大開.....
我有個大膽的想法(´≖◞౪◟≖)

想玩玩的朋友可以試試看喔~
完整的程式碼都在我的Github上~
d(d'∀')

文後

前端工程師的生活,往往就是這麼樸實無華,且枯燥~
然後做出一些無用的東西....XD


本系列的程式碼皆會上傳到 GitHub 上開源

2019ironman-JS-IoT :
https://github.com/tinatyc/2019ironman-JS-IoT

喜歡按個星星吧~乾蝦乾蝦<(_ _)>


團隊系列文:

CSScoke - 金魚都能懂的這個網頁畫面怎麼切 - 金魚都能懂了你還怕學不會嗎
Hina Hina - 陣列大亂鬥
阿斬 - Python 程式交易 30 天新手入門
Clarence - LINE bot 好好玩 30 天玩轉 LINE API
塔塔默 - 用Python開發的網頁不能放到Github上?Lektor說可以!!
Vita Ora - 好 Js 不學嗎 !? JavaScript 入門中的入門。


同步連載於blogger-King 學習前端之人生


上一篇
[Day 19] -用JS控制Arduino吧!聖光啊!你看見那個鐵人了嗎?Johnny-Five 之 光敏電阻 Photoresistor
下一篇
[Day 21]-用JS控制Arduino吧!喵的一個Move!Hold住你的動作 - Johnny Five 之 Motion 動作感測器
系列文
IoT沒那麼難!新手用JavaScript入門做自己的玩具~33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
ShawnL
iT邦新手 1 級 ‧ 2019-10-05 12:11:07

看到這篇文章之後,
我媽問我家裡怎麼多了一個 Arduino 板子。 XD (?

一起來掉坑~XDDDDD/images/emoticon/emoticon39.gif

dick iT邦新手 5 級 ‧ 2019-10-07 11:25:55 檢舉

滿酷的應用ㄟ,讓我想好好學一下Javascript、CSS、HTML(只知道名詞不知道是什麼)哈哈!但是目前還沒有時間

哈哈 歡迎大大一起掉進這個大坑XDDD

我要留言

立即登入留言