テニスゲーム
次はテニスゲームを考えてみましょう。
ライフゲームのソフトウェアプロジェクトを作成したときと同様に、テニスゲーム用にプロジェクトを作成します。
そして、以下のプログラムを tennis.c として作成します。
#include <xparameters.h>
#define VRAM_BASEADDR (int *)XPAR_VGA_0_MEM0_BASEADDR
#define PSW_BASEADDR (int *)XPAR_PUSH_BUTTONS_5BITS_BASEADDR
#define HEIGHT 45
#define DELAY 300
void v_puts( int , int , char * );
void v_putc( int , int , char );
unsigned int getsw( void );
void wait( int );
int ball; /* ball count */
int bx, by; /* ball x, y */
int vx, vy; /* ball vector x, y */
int nx, ny; /* ball next x, y */
int py, pl, npy; /* paddle position, length and next position */
int hit; /* paddle hit */
int count; /* paddle hit count */
unsigned int sw; /* sw status */
int delay; /* delay counter */
int
main()
{
int i,j;
ball = 3;
bx = 2; by = 4;
vx = 1; vy = 1;
py = 10; pl = 3;
count=0;
delay = DELAY;
/* make field */
for( i=0; i < 80; i++ ){ /* all clear */
for( j=0; j < HEIGHT; j++ ) {
v_putc( i, j, ' ' );
}
}
v_puts( 0, 0, "Microblaze Softcore Processor Video System" );
v_puts( 0, 1, "Tennis Game" );
v_puts(58, 1, "Balls:" );
v_puts(68, 1, "Hit count:" );
for( i=0; i < 80; i++ ){
v_putc( i, 2, 0x00 ); /* Top wall */
v_putc( i,HEIGHT-1, 0x00 ); /* Bottom wall */
}
for( i=2; i < HEIGHT ; i++ ){
v_putc( 0, i, 0x00 ); /* Left side wall */
}
while( 1 ) {
/* make paddle */
for( i=0; i < pl; i++ ){
v_putc( 78, py+i, 0x00 );
}
v_putc( bx, by, '@' ); /* make ball */
v_putc( 64, 1, '0'+ball ); /* display ball count */
v_putc( 78, 1, '0'+(count/10)); /* display paddle hit count */
v_putc( 79, 1, '0'+(count%10)); /* display paddle hit count */
/* wait */
wait( delay );
/* ball move */
nx = bx + vx; ny = by + vy; /* next position */
if( nx == 0 ) { /* left wall check */
nx = 1; ny = by; vx = -vx;
}
if( ny == 2 ) { /* top wall check */
nx = bx; ny = 3; vy = -vy;
}
if( ny == HEIGHT-1 ) { /* bottom wall check
*/
nx = bx; ny = HEIGHT-2; vy = -vy;
}
if( nx == 78 ) { /* paddle check */
for( i=0 , hit=0 ; i < pl ; i++ ) {
if( ny == py+i ) {
hit++;
}
}
if( hit ) { /* paddle hit */
nx = bx; ny = by; vx = -vx;
count++;
v_putc( 78, 1, '0'+(count/10)); /* display paddle hit count */
v_putc( 79, 1, '0'+(count%10)); /* display paddle hit count */
if( count >= 5 && delay == DELAY ) delay = DELAY/3;
}
}
if( nx == 80 ) { /* paddle miss hit */
ball--;
v_putc( 64, 1, '0'+ball ); /* ball count */
v_putc( bx, by, ' ' ); /* delete ball */
nx = 2; ny = 4;
vx = 1; vy = 1;
if( ball == 0 ) break;
}
/* paddle move */
sw = getsw();
if( sw == 16 ) npy = py - 1; else /* up SW */
if( sw == 4 ) npy = py + 1; else /* down SW */
npy = py;
if( npy == 2 ) npy = 3; else /* top wall */
if( npy == HEIGHT-pl ) npy = HEIGHT-1-pl; /* bottom wall */
for( i=0 ; i < pl ; i++ ){ /* delete paddle */
v_putc( 78, py+i, ' ' );
}
py = npy;
v_putc( bx, by, ' ' ); /* delete ball */
bx = nx; by = ny;
}
/* delete ball */
v_putc( bx, by, ' ' );
return 0;
}
void v_puts( int x, int y, char *str )
{
while( *str != '\0' ) {
v_putc( x++, y, *str++ );
}
}
void v_putc( int x, int y, char ch )
{
int *addr;
addr = VRAM_BASEADDR + (y*80 + x);
*addr = ch;
}
unsigned int getsw(void)
{
return *(PSW_BASEADDR);
}
void wait( int delay )
{
int i,j;
for( i=0; i <= 127; i++ ){
for( j=0 ; j < delay ; j++ ) {
v_putc( 79, 0, i );
}
}
}
以下のように、うまく動作したでしょうか。