Tutorial: moving sunnyboys ========================== Multiplayer program, where every player moves his own sunnyboy with arrow keys. Up to 4 players are can connect, virtual players replace missing players. step 0 The global declaration of the program in tut-network1.h, used by master player and client players: We declare the network ports: ==>
static char serverport[]="2222"; // port of network-server static char mbcastport[]="2223"; // broadcast/multicast port to get server-ip |
struct {
/* player's values */
bitmap * sunboy; /* players sunnyboy */
int xpos,ypos; /* position of sunnyboy */
int keyno,keycount; /* only for virtual player's moving algorithmus */
/* network pointers */
unsigned short * n_xypos; /* pointer to network-x/y-position */
} pl_data[NW_MAXCLIENT];
|
static int set_variables() {
memset(pl_data,0,sizeof(pl_data));
/* define network variables: pl_data[].n_xypos[0] */
if (vg_nw_setvar(NWVAR_USHORT,1,"xypos") < 1) {return(-1);}
return(0);
} /* end set_variables */
|
static int get_pointers(int number_of_pl) {
/* 1.arg: total number of players */
int i1;
/* selection of colors for sunnyboys */
int sunny_color[8]={CL_RED, CL_YELLOW, CL_GREEN, CL_BLUE, CL_VIOLET, CL_PINK, CL_ORANGE, CL_TURQUOISE};
memset(pl_data,0,sizeof(pl_data));
/* get network pointers */
for (i1=1; i1 <= number_of_pl; i1++) { // for each player
pl_data[i1-1].n_xypos=(unsigned short *)vg_nw_getvar("xypos",i1);
/* create sunnyboy of player */
pl_data[i1-1].sunboy=create_sunnyboy(vg_color_index(sunny_color[(i1-1)%8],100));
if (pl_data[i1-1].sunboy==NULL) {return(-1);}
}
return(0);
} /* end get_pointers */
|
/* +++ start networking +++ */
/* set network variables */
if (set_variables() < 0) {vg_window_close(); exit(1);}
/* start network-server and connect to it,
** pass the number of players we want to have
*/
if (start_server(nop_from,nop_to) < 0) {vg_window_close(); exit(1);}
/* get network pointers and create sunnyboys */
if (get_pointers(vg_nw_maxplayer()) < 0) {vg_nw_close(); vg_window_close(); exit(1);}
/* initialize values for network pointers */
init_values(vg_nw_maxplayer());
/* send initial packet to clients */
vg_nw_sendinit();
|
static int start_server(int nop_from,int nop_to) {
/* start and make connection to server
** 1.+2.arg: number of players: at least and at most
*/
if (vg_nw_setplayer(nop_from,nop_to) < nop_from) {return(-1);}
/* start network-server
** using UDP,
** timeout for connects 20 sec.,
** IPv4,
** timeout for not receiving any packet 30 sec.
*/
if (vg_nw_startserver(PROTO_UDP,serverport,20,4,mbcastport,30) < 0) {return(-1);}
/* wait for all other connects */
if (vg_nw_waitforconnects() < 0) {vg_nw_close(); return(-1);}
return(0);
} /* end start_server */
|
static void init_values(int number_of_pl) {
/* master: set initial values for all players
** 1.arg: total number of players
*/
int i1;
/* set values for players */
for (i1=1; i1 <= number_of_pl; i1++) {
/* set initial x- and y-position */
pl_data[i1-1].xpos=SC_WIDTH/2;
pl_data[i1-1].ypos=SC_HEIGHT/2;
/* set network variable: n_xypos[0]=ypos*SC_WIDTH+xpos */
pl_data[i1-1].n_xypos[0]=(unsigned short)(pl_data[i1-1].ypos*SC_WIDTH+pl_data[i1-1].xpos);
}
} /* end init_values */
|
/* +++ start networking +++ */
/* set network variables */
if (set_variables() < 0) {vg_window_close(); exit(1);}
/* connect to network-server */
if (connect_server() < 0) {vg_window_close(); exit(1);}
/* get network pointers and create sunnyboys */
if (get_pointers(vg_nw_maxplayer()) < 0) {vg_nw_close(); vg_window_close(); exit(1);}
/* receive initial packet from master */
if (vg_nw_recvinit() < 0) {vg_nw_close(); vg_window_close(); exit(1);}
|
static int connect_server() {
/* connect to network-server via broadcast/multicast */
if (vg_nw_connect(PROTO_UDP,NULL,serverport,mbcastport) < 0) {return(-1);}
/* wait for all other connects */
if (vg_nw_waitforconnects() < 0) {vg_nw_close(); return(-1);}
return(0);
} /* end connect_server */
|
/* go through all players */
for (plno=1; plno <= vg_nw_maxplayer(); plno++) {
/* get keystrokes and set pl_data[] */
rval=getkeys(plno);
if (rval < 0) {break;} /* network closed or end of game requested */
/* draw sunnyboy, if it is alive */
if (vg_nw_isalive(plno)) { /* player is alive */
vg_bitmap_copyto(NULL,pl_data[plno-1].xpos,pl_data[plno-1].ypos,pl_data[plno-1].sunboy,0,0,0,0,RGB_TRANS);
} else if (plno==vg_nw_myplayer()) { /* master is dead, draw it rotated */
vg_bitmap_copyto(NULL,pl_data[plno-1].xpos,pl_data[plno-1].ypos,vg_bitmap_rotate(pl_data[plno-1].sunboy,180),0,0,0,0,RGB_TRANS);
}
} // end for each player
|
static int getkeys(int plno) {
/* get keystrokes (from keyboard or network or via an algorithm)
** and set pl_data[] (moving sunnyboy)
** 1.arg: number of a player
** return: 0=OK
** -1=end of game requested or network closed
*/
if (vg_nw_isalive(plno)) { /* player is alive */
int x,y;
/* get sunnyboys moving request */
x=y=0;
if (plno==vg_nw_myplayer()) {
/* your sunnyboy, move with keystrokes */
if (vg_key_update() < 0) {return(-1);} /* network closed */
if (vg_key_pressed(KEY_SPACE,SHORTKEY)) { // quit with space-key
vg_nw_setdead(plno); // set dead to inform network-server
return(0); // do not end the game (wait for the second keystroke)
}
/* save request values in x,y */
if (vg_key_pressed(KEY_DCURS,LONGKEY)) {y=1;} /* down */
if (vg_key_pressed(KEY_UCURS,LONGKEY)) {y=-1;} /* up */
if (vg_key_pressed(KEY_LCURS,LONGKEY)) {x=-1;} /* left */
if (vg_key_pressed(KEY_RCURS,LONGKEY)) {x=1;} /* right */
} else if (plno >= vg_nw_virtualplayer()) {
/* virtual players, move with a simple algorithmus */
if (pl_data[plno-1].keycount==0) {
pl_data[plno-1].keyno=ZUFALL(4); /* which arrow key */
pl_data[plno-1].keycount=ZUFALL(25)+5; /* how long pressed */
}
pl_data[plno-1].keycount--;
/* save request values in x,y */
switch (pl_data[plno-1].keyno) {
case 0: y=1; break;
case 1: y=-1; break;
case 2: x=-1; break;
case 3: x=1; break;
}
} else {
/* sunnyboys of other clients,
save request values in x,y
*/
if (vg_nw_recvkeys(plno)) { /* client has sent a request */
if (vg_nw_keypressed(KEY_DCURS,LONGKEY)) {y=1;} /* down */
if (vg_nw_keypressed(KEY_UCURS,LONGKEY)) {y=-1;} /* up */
if (vg_nw_keypressed(KEY_LCURS,LONGKEY)) {x=-1;} /* left */
if (vg_nw_keypressed(KEY_RCURS,LONGKEY)) {x=1;} /* right */
}
}
/* now really move sunnyboy, checking boundaries before */
if (y==1) { /* down request */
int bound=SC_HEIGHT-vg_bitmap_height(pl_data[plno-1].sunboy)/2;
if (++pl_data[plno-1].ypos > bound) {
pl_data[plno-1].ypos=bound;
pl_data[plno-1].keycount=0;
}
} else if (y==-1) { /* up request */
int bound=vg_bitmap_height(pl_data[plno-1].sunboy)/2;
if (--pl_data[plno-1].ypos < bound) {
pl_data[plno-1].ypos=bound;
pl_data[plno-1].keycount=0;
}
}
if (x==-1) { /* left request */
int bound=vg_bitmap_width(pl_data[plno-1].sunboy)/2;
if (--pl_data[plno-1].xpos < bound) {
pl_data[plno-1].xpos=bound;
pl_data[plno-1].keycount=0;
}
} else if (x==1) { /* right request */
int bound=SC_WIDTH-vg_bitmap_width(pl_data[plno-1].sunboy)/2;
if (++pl_data[plno-1].xpos > bound) {
pl_data[plno-1].xpos=bound;
pl_data[plno-1].keycount=0;
}
}
/* update values of network pointers and send data */
pl_data[plno-1].n_xypos[0]=(unsigned short)(pl_data[plno-1].ypos*SC_WIDTH+pl_data[plno-1].xpos);
vg_nw_senddata(plno);
} else { /* player is not alive */
if (plno==vg_nw_myplayer()) { /* your sunnyboy */
if (vg_key_update() < 0) {return(-1);} /* network closed */
if (vg_key_pressed(KEY_SPACE,SHORTKEY)) { // quit with space-key
return(-1);
}
}
}
return(0);
} /* end getkeys */
|
// get keystrokes and do network-transfer
if (vg_key_update() < 0) {break;} // network closed
if (vg_key_pressed(KEY_SPACE,SHORTKEY)) { // player wants to quit
vg_nw_setdead(vg_nw_myplayer());
break;
}
/* get sunnyboys position, decompressing value of network-variable n_xypos */
for (plno=1; plno <= vg_nw_maxplayer(); plno++) {
pl_data[plno-1].xpos=pl_data[plno-1].n_xypos[0]%SC_WIDTH;
pl_data[plno-1].ypos=pl_data[plno-1].n_xypos[0]/SC_WIDTH;
}
/* go through all players */
for (plno=1; plno <= vg_nw_maxplayer(); plno++) {
/* draw sunnyboy, if it is alive */
if (vg_nw_isalive(plno)) { /* player is alive */
vg_bitmap_copyto(NULL,pl_data[plno-1].xpos,pl_data[plno-1].ypos,pl_data[plno-1].sunboy,0,0,0,0,RGB_TRANS);
}
} // end for each player
|