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

📄 ntetris.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}int drop_block_1(nstate *state){	if(will_collide(state, state->current_shape.x,				(state->current_shape.y + 1),				state->current_shape.orientation)) {		block_reached_bottom(state);		return 1;	}	draw_shape(state, state->current_shape.x, state->current_shape.y, 1);	state->current_shape.y++;	draw_shape(state, state->current_shape.x, state->current_shape.y, 0);	draw_well(state, 0);	return 0;}void drop_block(nstate *state){	while(!drop_block_1(state)) msleep(DROP_BLOCK_DELAY);}void handle_exposure_event(nstate *state){	GR_EVENT_EXPOSURE *event = &state->event.exposure;	if(event->wid == state->score_window) {		draw_score(state);		return;	}	if(event->wid == state->next_shape_window) {		draw_next_shape(state);		return;	}	if(event->wid == state->new_game_button) {		draw_new_game_button(state);		return;	}	if(event->wid == state->pause_continue_button) {		draw_pause_continue_button(state);		return;	}	if(event->wid == state->anticlockwise_button) {		draw_anticlockwise_button(state);		return;	}	if(event->wid == state->clockwise_button) {		draw_clockwise_button(state);		return;	}	if(event->wid == state->left_button) {		draw_left_button(state);		return;	}	if(event->wid == state->right_button) {		draw_right_button(state);		return;	}	if(event->wid == state->drop_button) {		draw_drop_button(state);		return;	}	if(event->wid == state->well_window) {		draw_well(state, 1);		return;	}}void handle_mouse_event(nstate *state){	GR_EVENT_MOUSE *event = &state->event.mouse;	if(event->wid == state->new_game_button) {		state->state = STATE_NEWGAME;		return;	}	if(event->wid == state->pause_continue_button) {		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;		else state->state = STATE_PAUSED;		return;	}	if(event->wid == state->anticlockwise_button) {		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;		rotate_block(state, 0);		return;	}	if(event->wid == state->clockwise_button) {		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;		rotate_block(state, 1);		return;	}	if(event->wid == state->left_button) {		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;		move_block(state, 0);		return;	}	if(event->wid == state->right_button) {		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;		move_block(state, 1);		return;	}	if(event->wid == state->drop_button) {		if(state->state == STATE_PAUSED) state->state = STATE_RUNNING;		drop_block(state);		return;	}}void handle_keyboard_event(nstate *state){	GR_EVENT_KEYSTROKE *event = &state->event.keystroke;	switch(event->ch) {		case 'q':		case 'Q':		case MWKEY_CANCEL:			state->state = STATE_EXIT;			return;		case 'n':		case 'N':		case MWKEY_APP1:			state->state = STATE_NEWGAME;			return;	}	if(state->state == STATE_STOPPED) return;	state->state = STATE_RUNNING;	switch(event->ch) {		case 'p':		case 'P':			state->state = STATE_PAUSED;			break;		case 'j':		case 'J':        	case MWKEY_LEFT:			move_block(state, 0);			break;		case 'k':		case 'K':        	case MWKEY_RIGHT:			move_block(state, 1);			break;		case 'd':		case 'D':        	case MWKEY_UP:			rotate_block(state, 0);			break;		case 'f':		case 'F':        	case MWKEY_DOWN:			rotate_block(state, 1);			break;		case ' ':        	case MWKEY_MENU:			drop_block(state);			break;	}}void handle_event(nstate *state){	switch(state->event.type) {		case GR_EVENT_TYPE_EXPOSURE:			handle_exposure_event(state);			break;		case GR_EVENT_TYPE_BUTTON_DOWN:			handle_mouse_event(state);			break;		case GR_EVENT_TYPE_KEY_DOWN:			handle_keyboard_event(state);			break;		case GR_EVENT_TYPE_CLOSE_REQ:			state->state = STATE_EXIT;			break;		case GR_EVENT_TYPE_TIMEOUT:			break;		default:			fprintf(stderr, "Unhandled event type %d\n",							state->event.type);			break;	}}void clear_well(nstate *state){	int x, y;	for(y = 0; y < WELL_HEIGHT; y++)		for(x = 0; x < WELL_WIDTH; x++) {			state->blocks[0][y][x] = 0;			state->blocks[1][y][x] = 0;		}}/* Dirty hack alert- this is to avoid using any floating point math */int random8(int limit){	int ret;	do { ret = random() & 7; } while(ret > limit);	return ret;}void choose_new_shape(nstate *state){	state->current_shape.type = state->next_shape.type;	state->current_shape.orientation = state->next_shape.orientation;	state->current_shape.colour = state->next_shape.colour;	state->current_shape.x = (WELL_WIDTH / 2) - 2;	state->current_shape.y = WELL_NOTVISIBLE -			shape_sizes[state->next_shape.type]				[state->next_shape.orientation][1] - 1;	state->next_shape.type = random8(MAXSHAPES - 1);	state->next_shape.orientation = random8(MAXORIENTATIONS - 1);	state->next_shape.colour = block_colours[random8(MAX_BLOCK_COLOUR)];}void new_game(nstate *state){	clear_well(state);	if(state->score > state->hiscore) state->hiscore = state->score;	state->score = 0;	state->level = 0;	draw_score(state);	choose_new_shape(state);	draw_next_shape(state);	draw_well(state, 1);	if(state->state == STATE_NEWGAME) state->state = STATE_RUNNING;}void init_game(nstate *state){	GR_WM_PROPERTIES props;	if(GrOpen() < 0) {		fprintf(stderr, "Couldn't connect to Nano-X server\n");		exit(1);	}	state->main_window = GrNewWindow(GR_ROOT_WINDOW_ID,					MAIN_WINDOW_X_POSITION,					MAIN_WINDOW_Y_POSITION,					MAIN_WINDOW_WIDTH,					MAIN_WINDOW_HEIGHT, 0,					MAIN_WINDOW_BACKGROUND_COLOUR, 0);	/* set title */	props.flags = GR_WM_FLAGS_TITLE | GR_WM_FLAGS_PROPS;	props.props = GR_WM_PROPS_BORDER | GR_WM_PROPS_CAPTION;	props.title = "Nano-Tetris";	GrSetWMProperties(state->main_window, &props);	GrSelectEvents(state->main_window, GR_EVENT_MASK_EXPOSURE |					GR_EVENT_MASK_CLOSE_REQ |					GR_EVENT_MASK_KEY_DOWN |					GR_EVENT_MASK_TIMEOUT);	state->score_window = GrNewWindow(state->main_window,					SCORE_WINDOW_X_POSITION,					SCORE_WINDOW_Y_POSITION,					SCORE_WINDOW_WIDTH,					SCORE_WINDOW_HEIGHT, 0,					SCORE_WINDOW_BACKGROUND_COLOUR, 0);	GrSelectEvents(state->score_window, GR_EVENT_MASK_EXPOSURE);	GrMapWindow(state->score_window);	state->scoregcf = GrNewGC();	GrSetGCForeground(state->scoregcf, SCORE_WINDOW_FOREGROUND_COLOUR);	GrSetGCBackground(state->scoregcf, SCORE_WINDOW_BACKGROUND_COLOUR);	state->scoregcb = GrNewGC();	GrSetGCForeground(state->scoregcb, SCORE_WINDOW_BACKGROUND_COLOUR);	state->next_shape_window = GrNewWindow(state->main_window,					NEXT_SHAPE_WINDOW_X_POSITION,					NEXT_SHAPE_WINDOW_Y_POSITION,					NEXT_SHAPE_WINDOW_WIDTH,					NEXT_SHAPE_WINDOW_HEIGHT, 0,					NEXT_SHAPE_WINDOW_BACKGROUND_COLOUR, 0);	GrSelectEvents(state->next_shape_window, GR_EVENT_MASK_EXPOSURE);	GrMapWindow(state->next_shape_window);	state->nextshapegcf = GrNewGC();	state->nextshapegcb = GrNewGC();	GrSetGCForeground(state->nextshapegcb,				NEXT_SHAPE_WINDOW_BACKGROUND_COLOUR);	state->new_game_button = GrNewWindow(state->main_window,					NEW_GAME_BUTTON_X_POSITION,					NEW_GAME_BUTTON_Y_POSITION,					NEW_GAME_BUTTON_WIDTH,					NEW_GAME_BUTTON_HEIGHT, 0,					BUTTON_BACKGROUND_COLOUR, 0);	GrSelectEvents(state->new_game_button, GR_EVENT_MASK_EXPOSURE |					GR_EVENT_MASK_BUTTON_DOWN);	GrMapWindow(state->new_game_button);	state->buttongcf = GrNewGC();	GrSetGCForeground(state->buttongcf, BUTTON_FOREGROUND_COLOUR);	GrSetGCBackground(state->buttongcf, BUTTON_BACKGROUND_COLOUR);	state->buttongcb = GrNewGC();	GrSetGCForeground(state->buttongcb, BUTTON_BACKGROUND_COLOUR);	state->pause_continue_button = GrNewWindow(state->main_window,					PAUSE_CONTINUE_BUTTON_X_POSITION,					PAUSE_CONTINUE_BUTTON_Y_POSITION,					PAUSE_CONTINUE_BUTTON_WIDTH,					PAUSE_CONTINUE_BUTTON_HEIGHT, 0,					BUTTON_BACKGROUND_COLOUR, 0);	GrSelectEvents(state->pause_continue_button, GR_EVENT_MASK_EXPOSURE |					GR_EVENT_MASK_BUTTON_DOWN);	state->anticlockwise_button = GrNewWindow(state->main_window,					ANTICLOCKWISE_BUTTON_X_POSITION,					ANTICLOCKWISE_BUTTON_Y_POSITION,					ANTICLOCKWISE_BUTTON_WIDTH,					ANTICLOCKWISE_BUTTON_HEIGHT, 0,					BUTTON_BACKGROUND_COLOUR,					0);	GrSelectEvents(state->anticlockwise_button, GR_EVENT_MASK_EXPOSURE |					GR_EVENT_MASK_BUTTON_DOWN);	state->clockwise_button = GrNewWindow(state->main_window,					CLOCKWISE_BUTTON_X_POSITION,					CLOCKWISE_BUTTON_Y_POSITION,					CLOCKWISE_BUTTON_WIDTH,					CLOCKWISE_BUTTON_HEIGHT, 0,					BUTTON_BACKGROUND_COLOUR,					0);	GrSelectEvents(state->clockwise_button, GR_EVENT_MASK_EXPOSURE |					GR_EVENT_MASK_BUTTON_DOWN);	state->left_button = GrNewWindow(state->main_window,					LEFT_BUTTON_X_POSITION,					LEFT_BUTTON_Y_POSITION,					LEFT_BUTTON_WIDTH,					LEFT_BUTTON_HEIGHT, 0,					BUTTON_BACKGROUND_COLOUR,					0);	GrSelectEvents(state->left_button, GR_EVENT_MASK_EXPOSURE |					GR_EVENT_MASK_BUTTON_DOWN);	state->right_button = GrNewWindow(state->main_window,					RIGHT_BUTTON_X_POSITION,					RIGHT_BUTTON_Y_POSITION,					RIGHT_BUTTON_WIDTH,					RIGHT_BUTTON_HEIGHT, 0,					BUTTON_BACKGROUND_COLOUR,					0);	GrSelectEvents(state->right_button, GR_EVENT_MASK_EXPOSURE |					GR_EVENT_MASK_BUTTON_DOWN);	state->drop_button = GrNewWindow(state->main_window,					DROP_BUTTON_X_POSITION,					DROP_BUTTON_Y_POSITION,					DROP_BUTTON_WIDTH,					DROP_BUTTON_HEIGHT, 0,					BUTTON_BACKGROUND_COLOUR,					0);	GrSelectEvents(state->drop_button, GR_EVENT_MASK_EXPOSURE |					GR_EVENT_MASK_BUTTON_DOWN);	state->well_window = GrNewWindow(state->main_window,					WELL_WINDOW_X_POSITION,					WELL_WINDOW_Y_POSITION,					WELL_WINDOW_WIDTH,					WELL_WINDOW_HEIGHT, 0,					WELL_WINDOW_BACKGROUND_COLOUR, 0);	GrSelectEvents(state->well_window, GR_EVENT_MASK_EXPOSURE);	GrMapWindow(state->well_window);	state->wellgc = GrNewGC();	GrMapWindow(state->main_window);	state->state = STATE_STOPPED;	state->score = 0;	read_hiscore(state);	state->level = 0;	state->running_buttons_mapped = 0;	srandom(time(0));	choose_new_shape(state);	new_game(state);}void calculate_timeout(nstate *state){	struct timeval t;	long u;	gettimeofday(&t, NULL);	u = t.tv_usec + (delays[state->level] * 1000);	state->timeout.tv_sec = t.tv_sec + (u / 1000000);	state->timeout.tv_usec = u % 1000000;}unsigned long timeout_delay(nstate *state){	struct timeval t;	signed long s, m, ret;	gettimeofday(&t, NULL);	if((t.tv_sec > state->timeout.tv_sec) ||			((t.tv_sec == state->timeout.tv_sec) &&			t.tv_usec >= state->timeout.tv_usec)) return 1;	s = state->timeout.tv_sec - t.tv_sec;	m = ((state->timeout.tv_usec - t.tv_usec) / 1000);	ret = (unsigned long)((1000 * s) + m);/*	fprintf(stderr, "t.tv_sec = %ld, t.tv_usec = %ld, timeout.tv_sec = "		"%ld, timeout.tv_usec = %ld, s = %ld, m = %ld, ret = %ld\n",		t.tv_sec, t.tv_usec, state->timeout.tv_sec,			state->timeout.tv_usec, s, m, ret);*/	if(ret <= 0) return 1;	else return ret;}void do_update(nstate *state){	struct timeval t;	gettimeofday(&t, NULL);	if((t.tv_sec > state->timeout.tv_sec) ||			((t.tv_sec == state->timeout.tv_sec) &&			(t.tv_usec >= state->timeout.tv_usec))) {		drop_block_1(state);		calculate_timeout(state);	} }void do_pause(nstate *state){	draw_pause_continue_button(state);	while(state->state == STATE_PAUSED) {		GrGetNextEvent(&state->event);		handle_event(state);	}	draw_pause_continue_button(state);}void wait_for_start(nstate *state){	draw_pause_continue_button(state);	while(state->state == STATE_STOPPED) {		GrGetNextEvent(&state->event);		handle_event(state);	}	if(state->state == STATE_NEWGAME) state->state = STATE_RUNNING;	draw_pause_continue_button(state);	calculate_timeout(state);}void run_game(nstate *state){	while(state->state == STATE_RUNNING) {		GrGetNextEventTimeout(&state->event, timeout_delay(state));		handle_event(state);		if(state->state == STATE_PAUSED) do_pause(state);		if(state->state == STATE_RUNNING) do_update(state);	}}void main_game_loop(nstate *state){	wait_for_start(state);	while(state->state != STATE_EXIT) {		if(state->state == STATE_RUNNING) run_game(state);		if(state->state == STATE_STOPPED) wait_for_start(state);		if(state->state != STATE_EXIT) new_game(state);	}}int main(int argc, char *argv[]){	nstate *state = my_malloc(sizeof(nstate));	init_game(state);	main_game_loop(state);	write_hiscore(state);	GrClose();	return 0;}

⌨️ 快捷键说明

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