架构练习:c语言实现贪吃蛇(三):封装蛇的移动方法

目前进展:

封装蛇的移动方法:

typedef struct snakeinfo
{
	int numParts;/* how many parts,蛇身体分多少个段 */
	int lenParts[GAME_WIDTH];/* 蛇身体每段的长度 */
	int xPartsHead[GAME_WIDTH];/* 蛇身体第i段的x坐标,初始值为1 */
	int yPartsHead[GAME_WIDTH];/* 蛇身体第i段的y坐标,初始值为1 */
	uchar direction;/* 蛇当前在像哪个方向移动,2:下,4:左,6:右,8:上 */
	int (*moveDown)(WINDOW *win);
	int (*moveUp)(WINDOW *win);
	int (*moveLeft)(WINDOW *win);
	int (*moveRight)(WINDOW *win);
}SnakeSt;

static SnakeSt snake = {1,{1,},{GAME_WIDTH/2,},{GAME_HIGTH/2,}, 6};

完成蛇的初始化:

int snakeInit(WINDOW *win)
{
	int i;

	for(i=0; i<snake.lenParts[0];i++)
	{
		mvwprintw(win,snake.yPartsHead[0],snake.xPartsHead[0],"*");
	}

	snake.moveDown = snakeMoveDown;
	snake.moveUp   = snakeMoveUp;
	snake.moveLeft = snakeMoveLeft;
	snake.moveRight= snakeMoveRight;

	snake.direction = 6;

	return 0;
}

源码:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <curses.h>
#include <curses.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <ncurses.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>

#define GAME_WIDTH 50
#define GAME_HIGTH 25

int targetGenerate(int *x_site, int *y_site)
{
	int seconds= time((time_t*)NULL); 

	*y_site = abs(seconds*random())%GAME_HIGTH;
	*x_site = abs(seconds*random())%GAME_WIDTH;

	return 0;
}

typedef unsigned char uchar;

typedef struct snakeinfo
{
	int numParts;/* how many parts,蛇身体分多少个段 */
	int lenParts[GAME_WIDTH];/* 蛇身体每段的长度 */
	int xPartsHead[GAME_WIDTH];/* 蛇身体第i段的x坐标,初始值为1 */
	int yPartsHead[GAME_WIDTH];/* 蛇身体第i段的y坐标,初始值为1 */
	uchar direction;/* 蛇当前在像哪个方向移动,2:下,4:左,6:右,8:上 */
	int (*moveDown)(WINDOW *win);
	int (*moveUp)(WINDOW *win);
	int (*moveLeft)(WINDOW *win);
	int (*moveRight)(WINDOW *win);
}SnakeSt;

static SnakeSt snake = {1,{1,},{GAME_WIDTH/2,},{GAME_HIGTH/2,}, 6};
/* 初始值蛇身体长1段,第一段长度为1,初始向右移动,蛇的初始位置在中间 */
int snakeMove(WINDOW *win);

int snakeMoveDown(WINDOW *win)
{
	snake.yPartsHead[0] -= 1;

	return 0;
}

int snakeMoveUp(WINDOW *win)
{

	snake.yPartsHead[0] += 1;

	return 0;
}

int snakeMoveLeft(WINDOW *win)
{

	snake.xPartsHead[0] -= 1;

	return 0;
}

int snakeMoveRight(WINDOW *win)
{

	snake.xPartsHead[0] += 1;

	return 0;
}

int snakeInit(WINDOW *win)
{
	int i;

	for(i=0; i<snake.lenParts[0];i++)
	{
		mvwprintw(win,snake.yPartsHead[0],snake.xPartsHead[0],"*");
	}

	snake.moveDown = snakeMoveDown;
	snake.moveUp   = snakeMoveUp;
	snake.moveLeft = snakeMoveLeft;
	snake.moveRight= snakeMoveRight;

	snake.direction = 6;

	return 0;
}

int snakeMove(WINDOW *win)
{
	switch(snake.direction)
	{
		case 2:
			snake.moveDown(win);
			break;
		case 4:
			snake.moveLeft(win);
			break;
		case 6:
			snake.moveRight(win);
			break;
		case 8:
			snake.moveUp(win);
			break;
		default:
			printf("Invalid Direct!\n");
			return -1;
	}
}

int frameCreate(WINDOW *win,int x_site, int y_site)
{
	int i, j;

	for(j=0;j<GAME_HIGTH;j++)
	{
		for(i=0;i<GAME_WIDTH;i++)
		{
			if(i == snake.xPartsHead[0] && j == snake.yPartsHead[0])
			{
				mvwprintw(win,j,i,"+");
			}
			else if(i == x_site && j == y_site)
			{
				mvwprintw(win,j,i,"*");
			}
			else if(j == 24 || j ==0)
			{
				mvwprintw(win,j,i,"-");
			}
			else if(1 == i)
			{
				mvwprintw(win,j,i,"|");
			}
			else if(i== (GAME_WIDTH-1))
			{
				mvwprintw(win,j,i,"|");
			}
			else
			{
				mvwprintw(win,j,i," ");
			}
		}
	}

	return 0;
}

static int need_new_target = 1;
static int x_site, y_site;

int snakeCreate(WINDOW *win)
{
	int i, j;

	if(need_new_target == 1)
	{
		targetGenerate(&x_site, &y_site);
		need_new_target = 0;
	}

	snakeInit(win);

	snakeMove(win);

	frameCreate(win, x_site, y_site);

	return 0;
}

/*
resource ncurses_newwin ( int rows, int cols, int y, int x);

ncurses_newwin() creates a new window to draw elements in. Windows can be positioned using x, y, rows and cols. When creating additional windows, remember to use ncurses_getmaxyx() to check for available space, as terminal size is individual and may vary. The return value is a resource ID used to differ between multiple windows.
*/

int main(int argc, char *argv[])
{
	int x,y;
   	time_t t;
   	pthread_t thread;
   	WINDOW *win;

   	initscr();          //鍒濆鍖栨爣鍑嗙獥鍙?蹇呴渶婊?
   	curs_set(0);        //闅愯棌鍏夋爣鍔ㄦ€?
   	noecho();           //杈撳叆鏃犲洖鏄?
	win=newwin(25,50,0,0);
	getmaxyx(win,y,x);
 	printf("a:%d, b:%d\n",x,y);
   	refresh();          //鍒锋柊涓€涓嬫爣鍑嗙獥鍙?涓嶇劧鏃犳硶鏄剧ず鏂板缓鐨勭獥鍙?
   	wrefresh(win);      //鍒锋柊涓€涓嬫柊寤虹殑绐楀彛
	while(1)
	{
		snakeCreate(win);
		wrefresh(win);
		sleep(1);
	}

	endwin();

	return 0;
}
时间: 2024-08-03 03:01:13

架构练习:c语言实现贪吃蛇(三):封装蛇的移动方法的相关文章

C语言实现贪吃蛇之图形界面篇

这已经是贪吃蛇系列的第五篇了,讲真一直写这个也挺无聊的,所以这一篇博文将是系列的最后一篇.虽然已经介绍了贪吃蛇的几种写法,但说到底我们的游戏还只是在一个黑框框里移动的星号.和我们平时玩的贪吃蛇游戏有不少差距.游戏嘛,画面也是很重要的一环.接下来就是让之前的贪吃蛇游戏脱胎换骨的时候了.话不多说,这就开干吧. 首先,为了摆脱无趣的黑框(控制台),我们这次新建一个win32项目,直接点击完成.初次接触win32项目的同学可能会感到一股扑面而来的伤害,满屏都是意义不明的字符,这TM还是C语言吗!先不要沮

从无到有构建大型电商微服务架构实际开发案例教程(第三阶段)

从无到有构建大型电商微服务架构实际开发案例教程(第三阶段)课程下载地址:https://pan.baidu.com/s/1oTfj9d-o4URKFzMoVXKxBQ 提取码:8p0s 本课程将手把手带大家从无到有实现一个真实的大型电商微服务项目,该项目是基于真实的知名互联网企业项目讲解的 本课程将讲解如何从无到有搭建一个真实的大型电商微服务项目,涉及的内容较多,录制所需的时间也会比较久,因此整部课程下来售价也比较高,但考虑到课程中讲解的某阶段的知识点,有部分学员可能已经掌握了解,并不需要再次学

C语言基础课程 第三课 ADB(Android Debug Bridge)的使用

?? C语言基础课程 第三课 ADB(Android Debug Bridge)的使用 由于前面已经发布过Linux的博客了 基础班将Linux基础命令就不单独发表博客了,本节课主要就是利用adb连接手机进行一个Linux基本命令的复习.而且熟悉手机的底层运作,不用界面操作照样也能安装软件  卸载软件与pc传数据 目  录 1       将android设备通过USB连接到PC. 3 2       查看当前设备... 3 3       进入设备shell. 4 4       执行shel

【C语言天天练(三)】函数

对于程序来讲,函数的地位是不言而喻的.下面先给出函数的定义,然后根据定义分析C语言中的函数. 函数定义: 类型 函数名(形式参数) 代码块 由定义可以看出函数主要包括四部分:函数类型.函数名.函数形参.函数代码块. 函数类型:指明了函数返回值的类型,是整数.浮点数.指针甚至是结构体等等.需要注意的两点:1.如果类型是void,则没有返回值.如果是void *型的返回值,那可以返回任意类型的指针,这是ANSI C标准定义的,void *可以是任意类型的指针.2.返回值的类型应该与函数定义的类型相同

数据结构与问题求解-Java语言描述(第三版)

数据结构对程序的重要性不言而喻,用java语言来实现常见的一些数据结构,以及在相应数据结构上的操作对学习java的同学来说是必须掌握的. 本系列博文参考<数据结构与问题求解-Java语言描述(第三版)>来实现 在自己学习的过程中,更希望有机会与大家交流. PS :本人是菜鸟,只是用博客的方式激励自己.请轻喷.Fighting!

C语言文件操作(三)

实例3:读写字节文件,每次读入一个缓存里面. #include<stdio.h> #include <stdlib.h> #define MAXLEN 1024 int main() { FILE *fpin ; FILE *fpout; unsigned char buf[MAXLEN]; int c; fpout=fopen("c:\\dest.jpg","wb"); if((fpin=fopen("c:\\test.jpg&q

C语言快速入门系列(三)

C语言快速入门系列(三) 结构化的程序设计 -----------------------------------转载请注明出处:coder-pig 本节引言: 在前面的学习中,我们对C语言的基本语法进行了了解,可以暂时理解成我们学了单词; 现在要做得就是学语法,也就是算法;就是构成一个一个基本的程序! 在这一节中我们要学习的是C语言中的输入输出,以及程序的三种结构(顺序,选择,循环结构) 本节学习路线图: 正文: 1.字符输入/输出函数 2.格式输入/输出函数 跟前面的单个字符的输入输出不同,

C语言的那些题(三) —— 编程计算身高问题

今天,再和大家分享一道关于编程计算身高的问题. 每个做父母的都关心自己孩子成人后的身高,据有关生理卫生知识与数理统计分析表明,影响小孩成人后身高的因素有遗传.饮食习惯与坚持体育锻炼等.小孩成人后身高与其父母身高和自身性别密切相关.设faHeight为其父身高,moHeight为其母身高,身高预测公式为:男性成人时身高 = (faHeight + moHeight) * 0.54(cm),女性成人时身高 = (faHeight * 0.923 + moHeight) / 2(cm),此外,如果喜爱

Android架构分析之Android消息处理机制(三)

作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android版本:4.4.2 本文我们来分析AndroidUI线程即主线程是怎样实现对消息的处理的. UI线程的实现类定义在frameworks/base/core/java/android/app/ActivityThread.java文件中.我们来看Android对ActivityThread类的说明 : 130/** 131 * This manages the execution of the main