Provide the source code of a microcontroller or tiny computer in JavaScript. Node.js-based computers are supported. Require f3js
package and use its API to design the device enclosure.
var useJoystick = false; // ジョイスティックを使う
var groveSensor = require('jsupm_grove');
var button = new groveSensor.GroveButton(2);
var upmBuzzer = require("jsupm_buzzer");
var buzzer = new upmBuzzer.Buzzer(3);
var buzzer_volume = 50; // ブザーのボリューム [0, 100]
buzzer.setVolume(buzzer_volume / 100);
buzzer.stopSound();
var jsupm_joystick = require('jsupm_joystick12');
var joystick = new jsupm_joystick.Joystick12(0, 1);
var upm_grove = require('jsupm_grove');
var groveRotary = new upm_grove.GroveRotary(0);
var LCD = require("jsupm_i2clcd");
var lcd = new LCD.Jhd1313m1(6, 0x3E, 0x62);
var f3js = require('f3js')
, c = f3js.createContainer()
, x = 10
, y = 10
, width = 160
, height = 105
, thickness = 42
, jw = 7 /* かみ合わせ幅 [5, 10] */
, jh = 2 /* 板厚[mm] [1, 5] */;
c.x = x;
c.y = y;
// 表の面を作る
var p = c.jrc(0, 0, width, height, jw, jh);
/*
// 上記は次のコードと同じ
//var p = c.drawJointRectangle(0, 0, width, height, jw, jh);
// または次のコードと同じ
var p = c.createPath();
p.moveTo(0, 0);
p.jointTo(width, 0, jw, jh);
p.jointTo(width, height, jw, jh);
p.jointTo(0, height, jw, jh);
p.jointTo(0, 0, jw, jh);
p.close();
*/
// 表面にいろいろ配置する
c.add(lcd, { x: 81, y: 40 });
c.add(button, { x: 20, y: 85, rotation: 90 });
c.add(buzzer, { x: 140, y: 20, rotation: 90 });
if (useJoystick) {
c.add(joystick, { x: 140, y: 80, rotation: 90 });
} else {
c.add(groveRotary, { x: 140, y: 85 });
}
// 配線用の穴を開ける
// Buzzer
c.drawRectangle(135, 35, 10, 6);
c.drawRectangle(133, 13, 14, 14);
// Button
c.drawRectangle(15, 64, 10, 6);
c.drawRectangle(13, 78, 14, 14);
if (useJoystick) {
// Joystick
c.drawRectangle(135, 49, 10, 6);
c.drawRectangle(133, 63, 14, 34);
c.drawRectangle(130, 63, 20, 26);
} else {
// RotaryAngleSensor
c.drawRectangle(135, 64, 10, 6);
c.drawRectangle(133, 78, 14, 14);
}
// 側面と裏面を作る
var ps = p.extrude(45);
ps[0].x = width + 5;
ps[0].y = jh;
ps[1].x = width + 5;
ps[1].y = (thickness + 5) * 2 + jh;
ps[2].x = width + 5;
ps[2].y = thickness + 5 + jh;
ps[3].x = width + 5;
ps[3].y = (thickness + 5) * 3 + jh;
ps[4].x = 0; // 最後の要素が裏面
ps[4].y = height + 5; // 表の面の真下に配置する
for (var i = 0; i < ps.length; i ++) {
c.add(ps[i]);
}
// // 側面の一つに電源用の穴を開ける
ps[1].drawRectangle(jh + 5, thickness - jh - 5, height - jh*2 - 10, -10);
// 以降はゲームのソースコード
var iv_idle = false;
var iv_game = false;
var iv_gameover = false;
var timelimit_sec = 30; /* 制限時間 [10, 60] */
var count = 0;
var prev_button_val = 0;
var prev_prev_button_val = 0;
var score = 0;
function startIdle() {
lcd.setColor(255, 255, 255);
lcd.setCursor(0,0);
lcd.write(' Mogura Tataki ');
lcd.setCursor(1,0);
lcd.write(' Push Button ');
if (iv_gameover) {
clearInterval(iv_gameover);
iv_gameover = false;
}
iv_idle = setInterval(function() {
if (count >= 16) {
lcd.setCursor(0,0);
lcd.write(' Mogura Tataki ');
count = 0;
} else if (count >= 8) {
lcd.setCursor(0,0);
lcd.write(' Whack a Mole ');
count++;
} else {
count++;
}
if (prev_button_val == 0 && button.value() > 0) {
buzzer.playSound(upmBuzzer.DO, 100000);
buzzer.stopSound();
clearInterval(iv_idle);
iv_idle = false;
startGame();
}
prev_button_val = button.value();
}, 100);
}
function stopGame() {
console.log("time up");
console.log("score: " + score);
buzzer.playSound(upmBuzzer.DO, 100000);
buzzer.stopSound();
lcd.setColor(255, 255, 255);
lcd.setCursor(0,0);
lcd.write(' ');
lcd.setCursor(0,0);
lcd.write(' Score : ' + score);
lcd.setCursor(1,0);
lcd.write(' Time Up ');
if (iv_game) {
clearInterval(iv_game);
iv_game = false;
}
setTimeout(function() {
iv_gameover = setInterval(function() {
if (count >= 16) {
lcd.setCursor(1,0);
lcd.write(' Push Button ');
count = 0;
} else if (count >= 8) {
lcd.setCursor(1,0);
lcd.write(' Game Over ');
count++;
} else {
count++;
}
if (prev_button_val == 0 && button.value() > 0) {
buzzer.playSound(upmBuzzer.DO, 100000);
buzzer.stopSound();
clearInterval(iv_gameover);
iv_gameover = false;
startIdle();
}
prev_button_val = button.value();
}, 100);
}, 3000);
}
function startGame() {
var arr_mole = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
var mole_count_max = 5;
var mole_count = mole_count_max;
var time_count_max = timelimit_sec * 10;
var time_count = 0;
prev_button_val = 0;
prev_prev_button_val = 0;
score = 0;
var pos = 0;
iv_game = setInterval(function() {
if (useJoystick) {
if (joystick.getYInput() + 0.685 < -0.05 && pos > 0) {
pos--;
} else if (joystick.getYInput() + 0.685 > 0.05 && pos < 15) {
pos++;
}
} else {
pos = 15 - Math.floor(groveRotary.abs_value() / (1024 / 16));
}
if (time_count >= time_count_max) {
// time over
stopGame();
} else {
time_count++;
// add_mole
if (mole_count >= mole_count_max) {
var changes = Math.floor(Math.random() * 5 + 1);
for (i = 0; i < changes; i++) {
var place = Math.floor(Math.random() * 16);
if (arr_mole[place] == 0) {
arr_mole[place] = 1;
} else {
arr_mole[place] = 0;
}
}
mole_count = 0;
} else {
mole_count++;
}
// whack
if ((prev_prev_button_val == 0 || prev_button_val == 0) && button.value() > 0 && arr_mole[pos] == 1) {
arr_mole[pos] = 2;
score++;
console.log("score = " + score);
if (score % 10 == 0) {
buzzer.playSound(upmBuzzer.DO, 100000);
buzzer.playSound(upmBuzzer.MI, 100000);
buzzer.stopSound();
if (mole_count_max > 1) {
mole_count_max--;
console.log("mole_count_max = " + mole_count_max);
}
} else {
buzzer.playSound(upmBuzzer.DO, 100000);
buzzer.stopSound();
}
}
// background color
hoge = Math.floor(Math.pow(time_count/time_count_max, 2)*255);
lcd.setColor(255, 255-hoge, 255-hoge);
// disp
for (i = 0; i < 16; i++) {
lcd.setCursor(0,i);
if (arr_mole[i] == 1) {
lcd.write('O');
} else if (arr_mole[i] == 2) {
lcd.write('X');
arr_mole[i] = 0;
} else {
lcd.write(' ');
}
lcd.setCursor(1,i);
if (i == pos) {
lcd.write('T');
} else {
lcd.write(' ');
}
}
}
prev_prev_button_val = prev_button_val;
prev_button_val = button.value();
}, 100);
}
startIdle();
process.on('SIGINT', function() {
if (iv_idle) {
clearInterval(iv_idle);
}
if (iv_game) {
clearInterval(iv_game);
}
if (iv_gameover) {
clearInterval(iv_gameover);
}
lcd.setColor(255, 255, 255);
process.exit(0);
});