⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nxsnake.c

📁 PIXIL is a small footprint operating environment, complete with PDA PIM applications, a browser and
💻 C
📖 第 1 页 / 共 2 页
字号:
	    case PLAYGROUND_NIBBLE:		draw_tile(TILE_NIBBLE, (x * XUNITSIZE), (y * YUNITSIZE));		/* GrSetGCForeground(gc, BLACK); */		break;	    }#ifdef NOTUSED	    GrFillRect(offscreen, gc, (x * XUNITSIZE),		       (y * YUNITSIZE), XUNITSIZE, YUNITSIZE);#endif#ifdef NOTUSED	    if (playground[y][x] == PLAYGROUND_NIBBLE && nibble.active) {		GR_POINT points[4];		points[0].x = (x * XUNITSIZE) + 1;		points[0].y = points[2].y =		    (y * YUNITSIZE) + 1 + ((YUNITSIZE - 2) / 2);		points[1].x = points[3].x =		    (x * YUNITSIZE) + 1 + ((XUNITSIZE - 2) / 2);		points[1].y = (y * YUNITSIZE) + 1;		points[2].x = points[0].x + (XUNITSIZE - 2);		points[3].y = points[1].y + (YUNITSIZE - 2);		GrFillPoly(offscreen, gc, 4, points);	    }	    if (playground[y][x] == PLAYGROUND_NIBBLE && nibble.active) {		int xpos = (x * XUNITSIZE) + (XUNITSIZE / 2);		int ypos = (y * YUNITSIZE) + (YUNITSIZE / 2);		GrSetGCForeground(gc, YELLOW);		GrFillEllipse(offscreen, gc, xpos, ypos,			      (XUNITSIZE / 2) - 1, (YUNITSIZE / 2) - 1);	    }#endif	}	/* If we have background clear up to the edge, handle that here */	if (bstart != -1) {	    GrSetGCForeground(gc, BGCOLOR);	    GrFillRect(offscreen, gc, (bstart * XUNITSIZE), (y * YUNITSIZE),		       (bend - bstart + 1) * XUNITSIZE, YUNITSIZE);	    bend = bstart = 0;	}    }    GrDestroyGC(gc);}voiddraw_nibble(void){    /* If there is no nibble assigned, then pick an new spot */    if (!nibble.active) {	while (1) {	    int x = 0 + (int) (rand() % (XUNITS - 1));	    int y = 0 + (int) (rand() % (YUNITS - 1));	    if (playground[y][x] != PLAYGROUND_EMPTY)		continue;	    if (y > 0 && playground[y - 1][x] != PLAYGROUND_EMPTY)		continue;	    if (y < (YUNITS - 1) && playground[y + 1][x] != PLAYGROUND_EMPTY)		continue;	    if (x > 0 && playground[y][x - 1] != PLAYGROUND_EMPTY)		continue;	    if (x < (XUNITS - 1) && playground[y][x + 1] != PLAYGROUND_EMPTY)		continue;	    /* For now, make sure that the nibble doesn't */	    /* show up near the border */	    nibble.x = x;	    nibble.y = y;	    nibble.active = 1;	    break;	}    }    playground[nibble.y][nibble.x] = PLAYGROUND_NIBBLE;}voiddraw_border(void){#ifdef NOTUSED    int y = 0;    /* FIXME:  This should be more dynamic, eh? */    /* For now, just a square box */    memset(&playground[0][0], PLAYGROUND_BORDER, XUNITS);    memset(&playground[YUNITS - 1][0], PLAYGROUND_BORDER, XUNITS);    for (y = 0; y < YUNITS; y++) {	playground[y][0] = PLAYGROUND_BORDER;	playground[y][XUNITS - 1] = PLAYGROUND_BORDER;    }#endif    memcpy(playground, level[current_level].bitmap, XUNITS * YUNITS);}/* This just draws the snake into the matrix *//* draw_playground() actually puts it on the screen */voiddraw_snake(void){    int i = 0;    int sx = global_snake.headx;    int sy = global_snake.heady;    int ex = 0;    int ey = 0;    int pos = 0;    while (global_snake.body[pos]) {	unsigned char dir = GET_SNAKE_DIRECTION(global_snake.body[pos]);	unsigned short off = GET_SNAKE_OFFSET(global_snake.body[pos]);	switch (dir) {	case SNAKE_DIR_RIGHT:	    if (sx - off < 0) {		int remainder;		/* Split the line */		memset(&playground[sy][0], PLAYGROUND_SNAKE, sx);		remainder = off - sx - 1;		memset(&playground[sy][XUNITS - remainder], PLAYGROUND_SNAKE,		       remainder);		ex = XUNITS - 1 - remainder;	    } else {		/* We can just memset the line, because it goes horizontal */		memset(&playground[sy][sx - off], PLAYGROUND_SNAKE, off);		ex = sx - off;	    }	    ey = sy;	    break;	case SNAKE_DIR_LEFT:	    if (sx + off > (XUNITS - 1)) {		int remainder;		/* Split the line */		memset(&playground[sy][sx], PLAYGROUND_SNAKE, XUNITS - sx);		remainder = off - ((XUNITS - 1) - sx) - 1;		memset(&playground[sy][0], PLAYGROUND_SNAKE, remainder);		ex = remainder;	    } else {		/* We can just memset the line, because it goes horizontal */		memset(&playground[sy][sx], PLAYGROUND_SNAKE, off);		ex = sx + off;	    }	    ey = sy;	    break;	case SNAKE_DIR_DOWN:	    ex = sx;	    if (sy - off < 0) {		int remainder;		remainder = off - sy - 1;		ey = YUNITS - 1 - remainder;		for (i = 0; i <= sy; i++)		    playground[i][sx] = PLAYGROUND_SNAKE;		for (i = ey; i <= YUNITS - 1; i++)		    playground[i][sx] = PLAYGROUND_SNAKE;	    } else {		ey = sy - off;		for (i = ey; i <= sy; i++)		    playground[i][sx] = PLAYGROUND_SNAKE;	    }	    break;	case SNAKE_DIR_UP:	    ex = sx;	    if (sy + off > (YUNITS - 1)) {		int remainder;		for (i = sy; i <= YUNITS - 1; i++)		    playground[i][sx] = PLAYGROUND_SNAKE;		remainder = off - ((YUNITS - 1) - sy) - 1;		for (i = 0; i <= remainder; i++)		    playground[i][sx] = PLAYGROUND_SNAKE;		ey = remainder;	    } else {		ey = sy + off;		for (i = sy; i <= ey; i++)		    playground[i][sx] = PLAYGROUND_SNAKE;	    }	    break;	}	sx = ex;	sy = ey;	pos++;    }}voiddraw_score(void){    int tw, th, tb;    char text[100];    GR_GC_ID gc = GrNewGC();    GR_FONT_ID font = GrCreateFont((GR_CHAR *) GR_FONT_GUI_VAR, 0, 0);    GrSetGCForeground(gc, BGCOLOR);    GrFillRect(offscreen, gc, 0, PHEIGHT + 1, WWIDTH, WHEIGHT - PHEIGHT);    GrSetGCFont(gc, font);    GrSetGCBackground(gc, BGCOLOR);    GrSetGCForeground(gc, TXTCOLOR);    sprintf(text, "Level: %d", current_level + 1);    GrGetGCTextSize(gc, text, -1, GR_TFTOP, &tw, &th, &tb);    GrText(offscreen, gc, 10,	   PHEIGHT + ((WHEIGHT - PHEIGHT) / 2) - (th / 2),	   text, -1, GR_TFTOP);    sprintf(text, "Snakes: %d", global_snake.lives);    GrGetGCTextSize(gc, text, -1, GR_TFTOP, &tw, &th, &tb);    GrText(offscreen, gc, (WWIDTH / 2) - (tw / 2),	   PHEIGHT + ((WHEIGHT - PHEIGHT) / 2) - (th / 2),	   text, -1, GR_TFTOP);    sprintf(text, "Score: %d", global_snake.score);    GrGetGCTextSize(gc, text, -1, GR_TFTOP, &tw, &th, &tb);    GrText(offscreen, gc, (WWIDTH - 10 - tw),	   PHEIGHT + ((WHEIGHT - PHEIGHT) / 2) - (th / 2),	   text, -1, GR_TFTOP);    GrDestroyFont(font);    GrDestroyGC(gc);}voiddo_frame(int full){    /* Clear it out */    memset(playground, PLAYGROUND_EMPTY, XUNITS * YUNITS);    /* Fill the matrix */    draw_border();    draw_snake();    draw_nibble();    /* Only draw the score if we need to */    /* draw_score(); */    /* Draw it to the offscreen buffer */    draw_screen(full);    /* And finally, show it on the screen */    show_buffer();    if (draw_fullscreen)	draw_fullscreen = 0;}voidstart_level(int l){    init_level(l);		/* Initalize the snake */    game_state = SNAKE_PLAYING;    nibble.active = 0;    nibble.x = 0;    nibble.y = 0;    /* Construct a clip mask to avoid drawing the border so many times */    make_clipmask(l);    /* Set us up to draw the full screen at least once */    draw_fullscreen = 1;    draw_score();}voidstart_game(void){    srand(time(0));    current_level = 0;    global_snake.lives = 3;    global_snake.score = 0;    game_speed = start_speed;    start_level(current_level);    draw_score();    do_frame(1);}voidend_game(void){    game_state = SNAKE_DONE;    /* draw_score(); */    draw_string((char *) welcome, 1);    show_buffer();}voiddo_snake_advance(void){    switch (advance_snake()) {    case MOVE_LEGAL:	do_frame(0);	break;    case MOVE_NIBBLE:	if ((global_snake.score % LEVEL_SCORE) == 0) {	    current_level++;	    game_state = SNAKE_NEXTLEVEL;	    draw_string((char *) nextlevel, 2);	    show_buffer();	} else {	    draw_score();	}	break;    case MOVE_ILLEGAL:	global_snake.lives--;	if (!global_snake.lives)	    end_game();	else {	    game_state = SNAKE_NEXTLEVEL;	    draw_string((char *) snakedied, 2);	    show_buffer();	}	break;    }}voidhandle_event(GR_EVENT * event){    switch (event->type) {    case GR_EVENT_TYPE_KEY_DOWN:	/* Allow Q to quit no matter where we are */	if (event->keystroke.ch == 'Q' || event->keystroke.ch == 'q') {	    GrClose();	    exit(0);	}	switch (game_state) {	case SNAKE_START:	case SNAKE_INSTRUCTIONS:	case SNAKE_DONE:	    switch (event->keystroke.ch) {	    case 'I':	    case 'i':	    case MWKEY_APP1:		if (game_state != SNAKE_INSTRUCTIONS) {		    game_state = SNAKE_INSTRUCTIONS;		    draw_string((char *) instructions, 1);		    show_buffer();		    break;		}	    default:		start_game();		break;	    }	    break;	case SNAKE_PAUSED:	    if (event->keystroke.ch == 'p' || event->keystroke.ch == 'P') {		draw_score();		do_frame(1);		game_state = SNAKE_PLAYING;	    }	    break;	case SNAKE_NEXTLEVEL:	    if (current_level >= LEVELCOUNT)		current_level = 0;	    start_level(current_level);	    draw_score();	    do_frame(1);	/* and show the first frame */	    break;	case SNAKE_PLAYING:	    if (event->keystroke.ch == 'p' ||		event->keystroke.ch == 'P' ||		event->keystroke.ch == MWKEY_RECORD) {		game_state = SNAKE_PAUSED;		break;	    }	    if (redirect_snake(event->keystroke))		do_snake_advance();	    break;	}	break;    case GR_EVENT_TYPE_EXPOSURE:	show_buffer();	break;    }}voidhandle_idle(){    switch (game_state) {    case SNAKE_START:    case SNAKE_INSTRUCTIONS:    case SNAKE_DONE:    case SNAKE_NEXTLEVEL:    case SNAKE_PAUSED:	/* nothing to do here */	break;    case SNAKE_PLAYING:	do_snake_advance();	break;    }}intmain(int argc, char **argv){    extern char *optarg;    while (1) {	signed char c = getopt(argc, argv, "s::");	if (c == -1)	    break;	if (c == 's') {	    start_speed = atoi(optarg);	    game_speed = start_speed;	    printf("Setting the start speed to %ld\n", start_speed);	}    }    if (GrOpen() < 0)	exit(-1);    load_tileset("snake.xpm");    game_state = SNAKE_START;    /* Make the window */    swindow = GrNewWindowEx(WM_PROPS, "Pixil Snake", GR_ROOT_WINDOW_ID,			    0, 0, WWIDTH, WHEIGHT, BGCOLOR);    GrSelectEvents(swindow, GR_EVENT_MASK_EXPOSURE | GR_EVENT_MASK_CLOSE_REQ |		   GR_EVENT_MASK_KEY_DOWN);    offscreen = GrNewPixmap(WWIDTH, WHEIGHT, 0);    GrMapWindow(swindow);    /* Draw the instructions into the buffer */    draw_string((char *) welcome, 1);    while (1) {	GR_EVENT event;	/* We start at 130ms, but it goes down every */	/* time a nibble is eaten */	/* If they get this far, then they rock! */	if (game_speed < 1)	    game_speed = 1;	GrGetNextEventTimeout(&event, game_speed);	switch (event.type) {	case GR_EVENT_TYPE_EXPOSURE:	case GR_EVENT_TYPE_KEY_DOWN:	    handle_event(&event);	    break;	case GR_EVENT_TYPE_TIMEOUT:	    handle_idle();	    break;	case GR_EVENT_TYPE_CLOSE_REQ:	    GrClose();	    exit(0);	}    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -