JH7UBCブログ

アマチュア無線 電子工作 家庭菜園など趣味のブログです

Raspberry Pi Pico MicroPython スカッシュゲーム

2022-02-23 22:14:21 | Raspberry Pi Pico
 Raspberry Pi Picoに2.2インチTFTを接続し、MicroPythonでプログラミングして、懐かしい「スカッシュゲーム」を作ってみました。
 接続回路図です。



 ブレッドボードです。


 ラケットを操作する左ボタン(L Button)と右ボタン(R Button)は別なブレッドボードに取り付けました。

 ゲーム画面です。上にスコアを表示しています。
 ボールは、10×9ドットで、X方向24、Y方向30ステップで移動します。



 ゲームオーバー画面です。

スクリプトです。main.pyとしてPicoに保存します。
なお、以前にアップしたTFT表示テスト1及びテスト2を参考にして、
Picoに、ili9341.pyとxglcd_font.pyを保存し、
pico内のfontというフォルダにUnispace12x24.cとBroadway17x15.cを保存しておきます。
---------------------------------------------------------------------------------
"""
Raspberry Pi Pico MicroPython
Squash game
2022.2.23
JH7UBC Keiji Hata
"""

from machine import Pin, SPI
import ili9341
from xglcd_font import XglcdFont
import utime
from random import random, seed

#Button設定
Button_L = Pin(4,Pin.IN,Pin.PULL_UP)
Button_R = Pin(5,Pin.IN,Pin.PULL_UP)

#SPI設定
TFT_CLK_PIN = const(6)
TFT_MOSI_PIN = const(7)
TFT_MISO_PIN = const(4)
TFT_CS_PIN = const(13)
TFT_RST_PIN = const(14)
TFT_DC_PIN = const(15)

spiTFT = SPI(0, baudrate=51200000,
                 sck=Pin(TFT_CLK_PIN), mosi=Pin(TFT_MOSI_PIN))
display = ili9341.Display(spiTFT,dc=Pin(TFT_DC_PIN),
             cs=Pin(TFT_CS_PIN), rst=Pin(TFT_RST_PIN),
             width=240, height=320,rotation=0)
#フォントの設定
unispace = XglcdFont('fonts/Unispace12x24.c', 12, 24)
broadway = XglcdFont('fonts/Broadway17x15.c',17,15)

#score枠を描く
def display_score_bar():
     display.fill_hrect(0,0,240,20,ili9341.color565(255,255,255))
     display.draw_text(70,3,'score',broadway,ili9341.color565(0,0,255),
                   background=ili9341.color565(255,255,255))

#score表示
def display_score(s):
     display.fill_hrect(130,0,100,9,ili9341.color565(255,255,255))
     s_text = str(s)
     len_s=len(s_text)
     for i in range(4-len_s):
        s_text='0'+s_text
     display.draw_text(130,3,s_text,broadway,ili9341.color565(0,0,255),
                   background=ili9341.color565(255,255,255))

#ラケットを描く
def display_racket():
     global prev_rx,rx
     display.fill_hrect(prev_rx*10,310,50,9,0)
    display.fill_hrect(rx*10,310,50,9,ili9341.color565(255,255,255))
     prev_rx=rx

#ボールを描く
def display_ball(x,y):
     global prev_x,prev_y
     display.fill_hrect(prev_x*10,prev_y*10,10,10,0)
     display.fill_hrect(x*10,y*10,10,9,ili9341.color565(255,255,0))
     prev_x = x
     prev_y = y

#初期画面表示
start_Flag=0
display.draw_text(60,110,'Squash Game',unispace,ili9341.color565(255,255,0))
display.draw_text(20,150,'Push L or R Button',unispace,ili9341.color565(0,255,255))

#ボールのスピード設定(値を小さくすると速くなる)
speed=50

#メインループ
while True:
     if start_Flag == 0:
         #LまたはRボタンが押されるまで待つ
         while Button_L.value()==1 and Button_R.value()==1:
             pass
         start_Flag = 1
         display.clear()
        display_score_bar()
         score = 0
         display_score(score)
         rx=10
         prev_rx=rx
         display_racket()
         bx=10
         by=10
         #方向をランダムに決める
         direction=int(random()*4)
         if direction == 0:
             dx=1
             dy=1
         elif direction == 1:
             dx=1
             dy=-1
         elif direction == 2:
             dx=-1
             dy=1
         elif direction == 3:
             dx=-1
             dy=-1
         prev_x=bx
         prev_y=by
         display_ball(bx,by)

     else:
         #ボールを動かす
         #X方向に動かす
         bx = bx + dx
         if bx < 0 or bx > 23:#bx<0 またはbx>23なら
             bx = bx -dx#一つ戻す
             dx = -dx#方向を変える
             bx = bx + dx
         #Y方向に動かす
         by = by + dy
         if by<2:
             by = by - dy#一つ戻す
             dy = -dy#方向を変える
             by = by + dy
         if by == 31:
             if bx >= rx and bx <= rx+4:
                by = by - dy#一つ戻す
                dy = -dy#方向を変える
                 by = by + dy
                score = score + 1
                display_score(score)
             else:
                start_Flag=0
                display.draw_text(70,150,'GAME OVER',unispace,ili9341.color565(255,0,0))
                utime.sleep(0.5)
                while Button_L.value()==1 and Button_R.value()==1:
                    pass
         #ラケットを動かす
         if Button_L.value() == 0:
             rx=rx-1
             if rx<=0:
                rx=0
             display_racket()
         if Button_R.value() == 0:
             rx=rx+1
             if rx > 19:
                rx=19
             display_racket()

         display_ball(bx,by)
         utime.sleep_ms(speed)
---------------------------------------------------------------------------------
 とりあえず、ボールが動いてゲームができる状態です。
 音を出したり、スピードをボタンで変えられるようにしたり、改良点はたくさんあります。これを参考にしてオリジナルのゲームを作ってみてください。

 最初、ボールの動きをタイマー割込みを利用して行おうと実験しましたが、ラケットの表示に乱れが出てしまい、断念しました。後でまたチャレンジしてみようと思います。


オーネット・コールマン クロイドンコンサート

2022-02-15 13:26:17 | JAZZ
 1970年頃、NHK FMのジャズ番組で、オーネットコールマンのクロイドンコンサートを聞きました。
 2曲目、「サッドネス」を聞いたとき、背筋がゾクゾクッとする感動を覚えました。それまでの人生で初めてのことでした。

 高校生の頃からジャズを聴き始め、スウィング感のあるジャズばかり聞いてきた私には、衝撃的なことでした。こういうジャズもあるんだ。私がジャズの様々な演奏を聴き始めるきっかけになった演奏でした。

 その後、自分でレコードを購入しました。ジャケットには演奏するオーネット・コールマンの姿。2枚組のレコードです。
表面
裏面

 オーネット・コールマンはフリージャズの創始者と言われます。
 リズムやメロディの制約を極力なくして、自由に表現するジャズ。
「スウィングしなけりゃジャズじゃない」と良く言われますが、そうでないジャズがあっても良い。
 では、ジャズとは何?
 いろいろ定義するする人はいるのですが、演奏する人がジャズだと思い、聞く人がジャズだと思えば、ジャズ。非常にあいまいなのですが、それくらい幅のある音楽だと思うのです。

 なお、オーネット・コールマンについてのうんちくを書く気はありません。
オーネットのレコード1枚、CDを5枚持っていますが、そんなに詳しくは知っているわけではありません。
 手元に「ジャズ批評 No.98」オーネット・コールマン大全集(1999年刊 ジャズ批評社)がありました。表紙は、故和田誠氏の味のあるイラストです。

 詳しく知りたい方には、ぜひご一読願いたいと思います。

Raspberry Pi Pico MicroPython TFT sin cos カーブを描く

2022-02-12 11:46:49 | Raspberry Pi Pico
 Raspberry Pi Pico MicroPython でTFTディスプレイにサインとコサインカーブを描いてみました。


 スクリプトです。Picoはクロックが133MHzと速く、MicroPythonインタープリタでもけっこう速くカーブを描くことができます。
-------------------------------------------------------------------------------------------------
from machine import Pin, SPI
import ili9341
from xglcd_font import XglcdFont
import math

#SPI設定
TFT_CLK_PIN = const(6)
TFT_MOSI_PIN = const(7)
TFT_MISO_PIN = const(4)
TFT_CS_PIN = const(13)
TFT_RST_PIN = const(14)
TFT_DC_PIN = const(15)

spiTFT = SPI(0, baudrate=51200000,
                 sck=Pin(TFT_CLK_PIN), mosi=Pin(TFT_MOSI_PIN))
display = ili9341.Display(spiTFT,dc=Pin(TFT_DC_PIN),
             cs=Pin(TFT_CS_PIN), rst=Pin(TFT_RST_PIN),
             width=320, height=240,rotation=90)
#font設定
unispace = XglcdFont('fonts/Unispace12x24.c', 12, 24)
bally7x9 = XglcdFont('fonts/Bally7x9.c',7,9)

#title表示
display.draw_text(100, 0, 'sin', unispace,
                  ili9341.color565(255, 255, 255))
display.draw_text(200, 0, 'cos', unispace,
                  ili9341.color565(255, 255, 0))
#軸線の表示
display.draw_hline(20,120,270,ili9341.color565(255,255,255))
display.draw_vline(20,20,200,ili9341.color565(255,255,255))
display.draw_text(5, 115, '0', bally7x9,ili9341.color565(255, 255, 255))
display.draw_text(5, 20, '1', bally7x9,ili9341.color565(255, 255, 255))
display.draw_text(0, 215, '-1', bally7x9,ili9341.color565(255, 255, 255))

#sine waveを描く
for x in range(0,270):
     y=-int(math.sin(6.283185*x/270)*100)
     display.draw_pixel(x + 20,y+120,ili9341.color565(255,255,255))
#cos waveを描く
for x in range(0,270):
     y=-int(math.cos(6.283185*x/270)*100)
     display.draw_pixel(x + 20,y+120,ili9341.color565(255,255,0))    
-------------------------------------------------------------------------------------------------

Raspberry Pi Pico MicroPython 2.2インチTFT表示テストその2

2022-02-11 21:13:55 | Raspberry Pi Pico
 前の記事に続き、Raspberry Pi Picoで2.2インチTFTの表示テストをします。
 今回は、表示できるフォントのテストをしました。
 GitHubのrdagger/micropython-ili9341 のページのfontsには、15種類のフォントがあります。そのうちいくつかはうまく表示できませんでしたが、今後使えそうなフォントで表示させてみました。


 スクリプトです。比較ができるように色は黄色だけにしました。フォントがロードされるまで、若干時間がかかります。
------------------------------------------------------------------------------------
from machine import Pin, SPI
import ili9341
from xglcd_font import XglcdFont

#SPI設定
TFT_CLK_PIN = const(6)
TFT_MOSI_PIN = const(7)
TFT_MISO_PIN = const(4)
TFT_CS_PIN = const(13)
TFT_RST_PIN = const(14)
TFT_DC_PIN = const(15)

spiTFT = SPI(0, baudrate=51200000,
                 sck=Pin(TFT_CLK_PIN), mosi=Pin(TFT_MOSI_PIN))
display = ili9341.Display(spiTFT,dc=Pin(TFT_DC_PIN),
             cs=Pin(TFT_CS_PIN), rst=Pin(TFT_RST_PIN),
             width=240, height=320,rotation=0)
#font設定
unispace = XglcdFont('fonts/Unispace12x24.c', 12, 24)
bally7x9 = XglcdFont('fonts/Bally7x9.c',7,9)
espresso = XglcdFont('fonts/EspressoDolce18x24.c', 18, 24)
arcadepix = XglcdFont('fonts/ArcadePix9x11.c', 9, 11)

#テキストの表示
display.draw_text(10, 0, 'Unispace12x24', unispace,
                  ili9341.color565(255, 255, 0),spacing=2)
display.draw_text(10, 50, 'Bslly7x9', bally7x9,
                  ili9341.color565(255, 255, 0))
display.draw_text(10, 100, 'EspressoDolce18x24', espresso,
                  ili9341.color565(255, 255, 0))
display.draw_text(10, 150, 'ArcadePix9x11', arcadepix,
                  ili9341.color565(255, 255, 0),spacing=2)
------------------------------------------------------------------------------------

Raspberry Pi Pico MicroPython 2.2インチ TFT表示テストその1

2022-02-10 19:43:18 | Raspberry Pi Pico
 Raspberry Pi Picoで2.2インチのTFTディスプレイの表示テストをします。

 PicoでのTFT表示に関連する記事をネット上で探すと、Hello Raspberry Piというサイトに表示のデモがありました。
 TFTディスプレイの表示方法は、このサイトの動画と記事を見ていただくと分かるのですが、簡単に説明します。

 2.2インチTFTディスプレイには、ILI9341というコントローラが使われています。そこで、Pico用のILI9341ライブラリをGitHubの下のURLから取得します。
このページから、ili9341.pyとxglcd_font.pyをPi Picoにコピーします。コピー方法は、動画を参考にしてください。
上記ページのfontsからUnispace12x24.c というフォントをPi Picoにfontsというフォルダを作り、そこにコピーします。これで準備ができました。

 Hello Raspberry Piのページの説明に従って、いくつかデモのスクリプトを試し、動作(表示)を確認しました。しかし、どうも使い方が良く分かりません。そこで、自分なりにスクリプトを書いてテストをしてみました。

 まず、PicoとTFTの接続回路図です。SPI0を利用します。

テストしたスクリプトです。各図形の描画書式は、ili9341.pyの中で説明されています。
--------------------------------------------------------------------------------------------
'''
Raspberry Pi Pico SPI LIL9341 Display test
2022.2.10
JH7UBC Keiji Hata
'''

from machine import Pin, SPI
import ili9341
from xglcd_font import XglcdFont

#SPI設定
TFT_CLK_PIN = const(6)
TFT_MOSI_PIN = const(7)
TFT_MISO_PIN = const(4)
TFT_CS_PIN = const(13)
TFT_RST_PIN = const(14)
TFT_DC_PIN = const(15)

spiTFT = SPI(0, baudrate=51200000,
                 sck=Pin(TFT_CLK_PIN), mosi=Pin(TFT_MOSI_PIN))
display = ili9341.Display(spiTFT,dc=Pin(TFT_DC_PIN),
             cs=Pin(TFT_CS_PIN), rst=Pin(TFT_RST_PIN),
             width=320, height=240,rotation=90)
#font設定
unispace = XglcdFont('fonts/Unispace12x24.c', 12, 24)

#テキストの表示
display.draw_text(10, 0, 'Hello World!', unispace,
                  ili9341.color565(255, 255, 255))
#点を描く
display.draw_pixel(180,20,ili9341.color565(255, 255, 0))
#水平な線を描く
display.draw_hline(200,20,90,ili9341.color565(255, 0, 0))
#垂直線を描く
display.draw_vline(300,20,100,ili9341.color565(0, 255, 0))
#直線を描く
display.draw_line(200,30,280,80, ili9341.color565(0,0,255))
#円を描く
display.draw_circle(50, 80, 30, ili9341.color565(0,255,255))
#円を描き、内部を塗りつぶす
display.fill_circle(150, 80, 30, ili9341.color565(0,255,255))
#長方形を描く
display.draw_rectangle(20, 150, 70, 50, ili9341.color565(255,0,255))
#長方形を描き、内部を塗りつぶす
display.fill_rectangle(120, 150, 70, 50, ili9341.color565(255,255,0))
#多角形を描く(例6角形)
display.draw_polygon(6,250,110,30,ili9341.color565(255,255,255))
#多角形を描き、内部を塗りつぶす
display.fill_polygon(6,250,180,30,ili9341.color565(255,0,0))

--------------------------------------------------------------------------------------------
色の指定は、color565(R,G,B)で指定します。

ブレッドボードと上記スクリプトの表示結果です。他に楕円を描いたり、反転させたりすることができます。