基本情報

このページではIoTコンテンツ(カード合わせゲーム)をベースにして、新しいコンテンツを「フォーク」できます。フォークしたコンテンツは、プロジェクトの一覧ページに新しい項目として表示されます。元の項目を上書きしたい場合は編集してください。

※写真URLは.jpg, .jpeg, .pngのいずれかで終わるもの、またはGyazoへアップロードされたページのURL(https://gyazo.com/hogehogeなど)に対応しています。

※IoTコンテンツの説明、エントリポイントに関する情報 main: index.js およびf3jsモジュールへの依存情報 dependencies: { f3js: (略) } は、この欄の内容とマージされるため記入不要です。

カードのプレビュー
カード合わせゲーム
'16/9/18 8:33
神経衰弱ゲームが遊べます
arc@dmz

プライベートコンテンツ

チェックを外すと、このコンテンツはすぐ一覧に公開され、誰でもアクセスできるようになります。 なるべくコンテンツを共有していただきたいので、チェックは初めから外れています。また、ログインしていない状態ではチェックをつけられません。 一度公開されたコンテンツは、プライベートにできません。(一度チェックを外すと、以降そのコンテンツを編集するときにはチェックをつけられなくなります。)

ソースコード

マイコン・小型コンピュータのプログラムのソースコードを記述してください。f3jsパッケージをrequireすることで筐体設計が可能です。詳しくはAPIドキュメントをご覧ください。

//upmを編集したため、ダウンロードするだけでは動作しません //#ビルド方法 //arduinoの端末上で //$ cd /usr/lib/node/jsupm_i2clcd //$ mv jsupm_i2clcd.node jsupm_i2clcd.node.old //$ wget --no-check-certificate 'https://drive.google.com/uc?export=download&id=0B4Hp2uhJD5H7dHBBMWdGcmktSzQ' -O jsupm_i2clcd.node //#元に戻す場合 //$ cd /usr/lib/node/jsupm_i2clcd //$ rm -f jsupm_i2clcd.node //$ mv jsupm_i2clcd.node.old jsupm_i2clcd.node var var32783 = true; // Audio feedback var singlePlayer = false; // Single player-mode var var03670 = singlePlayer ? 1 : 2; // プレイ人数 var upmBuzzer = require("jsupm_buzzer"); var groveSensor = require('jsupm_grove'); var LCD = require("jsupm_i2clcd"); var joystick = require('jsupm_joystick12'); var tm1637 = require('jsupm_tm1637'); var myBuzzer = new upmBuzzer.Buzzer(6); var display = new tm1637.TM1637(0,1); var sw = new groveSensor.GroveButton(4); var lcd = new LCD.Jhd1313m1 (6, 0x3E, 0x62); if(var03670 == 1) { var js = [new joystick.Joystick12(0,1)]; } else { var js = [new joystick.Joystick12(0,1), new joystick.Joystick12(2,3)]; } if(var03670 == 1) { var button = [new groveSensor.GroveButton(2)]; } else { var button = [new groveSensor.GroveButton(2), new groveSensor.GroveButton(3)]; } var f3js = require('f3js') , c = f3js.createContainer() , x = 10 , y = 10 , width = 160 , height = 105 , thickness = 42 , jw = 7 , jh = 2; c.x = x; c.y = y; var f3js_contr = require('f3js') , c_contr1 = f3js_contr.createContainer() , x_contr1 = 340 , y_contr1 = 10 , c_contr2 = f3js_contr.createContainer() , x_contr2 = 395 , y_contr2 = 10 , width_contr = 140 , height_contr = 50 , thickness_contr = 23 , jw_contr = 7 , jh_contr = 2; c_contr1.x = x_contr1; c_contr1.y = y_contr1; c_contr2.x = x_contr2; c_contr2.y = y_contr2; // 本体側 // 表の面を作る var p = c.jrc(0, 0, width, height, jw, jh); // 表面にいろいろ配置する c.add(lcd, { x: 80 + 0, y: 30 + 0 }); c.add(sw, { x: 140, y: 40 }); c.add(myBuzzer, { x: 40, y: 70 }); // 配線用の穴を開ける c.drawRectangle(136, 33, 8, 2); c.drawRectangle(134, 38, 12, 10); if(var03670 == 2) { c.drawRectangle(135, 89, 10, 10); } c.drawRectangle(15, 89, 10, 10); c.drawRectangle(88.5, 61.5, 32, 17); c.drawCircle(113, 60, 2); c.drawCircle(113, 80, 2); c.drawCircle(83, 70, 2); c.drawCircle(70, 155.5, 1.5); c.drawCircle(70, 183, 1.5); // 側面と裏面を作る 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, -13); // コントローラ側 // 表面 var p_contr1 = c_contr1.jrc(0, 0, height_contr, width_contr, jw_contr, jh_contr); var p_contr2 = c_contr2.jrc(0, 0, height_contr, width_contr, jw_contr, jh_contr); // 側面と裏面 var ps_contr1 = p_contr1.extrude(23); ps_contr1[0].x = -height_contr - 5; ps_contr1[0].y = (thickness + 5) * 2 + jh_contr; ps_contr1[1].x = -width_contr - 5; ps_contr1[1].y = width_contr * 2 - thickness_contr * 2 + 5; ps_contr1[2].x = -height_contr - 5; ps_contr1[2].y = (thickness + 5) * 2 + thickness_contr + jh_contr * 2; ps_contr1[3].x = -width_contr - 5; ps_contr1[3].y = width_contr * 2 - thickness_contr + jh_contr + 5; ps_contr1[4].x = 0; ps_contr1[4].y = width_contr + 5; for (i = 0; i < ps_contr1.length; i ++) { c_contr1.add(ps_contr1[i]); } var ps_contr2 = p_contr2.extrude(23); ps_contr2[0].x = (-height_contr - 5) * 2; ps_contr2[0].y = (thickness + 5) * 2 + thickness_contr * 2 + jh_contr * 3; ps_contr2[1].x = -width_contr * 2 - height_contr - 5 * 3; ps_contr2[1].y = width_contr * 2 - thickness_contr * 2 + 5; ps_contr2[2].x = (-height_contr - 5) * 2; ps_contr2[2].y = (thickness + 5) * 2 + thickness_contr * 3 + jh_contr * 4; ps_contr2[3].x = -width_contr * 2 - height_contr - 5 * 3; ps_contr2[3].y = width_contr * 2 - thickness_contr + jh_contr + 5; ps_contr2[4].x = 0; ps_contr2[4].y = width_contr + 5; for (i = 0; i < ps_contr2.length; i ++) { c_contr2.add(ps_contr2[i]); } //ボタン類 var b1 = c_contr1.add(button[0], { x: 29, y: width_contr + 40 }); if(var03670 == 2) { var b2 = c_contr2.add(button[1], { x: 29, y: width_contr + 40 }); } b1.rotate(-90); if(var03670 == 2) { b2.rotate(-90); } var st1 = c_contr1.add(js[0], { x: 25, y: 110 }); if(var03670 == 2) { var st2 = c_contr2.add(js[1], { x: 25, y: 110 }); } st1.rotate(-90); if(var03670 == 2) { st2.rotate(-90); } //ボタン類用の穴 c.drawRectangle(351, 175, 8, 10); c.drawRectangle(362, 175, 2, 10); if(var03670 == 2) { c.drawRectangle(406, 175, 8, 10); c.drawRectangle(417, 175, 2, 10); } c.drawCircle(355, 255, 12); if(var03670 == 2) { c.drawCircle(410, 255, 12); } //配線用の穴 if(var03670 == 2) { c.drawRectangle(105, 244, 10, 10); } c.drawRectangle(250, 244, 10, 10); // 以降はゲームのソースコード var picture1 = new LCD.uint8Array(8); picture1.setitem(0, 31); picture1.setitem(1, 27); picture1.setitem(2, 21); picture1.setitem(3, 27); picture1.setitem(4, 21); picture1.setitem(5, 27); picture1.setitem(6, 21); picture1.setitem(7, 31); var picture2 = new LCD.uint8Array(8); picture2.setitem(0, 31); picture2.setitem(1, 27); picture2.setitem(2, 21); picture2.setitem(3, 21); picture2.setitem(4, 21); picture2.setitem(5, 21); picture2.setitem(6, 27); picture2.setitem(7, 31); var ten = new LCD.uint8Array(8); ten.setitem(0, 0); ten.setitem(1, 18); ten.setitem(2, 21); ten.setitem(3, 21); ten.setitem(4, 21); ten.setitem(5, 21); ten.setitem(6, 18); ten.setitem(7, 0); var downArrow = new LCD.uint8Array(8); downArrow.setitem(0, 4); downArrow.setitem(1, 4); downArrow.setitem(2, 4); downArrow.setitem(3, 4); downArrow.setitem(4, 4); downArrow.setitem(5, 21); downArrow.setitem(6, 14); downArrow.setitem(7, 4); var upArrow = new LCD.uint8Array(8); upArrow.setitem(0, 4); upArrow.setitem(1, 14); upArrow.setitem(2, 21); upArrow.setitem(3, 4); upArrow.setitem(4, 4); upArrow.setitem(5, 4); upArrow.setitem(6, 4); upArrow.setitem(7, 4); lcd.createChar(0,picture1); lcd.createChar(1,picture2); lcd.createChar(2,ten); lcd.createChar(3,downArrow); lcd.createChar(4,upArrow); var cards = []; var back = ["[0]", "[1]"]; var flip = "*"; var isAnimating = false; var flipCount = 0; var pair = [0, 0]; var height = 15; var neut = [{x:0,y:0}, {x:0,y:0}]; var page = 1; var scene = "title"; var changingScene = false; var maxTryLimit = 10; var tryLimit = maxTryLimit; var mode = 0; var turn = 0; var input = [{x:0, y:0, button:false}, {x:0, y:0, button:false}]; var waitingButton = false; var cPos = {x:0,y:0} var level = 1; var score = [0, 0]; var lastPage = 1; var gameLength = "full"; init(); initTitle(); setInterval(function() { getInput(); if (sw.value() == 0 && scene != "off") { lcd.displayOff(); lcd.backlightOff(); lcd.setColor(0,0,0); scene = "off"; } switch (scene) { case "title": if (changingScene) { changingScene = !changingScene; initTitle(); } startScreen(); break; case "levelSelect": if (changingScene) { changingScene = !changingScene; level = 1; lcd.clear(); lcd.setCursor(0,0); lcd.write("Select Level"); lcd.setCursor(1,3); lcd.write("NORMAL"); lcd.setCursor(0,15); lcd.write("[4]"); lcd.setCursor(1,15); lcd.write("[3]"); } if (input[0].x < 0) { if (level < 2) { level++; } } else if (input[0].x > 0) { if (level > 0) { level--; } } var c = [" EASY", "NORMAL", " HARD"]; lcd.setCursor(1,3); lcd.write(c[level]); if (input[0].button) { changeScene("lengthSelect"); } break; case "lengthSelect": if (changingScene) { changingScene = !changingScene; gameLength = "full"; lcd.clear(); lcd.setCursor(0,0); lcd.write("Select Mode"); lcd.setCursor(1,3); lcd.write(" FULL GAME"); lcd.setCursor(0,15); lcd.write("[4]"); lcd.setCursor(1,15); lcd.write("[3]"); } if (input[0].x < 0) { if (gameLength == "half") { gameLength = "full"; lcd.setCursor(1,3); lcd.write(" FULL"); } } else if (input[0].x > 0) { if (gameLength == "full") { gameLength = "half"; lcd.setCursor(1,3); lcd.write(" HALF"); } } if (input[0].button) { if (mode == 0) { changeScene("singlePlay"); } else { changeScene("multiPlay"); } } break; case "singlePlay": gamePlay(); break; case "multiPlay": gamePlay(); break; case "victory": if (changingScene) { changingScene = !changingScene; lcd.clear(); } lcd.setCursor(0,0); lcd.write("Success!!!"); if (input[0].button) { changeScene("title"); } break; case "defeat": if (changingScene) { changingScene = !changingScene; lcd.clear(); melody_mro(); } lcd.setCursor(0,0); lcd.write("Failure"); lcd.setCursor(1,0); lcd.write("Score: " + score[0]); if (input[0].button) { changeScene("title"); } break; case "off": if (sw.value() > 0) { lcd.displayOn(); lcd.backlightOn(); init(); scene = "title"; changingScene = true; } break; case "result": var s1 = score[0]; var s2 = score[1]; lcd.clear(); lcd.setCursor(0,0); if (s1 > s2) { lcd.write("Winner: 1P"); } else if (s2 > s1) { lcd.write("Winner: 2P"); } else { lcd.write("Draw Game"); } if (input[0].button) { changeScene("title"); } break; case "interval": break; } }, 100); function changeScene(s) { changingScene = true; scene = "interval"; setTimeout(function() { scene = s; }, 500); } function gamePlay() { if (changingScene) { changingScene = !changingScene; turn = 0; initGamePlay(); } if (waitingButton) { if (input[0].button || input[0].x != 0 || input[0].y != 0 || input[1].button || input[1].x != 0 || input[1].y != 0) { waitingButton = !waitingButton; lcd.setColor(100,255,100); faceDown(pair[0], pair[1]); } } else { mainLoop(); } showScore(); showPageInfo(); showCards(); showCursor(); endGamePlay(); } function endGamePlay() { if (mode == 0) { if (score[0] >= cards.length) { melody_ff(); changeScene("victory"); } if (tryLimit <= 0) { changeScene("defeat"); } } else { if (score[0] + score[1] >= cards.length) { melody_ff(); changeScene("result"); } } } function startScreen() { /* if (input[0].y == -1) { writePair("[", "]", 2); writePair(" ", " ", 6); mode = 0; } else if (input[0].y == 1) { writePair(" ", " ", 2); writePair("[", "]", 6); mode = 1; } if (input[0].button) { if (mode == 0) { changeScene("levelSelect"); } else { changeScene("lengthSelect"); } } */ // NOTE: Skip 'startScreen' if (mode == 0) { changeScene("levelSelect"); } else { changeScene("lengthSelect"); } } function writePair(c1, c2, pos) { lcd.setCursor(1,pos); lcd.write(c1); lcd.setCursor(1,pos+3); lcd.write(c2); } function init() { neut[0].x = js[0].getXInput(); neut[0].y = js[0].getYInput(); if(var03670 == 2) { neut[1].x = js[1].getXInput(); neut[1].y = js[1].getYInput(); } myBuzzer.setVolume(0.05); lcd.setColor(100,255,100); } function initTitle() { lcd.clear(); lcd.setColor(100,255,100); //mode = 0; mode = parseInt(var03670 - 1); // NOTE: Change to integer type. tryLimit = maxTryLimit; lcd.setCursor(0,2); lcd.write("[0]"); lcd.write("Select Mode"); lcd.write("[0]"); lcd.setCursor(1,2); lcd.write("[1P]") lcd.setCursor(1,7); lcd.write("2P"); } function initGamePlay() { lcd.clear(); var type = ["A","2","3","4","5","6","7","8","9","[2]","J","Q","K"]; var num; if (gameLength == "half") { num = 2; } else { num = 4; } var deck = new Array(num*13); for (var i = 0; i < 13; i++) { for (var j = 0; j < num; j++) { deck[i*num+j] = type[i]; } } deck.sort(function() { return Math.random() - 0.5; }); for (var i = 0; i < deck.length; i++) { cards[i] = {name:deck[i], valid:true, state:"back", pic:back[i%2]}; } flipCount == 0; turn = 0; var tls = [40, 30, 20]; tryLimit = tls[level]; if (gameLength == "half") { tryLimit /= 2; } score[0] = 0; score[1] = 0; page = 1; lastPage = 1; cPos.x = 0; cPos.y = 0; } function mainLoop() { moveCursor(); var index = (cPos.x+(page-1)*2)*height + cPos.y; if (index >= cards.length || cPos.y >= height) { return; } if (input[turn].button && flipCount < 2 && cards[index].state == "back") { if (flipCount == 0 && isAnimating) { return; } faceUp(index); return; } if (flipCount >= 2) { checkPair(); return; } } function getInput() { for (i = 0; i < var03670; i++) { var y = js[i].getXInput() - neut[i].x; var x = -js[i].getYInput() + neut[i].y; if (x > 0.1) { input[i].x = 1; } else if (x < -0.1) { input[i].x = -1; } else { input[i].x = 0; } if (y > 0.05) { input[i].y = 1; } else if (y < -0.05) { input[i].y = -1; } else { input[i].y = 0; } if (button[i].value() > 0) { input[i].button = true; } else { input[i].button = false; } } } function moveCursor() { if (input[turn].x == 1) { if (cPos.x == 0) { cPos.x++; playMove(); } else if (page == 1) { cPos.x--; page++; playMove(); } } else if (input[turn].x == -1) { if (cPos.x == 1) { cPos.x--; playMove(); } else if (page == 2) { cPos.x++; page--; playMove(); } } if (input[turn].y == 1 && cPos.y < height) { cPos.y++; playMove(); } else if (input[turn].y == -1 && cPos.y > 0) { cPos.y--; playMove(); } } function faceUp(i) { cards[i].state = "front"; pair[flipCount] = i; flipCount++; } function checkPair() { var p0 = pair[0]; var p1 = pair[1]; flipCount = 0; var success = cards[pair[0]].name == cards[pair[1]].name; if (!success) { lcd.setColor(255,100,100); incorrect(); tryLimit--; } else { correct(); } if (success) { pickCard(p0); pickCard(p1); } else { waitingButton = true; } } function faceDown(i1, i2) { cards[i1].state = "back"; cards[i2].state = "back"; if (mode == 1) { turn ^= 1; } } function pickCard(i) { cards[i].state = "invalid"; score[turn]++; } function showScore() { if (mode == 0) { display.writeString(("000"+tryLimit).slice(-4)); display.setColon(false); } else { display.writeString(("0"+score[0]).slice(-2)+("0"+score[1]).slice(-2)); display.setColon(true); } } function showCursor() { lcd.cursorBlinkOn(); lcd.setCursor(cPos.x, cPos.y); } function showPageInfo() { if (page == 1) { lcd.setCursor(1,15); lcd.write("[3]"); lcd.setCursor(0,15); lcd.write(" "); } else { if (lastPage != page) { lcd.clear(); } lcd.setCursor(0,15); lcd.write("[4]"); lcd.setCursor(1,15); lcd.write(" "); } lastPage = page; } function showCards() { cards.forEach(function(card, num) { var y = num%height; var x = (num-y)/height; if (page == 1) { if (x < 2) { lcd.setCursor(x, y); switch (card.state) { case "front": lcd.write(card.name); break; case "flip": lcd.write(flip); break; case "back": lcd.write(card.pic); break; case "invalid": lcd.write(" "); break; } } } else { if (x >= 2) { lcd.setCursor(x-2, y); switch (card.state) { case "front": lcd.write(card.name); break; case "flip": lcd.write(flip); break; case "back": lcd.write(card.pic); break; case "invalid": lcd.write(" "); break; } } } }); } var defVolume = 0.05; function stopSound() { myBuzzer.stopSound(); } function playMove() { if(var32783) { myBuzzer.setVolume(defVolume*2); } else { myBuzzer.setVolume(0); } myBuzzer.playSound(500,10000); stopSound(); } function correct(){ if(var32783) { myBuzzer.setVolume(defVolume); } else { myBuzzer.setVolume(0); } myBuzzer.playSound(1900, 100000); myBuzzer.playSound(upmBuzzer.SOL, 200000); stopSound(); } function incorrect(){ if(var32783) { myBuzzer.setVolume(defVolume); } else { myBuzzer.setVolume(0); } myBuzzer.playSound(10000, 100000); myBuzzer.playSound(10000, 200000); stopSound(); } //宣言文でconstを用いるとプレビューが表示されなくなるようです function melody_ff() { if(var32783) { myBuzzer.setVolume(defVolume); } else { myBuzzer.setVolume(0); } var F = upmBuzzer.FA; var G = upmBuzzer.SOL; var A = upmBuzzer.LA; var FOUR = 300000; var THREE = 100000; var chords = [A,A,A,A,F,G,A,A,G,A]; var length = [THREE,THREE,THREE,FOUR,FOUR,FOUR,THREE,THREE,THREE,FOUR*3]; var chordIndex = 0; if (chords.length != 0) { for(chordIndex = 0; chordIndex < chords.length; chordIndex++){ //Play sound for one second myBuzzer.playSound(chords[chordIndex], length[chordIndex]); myBuzzer.stopSound(); } //Reset the sound to start from the beginning. if (chordIndex > chords.length - 1) chordIndex = 0; } stopSound(); } function melody_mro(){ if(var32783) { myBuzzer.setVolume(defVolume); } else { myBuzzer.setVolume(0); } var G = upmBuzzer.SOL; var HIF = (upmBuzzer.FA / 2); var HIE = (upmBuzzer.MI / 2); var HID = (upmBuzzer.RE / 2); var HIC = (upmBuzzer.DO / 2); var B = upmBuzzer.SI; var E = upmBuzzer.MI; var C = upmBuzzer.DO; var EIGHT = 150000; var THREE = 200000; var chords = [B,HIF,HIF,HIF,HIE,HID,HIC,E,E,C]; var length = [EIGHT,EIGHT*2,EIGHT,THREE,THREE,THREE,EIGHT,EIGHT*2,EIGHT,EIGHT*2]; var chordIndex = 0; if (chords.length != 0) { for(chordIndex = 0; chordIndex < chords.length; chordIndex++){ //Play sound for one second myBuzzer.playSound(chords[chordIndex], length[chordIndex]); myBuzzer.stopSound(); } //Reset the sound to start from the beginning. if (chordIndex > chords.length - 1) chordIndex = 0; } stopSound(); }
カスタマイズ

このコンテンツにはカスタマイズできる項目がありません。

表示オプション
ソースコード中で変数宣言にコメントをつけるとカスタマイズ項目としてGUIウィジェットが表示されます。グレーアウトしているウィジェットはユーザが提案した項目で、ソースコード末尾の変数宣言に対応しています。

設計のダウンロード

モジュール

このプロジェクトは組み立てにモジュールを必要としません。

レイアウト
プログラム

ログインしないと使えない機能です。