alanhc 互動技術-week16
alanhc 互動技術-week16
December 26, 2019
多人遊戲的電子鼓v1
server 端程式
處理socket及routing(express)
serverjs.js
let express = require('express'); let app = express(); let server = app.listen(3000); app.use(express.static('public')) console.log("My socket server is running"); let socket = require('socket.io'); let io = socket(server); io.sockets.on('connection', newConnection); let player=0; let playerList=[]; let nowHost=0; function newConnection(socket) { playerList.push(socket.id); player++; socket.broadcast.emit('players',player); socket.broadcast.emit('hoster name',playerList[nowHost]); socket.on('disconnect', ()=>{ --player; socket.broadcast.emit('players',player); playerList = playerList.filter( (value, index, arr)=> value!=socket.id ); }); socket.on('send pattern', (patternIn)=>{ socket.broadcast.emit('answer pattern',patternIn); }); //console.log(playerList.length); } setInterval(function() { io.local.emit('players',player); io.local.emit('hoster name',playerList[nowHost]); //console.log(nowHost); }, 100); setInterval(function() { if (nowHost>playerList.length-2) nowHost=0; else nowHost++; }, 4*4*1000); let nowBeat=0; setInterval(function() { nowBeat++; nowBeat%=8; io.local.emit('beat',nowBeat); }, 500); |
client端
public資料夾
- index.html 處理首頁配置
- player.js 處理播放音樂(Tone.js)
- sketch.js主程式
index.html
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tone/13.0.1/Tone.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"> </script>
<script src="https://unpkg.com/p5.touchgui@0.5.2/lib/p5.touchgui.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
<script language="javascript" type="text/javascript" src="player.js"></script>
<script language="javascript" type="text/javascript" src="serial.js"></script>
<script >
</script>
<style> body { padding: 0; margin: 0; } </style>
</head>
<body>
</body>
</html>
<html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <script language="javascript" type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/p5.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.10.2/addons/p5.sound.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/13.0.1/Tone.min.js" type="text/javascript"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"> </script> <script src="https://unpkg.com/p5.touchgui@0.5.2/lib/p5.touchgui.js"></script> <script language="javascript" type="text/javascript" src="sketch.js"></script> <script language="javascript" type="text/javascript" src="player.js"></script> <script language="javascript" type="text/javascript" src="serial.js"></script> <script > </script> <style> body { padding: 0; margin: 0; } </style> </head> <body> </body> </html> |
player.js
let myPattern = [
[0,0,0,0,0,0,0,0], //bd
[0,0,0,0,0,0,0,0], //cr
[0,0,0,0,0,0,0,0], //hh
[0,0,0,0,0,0,0,0], //t1
[0,0,0,0,0,0,0,0], //t2
]
let ansPattern = [
[0,0,0,0,0,0,0,0], //bd
[0,0,0,0,0,0,0,0], //cr
[0,0,0,0,0,0,0,0], //hh
[0,0,0,0,0,0,0,0], //t1
[0,0,0,0,0,0,0,0], //t2
]
let bdrum;
let crash;
let hh_c;
let tom1;
let tom2;
//let totalBeat=0;
//Tone.Transport.scheduleRepeat(playBeat, "0.5s");
Tone.Buffer.on('load', play);
let img_bdrum;
let img_cymbals;
let img_drum;
function preload() {
bdrum = new Tone.Player('assets/80s-Bdrum1.mp3');
crash = new Tone.Player('assets/80s-CRASH1.mp3');
hh_c = new Tone.Player('assets/80s-HHCLOSE1.mp3');
tom1 = new Tone.Player('assets/80s-TOM1.mp3');
tom2 = new Tone.Player('assets/80s-TOM2.mp3');
bdrum.toMaster();
crash.toMaster();
hh_c.toMaster();
tom1.toMaster();
tom2.toMaster();
img_bdrum = loadImage('assets/bdrum.png');
img_cymbals = loadImage('assets/cymbals.png');
img_drum = loadImage('assets/drum.png');
}
function play() {
Tone.Transport.start();
}
function keyTyped() {
if (key>0&&key<6) ansPattern[key-1][steps]=1;
}
function playBeat(steps, pattern) {
if (pattern[0][steps] == 1) {
bdrum.start();
}
if (pattern[1][steps] == 1) {
crash.start();
}
if (pattern[2][steps] == 1) {
hh_c.start();
}
if (pattern[3][steps] == 1) {
tom1.start();
}
if (pattern[4][steps] == 1) {
tom2.start();
}
}
sketch.js
let myPattern = [ [0,0,0,0,0,0,0,0], //bd [0,0,0,0,0,0,0,0], //cr [0,0,0,0,0,0,0,0], //hh [0,0,0,0,0,0,0,0], //t1 [0,0,0,0,0,0,0,0], //t2 ] let ansPattern = [ [0,0,0,0,0,0,0,0], //bd [0,0,0,0,0,0,0,0], //cr [0,0,0,0,0,0,0,0], //hh [0,0,0,0,0,0,0,0], //t1 [0,0,0,0,0,0,0,0], //t2 ] let bdrum; let crash; let hh_c; let tom1; let tom2; //let totalBeat=0; //Tone.Transport.scheduleRepeat(playBeat, "0.5s"); Tone.Buffer.on('load', play); let img_bdrum; let img_cymbals; let img_drum; function preload() { bdrum = new Tone.Player('assets/80s-Bdrum1.mp3'); crash = new Tone.Player('assets/80s-CRASH1.mp3'); hh_c = new Tone.Player('assets/80s-HHCLOSE1.mp3'); tom1 = new Tone.Player('assets/80s-TOM1.mp3'); tom2 = new Tone.Player('assets/80s-TOM2.mp3'); bdrum.toMaster(); crash.toMaster(); hh_c.toMaster(); tom1.toMaster(); tom2.toMaster(); img_bdrum = loadImage('assets/bdrum.png'); img_cymbals = loadImage('assets/cymbals.png'); img_drum = loadImage('assets/drum.png'); } function play() { Tone.Transport.start(); } function keyTyped() { if (key>0&&key<6) ansPattern[key-1][steps]=1; } function playBeat(steps, pattern) { if (pattern[0][steps] == 1) { bdrum.start(); } if (pattern[1][steps] == 1) { crash.start(); } if (pattern[2][steps] == 1) { hh_c.start(); } if (pattern[3][steps] == 1) { tom1.start(); } if (pattern[4][steps] == 1) { tom2.start(); } } |
let socket; let players; let host; let myId; let serverIp='192.168.1.109:3000'; let state; function setup() { createCanvas(windowWidth,windowHeight); background(220); socket = io('http://'+serverIp); //change server ip here socket.on('players', (num)=>{ players=num; }); socket.on('hoster name', (hostInput)=>{ host=hostInput; if (host==myId) { socket.emit('send pattern', myPattern); } }); socket.on('answer pattern', (patternIn)=>{ ansPattern=patternIn; }); let init_myPattern=false; let init_ansPattern=false; socket.on('beat', (stepsIn)=>{ havePlayed=false; playBeat(steps, ansPattern); steps=stepsIn; if (host!=myId) { // now is play mode state='play'; myPattern= [ [0,0,0,0,0,0,0,0], //bd [0,0,0,0,0,0,0,0], //cr [0,0,0,0,0,0,0,0], //hh [0,0,0,0,0,0,0,0], //t1 [0,0,0,0,0,0,0,0], //t2 ] init_myPattern=false; } else { // now is host mode state='host'; playBeat(steps, myPattern); ansPattern= [ [0,0,0,0,0,0,0,0], //bd [0,0,0,0,0,0,0,0], //cr [0,0,0,0,0,0,0,0], //hh [0,0,0,0,0,0,0,0], //t1 [0,0,0,0,0,0,0,0], //t2 ] if (!init_myPattern) { myPattern= [ [0,0,0,0,0,0,0,0], //bd [0,0,0,0,0,0,0,0], //cr [0,0,0,0,0,0,0,0], //hh [0,0,0,0,0,0,0,0], //t1 [0,0,0,0,0,0,0,0], //t2 ] init_myPattern=true; } } //console.log(state); }); } let steps; let havePlayed; function draw() { myId=socket.id; if (key>0 && key<6 && keyIsPressed && state=='host') { myPattern[key-1][steps]=1; if (!havePlayed) { playBeat(steps, myPattern); havePlayed=true; } } if (state=='host') background(255,0,0,10); else background(0,128,220); let spaceW=windowWidth/9; let spaceH=windowHeight/7; let shW=spaceW/2; let shH=spaceH; fill(0); textSize(16); text('online: '+players, shW, shH/3); text('Host : '+host, shW, shH/2); text('state: '+ state, shW, shH/1.5); for (let i=0; i<8; i++) { for (let j=0; j<5; j++) { if (myPattern[j][i]==1) { let minW=Math.min(spaceH,spaceW); switch(j) { default: break; case 0: image(img_bdrum, shW+spaceW*i, shH+spaceH*j, minW,minW); break; case 1:case 2: image(img_cymbals, shW+spaceW*i, shH+spaceH*j, minW,minW); break; case 3: case 4: image(img_drum, shW+spaceW*i, shH+spaceH*j, minW,minW); } fill(0,30); } else if (ansPattern[j][i]==1) { fill(150); let minW=Math.min(spaceH,spaceW); switch(j) { default: break; case 0: image(img_bdrum, shW+spaceW*i, shH+spaceH*j, minW,minW); break; case 1:case 2: image(img_cymbals, shW+spaceW*i, shH+spaceH*j, minW,minW); break; case 3: case 4: image(img_drum, shW+spaceW*i, shH+spaceH*j, minW,minW); } } else { fill(255); } //rect(shW+spaceW*i, shH+spaceH*j, spaceW,spaceH); //draw player } fill(255,255,0,10); rect(shW+steps*spaceW,shH,spaceW,spaceH*5); stroke(0); } } |
device
#include "CurieIMU.h" void setup() { Serial.begin(9600); // initialize Serial communication while (!Serial); // wait for the serial port to open // initialize device Serial.println("Initializing IMU device..."); CurieIMU.begin(); // Set the accelerometer range to 2G CurieIMU.setAccelerometerRange(2); } void loop() { float ax, ay, az; CurieIMU.readAccelerometerScaled(ax, ay, az); Serial.print("a:\t"); Serial.print(ax); Serial.print("\t"); Serial.print(ay); Serial.print("\t"); Serial.print(az); Serial.println(); } |
目前實驗到:
serial連線 https://editor.p5js.org/alanhc/sketches/ILrZMsoO7
深度學習訓練 https://editor.p5js.org/alanhc/sketches/FmNlDsPjv
介面調整及測試 https://editor.p5js.org/alanhc/sketches/Tpc-lw1Xi
可至15週筆記看實驗