アトリエ・エクレア

2DCG&3DCG, プログラミング, 日記などを掲載してます。

12歳からはじめる ゼロからの Pythonゲームプログラミング教室

12歳からはじめる ゼロからの Pythonゲームプログラミング教室

2017/5/11発売予定 大槻有一郎 (著), リブロワークスPython部 (著), 雪印 (イラスト)

( ゚Д゚)すごい表紙だ・・・。
お値段が手ごろで素晴らしい。


SmileBASIC プチコン3号

SmileBASIC プチコン3号

自分用の覚書

※間違いがあるかも。

<参考サイト>


<画面構成>

プチコン画面構成.png

<上画面(3Dスクリーン)>
画面奥から、

  1. 背景色:全ての画面の後ろに表示される単色面
  2. グラフィック画面:グラフィック命令で描いた図形が表示される画面
  3. BG画面:ゲームのマップなどを作るための画面。
  4. 1コマ16×16ドットのキャラを、最大128×127個並べて表示できる。
  5. 4層のレイヤーがあり、多重スクロールなどの表現が可能。
  6. SPRITE:ゲームのキャラなどに使用する要素。上画面・下画面合わせて、512個までのSPRITEを使用可能。サイズは16×16ドットを基本(異なるサイズあり)とし、個別に任意のサイズで使用可能。アニメーションを作る命令あり。
  7. コンソール画面:PRINT命令などで文字を書くことができるテキスト画面
グラフィック画面は、コンソール画面の裏側に重なっている存在。
横400ドット×縦240ドットの解像度
X座標: 0~399
Y座標: 0~239
左上が原点(0, 0)  ※右下が(399, 239)

グラフィック解像度: 400×240ドット
座標原点: 左上(0, 0)
X座標:右に向かって+
Y座標:下に向かって+
Z座標:奥に向かって+

<下画面(タッチスクリーン)>
画面構成は上画面と同様だが、画面サイズが異なる。
グラフィック解像度: 320×240ドット
座標原点: 左上(0, 0)

<グラフィックページ>

画面に表示する元画像を置く場所が、全部で6つある(GRP0~GRP5)。
各ページの解像度は 512×512 ドット。※GPR4、GPR5では、16×16ドットのキャラが、横に32個並んでいる。

<画面とグラフィックページの対応>
上画面(DISPLAY 0)
  • グラフィック画面GRP0
  • BG画面GRP5
  • SPRITEGRP4
下画面(DISPLAY 1)
  • グラフィック画面GRP1
  • BG画面GRP5
  • SPRITEGRP4

初期状態では、描画ページと表示ページは同じGRP0(下画面ではGRP1)だが、GPAGE命令で変更可能。

GPAGE :  グラフィック表示ページと操作ページの指定。※GPAGE 4,4 で、GRP4を表示できる。
GCOPY : 他のグラフィックページから画像をコピー。

<上下連続表示>
上下連続表示: XSCREEN 4 で、上下をつないで1枚のように扱うことができる。※上画面の両外側は使えない。

<サンプル>

トップメニュー → 「サンプルを見る」ボタンを押 す → ファイル一覧から選んで実行。
DIRECTモード → LOAD "SYS/ファイル名" → 実行する。※STARTボタンで停止できるものと、できないものがある。

<基本サンプル>
BASICの基本的な命令を利用した学習用のサンプルプログラム。

  • EX1TEXT :  コンソールへの文字表示
  • EX2CALC :  文字入力を使った簡易計算機
  • EX3KEYDRUM :  キーボードを使った簡易鍵盤とドラム
  • EX4NUMGAME :  数当てゲーム
  • EX5BIORHYTHM :  バイオリズムのグラフィック表示
  • EX6SEQUENCER :  タッチ操作を使った簡易シーケンサー
  • EX7ALIEN :  複数の敵を動かして弾を発射するデモ
  • EX8TECDEMO :  命令ごとの説明と技術評価用デモ

<高度なサンプル>
様々なBASIC命令を駆使したサンプルプログラム。

  • GAME1DOTRC :  敵の攻撃をよけながら画面上のドットをすべて消す絵文字で作ったレースゲーム
  • GAME2RPG :  敵を倒しながら3D風ダンジョンを進むロールプレイングゲーム
  • GAME3JUMP :  敵や障害物をよけながらゴールを目指す横スクロールジャンプアクションゲーム
  • GAME4SHOOTER :  ステージが進むと強化される敵を倒してスコアを稼ぐ弾幕シューティングゲーム
  • GAME5VS :  大きなキャラクターが剣で戦うシンプルな対戦型格闘ゲーム
  • GAME6TALK :  適当な質問に答えると適当な答えが返ってくるナンセンスな占い?ゲーム
  • GAME7EXPAD :  拡張スライドパッド専用。スティックを使ったお手玉ゲーム

<基本>

<基本的な事項>

  • 文字列はダブルクォーテーション( " )で囲む。
  • 条件式において、数値変数または数値が、0なら結果はFALSE(0)、0以外なら結果はTRUE(1)となる。
  • カーソルの左側に命令が無い状態で、HELPボタン(?マーク)を押すと、ヘルプの操作方法や、命令の一覧等を表示できる。
  • 行ごとに一気に削除したい場合は、SELを選んで、十字キー上下で選択して、バックスペース(またはYボタン)が便利。
  • DIRECTモード時、十字キー上下で履歴
  • 小数の演算では誤差が生じる場合があるので要注意。FOR~NEXTのSTEPで、小数を扱うときは誤差に注意。


<モード>

  • DIRECTモード: コンピューターに命令を直接与えるモード。命令をひとつひとつ、入力するたびに実行する。DIRECTボタンで切り替える。
    ※実行するには、ENTERキー(またはAボタン)を押す。
  • EDITモード: プログラムを入力するためのテキスト編集モード。複数の命令をEDITボタンで切り替える。
    ※実行するには、DIRECTモードに移りRUN命令を実行するか、EDITモードのままSTARTボタンを押す。


<プログラミング時(EDITモード時)の操作>

  • 十字ボタン :  カーソル移動。
  • Aボタン :  Enterキーと同じ。
  • Yボタン :  BSキーと同じ。
  • Lボタン :  SHIFTキーとほぼ同じ。
                   ※SHIFTキーとの違い:
                    Lボタンを押しながら、十字ボタンの上下でページ単位(画面単位)の移動、左右で行頭・行末へ移動 (スライドパッド
    )
  • Rボタン :  SHIFTキーと同じ。
  • STARTボタン :  プログラムを実行。実行中の時は、プログラムを中断する。
<プログラム読み書き支援機能>
Lボタン(or SHIFTキー)で、ファンクションキー部分に、ファイルの読み書き支援用ボタンが表示される。

<命令入力支援機能>  ※Visual Studioのインテリセンスみたいなもの。
最初の数文字を入力すると、入力候補選択エリアに、該当する命令を一覧表示。さらに続けて文字を入力すると候補が絞り込まれる。

<命令>
RUN :  (EDITモードで入力した)プログラムを実行する。※DIRECTモードで実行する。
  ※EDITモードのまま、STARTボタンで、RUN命令を記述せずに直接実行することが可能。実行中にSTARTボタンで停止
NEW :  (EDITモードで入力した)プログラムを消去する。※DIRECTモードで実行する。
  ※全てのプログラムSLOTが消去される(引数で限定可能)。
SAVE :  プログラムを保存する。※DIRECTモードで実行する。
  ※使用できる文字: 英数字と_(アンダースコア)
  ※引数でファイル名だけ指定した場合、プログラムSLOT0の内容が保存される。
  SLOT1, SLOT2, SLOT3 の場合は、それぞれファイル名の前にPRG1:, PRG2:, PRG3: を付ける。
  ※Lボタン(or SHIFTキー)で、ファンクションキー部分に、ファイルの読み書き支援用ボタンを表示して、保存することも可能(SAVEボタン)。
LOAD :  プログラムを読み込む。プロジェクト内のファイルの場合、"プロジェクト名 / ファイル名" の形式で指定する。
  ※引数でファイル名だけ指定した場合、プログラムSLOT0に読み込まれる。
  SLOT1, SLOT2, SLOT3 の場合は、それぞれファイル名の前にPRG1:, PRG2:, PRG3: を付ける。
  ※Lボタン(or SHIFTキー)で、ファンクションキー部分に、ファイルの読み書き支援用ボタンを表示して、読み込むことも可能(LOADボタン)。
FILES :  SDメモリーカードに保存したファイルの一覧を、コンソール画面に表示
DELETE :  SDメモリーカードに保存したファイルを、ファイル名を指定して削除する。
ACLS :  描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
CLS :  コンソール画面を消去。※グラフィック画面は消えない。
GCLS :  グラフィック画面を消去する(※コンソール画面は消えない)。色コードを指定した塗りつぶしも可能。
COLOR :  コンソール画面の表示色を指定。
RGB() :  8ビットRGB値をもとに色コードを得る。
RGBREAD :  色コードからRGBの各成分を得る。
PRINT :  文字(文字列)を表示する。

<グラフィック命令>

一般にGで始まる命令は、グラフィック画面に対する命令
GCLS :  グラフィック画面を消去する(※コンソール画面は消えない)。色コードを指定した塗りつぶしも可能。
ACLS :  描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
CLS :  コンソール画面を消去。※グラフィック画面は消えない。
GPAGE :  グラフィック表示ページと操作ページの指定。※GPAGE 4,4 で、GRP4を表示できる。
GCOPY : 他のグラフィックページから画像をコピー。
GLINE :  グラフィック画面に直線を引く
GCOLOR :  グラフィック描画色の指定
GPSET :  グラフィック画面に点を打つ
GBOX :  グラフィック画面に四角形を描く
GFILL :  グラフィック画面に四角形を描いて塗りつぶす
GCIRCLE :  グラフィック画面に円を描く
GPAINT :  グラフィック画面を塗りつぶす
GTRI :  グラフィック画面に三角形を描いて塗りつぶす
GPUTCHR :  グラフィック画面に文字を描く
GSPOIT() :  グラフィック画面の指定座標の色を取得

<サウンド命令>

BEEP :  音を出す。周波数、音量、パンポットの調整などが可能。
BGMPLAY :  音楽演奏 ※トラック番号省略時は0番。
MML(Music Macro Language)を使用した音楽演奏も可能。MMLと入力してHELPボタンで詳しい説明が見られる。
BGMSTOP :  音楽演奏停止 ※フェードアウトが可能。

・特にサウンド系の命令というわけではないが、併用すると便利な命令
WAIT :  指定回数分の垂直同期が来るまでプログラム停止。引数にはフレーム数を指定。※デフォルトで60fpsなので、60で1秒待つことになる。

<立体視>

上画面のみ対応。
奥行き座標(Z座標)の設定  ※Z=1024(引っ込む), Z=0(奥行きなし), Z=-256(飛び出す)

  • コンソール画面 :  LOCATE命令
  • グラフィック画面 :  GPRIO命令
  • スプライト :  SPOFS命令
  • BG :  BGOFS命令

<カラー指定>

画面全体で65536色のカラーを使用できる。
・グラフィックページでは、ドット単位で32768色が使用可能。RGB関数で指定する。
※内部的にはRGB各色5ビット+透明1ビット(RGBA=5551)となるが、指定の際にはRGB関数を利用し、RGB各8ビットとして指定する。
2^5 * 2^5 * 2^5 = 2^15 = 32768
・コンソール画面(テキスト)では、透明色を含む16色から選択する。文字色と文字の背景色を設定できる。

<BG>

BGは、Back Groundの略。"BG画面"、"BGスクリーン" とも呼ぶ。
BG画面は4枚のレイヤーが重なった構造(レイヤー番号:0~3)になっており、それぞれにBGキャラを配置できる。
4枚のレイヤーは、いずれも上画面に表示されている。
デフォルトでは、レイヤー0~3は、いずれも上画面と同じサイズ(400×240)。※横25個×縦15個=375個 のBGキャラを配置できる。
16×16ドットのBGキャラを並べて背景画面を作る。
16×16ドット単位で配置する。※1ドット単位ではない。
BGキャラは、GRP5(グラフィックページ5)にあらかじめ読み込まれている。※横32個×縦32個=1024個
1つのキャラは16×16ドット。

0~1023までのキャラ番号が付いている。

BGキャラはBG画面に配置して、画面に表示される。※BGPUT命令などでBG画面に配置するだけですぐ使える。
BG画面はキャラ単位の座標を持つ。
1画面には、横に25キャラ、縦に15キャラ並ぶ。
BGSCREEN命令で、画面を超える大きさのBG画面を使用可能。

左上が原点(0, 0)  ※右下(24, 14)
X座標 0~24  ※横
Y座標 0~14  ※縦
1つのキャラは16×16ドット

各レイヤーの表示位置は、BGOFS命令により、ドット単位で変更できる。→ スクロールが可能。
重ね順は、BGOFS命令でZ座標を指定することで変更可能。3D表示の奥行きにも関係する。

<BGスクリーンの移動方法> ※スクロールなど。

  • BGOFS命令を繰り返す。
    ※表示物が、逆方向に動いているように見えるので注意。例えば、X座標を-1オフセットすると、表示物は右に+1動いたように見える。
  • BGANIM命令で動かす。


<BGのアニメーション>

BGANIM :  BGによるアニメ表示。
配列で指定する方法、DATA命令で指定する方法、直接引数として指定する方法がある。
アニメ対象(変化させる要素)は、いろいろと指定できる。
時間(フレーム数)にマイナス値を指定すると、直前の値から線形補間を行う。

※BGキャラを並べるときはキャラ単位。
※BGOFSやBGANIMでの移動は、BG座標に対して、3DS画面を移動させていくような指定になるので注意。また、移動はキャラ単位ではなくドット単位なので注意。


BGPUT :  BGキャラを、BG画面の指定したレイヤーに配置する
BGFILL :  BGスクリーンをBGキャラで塗りつぶし。指定した矩形領域を、1つのBGキャラで埋める
BGOFS :  BGスクリーンの表示オフセットを変更 / BGの座標を得る。
  ※表示物が、逆方向に動いているように見えるので注意。例えば、X座標を-1オフセットすると、表示物は右に+1動いたように見える。
BGCLR :  BGスクリーンを消去。レイヤー指定が可能。
BGSCREEN :  BGスクリーンのサイズをレイヤーごとに設定
BGSCALE :  BGスクリーンの拡大縮小。
BGROT :  BGスクリーンの回転。
BGHOME :  レイヤーの表示原点設定。※BGスクリーンに対する回転や拡大縮小の原点
BGCOPY :  BGスクリーンをキャラ単位でコピー。※BGスクリーンの指定範囲を他の位置にコピーする。
BGANIM :  BGによるアニメ表示。
BGCOORD :  ディスプレイ座標とBGスクリーン座標との変換。※名前はcoodinate(座標)から???
BGGET() :  BGスクリーンのBGキャラ情報を得る。

<SPRITE>

基本16×16ドットのキャラ(異なるサイズあり)を、1つの動く物体として画面に表示する。大きさは任意に設定できる。画面には最大512個まで表示可能。

  • 最大512個を同時に表示できる。
  • サイズ(幅×高さ)を自由に定義できる。
  • 回転、拡大、縮小の機能がある。
  • 衝突判定の機能がある。
  • スプライト間に親子関係を設定できる
  • 半透明化の機能がある。
  • 内部変数の読み書きができる。
SPRITE用キャラは、GRP4(グラフィックページ4)にあらかじめ読み込まれている。
キャラの基本サイズは16×16ドットだが、それ以外のサイズもある。
※SPSET命令で任意の管理番号のSPRITEに割り当てる。管理番号: 0~511

表示するSPRITEは、SPSET命令で512個まで準備できる。それぞれの番号のSPRITEに、どの番号のキャラ定義を割り当てるかを設定する。
SPRITEの表示座標はSPOFS命令を使い、ドット単位で指定する。※BGと違いキャラ単位の座標ではない。

左上が原点(0, 0)  ※右下(399, 239)
X座標 0~399  ※横
Y座標 0~239  ※縦
中心座標 (200, 120)

<SPRITEの重ね順>
SPLITEの重ね順
  • 重ね順は、Z座標を指定することで変更可能。
  • BGのZ座標と同列に扱われるので、BGの手前に出したり、奥に隠したりできる。
  • Z座標は、3D表示の奥行きにも関係する。
  • SPOFS命令で、表示位置と奥行きを指定できる。

<SPRITEの表示>
ACLS ' 描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
SPSET 0, 12  ' テンプレートの定義番号0012の画像を管理番号0のSPRITEに設定 ※この時点で原点(0, 0)に描画される
SPOFS 0, 400/2-16/2, 240/2-16/2 ' 管理番号0のSPRITEを、画面の中心に描画

<SPRITEの移動方法>
SPLITEの移動方法

  • SPOFS命令を繰り返す。
  • SPANIM命令で動かす。


<SPRITEのアニメーション>
SPANIM :  SPRITEによるアニメ表示。
SPCHK() : SPRITEのアニメーション状態を取得。全て0の時、アニメ停止中。

  • 配列で指定する方法、DATA命令で指定する方法、直接引数として指定する方法がある。
  • アニメ対象(変化させる要素)は、いろいろと指定できる。
  • アニメ開始はSPANIMを実行した次フレームから。
  • 時間(フレーム数)にマイナス値を指定すると、直前の値から線形補間を行う。

SPANIMのループ処理。

'==========================
'TEST_SPANIM_01
'==========================

ACLS

CNT=0 'FRAME-COUNT

SPSET 0,0
SPOFS 0,100,100            '初期位置
SPANIM 0,"XY",-5,200,200,3 '3回ループ

PRINT "FRAME-COUNT,X,Y"

@LOOP
SPOFS 0 OUT X,Y
PRINT CNT;",";X;",";Y 'FRAME-COUNT,X,Y
IF CNT==19 THEN END   '適当に、多めにループさせてみる
INC CNT
VSYNC 1
GOTO @LOOP

'===============================================
' 結果:
'  ループ中は、初期位置(100,100)では表示されないことがわかる。
' 
' FRAME-COUNT,X,Y
' 0,100,100
' 1,100,100   '0 開始
' 2,120,120   '1
' 3,140,140   '2
' 4,160,160   '3
' 5,180,180   '4
' 6,200,200   '5     0
' 7,120,120   '      1
' 8,140,140   '      2
' 9,160,160   '      3
' 10,180,180  '      4
' 11,200,200  '      5     0
' 12,120,120  '            1
' 13,140,140  '            2
' 14,160,160  '            3
' 15,180,180  '            4
' 16,200,200  '            5 終了
' 17,200,200
' 18,200,200
' 19,200,200

SPANIMの最後のフレームで、初期位置に戻してループさせる。

'==========================
'TEST_SPANIM_02
'==========================

ACLS

CNT=0 'FRAME-COUNT

SPSET 0,0
SPOFS 0,100,100       '初期位置
SPANIM 0,"XY",-5,200,200,1,100,100,3 '3回ループ

PRINT "FRAME-COUNT,X,Y"

@LOOP
SPOFS 0 OUT X,Y
PRINT CNT;",";X;",";Y 'FRAME-COUNT,X,Y
IF CNT==19 THEN END   '適当に、多めにループさせてみる
INC CNT
VSYNC 1
GOTO @LOOP

'===============================================
' 結果:
' 
' FRAME-COUNT,X,Y
' 0,100,100
' 1,100,100   '0 開始
' 2,120,120   '1
' 3,140,140   '2
' 4,160,160   '3
' 5,180,180   '4
' 6,200,200   '5
' 7,100,100   '6     0
' 8,120,120   '      1
' 9,140,140   '      2
' 10,160,160  '      3
' 11,180,180  '      4
' 12,200,200  '      5
' 13,100,100  '      6     0
' 14,120,120  '            1
' 15,140,140  '            2
' 16,160,160  '            3
' 17,180,180  '            4
' 18,200,200  '            5
' 19,100,100  '            6 終了
' 20,100,100
' 21,100,100
' 22,100,100
' 23,100,100
' 24,100,100

SPANIMの最初のフレームで、初期位置に戻してループさせる。

'==========================
'TEST_SPANIM_03
'==========================

ACLS

CNT=0 'FRAME-COUNT

SPSET 0,0
'SPOFS 0,100,100       '初期位置
SPANIM 0,"XY",1,100,100,-5,200,200,3 '3回ループ

PRINT "FRAME-COUNT,X,Y"

@LOOP
SPOFS 0 OUT X,Y
PRINT CNT;",";X;",";Y 'FRAME-COUNT,X,Y
IF CNT==19 THEN END   '適当に、多めにループさせてみる
INC CNT
VSYNC 1
GOTO @LOOP

'===============================================
' 結果:
' 
' FRAME-COUNT,X,Y
' 0,0,0
' 1,0,0       '0 開始
' 2,100,100   '1
' 3,120,120   '2
' 4,140,140   '3
' 5,160,160   '4
' 6,180,180   '5
' 7,200,200   '6     0
' 8,100,100   '      1
' 9,120,120   '      2
' 10,140,140  '      3
' 11,160,160  '      4
' 12,180,180  '      5
' 13,200,200  '      6     0
' 14,100,100  '            1
' 15,120,120  '            2
' 16,140,140  '            3
' 17,160,160  '            4
' 18,180,180  '            5
' 19,200,200  '            6 終了
' 20,200,200
' 21,200,200
' 22,200,200
' 23,200,200
' 24,200,200

<SPRITEの内部変数>
各SPRITEは、8個の内部変数(内部変数番号0~7)を持つ。内部変数は、数値を扱うことができ、文字は扱えない。
SPVAR :  SPRITE用内部変数への書き込み。
SPVAR() :  SPRITE用内部変数の読み込み。

ACLS  ' 描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
SPSET 0,3  ' 管理番号0のスプライトに、テンプレートの定義番号3の画像を割り当てる
SPOFS 0,400/2-16/2,240/2-16/2  ' 管理番号0のスプライトを画面の中心にオフセット
SPVAR 0,5,777  ' 管理番号0のスプライトの、内部変数番号5の内部変数に、777を代入
FOR I=0 TO 7
 ' 管理番号0のスプライトの、内部変数を全て読み込む。改行無し、コンマ区切りで表示。
 PRINT SPVAR(0,I);",";  ' 結果: 0,0,0,0,0,777,0,0,
NEXT

<SPRITE同士の衝突判定>
SPCOL命令で衝突判定情報を設定し、SPHITSP関数で衝突判定を行う。
SPCOL実行後、SPHITSP実行前に、必ず、SPOFSまたはSPANIMで位置情報を更新する。
且つ、位置は一度、原点以外にする。その後は、直後に原点にしても良い。

1) SPCOL命令で、衝突判定の対象にしたいSPRITEを指定する(範囲指定可能)。
2) SPOFSまたはSPANIMで位置情報を更新する。※SPCOLとSPHITSPの間で実行すること。
3) SPHITSP関数で、引数に指定したSPRITEの衝突判定を行う。

SPOFSを、プログラム中に全く実行しなかった場合
・衝突判定するが、スケールが対応しない。→ ダメ。

SPCOL実行の前に、SPOFSを実行した場合
・位置が(0,0)だと、衝突判定するが、スケールが対応しない。→ ダメ。
・位置が(0,0)以外だと、衝突判定するが、スケールが対応しない。→ ダメ。
SPCOL実行の後に、SPOFSを実行した場合
・位置が(0,0)だと、衝突判定するが、スケールが対応しない。→ ダメ。
・位置が(0,0)以外だと、衝突判定する、スケールも対応する。→ 良さそう

SPCOL実行の後に、SPOFSで位置を(0,0)以外にして、その直後に位置を(0,0)にした場合
・位置を(0,0)にしたにも関わらず、衝突判定する、スケールも対応する。→ 良さそう
SPCOL実行の前に、SPOFSで位置を(0,0)以外にして、その直後に位置を(0,0)にした場合
・衝突判定するが、スケールが対応しない。→ ダメ。

SPCOLの後、SPOFSまたはSPANIMを実行しなかった場合、SPHITSPによる衝突判定が、おかしな挙動になる。
また、SPCOLの後に、SPOFSを実行しても、位置が(0,0)だと、おかしな挙動になる。(1,0)か(0,1)にしてみるとうまくいく。(0.1,0)などでもうまくいく。
SPCOL実行の後に、SPOFSで位置を(0,0)以外にして、その直後に位置を(0,0)にした場合はうまくいくことから、一度(0,0)以外に動かせば大丈夫らしい。

( ゚Д゚)意味不明・・・。バグなのか???

SPCOL実行後は、必ず、SPHITSP実行前に、SPOFSまたはSPANIMで位置情報を更新する。
且つ、位置は
一度、原点以外にする。その後は、直後に原点にしても良い。

'==========================
'TEST_COLLISION
'==========================

ACLS

'いちご======================
SPSET 0,0
SPSCALE 0,2,2
SPCOL 0,TRUE
SPOFS 0,1,0 '直後に、原点に戻す

'みかん======================
SPSET 1,1
SPCOL 1
X=70:Y=20
SPOFS 1,X,Y

@LOOP
GOSUB @MOVE_MIKAN
IF SPHITSP(1,0) THEN SPCOLOR 1, RGB(255,0,0) ELSE SPCOLOR 1,RGB(255,255,255)
VSYNC 1
GOTO @LOOP

@MOVE_MIKAN
B=BUTTON()
IF B AND #UP    THEN DEC Y '1
IF B AND #DOWN  THEN INC Y '2
IF B AND #LEFT  THEN DEC X '4
IF B AND #RIGHT THEN INC X '8
SPOFS 1,X,Y
RETURN

SPCOL :  SPRITE衝突判定情報の設定。範囲指定可能。
SPHITSP :  SPRITEの衝突判定。衝突したSPRITEの管理番号を返す(衝突無し -1)。
※SPCOLで衝突判定領域を設定したSPRITE同士で、衝突判定する。
※複数のSPRITEと衝突していても、返すのは、最も若いSPRITE管理番号ひとつだけなので要注意。
必ず衝突判定させたいもの毎にSPHITSPを実行させるなど、工夫が必要。

※存在していないSPRITEのID範囲であっても、指定は可能。→ いずれ使用するであろう範囲を、指定しておくことができる。

<自前のSPRITEの定義>
1) LOAD "GRP4:ファイル名" で、作ったスプライトファイルを読み込む。
2) SPDEF命令で、読み込んだスプライトから任意の領域を切り取って、定義番号にセット。

SPSET :  SPRITEを準備する。矩形での範囲指定可能。表示するSPRITEをメモリー上に準備して画面に表示する。
SPOFS :  SPRITEの座標の変更(移動)、または、SPRITEの座標を得る
SPCHR :  SPRITEのキャラクタ定義を変更。※キャラ画像だけ変更し、その他の設定はそのまま。
SPDEF :  SPRITEのキャラクタ定義用テンプレートを作成。
SPSCALE :  SPRITEを拡大縮小。
SPROT :  SPRITEの回転角度指定。※回転角度は度数法(0~360度)で指定する。正で時計回り、負で反時計回り。
SPHOME :  SPRITEの基点を変更する。
SPHIDE :  SPRITE表示を隠す。
SPSHOW :  隠れているSPRITEを表示する
SPCOLOR :  SPRITEの表示色を設定。透明度の設定が可能(0~255の256段階)。
SPANIM :  SPRITEによるアニメ表示。
SPCHK() :  SPRITEのアニメーション状態を取得。全て0の時、アニメ停止中。
SPLINK :  SPRITEを別のSPRITEにリンク。リンクは座標のみ(回転角度や倍率情報は対象外)。
リンク先(親)指定は自分よりも小さい管理番号のみ。
SPUNLINK :  SPLINK命令による連結を切り離す。
SPCLR :  指定SPRITEの使用をやめて、メモリーを解放。

<コンソール出力>

PRINT :  コンソール画面への文字表示。
式を省略すると改行のみ行う。
セミコロン( ; ) 表示後に改行せず、次の表示を密着させる。
カンマ( , ) 表示後に改行せず、次の表示を一定間隔開ける。※システム変数のTABSTEP単位に従う。

LOCATE :  コンソール画面への文字表示位置を指定。
X座標は右方向の文字数 (0~49) ※XSCREEN 4 と下画面(0~39)
Y座標は下方向の文字数 (0~29)
表示位置には奥行き(Z座標)も指定可能。画面奥は0~1024、画面手前は0~-256で指定。

CLS :  コンソール画面を消去。※グラフィック画面は消えない。
ACLS :  描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
GCLS :  グラフィック画面を消去する(※コンソール画面は消えない)。色コードを指定した塗りつぶしも可能。

<演算子>

<算術演算子>

  • +   加算
  • -   減算
  • *   乗算
  • /   除算
  • MOD   剰余
  • DIV   整数同士(それぞれの数値の小数点以下は切り捨て)の除算。結果も整数(小数点以下は切り捨て)。

<比較演算子>
式が評価された結果、真なら1、偽なら0を返す。

  • ==   等しい
  • !=   等しくない
  • >   より大きい
  • <   より小さい
  • >=   以上
  • <=   以下

<論理演算子> 複数条件の比較用

  • 条件1 && 条件2     論理積。同時に満たす。
  • 条件1 || 条件2     論理和。いずれかを満たす。 ※ || の文字は、キーボード上で ? の左上にある。
  • 条件1 AND 条件2     ビット論理積。同時に満たす。
  • 条件1 OR 条件2     ビット論理和。いずれかを満たす。

<コメント>

コメント記述用の記号として、アポストロフィー( ' )を使う。REM命令と同じ。※REMARK(コメント)
コメント内容は、プログラム実行に影響しない。

<命令を区切る>

コロン( : )複数の命令を区切って1行に書くことができる。

X=20:Y=30

<論理値>

論理値(真偽値, 真理値)

  • TRUE :  論理値の「真」。※TRUEの値は常に1である。
  • FALSE :  論理値の「偽」。※FALSEの値は常に0である。


※条件式において、数値変数または数値が、0なら結果はFALSE(0)、0以外なら結果はTRUE(1)となる。

<変数>

変数には、数値変数、文字列変数がある。
※変数名は1文字でなくても良い。英字で始まり、英数字とアンダースコア( _ )からなる任意の長さの名前が付けられる。

<数値変数>

  • 宣言時の型指定は、特に無い。
    サフィックスにより、型指定が可能。%で整数型。#で実数型。無指定(デフォルト)は実数型。
  • プログラム動作モードとして、OPTION STRICT指定の時は、全ての変数宣言が必要。※VAR命令やDIM命令で変数宣言できる。
  • 宣言時は、自動的に0で初期化される。
  • 文字列は代入できない。


<文字列変数>

  • 文字列変数は、変数名の末尾に$記号を付けて表す。
  • 文字列変数同士は、足し算によって結合できる。
A$ = "HELLO "
B$ = "WORLD"
C$ = A$ + B$
PRINT C$    ' HELLO WORLD

<変数のインクリメントとデクリメント>

変数のインクリメントとデクリメント
INC :  変数の値を+1。加算する値を指定可能(省略時:1)。
DEC :  変数の値を-1。減算する値を指定可能(省略時:1)。

<数値と文字列の変換>

・数値から文字列
FORMAT$():  表示書式を使って、値を整形し、文字列化する。
STR$() :  数値から文字列を得る。

・文字列から数値
VAL():  文字列から数値を得る。※数値になり得ないような文字列を指定した場合、0が返る。

<命令と関数>

<命令>
ACLS :  描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
INPUT :  キーボードから数値または文字列を入力。入力用のガイドメッセージを表示できる(省略可)。変数は複数指定可能。
IF~THEN ~ELSE~ENDIF :  条件分岐。ELSEとENDIFはオプション。処理が複数行にわたるときはENDIFを使用。
※一行で済む場合はENDIFはいらず、コロンで区切ることで、複数の処理も可能。
FOR~NEXT :  処理を指定回数繰り返す。STEP増分は、省略時は1。※STEPで増分を指定する際に、小数を扱うときは誤差に注意。
WHILE~WEND :  条件が成立している間、WENDまでを繰り返す。
BREAK :  ループから強制的に抜ける。
END :  プログラムを終了。プログラムを途中で終了させることができる。プログラムは最後の行に達すると終了するので、必ずしも必要ではない。
GOSUB @ラベル :  サブルーチンの呼び出し。サブルーチンからは、RETURN命令で、元のルーチンに戻れる。
GOTO @ラベル :  強制分岐。ラベルに強制ジャンプする。
ON~ GOTO @ラベル :  制御変数の値に合わせて、ラベル行に分岐。
ON~ GOSUB @ラベル :  制御変数の値に合わせて、サブルーチン呼び出し。

<関数>
RND() :  整数の乱数を得る(0~最大値-1まで)。
BUTTON() :  ハードウェアボタンの状態取得。各ボタンに対応した数値を返す。何も入力が無い場合は0を返す。
LEN() :  文字列内の文字数を得る / 配列の要素数を得る
RAD() :  度からラジアンを求める。度:0~360
SIN() :  サイン値を返す。角度はラジアンで指定する。
COS() :  コサイン値を返す。角度はラジアンで指定する。
TAN() :  タンジェント値を返す。角度はラジアンで指定する。

<ユーザー定義関数>

' ユーザー関数の定義例
DEF ADD(X, Y)   ' DEFからENDまでが定義範囲
 RETURN X+Y    ' 戻り値
END

<ユーザー定義命令>

' ユーザー命令の定義例
DEF FUNC_ADD  X, Y   ' DEFからENDまでが定義範囲
 PRINT X+Y
END

' 呼び出し
FUNC_ADD  10, 5   ' 結果は、15 と表示される

<配列>

配列の宣言
DIM :  使用する配列を宣言。※複数宣言するときは、カンマで区切る。

ACLS ' 描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
DIM RGB$[3]   ' 配列を宣言 ※要素数3の文字列変数RGB$の配列

' 各要素への、値の代入
RGB$[0] = "RED"
RGB$[1] = "GREEN"
RGB$[2] = "BLUE"

' 全ての要素を表示してみる
FOR I=0 TO LEN(RGB$)-1   ' LEN() : 配列の要素数を得る
 PRINT RGB$[I]   ' セミコロン無しなので、改行しながら表示
NEXT

UNSHIFT :  配列の先頭に要素を追加(要素数が1つ分増える)。

<配列変数に配列変数を代入>

  • 配列変数に、配列変数を代入することができる。
    ※Javaにおける、配列変数への配列変数の代入による、参照のコピーのイメージ。要素が複製されるわけではなく、それぞれの配列変数が、同一の要素を参照することになる。
    ※同一の実体を参照するため、ある配列で要素を変更すると、別の配列でも影響を受けるので注意。
    ※C言語では、配列変数への配列変数の代入は不可。ポインタへの配列変数の代入は可能。
  • ユーザー定義関数の戻り値としても、配列が利用可能。
  • 実体が異なる配列のコピーは、COPY命令で可能。


COPY :  配列を他の配列にコピー

ACLS ' 描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
DIM A[3] '要素数3の配列を宣言
A[0]=123
A[1]=456
A[2]=789

DIM B[0] '適当な要素数の配列を宣言
B=A ' 配列変数に配列変数を代入。※参照のコピー
PRINT B[0] '123(改行)
PRINT B[1] '456(改行)
PRINT B[2] '789(改行)

<サブルーチン>

GOSUB @ラベル :  サブルーチンの呼び出し。サブルーチンからは、RETURN命令で、元のルーチンに戻れる。
ON~ GOSUB @ラベル :  制御変数の値に合わせて、サブルーチン呼び出し。
ON~ GOTO @ラベル :  制御変数の値に合わせて、ラベル行に分岐。

'良くない例
'エラー RETURN without GOSUB

GOSUB @MYSUB

@MYSUB
 PRINT "テスト"
RETURN
'良い例
'エラー無し

GOSUB @MYSUB
END

@MYSUB
 PRINT "テスト"
RETURN

<垂直同期>

VSYNC :  Vertical Sync(垂直同期)の略。垂直同期と、同期を取る。
指定回数分の垂直同期が来るまでプログラム停止。WAITとは異なり、前回のVSYNCからのVSYNC回数。
引数には、前回のVSYNCからの経過フレーム数を指定。
※ループ内に VSYNC 1 で、そのループが1秒間に最大60回までしか繰り返さないように制限できる。
プチコン3号では、1/60秒間隔で垂直同期イベントが発生する。

垂直同期までに処理が完了しなかった場合、VSYNC命令の処理は無視される。
例えば、もしも、ループ内でVSYNC 1を実行している状況において、
ループ内の処理が1/60秒間で完了しなかった場合、VSYNC 1の処理は無視される。

プチコン3号では、ループ内の処理が軽く、ループの最後にVSYNC 1を記述した場合は、60fpsとなる。

' 60fps
@GAMELOOP
VSYNC 1 ' 指定回数分の垂直同期が来るまでプログラム停止
GOTO @GAMELOOP

<フレームカウント>

MAINCNT :  システム変数。SmileBASIC起動時からのフレームカウント数。
※1/60秒ごとに値が自動的に+1される。
→ 任意の変数をループ内でインクリメントした場合の実際のフレーム数に対して、処理が重い場合にフレーム数に差が出る場合がある。これを利用してFPSを算出できる。

<画面モード>

XSCREEN :  画面モードの設定
DISPLAY :  操作対象の上下画面を選択(0:上画面, 1:下画面)。

' 下画面を操作する場合
ACLS ' 描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
XSCREEN 3 ' 画面モードを2または3にする。
DISPLAY 1  ' 操作対象を下画面にする。

<入力>

BUTTON() :  ハードウェアボタンの状態取得。各ボタンに対応した数値を返す。何も入力が無い場合は0を返す。
STICK :  スライドパッドの情報取得
TOUCH :  タッチ情報取得

<漢字>

スマイルブーム公式サイトの文字コード表→LINK

<CHR$()関数で、文字コードを指定する方法>

UTF-16の文字コードを使用できる。
※プログラム実行が必要なので、コメント文には使えない。
※16進数表記: SmileBASIC, BASICでは&Hを前置する。C,C++では0xを前置。

ACLS ' 描画設定をBASIC起動時の状態に戻す。※サウンド設定には影響しない。
COLOR #TCYAN
PRINT "プチコン3";CHR$(&H53F7)  'UTF16文字コードでは、号はコードポイントU+53F7。16進数表記のための&Hを前置。

CHR$() :  指定された文字コードから文字を返す

<DIRECTモードで、プログラムSLOT 0 以外にKANJITBLを読み込み、漢字テーブルから1文字ずつコピー&ペーストする方法>
※コピペするだけなので、コメント文にも漢字が使える。

' DIRECTモードでLOAD "PRG1:SYS/KANJITBL"を実行しておく
PRINT "プチコン3号" ' 漢字をSLOT 1からコピペで持ってくる

※SLOT 1の内容を消したい場合は、NEW 1を実行

<データ>

READ~ DATA:  データを扱う。
※ループで連続的にDATA命令のデータを読み込む場合、最後のデータを、""や、0 にしておき、条件判断でループを抜けると良い。

READ :  DATA命令で列挙した情報を変数に読み込む
RESTORE :  READ命令が読み込む先頭データを指定。※READ命令が読みに行く先のDATA命令をラベルを使って指定できる。
DATA :  READで読み込むデータの定義。数値も文字列も混在可能。

<乱数>

RND() :  整数の乱数を得る。引数には最大値を指定する(0~最大値-1までを返す)。
RANDOMIZE :  乱数系列の初期化。※引数のシードIDとシード値が、毎回同じで実行すれば、RND()関数で、毎回同じ乱数を生成することが可能。

<コールバック>

各々のスプライトやBGから、サブルーチンを呼び出すことができる。
コールバックとして設定したサブルーチンは、CALL SPRITE命令、または、CALL BG命令を実行したタイミングで呼び出される。
SPFUNC :  SPRITEごとに処理を割り当て。CALL SPRITE により全SPRITEの処理を実行
BGFUNC :  BGレイヤーごとに処理を割り当て。CALL BG により全BGレイヤーの処理を実行
CALLIDX :  システム変数。SPFUNCおよびBGFUNCで呼び出された番号。
CALL SPRITE :  SPRITEコールバックの呼び出し。SPFUNCで設定されたSPRITE毎の処理を一斉呼び出し。
CALL BG :  BGコールバックの呼び出し。BGFUNCで設定されたBG毎の処理を一斉呼び出し。






実践力を身につける Pythonの教科書

実践力を身につける Pythonの教科書

クジラ飛行机 (著)

2016/10/26 発売

(*'ω'*)早く読みたい。



Win32 API

Win32 API

※自分専用の覚え書き

<参考文献>

  • msdn "Win32 アプリケーションの作成 (C++)" → Link
  • msdn "C++ による Windows プログラミングの学習" → Link

Win32 アプリケーション

クリックするとメッセージボックスが出るウィンドウ

// プリプロセッサ ディレクティブ
#include <windows.h>                      // Win32 API を使用するためインクルード
#include <tchar.h>                        // TCHAR型 ※char型かwchar型に置き換わる

// 関数プロトタイプ宣言
LRESULT CALLBACK MyWinProc(HWND, UINT, WPARAM, LPARAM);

// ===================================================================================
// WinMain関数
// ===================================================================================
// Win32アプリケーションの初期エントリポイント。Windowsシステムが呼び出す。
// 戻り値はOSでは使用しないが、別のプログラムにステータスコードを伝達できる
int WINAPI WinMain(                       // WINAPI : 関数の呼び出し規約 __stdcall の再定義
	HINSTANCE hInstance,                  // アプリケーションの現在のインスタンス(current instance)へのハンドル
	HINSTANCE hprevInstance,              // アプリケーションの以前のインスタンス(previous instance)へのハンドル ※現在は、常にNULL
	LPSTR lpCmdLine,                      // コマンドラインが格納されたヌル終端された文字列(プログラム名を除く)へのポインタ
	int nCmdShow)                         // ウィンドウの表示状態
{
	// ===================================================================================
	// ウィンドウクラスの、作成・設定・登録
	// ===================================================================================
	// 作成
	WNDCLASSEX wcex;                                 // ウィンドウクラス構造体

	// 設定 ※ウィンドウに関する情報
	wcex.cbSize = sizeof(WNDCLASSEX);                // WNDCLASSEX構造体のサイズ(バイト)
	wcex.style = CS_HREDRAW | CS_VREDRAW;            // クラススタイル ※ここではサイズ変更時に再描画
	wcex.lpfnWndProc = MyWinProc;                    // ウィンドウプロシージャーへのポインタ
	wcex.cbClsExtra = 0;                             // ウィンドウクラスの追加バイト数
	wcex.cbWndExtra = 0;                             // ウィンドウインスタンスの追加バイト数
	wcex.hInstance = hInstance;                      // アプリケーションの現在のインスタンスへのハンドル
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);    // アイコン素材へのハンドル
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);      // カーソル素材へのハンドル
	wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);   // 背景ブラシへのハンドル
	wcex.lpszMenuName = NULL;   // メニューリソース名。※ヌル終端された文字列へのポインタ。NULL:デフォルトメニューなし
	wcex.lpszClassName = _T("MySampleWindow");       // ウィンドウクラス名。※ヌル終端された文字列へのポインタ、またはATOM
	wcex.hIconSm = NULL;                             // 小アイコンへのハンドル。NULLの場合、hIconで指定されたアイコンを縮小

	// OSに登録
	if (RegisterClassEx(&wcex) == 0) return 0;       // 成功:登録されたクラスを一意に特定するATOMを返す。失敗:0を返す

	// ===================================================================================
	// ウィンドウのインスタンス作成
	// ===================================================================================
	// インスタンス作成  ※オーバーラップウィンドウ、ポップアップウィンドウ、子ウィンドウのいずれかを拡張スタイル付きで作成
	// 新しいウィンドウへのハンドルを返し、関数が失敗した場合はNULLを返す。  ※#define NULL 0
	HWND hWnd = CreateWindowEx(            // ウィンドウを作成し、ウィンドウへのハンドルを返す。失敗した場合、NULLを返す
		0,                                 // 拡張されたウィンドウスタイル ※0:既定の動作
		_T("MySampleWindow"),              // 登録されているウィンドウクラス名
		_T("マイ サンプル ウィンドウ"),      // ウィンドウ名 ※タイトルバーがあれば、そこに表示される
		// オーバーラップウィンドウ(キャプションと境界線), タイトルバーにコントロールメニューボックス, 最小化ボタン
		WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX,     // ウィンドウスタイル  ※WS_OVERLAPPEDWINDOWが便利
		100,                               // 横位置 (初期の水平位置)
		200,                               // 縦位置 (初期の垂直位置)
		300,                               // 幅
		400,                               // 高さ
		NULL,                              // 親ウィンドウ、またはオーナーウィンドウへのハンドル  ※NULL:最上位ウィンドウ
		NULL,                              // メニューへのハンドル、または、子ウィンドウ識別子    ※NULL:メニューを使用しない
		hInstance,                         // アプリケーションの現在のインスタンスへのハンドル
		NULL);                             // ウィンドウ作成データ(追加のアプリケーションデータ) ※void* 型の任意のデータへのポインタ

	// インスタンス作成の失敗時の処理
	if (hWnd == NULL) return 0;              // 失敗した場合、NULL  ※#define NULL 0

	// ===================================================================================
	// ウィンドウの表示
	// ===================================================================================
	// ウィンドウ表示  ※CreateWindowExによって返されるウィンドウハンドルを利用
	ShowWindow(hWnd, nCmdShow);         // 指定されたウィンドウの表示状態を設定
	// ウィンドウ更新
	UpdateWindow(hWnd);                 // 指定されたウィンドウの更新リージョンが空ではない場合、
										// ウィンドウへメッセージを送信し、そのウィンドウのクライアント領域を更新

	// ===================================================================================
	// メッセージループ
	// ===================================================================================
	// MSG構造体
	MSG msg;              // メッセージ情報を格納するための構造体

	// メッセージループ
	BOOL bRet;                          // typedef int BOOL;
	while ((bRet = GetMessage(          // キューからメッセージを取得し、指定の構造体に格納する
		&msg,             // MSG構造体へのポインタ ※メッセージ情報が格納される
		NULL,             // メッセージの取得に使う(取得元)ウィンドウへのハンドル
						  // ※NULL:呼び出し側スレッドに関連付けられている全てのウインドウへのメッセージを取得
		0,                // 取得するメッセージの最小値  ※第3、第4引数が共に0の場合、利用可能なすべてのメッセージを返す
		0                 // 取得するメッセージの最大値
		)) != 0) {                      // WM_QUITメッセージのとき、0。違う場合、0以外の値
		if (bRet == -1) {               // エラーの場合、-1
			break;                      // while文を抜ける
		}
		else {                          // 0と-1 以外の値の処理  ※WM_QUITとエラー以外
			TranslateMessage(&msg);     // キーボード入力に関連付けられており、キー操作を文字に変換

			// メッセージのターゲットウィンドウのウィンドウプロシージャを呼び出すようOSに通知する。
			// これでOSがウィンドウハンドルを検索し、ウィンドウに関連付けられた関数ポインターを特定し、関数を呼び出すことになる
			DispatchMessage(&msg);      // Windowsによるウィンドウプロシージャの呼び出しが間接的に実行される。
										// ウィンドウプロシージャは、戻り値をDispatchMessageに返す
		}
	}

	// ===================================================================================
	// 終了処理
	// ===================================================================================
	// ウィンドウクラスのOS登録解除
	UnregisterClass(_T("MySampleWindow"), hInstance);          // ウィンドウクラス名, インスタンスへのハンドル
	// アプリケーションの終了コード
	return msg.wParam;                                         // WM_QUITメッセージ時の、wParamの値を返す
}

// ===================================================================================
// ウィンドウプロシージャ(Window Procedure)
// ===================================================================================
// ウィンドウへ送信されたメッセージを処理する、アプリケーション定義のコールバック関数
LRESULT CALLBACK MyWinProc(       // CALLBACK : 関数の呼び出し規約 __stdcall の再定義 ※WINAPIと同じ
	HWND hWnd,                    // ウィンドウへのハンドル
	UINT uMsg,                    // メッセージ識別子
	WPARAM wParam,                // メッセージに関する、最初の追加情報
	LPARAM lParam)                // メッセージに関する、2番目の追加情報
{
	switch (uMsg)
	{
	case WM_DESTROY:              // ウィンドウが破棄された時のメッセージ
		// スレッドが自らの終了を要求したことをシステムに伝える。(キューへWM_QUITメッセージをポストし、すぐに制御を戻す)
		PostQuitMessage(0);       // 引数には、アプリケーションの終了コードを指定する。
								  // この値は、メッセージのwParamパラメータとして使われる。※終了時にWinMain関数が返す値になる。
		break;
	case WM_LBUTTONDOWN:          // ウィンドウのクライアント領域で、左マウスボタンを押した時のメッセージ
		MessageBox(hWnd, _T("hello, world!"), _T("messege"), MB_OK);
		break;
	default:
		// 既定のメッセージ処理をする、既定のウィンドウプロシージャ
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}


スッキリ版

上と内容は同じ

#include <windows.h>
#include <tchar.h>

LRESULT CALLBACK MyWinProc(HWND, UINT, WPARAM, LPARAM);

// WinMain関数
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hprevInstance, LPSTR lpCmdLine, int nCmdShow) {
	// ウィンドウクラスの、作成・設定・登録
	WNDCLASSEX wcex;
	wcex.cbSize = sizeof(WNDCLASSEX);
	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = MyWinProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION);
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = _T("MySampleWindow");
	wcex.hIconSm = NULL;
	if (RegisterClassEx(&wcex) == 0) return 0;

	// ウィンドウのインスタンス作成
	HWND hWnd = CreateWindowEx(0, _T("MySampleWindow"), _T("マイ サンプル ウィンドウ"),
		WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX, 100, 200, 300, 400, NULL, NULL, hInstance, NULL);
	if (hWnd == NULL) return 0;

	// ウィンドウの表示
	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	// メッセージループ
	MSG msg;
	BOOL bRet;
	while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0) {
		if (bRet == -1) {
			break;
		}
		else {
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	// 終了処理
	UnregisterClass(_T("MySampleWindow"), hInstance);
	return msg.wParam;
}

// ウィンドウプロシージャ
LRESULT CALLBACK MyWinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
	switch (uMsg)
	{
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	case WM_LBUTTONDOWN:
		MessageBox(hWnd, _T("hello, world!"), _T("messege"), MB_OK);
		break;
	default:
		return DefWindowProc(hWnd, uMsg, wParam, lParam);
	}
	return 0;
}





Visual Basic for Applications (VBA)

Visual Basic for Applications (VBA)

  • Office 2013 Visual Basic for Applications 言語リファレンス → Link
  • Excel 2013 開発者用リファレンス → Link


<データ型>

データ型の例   ※他にもある
データ型 サイズ 範囲
Byte
(バイト型)
1バイト 0 ~ 255
Boolean
(ブール型)
2バイト True または False
Integer
(整数型)
2バイト -32,768 ~ 32,767
Long
(長整数型)
4バイト -2,147,483,648 ~ 2,147,483,647
LongLong
(LongLong整数型)
8バイト -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807
(64ビットプラットフォームでのみ有効)
LongPtr
(32ビットシステム:
長整数型
64ビットシステム: LongLong 整数型)
32ビット
システム:
4バイト

64ビット
システム:
8 バイト
32ビットシステム:
-2,147,483,648 ~ 2,147,483,647
64ビットシステム:
-9,223,372,036,854,775,808 ~
9,223,372,036,854,775,807
Single
(単精度浮動小数点型)
4バイト 負の値の場合:
-3.402823E38  ~ -1.401298E-45
正の値の場合:
1.401298E-45  ~ 3.402823E38
Double
(倍精度浮動小数点型)
8バイト 負の値の場合:
-1.79769313486231E308  ~
-4.94065645841247E-324
正の値の場合:
4.94065645841247E-324  ~
1.79769313486232E308
Currency
(通貨型)
(サイズ固定整数)
8バイト -922,337,203,685,477.5808 ~
922,337,203,685,477.5807
Decimal
(10進型)
14バイト 小数点なしで
+/-79,228,162,514,264,337,593,543,
950,335
小数点の右に 28 桁で
+/-7.9228162514264337593543950335
最小の非ゼロ数は
+/-0.0000000000000000000000000001
Date
(日付型)
8バイト 100年1月1日 ~ 9999年12月31日
Object
(オブジェクト型)
4バイト いずれかのオブジェクト参照
String
(文字列型)
(可変長)
10バイト + 文字列の長さ 0 ~ およそ20億
String * n
(文字列型)
(固定長)
文字列の長さ 1 ~ およそ65,400
Variant
(バリアント型)
(数字使用)
16バイト 最大で倍精度浮動小数点型の範囲までのいずれかの数値
Variant
(バリアント型)
(文字使用)
22バイト + 文字列の長さ (64ビットシステムで24バイト) 可変長の文字列型と同じ範囲
ユーザー定義型
(Type を使用)
要素ごとに必要な数 各要素の範囲は、そのデータ型の範囲と同じ
※ 数値型をBoolean型の値に変換 → 0はFalse。0以外の値はTrue。
     Boolean型の値を数値型に変換 → Falseは0。Trueは-1。


<演算子>

演算子の例   ※他にもある
種類 演算子 意味
代入演算子 (単純代入) = 単純代入
代入演算子 (複合代入) += 加算代入
-= 減算代入
*= 乗算代入
/= 除算代入
\=   (円記号) 除算 (商) 代入
^= 累乗して代入
&= 文字列連結 代入
算術演算子 + 加算
- 減算
* 乗算
/ 除算
\   (円記号) 除算 (商)
^ 累乗
MOD 剰余
- マイナス化
連結演算子 & 文字列連結
+ 文字列連結
比較演算子 = 等しい
<> 等しくない
> より大きい
< より小さい
>= 以上
<= 以下
Like 文字列比較 (パターンマッチ)
Is 参照比較
論理演算子 And 論理積
Or 論理和
Not 論理否定
Xor 排他的論理和


<Optionキーワード>

Option Explicit        ' 明示的な、変数の宣言


<変数の宣言>

Option Explicit

Public a As Integer    ' パブリック変数 (パブリックモジュールレベル変数)

Private b As Integer   ' プライベート変数 (プライベートモジュールレベル変数)
Dim c As Integer       ' プライベート変数 (プライベートモジュールレベル変数)

Sub Sample()
    Dim d As Integer   ' ローカル変数 (プロシージャレベル変数)

    Dim e As Integer, f As Integer    ' e,fいずれも整数型
    Dim g, h  As Integer              ' g:Variant型, h:整数型
    
    Dim i                             ' 宣言時の型省略 → Variant型
End Sub


<配列変数>

Sub Sample()
	Dim i As Integer
	
	Dim a(2) As Integer
	a(0) = 10
	a(1) = 20
	a(2) = 30
	For i = 0 To 2
		MsgBox a(i)     ' a(0)=10, a(1)=20, a(2)=30
	Next i
	
	' 配列の要素数を変更 ※それまでの内容は失われる
	ReDim a(3)                      ' データ型は変更できない
	a(3) = 40
	For i = 0 To 3
		MsgBox a(i)     ' a(0)=0, a(1)=0, a(2)=0, a(3)=40
	Next i	
	
	a(0) = 10
	a(1) = 20
	a(2) = 30
	a(3) = 40
	
	' 配列の要素数を変更 ※それまでの内容は保持される
	ReDim Preserve a(5)        ' データ型は変更できない
	a(4) = 50
	a(5) = 60
	For i = 0 To 5
		MsgBox a(i)     ' a(0)=10, a(1)=20, a(2)=30, a(3)=40, a(4)=50, a(5)=60
	Next i
End Sub


<ステートメント>

If...Then...Else ステートメント

Sub Sample()
	Dim a As Integer
	a = 10

	If a > 10 Then
		MsgBox "UP"
	ElseIf a < 10 Then
		MsgBox "DOWN"
	Else
		MsgBox "EQUAL"
	End If     ' ブロック形式では必要。1行の形式では必要なし。
End Sub

Select Case ステートメント

Sub Sample()
	Dim a As Integer
	a = 9
	
	Select Case a
		Case 0 To 3
			MsgBox "0以上 3以下"
		Case 4, 5, 7
			MsgBox "4, 5, 7 のいずれか"
		Case Is >= 10                ' Isキーワード
			MsgBox "10以上"
		Case Is = 8                  ' 比較演算子の等価は= (※==ではない)
			MsgBox "8"
		Case Else
			MsgBox "6, 9 のいずれか"
	End Select
End Sub

For...Next ステートメント

Sub Sample()
	Dim a As Integer, i As Integer
	a = 15
 
	' 1 -------------------------------------   
	For i = 1 To 10
		 a = a + 1
	Next i  
	MsgBox a                    ' 25
     
	' 2 -------------------------------------   
	For i = 10 To 0 Step -2     ' Step はオプション
		a = a - 1
	Next i  
	MsgBox a                    ' 19
     
	' 3 -------------------------------------   
	For i = 0 To 30 Step 3
		a = a + 1
		If a > 25 Then
			Exit For            ' 直近の For Next を抜ける
		End If
	Next i  
	MsgBox a                    ' 26
End Sub

For Each...Next ステートメント

Sub Sample()
    Dim a(1 To 5)  As Integer
    Dim b As Integer

    a(1) = 12
    a(2) = 107
    a(3) = 0
    a(4) = 5
    a(5) = 21

    For Each b In a
        MsgBox b         ' 配列の全ての要素を表示
    Next b
End Sub

Do...Loop ステートメント

Sub Sample()
    Dim a As Integer
  
	' 条件判断してからループ ※Trueで実行 -----
	a = 5
	Do While a > 10
		a = a + 1
	Loop
	MsgBox a                  ' 5	
	
	' ループしてから条件判断 ※Trueで実行 -----
	a = 5
	Do
		a = a + 1
	Loop While a > 10
	MsgBox a                  ' 6
    
    ' ============================================
    ' 条件判断してからループ ※Falseで実行 -----
	a = 7
	Do Until a > 10
		a = a + 1
	Loop
	MsgBox a                  ' 11
	
	' ループしてから条件判断 ※Falseで実行 -----
	a = 7
	Do
		a = a + 1
	Loop Until a > 10
	MsgBox a                  ' 11
    
    ' ============================================
    ' 条件判断してからループ ※Trueで実行 -----
	a = 12
	Do While a > 10
		a = a + 1
		If a > 20 Then
			Exit Do   ' 直近の Do Loop を抜ける
		End if
	Loop
	MsgBox a                  ' 21
End Sub

With ステートメント

Sub Sample()
	' オブジェクトの名前を再修飾せずに、一連のステートメントを実行
	With Application.Workbooks("MyBook.xls").Worksheets("Sheet1").Range("C3")
		.Value = "テストです。"
		.Font.ColorIndex = 3
		.Interior.ColorIndex = 6
	End With
End Sub


<エラー処理>

On Error ステートメント

Sub Sample()
	On Error GoTo MyErrorHandler      ' line引数は、任意の行ラベル、または行番号
		Worksheet(3).Delete
	Exit Sub                          ' Functionの場合は、Exit Function
MyErrorHandler:                       ' ラベル
	MsgBox Err.Description, vbCritical, "重大なエラー!!"          ' Err Object
End Sub


<オブジェクトの階層構造>

Sub Sample()
	' オブジェクトの階層構造 ==============================================================
	' Applicationオブジェクト > Workbooksコレクション > Workbookオブジェクト >
	'                    Worksheetsコレクション > Worksheetオブジェクト > Rangeオブジェクト
	
	Application.Workbooks("TestBook.xls").Worksheets("Sheet1").Range("B5").Value = "test"
End Sub


<プロシージャの呼び出し>

Subプロシージャを呼び出す時は、Callは指定しても、しなくても良い。
 Callを指定する場合引数リストの括弧も書く指定しない場合括弧も書かない

Functionプロシージャを呼び出し、戻り値を利用する時は、
 Callは指定しない。ただし引数リストの括弧は書く
 ※戻り値を利用しない場合は、Callは指定しても、しなくても良い。

Sub Sample()
    ' Subプロシージャの呼び出し =============================================================================
    ' Callステートメント:コントロールを Subプロシージャ, Functionプロシージャ, DLLプロシージャに転送。
    ' ※ 組み込みまたはユーザー定義の関数を呼び出す場合、関数の戻り値は破棄される。
    ' もし引数がある場合: Callを指定するなら引数リストを括弧で囲む。(Callを省略 → 括弧も省略)
    Call mySub1                             ' Callキーワードは省略可。
    
    Call mySub2("mySub2です。")             ' Callキーワードは省略可。※ Callを省略 → 括弧も省略
    
    ' Functionプロシージャの呼び出し ========================================================================
    Dim returnValue As String
    returnValue = myFunc1       ' 戻り値を得る場合、Callを省略する必要がある。そもそも、ここにCallは書けない。
    MsgBox returnValue
    
    returnValue = myFunc2("myFunc")        ' 戻り値を利用する場合、Callが無くても括弧を書く。
    ' returnValue = Call myFunc2("myFunc") ※エラー (ここにCallは書けない)
    MsgBox returnValue
End Sub
 
' ===========================================================================================================
' Subプロシージャでは戻り値を返せない。引数は受け取り可。
Sub mySub1()
    MsgBox "mySub1です。"
End Sub
 
Sub mySub2(ByVal mySubStr As String) ' ByVal(値渡し)やByRef(参照渡し)はオプション。※デフォルトはByRef
    MsgBox mySubStr
End Sub
 
' ===========================================================================================================
' Functionプロシージャでは戻り値を返せる。引数の受け取りも可。
Function myFunc1() As String
    myFunc1 = "myFunc1です。"
End Function
 
Function myFunc2(ByVal myFuncStr As String)
    myFunc2 = myFuncStr + "2です。"
End Function


<MsgBox関数>

ボタン引数で使用する定数 の例   ※他にもある
定数 説明
vbOKOnly 0 [OK] ボタンのみを表示
vbOKCancel 1 [OK] ボタンと [キャンセル] ボタンを表示
vbAbortRetryIgnore 2 [中止] ボタン、[再試行] ボタン、および [無視] ボタンを表示
vbYesNoCancel 3 [はい] ボタン、[いいえ] ボタン、および [キャンセル] ボタンを表示
vbYesNo 4 [はい] ボタンと [いいえ] ボタンを表示
vbRetryCancel 5 [再試行] ボタンと [キャンセル] ボタンを表示
vbCritical 16 [警告メッセージ] アイコンを表示
vbQuestion 32 [問い合わせメッセージ] アイコンを表示
vbExclamation 48 [警告メッセージ] アイコンを表示
vbInformation 64 [情報メッセージ] アイコンを表示

戻り値
定数 説明
vbOK 1 OK
vbCancel 2 キャンセル
vbAbort 3 中止
vbRetry 4 再試行
vbIgnore 5 無視
vbYes 6 はい
vbNo 7 いいえ

Sub Sample()
	Dim myPrompt As String, myTitle As String
	Dim myButtons As Integer
	Dim response As Integer
	
	myPrompt = "続行しますか?"
	myButtons = vbYesNo + vbCritical
	myTitle = "警告"

	response = MsgBox(myPrompt, myButtons, myTitle)
	
	If response = vbYes Then
    	MsgBox  """はい""が選択されました。"  ' ダブルクォーテーションを文字列で扱うには、2つ連続して入力
	Else
    	MsgBox   """いいえ""が選択されました。"
	End If
End Sub


<セルの操作>

※ ApplicationオブジェクトのActiveWorkbookプロパティ, ActiveSheetプロパティ, ActiveCellプロパティなどを扱ったり、
直接Rangeプロパティを扱う場合は、どこがアクティブであるのかに注意する必要がある。

Sub Sample()
    ' いろいろなセルの指定 ===========================================================
	Application.Workbooks("MyBook.xls").Worksheets("Sheet1").Range("B5").Value = "B5です。"

	Worksheets("Sheet1").Activate	
	ActiveSheet.Range("B6").Value = "B7です。"                ' Applicationオブジェクト修飾子を省略
	
	Range("G2").Activate
	Application.ActiveCell.Font.Bold = True
	ActiveCell.Interior.ColorIndex = 3                        ' Applicationオブジェクト修飾子を省略
	
	Application.Range("B7").Value = "B9です。"	
	' Applicationオブジェクト修飾子を指定せずにRangeプロパティを使用すると、
	' ActiveSheet.Range のショートカットとなる。 ※エラーに注意
	Range("D1").Value = "D1です。"
	
	' =============================================================================
	Dim myRange As Range  ' オブジェクト型の変数
	' オブジェクトへの参照を代入する
	Set myRange = Worksheets("Sheet1").Range("A5")            ' Setステートメント
	myRange.Value = "A5です。"
	
	' =============================================================================
	With Worksheets("Sheet1").Range("B2")   ' ※アクティブなブックに注意
		.Value = "B2です。"
		.HorizontalAlignment = xlCenter
		.VerticalAlignment = xlBottom
		.Interior.ColorIndex = 6
		.BorderAround ColorIndex:=3, Weight:=xlThin            ' 名前付き引数
	End With

	' =============================================================================
	With Worksheets("Sheet1").Range("B10").Borders(xlEdgeBottom)   ' XlBordersIndex列挙 の定数
		.LineStyle = xlContinuous
		.Weight = xlThick
		.ColorIndex = 3
	End With
		
	' =============================================================================
	' セルの範囲指定
	Worksheets("Sheet1").Range("C3:F7").Interior.ColorIndex = 5    ' ワークシート名
	Worksheets(1).Range("H5:K7").Interior.ColorIndex = 7           ' ワークシートのindex
End Sub


<ワークシートの操作>

Sub Sample()
    ' アクティブなワークシートの操作 ========================================================================
    Worksheets("Sheet1").Activate                         ' アクティブなワークブックでの操作になることに注意
    ActiveSheet.PageSetup.Orientation = xlLandscape       ' どのワークシートがアクティブになっているかに注意
    ActiveSheet.PrintOut

    ' ワークシートの操作 ====================================================================================
    Worksheets("Sheet1").Range("C5").Value = "C5です。"   ' 引数indexに、ワークシートの名前を指定
    Worksheets(1).Range("B3").Value = "B3です。"          ' 引数indexに、ワークシートのインデックス番号を指定   
    
    ' ワークシートの追加 ====================================================================================
    Worksheets.Add Before:=Worksheets("Sheet1")           ' 前に追加  ※名前つき引数
    Worksheets.Add After:=Worksheets("Sheet1")            ' 後に追加
    
    Worksheets("Sheet1").Activate
    ' Addメソッドの、引数Beforeと引数Afterを共に省略 → アクティブシートの直前に新しいシートが追加される
    Worksheets.Add
    
    ' ワークシートの削除 ===================================================================================    
    ' ブール型(Boolean)の戻り値がある。確認用ダイアログボックス:[キャンセル] → False, [削除] → True
    Worksheets("Sheet3").Delete
    
    ' ワークシートのコピー =================================================================================
    ' 引数Beforeと引数Afterの両方を省略 → 新規ブックが自動的に作成され、シートはそのブック内にコピーされる
    Worksheets("Sheet1").Copy After:=Worksheets("Sheet2")      ' Sheet1をコピーして、Sheet2の後に挿入
    
    ' ワークシートの名前の変更 =============================================================================
    Worksheets("Sheet4").Name = "シート4"
End Sub


<ファイルの操作>

Sub Sample()   
    ' ファイルが存在するかチェック ============================================================
    If Dir("C:\Users\ d(*´∇`d*) \Desktop\MyBook2.xls") = "" Then
        MsgBox "ファイルが存在しません。", vbExclamation, "警告!"
        Exit Sub
    End If
    
    ' 既に開いているかチェック ================================================================
    Dim check As Workbook
    For Each  check In Workbooks            ' WorkbooksプロパティでWorkbooksコレクションを取得
        If  check.Name = "MyBook2.xls" Then
            MsgBox "既に開いています。"
            Exit Sub
        End If
    Next check
    
    ' ファイルを開く =========================================================================
    Workbooks.Open targetFile, ,True       ' ReadOnlyをtrueで指定
    ' 参考:  Application.FindFile ' [ファイルを開く] ダイアログ ボックスを表示
    
    ' ファイルを閉じる =======================================================================
    If MsgBox("ファイルを閉じますか?", vbYesNo, "質問!") = vbYes Then
    	Workbooks("MyBook2.xls").Close      ' 開かれているすべてのブックを閉じる
   	Else
    	MsgBox "(´・ω・`)ショボーン", vbInformation, "情報"
    End If
End Sub




マイブログへようこそ♪
PLEASANT_DRAGON

2DCG&3DCG,プログラミング,
日記などを掲載中☆

(*´▽`*)コメント大歓迎です☆

最新記事
記事一覧

全ての記事を表示する

カテゴリ
SAI (0)
mi (2)
C (1)
C++ (1)
C# (0)
VBA (0)
月別アーカイブ
最新コメント
RSSリンクの表示
リンク
FC2ブログランキング

FC2Blog Ranking

ピックアップ商品1♪










カレンダー
05 | 2017/06 | 07
- - - - 1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 -
ブログ内検索フォーム
プロフィール

エクレア

Author:エクレア


  • 2DCG&3DCGの創作活動をしています。

  • SF系のメカが大好物。

アクセスカウンター
Twitter
ピックアップ商品2♪