C语言_推箱子

本文介绍了一个简单的推箱子游戏实现过程,使用C语言编程,并利用Windows API进行控制台绘图。文章详细展示了游戏的地图设计、角色移动判断及绘图更新等核心功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include "list.h"
/****************************定义宏和结构******************************/
#define bool		int
#define false		0
#define true		1
#define BOX			40
#define WALL		100
#define BACKGROUND	0
#define KEYUP		72
#define KEYLEFT		75
#define KEYRIGHT	77
#define KEYDOWN		80
#define WALLCOLOR FOREGROUND_GREEN
#define HOLECOLOR FOREGROUND_BLUE|FOREGROUND_INTENSITY
#define BOXCOLOR  FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY
#define ROLECOLOR FOREGROUND_BLUE | FOREGROUND_GREEN
#define new(type,num) (type*)malloc(num * sizeof(type))
#define getX(Array, Max, Distance) (Array % Max + Distance)
#define getY(Array, Max, Distance) (Array / Max + Distance)

/***************************函数声明******************************/
inline void test(int x, int y, int valuex, int valuey);
void initMap();
inline void initialization();
inline bool InitializationMap(const int num);
bool keyEvent(int *Key);
bool mobileJudgment(int *Key);
void paint();
bool nextMap();
inline void gotoxy(const int X, const int Y);
void outputText(const int Array[], const int num, const int maxX, const int value, const COORD Distance, WORD Attribute);
inline void outputRole(int x, int y);
void map1();
void map2();
void map3();
/***************************全局变量******************************/
int MapPointer[20][20] = { 0 };//大地图
COORD Role;
int EndNumber;
int *Hole;
int MapX;//小地图X值---->用来取出XY值
COORD Distance;//小地图与大地图距离
COORD PaintPos[3];//游戏中需要重绘的坐标
/*****************************************************************/
int main()
{
	int num = 0;
	bool Sign = true;
	bool Level = true;
	int *Key = new(int, 1);
	initialization();
	
	while (Sign)
	{
		if (Level)
			Sign = InitializationMap(++num);
		if (!Sign)//如果做了结束地图,那么就可以绘制后按任意结束
		{
			_getch();
			continue;
		}
		Sign = keyEvent(Key);
		paint();
		Level = nextMap();
	}

	return EXIT_SUCCESS;
}

inline void test(int x, int y, int valuex, int valuey)
{
	gotoxy(x, y);
	printf("%02d:%02d", valuex, valuey);
}

inline void initialization()
{
	HANDLE handle =  GetStdHandle(STD_OUTPUT_HANDLE);
	const SMALL_RECT rect = { 0,0,100,200 };

	SetConsoleOutputCP(437);
	SetConsoleWindowInfo(handle, false, &rect);
	CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void initMap()
{
	for (int i = 0; i < 20; i++)
		for (int j = 0; j < 20; j++)
			MapPointer[i][j] = 0;
}

inline bool InitializationMap(const int num)
{
	system("cls");
	initMap();
	switch (num)
	{
	case 1:map1(); return true;
	case 2:map2(); return true;
	case 3:map3(); return true;
	}
	return false;
}

bool mobileJudgment(int *Key)
{
	COORD pos[2];
	switch (*Key)
	{
	case KEYLEFT:
		pos[0].Y = pos[1].Y = Role.Y;
		pos[0].X = Role.X - 1;
		pos[1].X = Role.X - 2;
		break;
	case KEYRIGHT:
		pos[0].Y = pos[1].Y = Role.Y;
		pos[0].X = Role.X + 1;
		pos[1].X = Role.X + 2;
		break;
	case KEYUP:
		pos[0].X = pos[1].X = Role.X;
		pos[0].Y = Role.Y - 1;
		pos[1].Y = Role.Y - 2;
		break;
	case KEYDOWN:
		pos[0].X = pos[1].X = Role.X;
		pos[0].Y = Role.Y + 1;
		pos[1].Y = Role.Y + 2;
		break;
	}

	PaintPos[0].X = pos[0].X;
	PaintPos[0].Y = pos[0].Y;
	PaintPos[1].X = pos[1].X;
	PaintPos[1].Y = pos[1].Y;
	PaintPos[2].X = Role.X;
	PaintPos[2].Y = Role.Y;

	if (MapPointer[pos[0].Y][pos[0].X] == BOX)//如果前面是箱子
	{
		//如果前面不是箱子或墙
		if (MapPointer[pos[1].Y][pos[1].X] != WALL && MapPointer[pos[1].Y][pos[1].X] != BOX)
		{
			MapPointer[pos[1].Y][pos[1].X] = MapPointer[pos[0].Y][pos[0].X];
			MapPointer[pos[0].Y][pos[0].X] = 0;
			return true;
		}
	}
	else if (MapPointer[pos[0].Y][pos[0].X] != WALL)//如果前面不是墙
		return true;

	return false;
}

bool keyEvent(int *Key)
{
	*Key = _getch();
	if (*Key < 0 || *Key == 0xE0)
		*Key = _getch();
	switch (*Key)
	{
	case KEYLEFT:
		if(mobileJudgment(Key))
			Role.X--;
		break;

	case KEYRIGHT:
		if (mobileJudgment(Key))
			Role.X++;
		break;

	case KEYUP:
		if (mobileJudgment(Key))
			Role.Y--;
		break;

	case KEYDOWN:
		if (mobileJudgment(Key))
			Role.Y++;
		break;

	case 27:return false;
	}
	
	return true;
}

void paint()
{
	if (PaintPos[2].X == Role.X && PaintPos[2].Y == Role.Y)//如果坐标没改变
		return;

	//test(0, 0, PaintPos[0].X, PaintPos[0].Y);
	//test(0, 1, PaintPos[1].X, PaintPos[1].Y);
	/*绘制*/
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), BOXCOLOR);
	for (int i = 0; i < 3; i++)
	{
		gotoxy(PaintPos[i].X, PaintPos[i].Y);
		switch (MapPointer[PaintPos[i].Y][PaintPos[i].X])
		{
		case BACKGROUND:
			putchar(' ');
			break;
		case BOX:
			putchar(254);
		}
	}

	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), HOLECOLOR);
	for (int i = 0; i < EndNumber; i++)
	{
		int x = getX(Hole[i], MapX, Distance.Y);
		int y = getY(Hole[i], MapX, Distance.X);
		gotoxy(x, y);
		if (MapPointer[y][x] != BOX)
			putchar(254);
	}

	gotoxy(Role.X, Role.Y);
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ROLECOLOR);
	putchar(254);
}

bool nextMap()
{
	int CurrentEntryNumber = 0;
	for (int i = 0; i < EndNumber; i++)
	{
		int x = getX(Hole[i], MapX, Distance.Y);
		int y = getY(Hole[i], MapX, Distance.X);
		if (MapPointer[y][x] == BOX)
			CurrentEntryNumber++;
	}
	/*如果都进洞了*/
	if (CurrentEntryNumber == EndNumber)
		return true;
	return false;
}

inline void gotoxy(const int X, const int Y)
{
	COORD pos;
	pos.X = X;
	pos.Y = Y;
	SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}

 void outputText(const int Array[], const int num, const int maxX, const int value,const COORD Distance, WORD Attribute)
{
	int x, y;
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), Attribute);
	for (int i = 0; i < num; i++)
	{
		y = getY(Array[i], maxX, Distance.X);
		x = getX(Array[i], maxX, Distance.Y);
		MapPointer[y][x] = value;
		gotoxy(x, y);
		putchar(254);
	}
}

inline void outputRole(int x, int y)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), ROLECOLOR);
	Role.X = x;
	Role.Y = y;
	gotoxy(Role.X, Role.Y);
	putchar(254);
}

void map1()
{
	//8*n
	int Wall[28] = { 
		2,3,4,
		10,12,
		18,20,21,22,23,
		24,25,26,31,
		32,37,38,39,
		40,41,42,43,45,
		51,53,
		59,60,61 };
	int box[4] = { 27,29,35,44 };
	int hole[4] = { 11, 30, 33, 52 };
	Hole = new(int, 4);
	for (int i = 0; i < 4; i++)
		Hole[i] = hole[i];

	MapX = 8;
	Distance.X = 5;
	Distance.Y = 5;

	outputText(Wall, 28, MapX,WALL, Distance, WALLCOLOR);
	outputText(Hole, 4, MapX, BACKGROUND, Distance, HOLECOLOR);
	outputText(box, 4, MapX, BOX, Distance, BOXCOLOR);
	outputRole(4 + Distance.X, 3 + Distance.Y);

	EndNumber = 4;
}

void map2()
{
	int Wall[] = { 
		0,1,2,3,4,
		9,13,
		18,22,24,25,26,
		27,31,33,35,
		36,37,38,40,41,42,44,
		46,47,53,
		55,59,62,
		64,68,69,70,71,
		73,74,75,76,77	};

	int box[3] = { 20,21,29 };
	int hole[3] = { 34,43,52 };
	Hole = new(int, 3);
	for (int i = 0; i < 3; i++)
		Hole[i] = hole[i];

	MapX = 9;
	Distance.X = 5;
	Distance.Y = 5;

	outputText(Wall, 39, MapX, WALL, Distance, WALLCOLOR);
	outputText(Hole, 3, MapX, BACKGROUND, Distance, HOLECOLOR);
	outputText(box, 3, MapX, BOX, Distance, BOXCOLOR);
	outputRole(1 + Distance.X, 1 + Distance.Y);

	EndNumber = 3;
	
}

void map3() 
{
	system("cls");
	gotoxy(50, 10);
	printf("GameOver!");
	EndNumber = 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼游戏开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值