Add AI to the pong plugin, to allow single-player operation.
Part of FS#5855 by Travis Hyyppa (the colour changes were removed from the patch) git-svn-id: svn://svn.rockbox.org/rockbox/trunk@29007 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
1c06d83c15
commit
17585a991c
2 changed files with 98 additions and 13 deletions
|
@ -28,6 +28,8 @@
|
|||
|
||||
#define SPEEDX ( LCD_WIDTH * 3 ) / 2 /* Recorder: 168 iRiver: 240 */
|
||||
#define SPEEDY LCD_HEIGHT * 2 /* Recorder: 128 iRiver: 256 */
|
||||
#define CPU_PLAYER_DIST ( (LCD_WIDTH/8 ) * 5 ) /* This is the width of the dead spot where the */
|
||||
#define DEM_PLAYER_DIST ( (LCD_WIDTH/8 ) * 3 ) /* cpu player doesnt care about the ball -- 3/8 of the screen */
|
||||
|
||||
#define RES 100
|
||||
|
||||
|
@ -263,8 +265,8 @@ struct pong {
|
|||
int e_pad[2]; /* existing current Y positions of pads */
|
||||
int ballspeedx; /* */
|
||||
int ballspeedy; /* */
|
||||
|
||||
int score[2];
|
||||
bool cpu_player[2]; /* Status of AI players */
|
||||
};
|
||||
|
||||
void singlepad(int x, int y, int set)
|
||||
|
@ -298,11 +300,11 @@ bool wallcollide(struct pong *p, int pad)
|
|||
the wall */
|
||||
if(pad) {
|
||||
/* right-side */
|
||||
if(p->ballx > LCD_WIDTH*RES)
|
||||
if(p->ballx > ( LCD_WIDTH*RES ) - PAD_WIDTH )
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
if(p->ballx < 0)
|
||||
if(p->ballx < PAD_WIDTH)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -346,9 +348,15 @@ bool padcollide(struct pong *p, int pad, int *info)
|
|||
|
||||
void bounce(struct pong *p, int pad, int info)
|
||||
{
|
||||
(void)pad; /* not used right now */
|
||||
p->ballspeedx = -p->ballspeedx;
|
||||
|
||||
if(pad==0) { /* Give ball a little push to keep it from getting stuck between wall and pad */
|
||||
p->ballx += PAD_WIDTH;
|
||||
}
|
||||
else {
|
||||
p->ballx -= PAD_WIDTH;
|
||||
}
|
||||
|
||||
/* info is the hit-angle into the pad */
|
||||
if(p->ballspeedy > 0) {
|
||||
/* downwards */
|
||||
|
@ -522,17 +530,53 @@ int keys(struct pong *p)
|
|||
|
||||
key = rb->button_status(); /* ignore BUTTON_REPEAT */
|
||||
|
||||
if(key & PONG_LEFT_DOWN) /* player left goes down */
|
||||
padmove(&p->w_pad[0], MOVE_STEP);
|
||||
if(p->cpu_player[1] == true) {
|
||||
if( (p->bally/RES > p->w_pad[0])
|
||||
& (p->ballx/RES < DEM_PLAYER_DIST) ) /* player right goes down */
|
||||
padmove(&p->w_pad[0], MOVE_STEP);
|
||||
|
||||
if(key & PONG_LEFT_UP) /* player left goes up */
|
||||
padmove(&p->w_pad[0], -MOVE_STEP);
|
||||
if( (p->bally/RES < p->w_pad[0])
|
||||
& (p->ballx/RES < DEM_PLAYER_DIST) ) /* player right goes up */
|
||||
padmove(&p->w_pad[0], -MOVE_STEP);
|
||||
|
||||
if(key & PONG_RIGHT_DOWN) /* player right goes down */
|
||||
padmove(&p->w_pad[1], MOVE_STEP);
|
||||
if( (key & PONG_LEFT_DOWN) || (key & PONG_LEFT_UP) ) {
|
||||
/* if left player presses control keys stop cpu player */
|
||||
p->cpu_player[1] = false;
|
||||
p->score[0] = p->score[1] = 0; /* reset the score */
|
||||
rb->lcd_clear_display(); /* get rid of the text */
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(key & PONG_LEFT_DOWN) /* player left goes down */
|
||||
padmove(&p->w_pad[0], MOVE_STEP);
|
||||
|
||||
if(key & PONG_RIGHT_UP) /* player right goes up */
|
||||
padmove(&p->w_pad[1], -MOVE_STEP);
|
||||
if(key & PONG_LEFT_UP) /* player left goes up */
|
||||
padmove(&p->w_pad[0], -MOVE_STEP);
|
||||
}
|
||||
|
||||
if(p->cpu_player[2] == true) {
|
||||
if( (p->bally/RES > p->w_pad[1])
|
||||
& (p->ballx/RES > CPU_PLAYER_DIST) ) /* player right goes down */
|
||||
padmove(&p->w_pad[1], MOVE_STEP);
|
||||
|
||||
if( (p->bally/RES < p->w_pad[1])
|
||||
& (p->ballx/RES > CPU_PLAYER_DIST) ) /* player right goes up */
|
||||
padmove(&p->w_pad[1], -MOVE_STEP);
|
||||
|
||||
if( (key & PONG_RIGHT_DOWN) || (key & PONG_RIGHT_UP) ) {
|
||||
/* if right player presses control keys stop cpu player */
|
||||
p->cpu_player[2] = false;
|
||||
p->score[0] = p->score[1] = 0; /* reset the score */
|
||||
rb->lcd_clear_display(); /* get rid of the text */
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(key & PONG_RIGHT_DOWN) /* player right goes down */
|
||||
padmove(&p->w_pad[1], MOVE_STEP);
|
||||
|
||||
if(key & PONG_RIGHT_UP) /* player right goes up */
|
||||
padmove(&p->w_pad[1], -MOVE_STEP);
|
||||
}
|
||||
|
||||
if(rb->default_event_handler(key) == SYS_USB_CONNECTED)
|
||||
return -1; /* exit game because of USB */
|
||||
|
@ -550,12 +594,28 @@ void showscore(struct pong *p)
|
|||
rb->lcd_putsxy( (LCD_WIDTH / 2) - (w / 2), 0, (unsigned char *)buffer);
|
||||
}
|
||||
|
||||
void blink_demo(void)
|
||||
{
|
||||
static char buffer[30];
|
||||
int w;
|
||||
|
||||
rb->snprintf(buffer, sizeof(buffer), "Press Key To Play");
|
||||
w = rb->lcd_getstringsize((unsigned char *)buffer, NULL, NULL);
|
||||
if(LCD_WIDTH > ( (w/8)*7 ) ) /* make sure text isn't too long for screen */
|
||||
rb->lcd_putsxy( (LCD_WIDTH / 2) - (w / 2), (LCD_HEIGHT / 2),
|
||||
(unsigned char *)buffer);
|
||||
}
|
||||
|
||||
/* this is the plugin entry point */
|
||||
enum plugin_status plugin_start(const void* parameter)
|
||||
{
|
||||
struct pong pong;
|
||||
int game = 1;
|
||||
|
||||
int blink_timer = 0;
|
||||
int blink_rate = 20;
|
||||
bool blink = true;
|
||||
|
||||
/* init the struct with some silly values to start with */
|
||||
|
||||
pong.ballx = 20*RES;
|
||||
|
@ -565,6 +625,7 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
pong.w_pad[0] = 7;
|
||||
pong.e_pad[1] = 0;
|
||||
pong.w_pad[1] = 40;
|
||||
pong.cpu_player[1] = pong.cpu_player[2] = true; /* start every game in demo mode */
|
||||
|
||||
pong.ballspeedx = SPEEDX;
|
||||
pong.ballspeedy = SPEEDY;
|
||||
|
@ -586,6 +647,24 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
game = keys(&pong); /* short circuit */
|
||||
rb->lcd_clear_display();
|
||||
}
|
||||
|
||||
if( (pong.cpu_player[1]==true) && (pong.cpu_player[2]==true) ) {
|
||||
if(blink_timer<blink_rate) {
|
||||
++blink_timer;
|
||||
}
|
||||
else {
|
||||
blink_timer=0;
|
||||
blink = !blink;
|
||||
}
|
||||
|
||||
if(blink==true) {
|
||||
blink_demo();
|
||||
}
|
||||
else {
|
||||
rb->lcd_clear_display();
|
||||
}
|
||||
}
|
||||
|
||||
showscore(&pong);
|
||||
pad(&pong, 0); /* draw left pad */
|
||||
pad(&pong, 1); /* draw right pad */
|
||||
|
|
|
@ -1,6 +1,12 @@
|
|||
\subsection{Pong}
|
||||
\screenshot{plugins/images/ss-pong}{Pong}{img:pong}
|
||||
Pong is a simple two player ``tennis game''. Whenever a player misses the ball the other scores.
|
||||
Pong is a simple one or two player ``tennis game''. Whenever a player misses the ball the other scores.
|
||||
|
||||
The game starts in demo mode, with the CPU controlling both sides.
|
||||
|
||||
As soon as a button to control one of the paddles is pressed, control of that paddle passes to the player,
|
||||
so for a single player game, just press the appropriate buttons to control the side you want to play. For
|
||||
a two player game, both players should just press the appropriate buttons for their side.
|
||||
|
||||
\begin{btnmap}
|
||||
\opt{RECORDER_PAD}{\ButtonFOne}
|
||||
|
|
Loading…
Reference in a new issue