Verilogでゲームを作る --Designing Video Game Hardware in Verilogの簡易和訳-- part3
Verilogでビデオゲーム
Verilogの参考書を探してるとアマゾンで以下の本に出会った。
Designing Video Game Hardware in Verilog
- 作者: Steven Hugg
- 出版社/メーカー: Independently published
- 発売日: 2018/12/15
- メディア: ペーパーバック
- この商品を含むブログを見る
プログラミング言語の入門書の多くに、ゲーム作製をテーマにしているものがある。
Verilogでは同様のコンセプトの書籍が見つからなかったので、さっそく購入。
まだ全部読んでいないため、良書かどうかの判断はできないが、
せっかくなので、重要な箇所だけかいつまんで和訳しようと思う。
全部翻訳すると著作権に抵触するらしいので。
なるべく最後まで完結できるように頑張る。
目次はこちら
17章 スプライト
跳ね返るボールは良いけど、もっと複雑なものを描きたい。
11章で学んだ数字の書き方を応用しよう。
最初の例として、白黒のレースカーのスプライトを作成する。
スプライトは16pixel x 16pixelサイズだ。ただし横方向は左右対称なので8pixelを折り返して表示する。
最初にビットマップROMが必要だ。
moudle car_bitmap( input [3:0] yofs, output [7:0] bits; ); reg [7:0] bitarray[16]; assign bits = bitarray[yofs]; initial begin bitarray[0] = 8'b00000000; // bitarray[1] = 8'b00001100; // ** bitarray[2] = 8'b11001100; //** ** bitarray[3] = 8'b11111100; //****** bitarray[4] = 8'b11101100; //*** ** bitarray[5] = 8'b11100000; //*** bitarray[6] = 8'b01100000; // ** bitarray[7] = 8'b01110000; // *** bitarray[8] = 8'b00110000; // ** bitarray[9] = 8'b00110000; // ** bitarray[10] = 8'b00110000; // ** bitarray[11] = 8'b01101110; // ** *** bitarray[12] = 8'b11101110; //*** *** bitarray[13] = 8'b11111110; //******* bitarray[14] = 8'b11101110; //*** *** bitarray[15] = 8'b00101110; // * *** end endmodule
次に11章と同様にYのオフセットを用いて8bitのビットマップをスライスする。
ROMモジュールと同様に入力をyofs、出力をbitsにつなげる。
各スキャンラインで以下を実行する。
スプライトのY座標はスキャンラインと等しい場合は、Yカウンタを15にする。
そうでない場合はYカウンタを0になるまでデクリメントする。
reg[3:0] car_sprite_xofs; reg[3:0] car_sprite_yofs; wire[7:0] car_sprite_bits; car_bitmap car( .yofs(car_sprite_yofs), .bits(car_sprite_bits) ); always @(posedge hsync)begin if(vpos == player_y) car_sprite_yofs <= 15; else if(car_sprite_yofs != 0) car_sprite_yofs <= car_sprite_yofs -1 ;
X座標についても同様のことをすればよい。
always @posedge clk) if(hpos == player_x) car_sprite_xofs <= 15: else if(car_sprite_xofs != 0) car_sprite_xofs <= car_sprite_xofs -1;
スプライトのビットを出力するための式は以下の記載となる。
x方向のビットは8で折り返される点を考慮する。
wire[3:0] car_bit = car_sprite_xofs >= 8? car_sprite_xofs ^ 7 : car_sprite_xofs; wire car_gfx = car_sprite_bits[car_bit[2:0]];