贪吃蛇项目(含源码)

游凡/贪吃蛇icon-default.png?t=N7T8https://gitee.com/you-fan-a/greedy-snake

#这里我们用控制台程序来完成贪吃蛇这个游戏。

首先,打开编译器,随便写点东西运行,出现运行窗口,右键运行窗口的上边窗。

点击属性,将默认终端应用程序改为控制台主机。

#需要用到的编程知识

1.cmd命令

//需要包含头文件 #include<Windows.h>

system("mode con cols=100 lines=30");
//设置窗口的大小 30行 100列

system("title 贪吃蛇");
//设置窗口的名称  贪吃蛇

效果如下:

2.控制台的坐标

COORD是windows API自带的一种结构体,说白了就是可以直接用的结构体。

typedef struct _COORD {
    SHORT X;   //光标的X坐标
    SHORT Y;   //光标的Y坐标
} COORD, *PCOORD;


COORD pos={12,13};    //给光标赋值(决定光标位置)

3.Windows API函数

3.1GetStdHandle 函数

该函数用来获取标准设备(标准输入、标准输出和标准错误)的一个句柄,有了这个句柄就可以操控设备了。(可以理解为获取了设备的操作权限)

//HANDLE是数据类型
HANDLE hOutput = NULL;

//获取标准输出的句柄(⽤来标识不同设备的数值) 
hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

3.2CONSOLE_CURSOR_INFO 结构体

        这个结构体包含控制台光标的信息

typedef struct _CONSOLE_CURSOR_INFO {
 DWORD dwSize;    //dwSize表示光标的宽度,宽度值介于1~100之间,100时是个高长方形
 BOOL bVisible;   //bVisible表示光标的可见性,当他的值时是TURE时光标可见 
} CONSOLE_CURSOR_INFO, *PCONSOLE_CURSOR_INFO;


cursorinfo.bVisible = false;    //隐藏光标
//cursorinfo是结构体名称

3.3GetConsoleCursorInfo 函数

函数原型:

BOOL WINAPI GetConsoleCursorInfo(
 HANDLE hConsoleOutput,
 PCONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);

获取控制台光标信息

HANDLE hOutput = NULL;

hOutput = GetStdHandle(STD_OUTPUT_HANDLE);    //获取标准输出的句柄(⽤来标识不同设备的数值) 
CONSOLE_CURSOR_INFO CursorInfo;

GetConsoleCursorInfo(hOutput, &CursorInfo);    //获取控制台光标信息 

3.4SetConsoleCursorInfo 函数

函数原型:

BOOL WINAPI SetConsoleCursorInfo(
 HANDLE hConsoleOutput,
 const CONSOLE_CURSOR_INFO *lpConsoleCursorInfo
);

设置控制台光标信息

HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);//STD_OUTPUT_HANDLE为输出设备句柄


//影藏光标操作 
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hOutput, &CursorInfo);//获取控制台光标信息 
CursorInfo.bVisible = false; //隐藏控制台光标 
SetConsoleCursorInfo(hOutput, &CursorInfo);//设置控制台光标状态

3.5SetConsoleCursorPosition 函数

函数原型:

BOOL WINAPI SetConsoleCursorPosition(
 HANDLE hConsoleOutput,
 COORD pos
);

设置控制台光标位置

COORD pos = { 10, 5};
 HANDLE hOutput = NULL;
 //获取标准输出的句柄(⽤来标识不同设备的数值) 
 hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
 //设置标准输出上光标的位置为pos 
 SetConsoleCursorPosition(hOutput, pos);

3.6GetAsyncKeyState 函数

函数原型:

SHORT GetAsyncKeyState(
 int vKey
);

//在上一次函数调用后,函数返回的16位数据,如果最高位是1,则说明按键是按下的状态,否则最高位为1.
                                     //如果最低位是1,则说明按键被按过,否则为0.

获取键盘状态。虚拟键码:虚拟键码 (Winuser.h) - Win32 apps | Microsoft Learn

将该函数的返回值与1,判断是否按过
#define KEY_PRESS(VK) ( (GetAsyncKeyState(VK) & 0x1) ? 1 : 0 )


使用案例
while (1)
 {
     if (KEY_PRESS(0x30))
     {
     printf("0\n");
     }
     else if (KEY_PRESS(0x31))
     {
     printf("1\n");
     }
     else if (KEY_PRESS(0x32))
     {
     printf("2\n");
     }
     else if (KEY_PRESS(0x33))
     {
     printf("3\n");
     }
     else if (KEY_PRESS(0x34))
     {
     printf("4\n");
     }
     else if (KEY_PRESS(0x35))
     {
     printf("5\n");
     }
}

#项目思路

一、设置游戏窗口

将窗口设置成合适大小,将窗口的名称改为贪吃蛇,并隐藏控制台光标。


void ConsoleInit()
{
	system("mode con cols=100 lines=30");//将窗口大小改为30行,100列
	system("title 贪吃蛇");//名称改为贪吃蛇
	HANDLE handleput = GetStdHandle(STD_OUTPUT_HANDLE);
	CONSOLE_CURSOR_INFO consolecursorinfo;
	GetConsoleCursorInfo(handleput, &consolecursorinfo);
	consolecursorinfo.bVisible = false;//将光标设置为不可见
	SetConsoleCursorInfo(handleput, &consolecursorinfo);
}

二、创建蛇及其相关结构体

typedef struct Snake//创建蛇结构体,用链表链接蛇身
{
	wchar_t body;
	int x;
	int y;
	struct Snake* next;
}Snake;

typedef enum state//创建状态枚举,用于判断游戏是否结束
{
	OK,
	END_BODY,
	END_WALL,
	END_ESC,
	SPACE
}state;

typedef enum key//游戏按键
{
	up,
	down,
	right,
	left
}key;

typedef enum food//贪吃蛇的食物,不同的食物又不同分数
{
	score1,//★
	score2,//▲
	score3,//▼
	uneat,
	eated
}food;

typedef struct pos//坐标
{
	int x;
	int y;
}pos;

typedef struct SnakeGame//游戏功能的集合
{
	Snake *snake;
	enum food food;
	enum state state;
	enum key key;
	int score;//游戏总分数
	int speed;//游戏速度
	int extrascore;//额外分
	pos foodpos;//食物坐标

}Game;

三、对游戏进行初始化

void GameInit(Game* const game)
{
	game->state = OK;//游戏状态
	game->key = right;//贪吃蛇最开始移动方向
	game->food = uneat;//食物状态
	game->score = 0;//分数
	game->speed = 0;//速度
	game->extrascore = 0;//额外分数
}

四、展示最开始的提示

#define cols 60
#define lines 20

//设置坐标
void setpos(int x,int y)//写一个设置控制台坐标的函数,方便以后设置坐标
{
	HANDLE handleput = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos = { x , y };
	SetConsoleCursorPosition(handleput, pos);
}

//展示最初提示
void ShowInitialScreen()
{
	setpos(40, 15);
	printf("欢迎来到贪吃蛇游戏");
	setpos(40, 24);
	system("pause");
	system("cls");
	setpos(25, 15);
	printf("使用↑ ↓ ← → 操控蛇,去吃食物(★、▲、▼),并避免撞到墙(□)");
	setpos(40, 24);
	system("pause");
	system("cls");
	setpos(0, 0);
	for (int i = 0; i < (cols/2); i++)
	{
		printf("□");
	}
	setpos(0, 20);
	for (int i = 0; i < (cols/2); i++)
	{
		printf("□");
	}
	for (int i = 1; i <= lines-1; i++)
	{
		setpos(0, i);
		printf("□");
	}
	for (int i = 1; i <= lines-1; i++)
	{
		setpos(58, i);
		printf("□");
	}

	setpos(65, 8);
	printf("F1加速          F2减速");
	setpos(70, 12);
	printf("当前分数:");
	setpos(70, 13);
	printf("当前速度:");
	setpos(65, 15);
	printf("★5分   ▲7分   ▼10分");
	setpos(65, 16);
	printf("每一点速度都会为食物加2分");
	
}

五、创建蛇身

5.1创建蛇头

//创建蛇的头
Snake* CreateSnake()
{
	Snake* ret = (Snake*)malloc(sizeof(Snake));
	if (ret != NULL)
	{
		ret->body = L'◆';//这是宽字符
		ret->next = NULL;
		return ret;
	}
	else
	{
		perror("malloc");
		return NULL;
	}
}

5.2创建蛇身

//创建最开始的蛇
void CreatInitialSnake(Game* game)
{
	Snake* ret = NULL;
	for (int i = 0; i < 5; i++)//从后往前建造蛇身
	{
		Snake* snake = (Snake*)malloc(sizeof(Snake));
		if (snake != NULL)
		{
			if (i == 4)
			{
				snake->body = L'◆';
			}
			else
			{
				snake->body = L'●';
			}
			snake->x = 30 + i*2;//设置蛇身的坐标
			snake->y = 9;
			snake->next = ret;
			ret = snake;
			game->snake = snake;
		}
		else
		{
			perror("malloc");
		}
	}
}

 六、判断当前状态

void JudgeState(Game* const game)
{
    //检测是否撞到墙
	if (game->snake->x == 0 || game->snake->x == cols - 2 || game->snake->y == 0 || game->snake->y == lines)
	{
		game->state = END_WALL;
		setpos(20, 10);
		printf("你撞到障碍物失败");
		return;
	}

    //检测是否撞到自己
	Snake* ret = game->snake->next;
	while (ret != NULL)
	{
		if (ret->x == game->snake->x && ret->y == game->snake->y)
		{
			game->state = END_BODY;
			setpos(20, 10);
			printf("你撞到自己失败");
			return;
		}
		ret = ret->next;
	}

    //检测是否按Esc退出
	if (game->state == END_ESC)
	{
		setpos(20, 10);
		printf("已退出");
	}

    //检测是否暂停
	if (game->state==SPACE)
	{
		setpos(0,24);
		system("pause");
		setpos(0, 24);
		printf("                   ");
		game->state = OK;
	}
}

七、食物

7.1判断食物是否被吃

void JudgeFoodEated(Game* const game)
{
	if (game->snake->x == game->foodpos.x && game->snake->y == game->foodpos.y)
	{

        //根据食物种类的不同,所加的分也不同
		if (game->food == score1)
		{
			game->score += (5+game->extrascore);
		}
		else if (game->food == score2)
		{
			game->score += (7 + game->extrascore);
		}
		else if (game->food == score3)
		{
			game->score += (10 + game->extrascore);
		}
		game->food = eated;//食物被吃后,将食物的状态改eated
	}

}

7.2生成食物

void Food(Game* const game)
{
	if (game->food == uneat)
	{
		int cl, lin;
	again:            //goto语句
		cl = rand() % (cols-5) + 1;//随机生成食物的位置
		lin = rand() % (lines - 2) + 1;
		if ((cl % 2) != 0)
		{
			cl = cl + 1;
		}
		for (Snake* ret = game->snake; ret != NULL; ret = ret->next)
		{
			if (cl == ret->x && lin == ret->y)//防止食物生成在蛇身里
			{
				goto again;
			}

		}
		game->foodpos.x = cl;
		game->foodpos.y = lin;
		int score = rand() % 2 + 1;//随机生成三种不同的食物
		if (score == 1)
		{
			game->food = score1;
			setpos(cl, lin);
			printf("★");
		}
		else if (score == 2)
		{
			game->food = score2;
			setpos(cl, lin);
			printf("▲");
		}
		else if (score == 3)
		{
			game->food = score3;
			setpos(cl, lin);
			printf("▼");
		}

	}
	else
	{
		JudgeFoodEated(game);//判断食物是否被吃
	}
	
}

八、检测虚拟按键

#define ASYNC(VK) ((GetAsyncKeyState(VK)&1)? 1 : 0 )


	//控制按钮
	if (ASYNC(VK_UP) && game->key != down)
	{
		game->key = up;
	}
	else if (ASYNC(VK_DOWN) && game->key != up)
	{
		game->key = down;
	}
	else if (ASYNC(VK_RIGHT) && game->key != left)
	{
		game->key = right;
	}
	else if (ASYNC(VK_LEFT) && game->key != right)
	{
		game->key = left;
	}
	else if (ASYNC(VK_SPACE))
	{
		game->state = SPACE;
	}
	else if (ASYNC(VK_ESCAPE))
	{
		game->state = END_ESC;
	}
	else if (ASYNC(0x70))
	{
		time = time - 20;
		game->extrascore += 2;
		game->speed += 1;

	}
	else if (ASYNC(0x71))
	{
		time = time + 20;
		game->extrascore -= 2;
		game->speed -= 1;
	}

    //按测到按键按下,对蛇头进行更改
	Snake* con = CreateSnake();
	if (con != NULL)
	{
		if (game->key == up)
		{
			con->body = L'◆';
			con->x = game->snake->x;
			con->y = game->snake->y - 1;
			game->snake->body = L'●';
			con->next = game->snake;
			game->snake = con;
		}
		if (game->key == down)
		{
			con->body = L'◆';
			con->x = game->snake->x;
			con->y = game->snake->y + 1;
			game->snake->body = L'●';
			con->next = game->snake;
			game->snake = con;
		}
		if (game->key == right)
		{
			con->body = L'◆';
			con->x = game->snake->x + 2;
			con->y = game->snake->y;
			game->snake->body = L'●';
			con->next = game->snake;
			game->snake = con;
		}
		if (game->key == left)
		{
			con->body = L'◆';
			con->x = game->snake->x - 2;
			con->y = game->snake->y;
			game->snake->body = L'●';
			con->next = game->snake;
			game->snake = con;
		}

	}
	else
	{
		perror("malloc");
	}

九、打印游戏进行的画面

if (game->food != eated)//判断食物是否被被吃
{
    //食物没有被吃,释放掉蛇尾(蛇移动时蛇尾要消失)
	for (Snake* ret = game->snake; ret->next != NULL; ret = ret->next)
	{
		if (ret->next->next == NULL)
		{
			setpos(ret->next->x, ret->next->y);
			wprintf(L"%lc", L' ');//这是宽字符打印
			free(ret->next);
			ret->next = NULL;
			break;
		}
	}


}
else
{
	game->food = uneat;//食物被吃,则更改食物状态,以便重新生成食物
}

//打印蛇身
if (game->snake != NULL && game->snake->next != NULL)
{
	setpos(game->snake->x, game->snake->y);
	wprintf(L"%lc", game->snake->body);
	setpos(game->snake->next->x, game->snake->next->y);
	wprintf(L"%lc", game->snake->next->body);
	Sleep(time);
}
else
{
	perror("NULL");
}

//打印份数和速度
setpos(79, 12);
printf("%d", game->score);
setpos(79, 13);
printf("%d", game->speed);


Food(game);//生成食物

#将八和九的代码放在一起(需添加格外的代码)

void SetGame(Game* game)
{
	CreatInitialSnake(game);
	for (Snake* ret = game->snake; ret != NULL; ret = ret->next)
	{

		setpos(ret->x, ret->y);
		wprintf(L"%lc", ret->body);

	}
	int time = 100;
	do
	{
		//控制按钮
		if (ASYNC(VK_UP) && game->key != down)
		{
			game->key = up;
		}
		else if (ASYNC(VK_DOWN) && game->key != up)
		{
			game->key = down;
		}
		else if (ASYNC(VK_RIGHT) && game->key != left)
		{
			game->key = right;
		}
		else if (ASYNC(VK_LEFT) && game->key != right)
		{
			game->key = left;
		}
		else if (ASYNC(VK_SPACE))
		{
			game->state = SPACE;
		}
		else if (ASYNC(VK_ESCAPE))
		{
			game->state = END_ESC;
		}
		else if (ASYNC(0x70))
		{
			time = time - 20;
			game->extrascore += 2;
			game->speed += 1;

		}
		else if (ASYNC(0x71))
		{
			time = time + 20;
			game->extrascore -= 2;
			game->speed -= 1;
		}
		Snake* con = CreateSnake();
		if (con != NULL)
		{
			if (game->key == up)
			{
				con->body = L'◆';
				con->x = game->snake->x;
				con->y = game->snake->y - 1;
				game->snake->body = L'●';
				con->next = game->snake;
				game->snake = con;
			}
			if (game->key == down)
			{
				con->body = L'◆';
				con->x = game->snake->x;
				con->y = game->snake->y + 1;
				game->snake->body = L'●';
				con->next = game->snake;
				game->snake = con;
			}
			if (game->key == right)
			{
				con->body = L'◆';
				con->x = game->snake->x + 2;
				con->y = game->snake->y;
				game->snake->body = L'●';
				con->next = game->snake;
				game->snake = con;
			}
			if (game->key == left)
			{
				con->body = L'◆';
				con->x = game->snake->x - 2;
				con->y = game->snake->y;
				game->snake->body = L'●';
				con->next = game->snake;
				game->snake = con;
			}

		}
		else
		{
			perror("malloc");
		}
		JudgeState(game);





		//打印游戏进行的画面
		if (game->food != eated)
		{

			for (Snake* ret = game->snake; ret->next != NULL; ret = ret->next)
			{
				if (ret->next->next == NULL)
				{
					setpos(ret->next->x, ret->next->y);
					wprintf(L"%lc", L' ');
					free(ret->next);
					ret->next = NULL;
					break;
				}
			}


		}
		else
		{
			game->food = uneat;
		}
		if (game->snake != NULL && game->snake->next != NULL)
		{
			setpos(game->snake->x, game->snake->y);
			wprintf(L"%lc", game->snake->body);
			setpos(game->snake->next->x, game->snake->next->y);
			wprintf(L"%lc", game->snake->next->body);
			Sleep(time);
		}
		else
		{
			perror("NULL");
		}
		setpos(79, 12);
		printf("%d", game->score);
		setpos(79, 13);
		printf("%d", game->speed);


		Food(game);

	} while (game->state == OK);
}

 十、重新开始

void test()
{
	char ch=-1;
	do
	{
		system("cls");//清屏
		Game game;
		GameInit(&game);
		ConsoleInit();
		ShowInitialScreen();
		SetGame(&game);
		setpos(10, 11);
		printf("按Enter重新开始, 输入其他结束游戏");
		ch= getchar();
	} while (ch == '\n');
	setpos(0, 26);
	system("exit");//结束退出
}

最后调用test就可以了

int main()
{


	srand((unsigned int)time(NULL));//随机数种子
	setlocale(LC_ALL, "");//本地化,可以不加,但是如果是用我的代码,必须加上
	test();
	return 0;
}

  • 12
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贪吃蛇项目是一个经典的游戏,适合初学者来学习Android开发。下面是一个简单的贪吃蛇项目源码: ``` MainActivity.java: import android.app.Activity; import android.os.Bundle; import android.view.Window; import android.view.WindowManager; public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 设置全屏 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 设置游戏画面 setContentView(new GameView(this)); } } GameView.java: import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import java.util.ArrayList; import java.util.List; public class GameView extends SurfaceView implements SurfaceHolder.Callback { private MainThread thread; private Snake snake; private Point food; private int score; public GameView(Context context) { super(context); getHolder().addCallback(this); thread = new MainThread(getHolder(), this); setFocusable(true); } @Override public void surfaceCreated(SurfaceHolder holder) { snake = new Snake(); food = new Point(); score = 0; thread.setRunning(true); thread.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { boolean retry = true; while (retry) { try { thread.setRunning(false); thread.join(); } catch (InterruptedException e) { e.printStackTrace(); } retry = false; } } @Override public boolean onTouchEvent(MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_DOWN) { snake.updateDirection(event.getX(), event.getY()); } return true; } public void update() { snake.move(); checkCollision(); } private void checkCollision() { if (snake.checkSelfCollision() || snake.checkWallCollision(getWidth(), getHeight())) { thread.setRunning(false); } if (snake.getHead().equals(food)) { food = createFood(); snake.grow(); score += 10; } } private Point createFood() { List<Point> snakePositions = snake.getPositions(); Point newFood = new Point(); while (true) { newFood.x = (int) Math.floor(Math.random() * (getWidth() - Snake.BLOCK_SIZE)); newFood.y = (int) Math.floor(Math.random() * (getHeight() - Snake.BLOCK_SIZE)); for (Point snakePosition : snakePositions) { if (!newFood.equals(snakePosition)) { return newFood; } } } } @Override public void draw(Canvas canvas) { super.draw(canvas); if (canvas != null) { // 清空画面 canvas.drawColor(Color.BLACK); // 绘制蛇 snake.draw(canvas); // 绘制食物 Paint paint = new Paint(); paint.setColor(Color.RED); canvas.drawRect(food.x, food.y, food.x + Snake.BLOCK_SIZE, food.y + Snake.BLOCK_SIZE, paint); // 绘制分数 Paint scorePaint = new Paint(); scorePaint.setColor(Color.WHITE); scorePaint.setTextSize(40); canvas.drawText("Score: " + score, 10, 50, scorePaint); } } } Snake.java: import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import java.util.ArrayList; import java.util.List; public class Snake { public static final int BLOCK_SIZE = 40; private static final int SPEED = 10; private List<Point> positions; private int direction; public Snake() { direction = 1; positions = new ArrayList<>(); positions.add(new Point(0, 0)); positions.add(new Point(BLOCK_SIZE, 0)); positions.add(new Point(BLOCK_SIZE * 2, 0)); positions.add(new Point(BLOCK_SIZE * 3, 0)); positions.add(new Point(BLOCK_SIZE * 4, 0)); } public void updateDirection(float x, float y) { if (Math.abs(x - getHead().x) > Math.abs(y - getHead().y)) { if (x < getHead().x) { direction = 0; } else { direction = 2; } } else { if (y < getHead().y) { direction = 1; } else { direction = 3; } } } public void move() { Point newHead = new Point(getHead().x, getHead().y); switch (direction) { case 0: newHead.x -= BLOCK_SIZE; break; case 1: newHead.y -= BLOCK_SIZE; break; case 2: newHead.x += BLOCK_SIZE; break; case 3: newHead.y += BLOCK_SIZE; break; } positions.add(0, newHead); positions.remove(positions.size() - 1); } public void grow() { Point newTail = new Point(getTail().x, getTail().y); positions.add(newTail); } public boolean checkSelfCollision() { for (int i = 1; i < positions.size(); i++) { if (getHead().equals(positions.get(i))) { return true; } } return false; } public boolean checkWallCollision(int screenWidth, int screenHeight) { if (getHead().x < 0 || getHead().y < 0 || getHead().x >= screenWidth || getHead().y >= screenHeight) { return true; } return false; } public Point getHead() { return positions.get(0); } public Point getTail() { return positions.get(positions.size() - 1); } public List<Point> getPositions() { return positions; } public void draw(Canvas canvas) { Paint paint = new Paint(); paint.setColor(Color.WHITE); for (Point position : positions) { canvas.drawRect(position.x, position.y, position.x + BLOCK_SIZE, position.y + BLOCK_SIZE, paint); } } } MainThread.java: import android.graphics.Canvas; import android.view.SurfaceHolder; public class MainThread extends Thread { private final SurfaceHolder surfaceHolder; private GameView gameView; private boolean running; private Canvas canvas; public MainThread(SurfaceHolder surfaceHolder, GameView gameView) { this.surfaceHolder = surfaceHolder; this.gameView = gameView; this.running = false; } public void setRunning(boolean running) { this.running = running; } @Override public void run() { while (running) { canvas = null; try { // 锁定画布并更新游戏状态 canvas = this.surfaceHolder.lockCanvas(); synchronized (surfaceHolder) { this.gameView.update(); this.gameView.draw(canvas); } } finally { if (canvas != null) { // 解锁画布并提交更改 surfaceHolder.unlockCanvasAndPost(canvas); } } } } } ``` 这个源码中,主要的类是`MainActivity`、`GameView`、`Snake`和`MainThread`,其中`MainActivity`是整个游戏的入口类,`GameView`是游戏的主要视图类,`Snake`是贪吃蛇的逻辑实现类,`MainThread`是游戏的主线程类。 在`MainActivity`中,我们设置全屏并将游戏视图设置为`GameView`。`GameView`中,我们维护了贪吃蛇的状态和画面,并监听用户的触摸事件,更新游戏状态并绘制画面。`Snake`中,我们实现了贪吃蛇的逻辑,包括移动、吃食物和检测碰撞等操作。`MainThread`中,我们使用主线程循环更新游戏状态和绘制画面。 这个贪吃蛇项目源码是一个简单的示例,供初学者参考学习。你可以根据自己的需求进行拓展和修改。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值