基本情報

このページでは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ウィジェットが表示されます。グレーアウトしているウィジェットはユーザが提案した項目で、ソースコード末尾の変数宣言に対応しています。

設計のダウンロード

モジュール

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

レイアウト
プログラム

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