工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

Arduinoタッチブレイクアウトゲーム

コンポーネントと消耗品

>
Arduino UNO
× 1
>
AZ-Delivery 2.4 TFTLCDタッチディスプレイArduinoシールド
× 1

アプリとオンラインサービス

>
Arduino IDE

このプロジェクトについて

これは、ArduinoUNOおよびTFTLCDスクリーン(240x320ピクセル)、8ビットパラレル通信を備えたドライバーILI9341用のクラシックなブレイクアウトビデオゲームの小さなバージョンです。

ゲーム

このブレイクアウトには、構成可能なレンガの行と列が異なる複数の画面があり、最大8行で、各2行は異なる色で、異なるパターンでオンまたはオフにプログラムできます。単一のボールを使用し、タッチパネルを使用して、プレーヤーは壁や下のパドルを使用してボールをレンガに跳ね返してそれらを排除することにより、できるだけ多くのレンガをノックダウンする必要があります。プレーヤーのパドルがボールのリバウンドを逃した場合、彼らはターンを失います。

各列のレンガはそれぞれ異なるポイントを獲得します。

  uint8_t pointsForRow [] ={7、7、5、5、3、3、1、1};  

各レベルで、パドルサイズとボールサイズを構成できます。ボールの速度はヒットするたびに増加します。画面ごとに初速度を設定できます。ボールを打つパドルのポイントに応じて、水平方向の速度も変化します

さまざまな壁のパターンを持つ新しい画面として定義できます:

<図> <図> <図> <図> <図> <図>

遊び方

デバイスを手で持ち、親指を使って画面上でパドルを左側または右側に移動します。

<図>

新しい画面を定義する

この構造は、新しい画面を定義するために使用されます:

  typedef struct game_type {
int ballsize;
int playerwidth;
int playerheight;
int exponent;
int top;
int行;
int列;
intbrickGap;
int live;
int wall [GAMES_NUMBER];
int initVelx;
int initVely;
} game_type;

セットに新しい画面を追加します:

  game_type games [GAMES_NUMBER] =
//ボールサイズ、playerwidth、playerheight、exponent、top、rows、columns、brickGap、lives、wall [8]、initVelx、initVely
{
{10、60、8、6、40、8、8、3、3、{0x18、0x66、0xFF、0xDB、0xFF、0x7E、0x24、0x3C}、28、-28}、

壁のパターン

壁のパターンは8x8ビット配列として定義されています

ej。

  {0xAA、0xAA、0xAA、0xAA、0xAA、0xAA、0xAA、0xAA}  

これはこのビット配列に対応します

  1,0,1,0,1,0,1,0 
1,0,1,0,1,0,1,0
1,0,1 0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0,1,0
1,0,1,0,1,0 、1,0

この壁を作成します。ミラーリングされていることに注意してください:

<図>

ハードウェア

このプロジェクトでは、抵抗性4線式タッチスクリーンと統合SDカードリーダーを備えたAZ-Delivery2.4インチTFTLCDディスプレイを使用します。 AZ-配信2.4インチTFTLCDディスプレイ。

<図>

このシールドの詳細については、私の記事「AZ-Delivery 2、4 TFTLCDタッチディスプレイの道路テスト」

をご覧ください。

シールドの組み立て

シールドをAduinoにかぶせるだけです。

<図> <図>

ライブラリ

  #include  //コアグラフィックライブラリ
#include
#include

タッチスクリーンの調整

ディスプレイに触れたときに位置情報が正しくなるように、ディスプレイを調整する必要があります。 MCUFriend_kbvライブラリは、「TouchScreen_Calibr_native」という名前の例を提供します。この例では、結果をシリアルポートに送信します。 Arduino IDEのシリアルモニターを起動して、例で生成されたコードをコピーできるようにします。

タッチディスプレイの指示に従い、白で強調表示されている位置マーカーを押し続けます。すべての位置マークを完了すると、ディスプレイのキャリブレーションがタッチディスプレイとシリアルポートに出力されます。

このプロジェクトでは、「ポートレートキャリブレーション」のデータが必要です。

  TouchScreen.h GFXキャリブレーション
すべての制御ピンとバスピンをINPUT_PULLUPにする
対応するピンを使用した一般的な30kアナログプルアップ
デジタルがLOWに書き込まれると、Lowになります
例: 300R X方向で〜25を読み取ります
例: 500R Y方向で〜30を読み取ります
テスト:(A2、D8)=26
テスト:(A3、D9)=28
ID =0x9341
cx =153 cy =103 cz =534 X、Y、圧力
cx =150 cy =475 cz =406 X、Y、圧力
cx =155 cy =868 cz =231 X、Y、圧力
cx =517 cy =103 cz =561 X、Y、圧力
cx =535 cy =855 cz =364 X、Y、圧力
cx =884 cy =88 cz =650 X、Y、圧力
cx =908 cy =478 cz =557 X、Y、圧力
cx =902 cy =864 cz =488 X、Y、圧力
***シリアル端末からのコピー-貼り付け:
const int XP =8、XM =A2、YP =A3、YM =9; // 240x320 ID =0x9341
const int TS_LEFT =118、TS_RT =931、TS_TOP =72、TS_BOT =887;
PORTRAIT CALIBRATION 240 x 320
x =map(px、LEFT =118 、RT =931、0、240)
y =map(py、TOP =72、BOT =887、0、320)
LANDSCAPE CALIBRATION 320 x 240
x =map(py、 LEFT =72、RT =887、0、320)
y =map(px、TOP =931、BOT =118、0、240)

アニメーション

時間の経過とともに画像を画面上で移動するには、静的速度を使用し、タイムステップごとに画像の位置に適用します。

pos + =vel * dt;

浮動小数点演算の回避

ILI9341の解像度は240x 320であるため、画面のピクセルを参照するには2つの9ビット整数が必要です。 16ビット整数を使用して、6ビットを自由に小数部を表します。

nnnn nnnn nndd dddd

この数を6と呼び、2進指数と呼びます。そして、この6ビットを使用して、0.000から0.63の範囲の小数部分を持つことができます。したがって、浮動小数点演算を避けて整数演算を使用できます。

数値の整数部分を取得するには、右の算術シフトを行います。

数値>>指数

  state.ballx + =state.velx; 
state.bally + =state.vely;

//ボールの衝突をチェックして終了
checkBallCollisions(game 、&​​state、state.ballx>> game-> exponent、state.bally>> game-> exponent);
checkBallExit(game、&state、state.ballx>> game-> exponent、state.bally>> game ->指数);

デモモード

デモビデオで見られるように、Define Directiveのコメントを外すと、パドルがボールに追従します。

  #define DEMO_MODE  

楽しんでください!

レベルに新しいパターンを作成して共有します!

コード

  • Arduinoブレイクアウト
Arduino Breakout Arduino
 / * Arduino Touch TFTブレイクアウトクラシックブレイクアウトゲーム必要な部品:Ardunio UNOAZ-配信2.4TFTLCDタッチディスプレイArduinoシールドまたは互換性このサンプルコードはパブリックドメインにあります。 2020年7月11日変更EnriqueAlbertos * /// #define DEMO_MODE#include  //コアグラフィックライブラリ#include  #include  #define BLACK 0x0000#define BLUE 0x001F#define RED 0xF800#define GREEN 0x07E0#define CYAN 0x07FF#define MAGENTA 0xF81F#define YELLOW 0xFFE0#define WHITE 0xFFFF#define PRIMARY_COLOR 0x4A11#define PRIMARY_LIGHT_COLOR 0x7A17#define PRIMARY_LIGHT_COLOR 0x7A17#define PRIMARY_LIGHT_COLOR 0x7A17#define PRIMARY_DARK_ #define LCD_CD A2 //コマンド/データはアナログ2に送られます#defineLCD_WR A1 // LCD書き込みはアナログ1に送られます#defineLCD_RD A0 // LCD読み取りはアナログ0に送られます#defineLCD_RESET A4 // Arduinoのリセットに接続することもできますpinAdafruit_TFTLCD tft(LCD_CS、LCD_CD、LCD_WR、LCD_RD、LCD_RESET); #define LOWFLASH(defined(__ AVR_ATmega328P __)&&defined(MCUFRIEND_KBV_H _))//タッチスクリーン圧力しきい値#defineMINPRESSURE 40#define MAXPRESSURE 1000 //タッチスクリーンキャリブレーション8、XM =A2、YP =A3、YM =9; // 240x320 ID =0x9341const int16_t TS_LEFT =122、TS_RT =929、TS_TOP =77、TS_BOT =884; const TouchScreen ts =TouchScreen(XP、YP、XM、YM、300); #define SCORE_SIZE 30char scoreFormat [] ="% 04d "; typedef struct gameSize_type {int16_t x、y、width、height;} gameSize_type; gameSize_type gameSize; uint16_t backgroundColor =BLACK; int level; const uint8_t BIT_MASK [] ={0x01、0x02、0x04、0x08、0x10、0x20、0x40 、0x80}; uint8_t pointsForRow [] ={7、7、5、5、3、3、1、1}; #define GAMES_NUMBER 16typedef struct game_type {int ballsize; int playerwidth; int playerheight; int指数; int top; int行; int列; intbrickGap; intは生きています。 int wall [GAMES_NUMBER]; int initVelx; int initVely;} game_type; game_type games [GAMES_NUMBER] =//ボールサイズ、playerwidth、playerheight、exponent、top、rows、columns、brickGap、lives、wall [8]、initVelx、initVely {{10、60、8、6 40、8、8、3、3、{0x18、0x66、0xFF、0xDB、0xFF、0x7E、0x24、0x3C}、28、-28}、{10、50、8、6、40、8、8、3 、3、{0xFF、0x99、0xFF、0xE7、0xBD、0xDB、0xE7、0xFF}、28、-28}、{10、50、8、6、40、8、8、3、3、{0xAA、0x55 、0xAA、0x55、0xAA、0x55、0xAA、0x55}、28、-28}、{8、50、8、6、40、8、8、3、3、{0xFF、0xC3、0xC3、0xC3、0xC3、 0xC3、0xC3、0xFF}、34、-34}、{10、40、8、6、40、8、8、3、3、{0xFF、0xAA、0xAA、0xFF、0xFF、0xAA、0xAA、0xFF}、 28、-28}、{10、40、8、 6、40、8、8、3、3、{0xAA、0xAA、0xAA、0xAA、0xAA、0xAA、0xAA、0xAA}、28、-28}、{12、64、8、6、60、4、2 、3、4、{0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF}、20、-20}、{12、60、8、6、60、5、3、3、4、{0xFF 、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF}、22、-22}、{10、56、8、6、30、6、4、3、4、{0xFF、0xFF、0xFF、0xFF、 0xFF、0xFF、0xFF、0xFF}、24、-24}、{10、52、8、6、30、7、5、3、4、{0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF }、26、-26}、{8、48、8、6、30、8、6、3、3、{0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF}、28、-28} 、{8、44、8、6、30、8、7、3、3、{0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF }、30、-30}、{8、40、8、6、30、8、8、3、3、{0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF}、32、-32} 、{8、36、8、6、40、8、8、3、3、{0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF、0xFF}、34、-34}、{8、36、8 、6、40、8、8、3、3、{0xAA、0xAA、0xAA、0xAA、0xAA、0xAA、0xAA、0xAA}、34、-34}}; game_type * game; typedef struct game_state_type {uint16_t ballx; uint16_tバリー; uint16_t ballxold; uint16_t ballyold; int velx; int vely; int playerx; int playerxold; int wallState [8]; intスコア; intremainingLives; int top; intボトム; intウォールトップ; int wallbottom; intbrickheight; intbrickwidth;}; game_state_type state; ////////////////////////////////////////// ////////////////////// ARDUINO SETUP ////////////////////////// //////////////////////////////////// void setup(){initTft(tft); gameSize ={0、0、tft.width()、tft.height()}; newGame(&games [0]、&state、tft);} ///////////////////////////////////// ////////////////////////// ARDUINO LOOP ///////////////////// ///////////////////////////////////////// int selection =-1; void loop( void){selection =readUiSelection(game、&state、selection); drawPlayer(game、&state); //古い位置を保存して、古いピクセルを削除しますstate.playerxold =state.playerx; //新しいボールの位置を計算しますx1 =x0 + vx * dt //最大速度をチェックしますif(abs(state.vely)>((1 < exponent)-1)){state.vely =((1 < exponent)-1)*((state.vely> 0)-(state.vely <0)); } if(abs(state.velx)>((1 < exponent)-1)){state.velx =((1 < exponent)-1)*((state.velx> 0 )-(state.velx <0)); } state.ballx + =state.velx; state.bally + =state.vely; //ボールの衝突をチェックし、checkBallCollisions(game、&state、state.ballx>> game-> exponent、state.bally>> game-> exponent);を終了します。 checkBallExit(game、&state、state.ballx>> game-> exponent、state.bally>> game-> exponent); //新しい位置にボールを描画しますdrawBall(state.ballx>> game-> exponent、state.bally>> game-> exponent、state.ballxold>> game-> exponent、state.ballyold>> game-> exponent、game ->ボールサイズ); //古い位置を保存して、古いピクセルを削除しますstate.ballxold =state.ballx; state.ballyold =state.bally; //速度をインクリメントstate.velx =(20 +(state.score>> 3))*((state.velx> 0)-(state.velx <0)); state.vely =(20 +(state.score>> 3))*((state.vely> 0)-(state.vely <0)); //次のレベルに進むブリックがない場合if(noBricks(game、&state)&&level ライブ、状態->残りのライブ); updateScore(state-> score); setupWall(ゲーム、状態); touchToStart(); clearDialog(gameSize); updateLives(ゲーム->ライブ、状態->残りのライブ); updateScore(state-> score); setupWall(game、state);} void setupStateSizes(game_type * game、game_state_type * state、Adafruit_TFTLCD&tft){state-> bottom =tft.height()-30;状態->ブリック幅=tft.width()/ゲーム->列; state-> brickheight =tft.height()/ 24;} void setupState(game_type * game、game_state_type * state、Adafruit_TFTLCD&tft){setupStateSizes(game、state、tft); for(int i =0; i  rows; i ++){state-> wallState [i] =0; } state-> playerx =tft.width()/ 2-game-> playerwidth / 2;状態-> remainingLives =game-> lives; state-> bally =state-> bottom < exponent; state-> ballyold =state-> bottom < exponent; state-> velx =game-> initVelx; state-> vely =game-> initVely;} void updateLives(intlives、intremainingLives){for(int i =0; i ウォールトップ=ゲーム->トップ+40; state-> wallbottom =state-> walltop + game-> rows * state-> brickheight; for(int i =0; i  rows; i ++){for(int j =0; j  columns; j ++){if(isBrickIn(game-> wall、j、i)){setBrick (state-> wallState、j、i); drawBrick(state、j、i、colors [i]); }}}} void drawBrick(game_state_type * state、int xBrick、int yBrickRow、uint16_t backgroundColor){tft.fillRect((state-> brickwidth * xBrick)+ game-> brickGap、state-> walltop +(state-> briefheight * yBrickRow)+ game-> brickGap、state-> brickwidth-game-> brickGap * 2、state-> brickheight-game-> brickGap * 2、backgroundColor);} boolean noBricks(game_type * game、game_state_type * state){for( int i =0; i  rows; i ++){if(state-> wallState [i])return false; } return true;} void drawPlayer(game_type * game、game_state_type * state){// paint tft.fillRect(state-> playerx、state-> bottom、game-> playerwidth、game-> playerheight、YELLOW); if(state-> playerx!=state-> playerxold){//古いピクセルを削除if(state-> playerx  playerxold){tft.fillRect(state-> playerx + game-> playerwidth、state-> bottom 、abs(state-> playerx --state-> playerxold)、game-> playerheight、backgroundColor); } else {tft.fillRect(state-> playerxold、state-> bottom、abs(state-> playerx --state-> playerxold)、game-> playerheight、backgroundColor); }}} void drawBall(int x、int y、int xold、int yold、int ballsize){//古いピクセルを削除する// if(xold!=x &&yold!=y){if(xold <=x &&yold <=y){tft.fillRect(xold、yold、ballsize、y-yold、BLACK); tft.fillRect(xold、yold、x-xold、ballsize、BLACK); } else if(xold> =x &&yold> =y){tft.fillRect(x + ballsize、yold、xold-x、ballsize、BLACK); tft.fillRect(xold、y + ballsize、ballsize、yold-y、BLACK); } else if(xold <=x &&yold> =y){tft.fillRect(xold、yold、x-xold、ballsize、BLACK); tft.fillRect(xold、y + ballsize、ballsize、yold-y、BLACK); } else if(xold> =x &&yold <=y){tft.fillRect(xold、yold、ballsize、y --yold、BLACK); tft.fillRect(x +ボールサイズ、yold、xold-x、ボールサイズ、BLACK); } //新しいボールをペイントするtft.fillRect(x、y、ballsize、ballsize、YELLOW); //}} void touchToStart(){drawBoxedString(0、200、 "BREAKOUT"、3、YELLOW、BLACK); drawBoxedString(0、240、 "TOUCH TO START"、2、RED、BLACK); while(waitForTouch()<0){}} void gameOverTouchToStart(){drawBoxedString(0、180、 "GAME OVER"、3、YELLOW、BLACK); drawBoxedString(0、220、 "TOUCH TO START"、2、RED、BLACK); while(waitForTouch()<0){}} void updateScore(int score){char buffer [5]; snprintf(buffer、sizeof(buffer)、scoreFormat、score); drawBoxedString(tft.width()-50、6、buffer、2、YELLOW、PRIMARY_DARK_COLOR);} void checkBrickCollision(game_type * game、game_state_type * state、uint16_t x、uint16_t y){int x1 =x + game-> ballsize; int y1 =y + game-> ballsize; int衝突=0;衝突+ =checkCornerCollision(game、state、x、y);衝突+ =checkCornerCollision(game、state、x1、y1);衝突+ =checkCornerCollision(game、state、x、y1);衝突+ =checkCornerCollision(game、state、x1、y); if(衝突> 0){状態-> vely =(-1 *状態-> vely); if((((x%状態->ブリック幅)==0)&&(状態-> velx <0))||((((x +ゲーム->ボールサイズ)%状態->ブリック幅)==0)&&(state-> velx> 0))){state-> velx =(-1 * state-> velx); }}} int checkCornerCollision(game_type * game、game_state_type * state、uint16_t x、uint16_t y){if((y> state-> walltop)&&(y  wallbottom)){int yBrickRow =(y --state->壁)/状態->レンガの高さ; int xBrickColumn =(x /状態-> brickwidth); if(isBrickIn(state-> wallState、xBrickColumn、yBrickRow)){hitBrick(state、xBrickColumn、yBrickRow); 1を返します。 }} return 0;} void hitBrick(game_state_type * state、int xBrick、int yBrickRow){state-> score + =pointsForRow [yBrickRow]; drawBrick(state、xBrick、yBrickRow、WHITE); delay(16); drawBrick(state、xBrick、yBrickRow、BLUE); delay(8); drawBrick(state、xBrick、yBrickRow、backgroundColor); unsetBrick(state-> wallState、xBrick、yBrickRow); updateScore(state-> score);} void checkBorderCollision(game_type * game、game_state_type * state、uint16_t x、uint16_t y){//壁の衝突をチェックif(x + game-> ballsize> =tft.width()){state -> velx =-abs(state-> velx); } if(x <=0){state-> velx =abs(state-> velx); } if(y <=SCORE_SIZE){state-> vely =abs(state-> vely); } if(((y + game-> ballsize)> =state-> bottom)&&((y + game-> ballsize)<=(state-> bottom + game-> playerheight))&&(x> =state-> playerx)&&(x <=(state-> playerx + game-> playerwidth))){//プレーヤーの境界近くのvel xを変更if(x>(state-> playerx + game-> playerwidth-6)){state -> velx =state-> velx-1; } else if(x  playerx + 6){state-> velx =state-> velx + 1; } state-> vely =-abs(state-> vely); }} void checkBallCollisions(game_type * game、game_state_type * state、uint16_t x、uint16_t y){checkBrickCollision(game、state、x、y); checkBorderCollision(game、state、x、y);} void checkBallExit(game_type * game、game_state_type * state、uint16_t x、uint16_t y){if(((y + game-> ballsize)> =tft.height())) {状態-> remainingLives--; updateLives(ゲーム->ライブ、状態->残りのライブ); delay(500); state-> vely =-abs(state-> vely); }} void setBrick(int wall []、uint8_t x、uint8_t y){wall [y] =wall [y] | BIT_MASK [x];} void unsetBrick(int wall []、uint8_t x、uint8_t y){wall [y] =wall [y]&〜BIT_MASK [x];} boolean isBrickIn(int wall []、uint8_t x、uint8_t y){return wall [y]&BIT_MASK [x];} /////////////////////////////////// ///////////////////////////// TFTセットアップ/////////////////// /////////////////////////////////////////// void initTft(Adafruit_TFTLCD&tft) {tft.reset(); uint16_t ID =tft.readID(); tft.begin(ID); tft.setRotation(0);} ////////////////////////////////////////// //////////////////////スクリーン塗装方法///////////////////////// ///////////////////////////////////// **塗りつぶされたボックスの上にフォアカラーでテキストを印刷します背景色。長方形のサイズは、余白のないテキスト全体を含むように計算されます@paramxポイントの水平座標左上隅@paramyポイントの左上隅の垂直座標@paramfontsize印刷するテキストのフォントサイズ@paramforeColor印刷するテキストの前色@parambackgroundColor塗りつぶされたrectの色@returnvoid * / void drawBoxedString(const uint16_t x、const uint16_t y、const char * string、const uint16_t fontsize、const uint16_t foreColor、const uint16_t backgroundColor){tft.setTextSize(fontsize); int16_t x1、y1; uint16_t w、h; tft.getTextBounds(string、x、y、&x1、&y1、&w、&h); tft.fillRect(x、y、w、h、backgroundColor); tft.setCursor(x、y); tft.setTextColor(foreColor); tft.print(string);} / **画面をデフォルトの背景にクリアします@paramvoid @return void * / void clearDialog(gameSize_type gameSize){tft.fillRect(gameSize.x、gameSize.y、gameSize.width、gameSize .height、backgroundColor); tft.fillRect(gameSize.x、gameSize.y、gameSize.width、SCORE_SIZE、PRIMARY_DARK_COLOR);} //////////////////////////// //////////////////////////////////// UIの選択を読む/////////// ////////////////////////////////////////////////// // *ユーザーが表示されている有効なUI要素のいずれかを選択しているかどうかを確認します選択した要素のonTapコールバックが呼び出され、押された状態に設定されます@paramlastSelected最後の選択@return新しい選択* / int readUiSelection(game_type * game、 game_state_type * state、const int16_t lastSelected){int16_t xpos、ypos; //画面座標TSPointtp =ts.getPoint(); //tp.x、tp.yはADC値です//ピンを共有する場合は、タッチスクリーンピンの方向を修正する必要がありますpinMode(XM、OUTPUT); pinMode(YP、OUTPUT); //「有効」と見なす最小圧力があります//圧力0は、押さないことを意味します! if(tp.z> MINPRESSURE &&tp.z  tft.width()/ 2){state-> playerx + =2; } else {state-> playerx- =2; } if(state-> playerx> =tft.width()-game-> playerwidth)state-> playerx =tft.width()-game-> playerwidth; if(state-> playerx <0)state-> playerx =0; 1を返します。 } #ifdef DEMO_MODE state-> playerx =(state-> ballx>> game-> exponent)-game-> playerwidth / 2; if(state-> playerx> =tft.width()-game-> playerwidth)state-> playerx =tft.width()-game-> playerwidth; if(state-> playerx <0)state-> playerx =0; #endif return -1;} int waitForTouch(){int16_t xpos、ypos; //画面座標TSPointtp =ts.getPoint(); //tp.x、tp.yはADC値です//ピンを共有する場合は、タッチスクリーンピンの方向を修正する必要がありますpinMode(XM、OUTPUT); pinMode(YP、OUTPUT); //「有効」と見なす最小圧力があります//圧力0は、押さないことを意味します! if(tp.z> MINPRESSURE &&tp.z  

回路図


製造プロセス

  1. MPU-6050を搭載したArduinoジャイロスコープゲーム
  2. ArduinoPongゲーム-OLEDディスプレイ
  3. ポータブル静電容量式タッチピアノ
  4. Arduinoゲームコントローラー
  5. MAX7219を搭載した24x16マトリックスのArduinoPongゲーム
  6. ジャイアントアニマトロニクスレゴミンフィグオペレーションゲーム
  7. USB-BLEワイヤレスMIDIアダプター
  8. ピクセルチェイサーゲーム
  9. Arduinoによる音声認識と合成
  10. arduinoを使用した自動恐竜ゲーム
  11. Arduinoを使用したタッチ制御ライト