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

📄 moveblock.c

📁 一个基于linux下图形的移动锁
💻 C
字号:
#include "head.h"
#include "callbacks.h"
extern Block_t *current_block;
extern Block_t *next_block;
extern Block_t block_form_table[BLOCK_FORM][BLOCK_FORM_STATE];
extern gint16 current_x;
extern gint16 current_y;
extern Save_image_t save_image;
extern GdkPixmap *drawing_area_pixmap;
extern guint drawing_area_width;
extern guint drawing_area_height;
extern gboolean block_map[LINE][ROW];
extern GdkGC *block_gc;
extern GtkWidget *drawing_area;
extern GdkPixmap *drawing_area_next_pixmap;
extern GtkWidget *drawing_area_next;
extern GtkWidget *label_game_state;
extern GtkWidget *label_time;
extern guint32 game_score;
extern guint32 game_level;
extern GtkWidget *label_user_socre;
extern GtkWidget *label_user_level;
extern GtkWidget *end_current_game;

/*
 * 改变方块的形状.首先取得当前方块所属组,在搜索其当前组内的位置,
 * 并找出其一个形状(如果是作后一个形状则变为第一个形状)。再判断是
 * 否允许变形,不允许则返回,否则进行变形。
 *
 */
void change_block_form()
{
	gint16 i, j;
	gint8 group;
	Block_t *next_form;

	group = current_block->group;
	for (i = 0;i < BLOCK_FORM_STATE;i++)
	{
		if (block_form_table[group][i].form == current_block->form)
		{
			next_form = (i != BLOCK_FORM_STATE - 1 ? \
					&block_form_table[group][i + 1] : \
					&block_form_table[group][0]);
			break;
		}

	}
	for (i = 0;i < next_form->draw_height;i++)
	{
		for (j = 0; j < next_form->draw_width; j++)
		{
			if (current_y + i*BLOCK_SIZE >= drawing_area_height ||
					current_x + j*BLOCK_SIZE >= drawing_area_width)
				return ;
			if (block_map[current_y / BLOCK_SIZE + i][current_x / BLOCK_SIZE + j] == TRUE)
				return ;
		}
	}
	current_block = next_form;
	gdk_draw_image (drawing_area_pixmap, block_gc, save_image.image,
			0, 0, save_image.x, save_image.y,
			save_image.width, save_image.height);
	save_image.x = current_x;
	save_image.y = current_y;
	save_image.width = current_block->draw_width * BLOCK_SIZE;
	save_image.height = current_block->draw_height * BLOCK_SIZE;
	if (save_image.image)
		gdk_image_unref(save_image.image);
	save_image.image = gdk_drawable_get_image (drawing_area_pixmap,
			save_image.x, save_image.y,
			save_image.width, save_image.height);
	draw_block(current_x, current_y, current_block, drawing_area_pixmap);
	gtk_widget_queue_draw_area(drawing_area, 0, 0,
			drawing_area_width, drawing_area_height);

}
/*
 * 在方块的移动中,判断是否允许移动。判断依据为判断其自当前位置向
 * 移动方向direction上,大小为当前方块所占的格数draw_area_wdith和
 * draw_area_height大小的地图区域进行搜索,如果该区域内没有方块
 * 则允许移动,否则不允许。
 *
 */
gboolean judge_move(guint16 form, Direction direction)
{
	gint8 i, j;
	gchar bin_form[17];
	Block_t *next_block;

	decimal_to_binary(bin_form, form);
	switch (direction)
	{
	case KEY_LEFT:
		for (i = 0;i < current_block->draw_height;i++)
		{
			for (j = 0;j < current_block->draw_width;j++)
				if (bin_form[i*4 + j] == '1')
					break;

			if (j < current_block->draw_width && (current_x + j*BLOCK_SIZE) == 2)
				return FALSE;

			if (block_map[current_y / BLOCK_SIZE + i][current_x / BLOCK_SIZE + j - 1] == TRUE)
				return FALSE;
		}
		current_x -= BLOCK_SIZE;
		break;
	case KEY_RIGHT:
		for (i = 0;i < current_block->draw_height;i++)
		{
			for (j = current_block->draw_width - 1;j >= 0;j--)
				if (bin_form[i*4 + j] == '1')
					break;
			if (j >= 0 && (drawing_area_width - (current_x + (j + 1)*BLOCK_SIZE) == 0))
				return FALSE;

			if (block_map[current_y / BLOCK_SIZE + i][current_x / BLOCK_SIZE + j + 1] == TRUE)
				return FALSE;
		}
		current_x += BLOCK_SIZE;
		break;
	case KEY_DOWN:
		if (current_y + current_block->draw_height*BLOCK_SIZE == drawing_area_height)
			return FALSE;
		for (i = 0;i < current_block->draw_width;i++)
		{
			for (j = current_block->draw_height - 1;j >= 0;j--)
				if (bin_form[j*4 + i] == '1')
					break;

			if (block_map[current_y / BLOCK_SIZE + j + 1][current_x / BLOCK_SIZE + i] == TRUE)
			{
				return FALSE;
			}
		}
		current_y += BLOCK_SIZE;
		break;
	}
	return TRUE;
}
/*
 * 移动方块
 */
gboolean move_block(Direction direction)
{
	if (!judge_move(current_block->form, direction))
		return FALSE;

	gdk_draw_image (drawing_area_pixmap, block_gc, save_image.image,
			0, 0, save_image.x, save_image.y,
			save_image.width, save_image.height);
	save_image.x = current_x;
	save_image.y = current_y;
	if (save_image.image)
		gdk_image_unref(save_image.image);
	save_image.image = gdk_drawable_get_image (drawing_area_pixmap,
			save_image.x, save_image.y,
			save_image.width, save_image.height);
	draw_block(current_x, current_y, current_block, drawing_area_pixmap);
	gtk_widget_queue_draw_area(drawing_area, 0, 0,
			drawing_area_width, drawing_area_height);

}
/*
 * 重新进行下一次循环。首先初始化当前方块为方块提示框内所显示的方块
 * ,置初始坐标,保存将要使用的区域,然后判断该初始区域是否已有方块
 * 如果有,则表示已经死亡,则返回,结束本次游戏。否则进入下一次循环。
 */
gboolean start_new_loop(gpointer pdata)
{
	Get_user_data_t *data = (Get_user_data_t *)pdata;
	current_block = next_block;
	current_x = BLOCK_SIZE * 7 + 2;
	current_y = 2;


	save_image.x = current_x;
	save_image.y = current_y;
	save_image.width = current_block->draw_width * BLOCK_SIZE;
	save_image.height = current_block->draw_height * BLOCK_SIZE;
	if (save_image.image)
		gdk_image_unref(save_image.image);
	save_image.image = gdk_drawable_get_image ( \
			drawing_area_pixmap,
			save_image.x, save_image.y,
			save_image.width, save_image.height);

	gtk_widget_queue_draw_area(drawing_area, 0, 0,
			drawing_area_width, drawing_area_height);

	if (!move_block(KEY_DOWN))
	{
		if (data->is_fight)
		{
			data->current_send.x = current_x;
			data->current_send.y = current_y;
			data->current_send.action = GAME_OVER;
			data->current_send.block = current_block;
			data->current_send.score = game_score;
			data->current_send.level = game_level;
			data->current_send.move_line = 0;
			send(data->is_service ? data->player_tcp : data->client_tcp,
					&data->current_send, sizeof(data->current_send), 0);

		}

		return FALSE;
	}

	next_block = random_block();
	gdk_draw_rectangle (drawing_area_next_pixmap,
			drawing_area_next->style->black_gc, TRUE, 0, 0,
			drawing_area_next->allocation.width,
			drawing_area_next->allocation.height);
	draw_block(BLOCK_SIZE + 2, BLOCK_SIZE + 2, next_block, drawing_area_next_pixmap);
	gtk_widget_queue_draw_area(drawing_area_next, 0, 0,
			drawing_area_next->allocation.width,
			drawing_area_next->allocation.width);


}

⌨️ 快捷键说明

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