使用SetTimer函数和线程函数编写一个贪吃蛇C语言程序
时间: 2024-03-02 09:52:32 浏览: 136
好的,下面是一个简单的贪吃蛇游戏程序示例,使用了SetTimer函数和线程函数:
```c
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
#define MAP_WIDTH 30
#define MAP_HEIGHT 20
#define SNAKE_INIT_LEN 3
#define SNAKE_INIT_X 5
#define SNAKE_INIT_Y 5
#define FOOD_CHAR '@'
#define SNAKE_CHAR '#'
#define BLANK_CHAR ' '
#define TIMER_ID 1
#define TIMER_INTERVAL 100
DWORD WINAPI InputThread(LPVOID lpParam);
char map[MAP_HEIGHT][MAP_WIDTH];
int snakeX[SNAKE_INIT_LEN], snakeY[SNAKE_INIT_LEN];
int snakeLen = SNAKE_INIT_LEN;
int snakeDir = 'd';
int foodX, foodY;
int main() {
HANDLE hInputThread;
DWORD dwInputThreadId;
// 初始化地图
for (int y = 0; y < MAP_HEIGHT; y++) {
for (int x = 0; x < MAP_WIDTH; x++) {
if (x == 0 || x == MAP_WIDTH - 1 || y == 0 || y == MAP_HEIGHT - 1) {
map[y][x] = '#';
} else {
map[y][x] = ' ';
}
}
}
// 初始化蛇
for (int i = 0; i < SNAKE_INIT_LEN; i++) {
snakeX[i] = SNAKE_INIT_X - i;
snakeY[i] = SNAKE_INIT_Y;
map[snakeY[i]][snakeX[i]] = SNAKE_CHAR;
}
// 随机生成食物
srand(GetTickCount());
foodX = rand() % (MAP_WIDTH - 2) + 1;
foodY = rand() % (MAP_HEIGHT - 2) + 1;
map[foodY][foodX] = FOOD_CHAR;
// 创建输入线程
hInputThread = CreateThread(NULL, 0, InputThread, NULL, 0, &dwInputThreadId);
// 安装定时器
SetTimer(NULL, TIMER_ID, TIMER_INTERVAL, NULL);
// 游戏循环
while (1) {
// 绘制地图
system("cls");
for (int y = 0; y < MAP_HEIGHT; y++) {
for (int x = 0; x < MAP_WIDTH; x++) {
putchar(map[y][x]);
}
putchar('\n');
}
Sleep(10);
}
return 0;
}
DWORD WINAPI InputThread(LPVOID lpParam) {
while (1) {
char ch = getchar();
switch (ch) {
case 'w':
if (snakeDir != 's') {
snakeDir = 'w';
}
break;
case 'a':
if (snakeDir != 'd') {
snakeDir = 'a';
}
break;
case 's':
if (snakeDir != 'w') {
snakeDir = 's';
}
break;
case 'd':
if (snakeDir != 'a') {
snakeDir = 'd';
}
break;
}
}
return 0;
}
void MoveSnake() {
// 计算新的蛇头位置
int newHeadX = snakeX[0], newHeadY = snakeY[0];
switch (snakeDir) {
case 'w':
newHeadY--;
break;
case 'a':
newHeadX--;
break;
case 's':
newHeadY++;
break;
case 'd':
newHeadX++;
break;
}
// 判断是否吃到食物
if (newHeadX == foodX && newHeadY == foodY) {
snakeLen++;
foodX = rand() % (MAP_WIDTH - 2) + 1;
foodY = rand() % (MAP_HEIGHT - 2) + 1;
map[foodY][foodX] = FOOD_CHAR;
}
// 判断是否撞墙或撞到自己
if (newHeadX <= 0 || newHeadX >= MAP_WIDTH - 1 || newHeadY <= 0 || newHeadY >= MAP_HEIGHT - 1) {
exit(0);
}
for (int i = 1; i < snakeLen; i++) {
if (newHeadX == snakeX[i] && newHeadY == snakeY[i]) {
exit(0);
}
}
// 更新蛇的位置
for (int i = snakeLen - 1; i >= 1; i--) {
snakeX[i] = snakeX[i - 1];
snakeY[i] = snakeY[i - 1];
}
snakeX[0] = newHeadX;
snakeY[0] = newHeadY;
for (int i = 0; i < snakeLen; i++) {
map[snakeY[i]][snakeX[i]] = SNAKE_CHAR;
}
}
void CALLBACK TimerProc(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime) {
if (idEvent == TIMER_ID) {
MoveSnake();
}
}
```
这个程序使用了一个输入线程来处理用户输入,主线程用于定时更新贪吃蛇的位置和状态,以及绘制地图。在MoveSnake函数中,处理了贪吃蛇的移动、吃食物、撞墙和撞到自己的情况。TimerProc函数作为定时器的回调函数,每隔一段时间调用MoveSnake函数。
当用户输入w、a、s、d时,分别表示贪吃蛇的上、左、下、右移动方向。如果撞墙或撞到自己,则直接退出程序。
阅读全文