Easyx | 游戏实例:打字游戏

目录

目录

游戏简介

准备素材

开始编写

1 预编译

2 字母结构体

3 初始化字母

4 字母下落

不断下落

掉到底下

MoveLetter() 函数

5 绘制屏幕

字母

分数

Draw() 函数

6 判断按键

7 音乐、背景

音乐

背景

Main函数

效果截图

完整代码


游戏简介

屏幕中不断下落字母判断按下这个字母的按键,得分;字母掉下去扣分

上面这句话中,我们要给蓝色背景的字定义一个结构体,然后一步步实现红色字的内容。

代码思路

1. 字母结构体

2. 初始化字母

3. 字母下落(到底失分)

4. 绘制屏幕

5. 判断按键(得分)

6. 音乐、背景(可加可不加)

准备素材

背景图:

(偷偷说一件事:我的这些背景图,都是在 Scratch 上截的) 

音效也是在 Scratch 上导出的……

开始编写

1 预编译

#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include <time.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib") // 音乐
#define WIDTH 640
#define HEIGHT 480
#define MAX_LETTER 10
#define SPEED 2

2 字母结构体

x x坐标

y y坐标

speed 下落速度

ch 字母

struct Letter
{
	int x;
	int y;
	char ch;
};

3 初始化字母

定义宏 MAX_LETTER 表示字母的数量。

定义 letter[MAX_LETTER] 表示所有字母的一维数组。

Letter letter[MAX_LETTER];

x坐标:25 ~ 615 的随机数

y坐标:-480 ~ 0 的随机数

字母:利用 ASCII码 取 A ~ Z 的随机数

// 初始化字母
void SetLetter()
{
	for (int i = 0; i < MAX_LETTER; i++)
	{
		letter[i].x = rand() % (WIDTH - 50) + 25;
		letter[i].y = rand() % HEIGHT - HEIGHT;
		letter[i].ch = rand() % 26 + 'A';
	}
}

4 字母下落

不断下落

只要增加每个字母的y坐标就行了。

for (int i = 0; i < MAX_LETTER; i++)
{
	letter[i].y += SPEED;
}

掉到底下

判断字母的y坐标,如果大于屏幕高度,扣分,并且重新初始化这个字母。

if (letter[i].y >= HEIGHT)
{
	score--;
	letter[i].x = rand() % (WIDTH - 50) + 25;
	letter[i].y = rand() % HEIGHT - HEIGHT;
	letter[i].ch = rand() % 26 + 'A';
}

MoveLetter() 函数

// 移动字母
void MoveLetter()
{
    for (int i = 0; i < MAX_LETTER; i++)
    {
        letter[i].y += SPEED;
        if (letter[i].y >= HEIGHT)
        {
            score--;
            letter[i].x = rand() % (WIDTH - 50) + 25;
            letter[i].y = rand() % HEIGHT - HEIGHT;
            letter[i].ch = rand() % 26 + 'A';
        }
    }
}

5 绘制屏幕

字母

setbkmode 函数设置字母背景的样子,这里用 TRANSPARENT 设为透明。

for (int i = 0; i < MAX_LETTER; i++)
{
	settextstyle(50, 20, "HandelGothic BT");
	setbkmode(TRANSPARENT);
	outtextxy(letter[i].x, letter[i].y, letter[i].ch);
}

分数

sprintf_s 函数:格式化输出到一个字符数组里。

char text[20];
sprintf_s(text, "Score: %d", score);
settextstyle(50, 20, "Arial");
outtextxy(20, 20, text);

Draw() 函数

// 绘制屏幕
void Draw()
{
	putimage(0, 0, &bk_img);

	for (int i = 0; i < MAX_LETTER; i++)
	{
		settextstyle(50, 20, "HandelGothic BT");
		setbkmode(TRANSPARENT);
		outtextxy(letter[i].x, letter[i].y, letter[i].ch);
	}

	char text[20];
	sprintf_s(text, "Score: %d", score);
	settextstyle(50, 20, "Arial");
	outtextxy(20, 20, text);
}

6 判断按键

// 用户输入
void GetKey()
{
	if (_kbhit())
	{
		char input = _getch();
		input = input - 'a' + 'A';
		for (int i = 0; i < MAX_LETTER; i++)
		{
			if (input == letter[i].ch)
			{
				score++;
				letter[i].x = rand() % (WIDTH - 50) + 25;
				letter[i].y = rand() % HEIGHT - HEIGHT;
				letter[i].ch = rand() % 26 + 'A';
			}
		}
	}
}

7 音乐、背景

音乐

Playsound 函数:

BOOL PlaySound(LPCSTR pszSound, HMODULE hmod,DWORD fdwSound);

pszSound : 音乐文件路径,只能是 .wav 类型

hmod : 一般直接写 NULL ,不用管

fdwSound : 声音播放模式 ,常用:

        SND_ASYNC 异步播放

        SND_LOOP 循环播放

        SND_NOSTOP 不打断原来的声音

在开始时 :PlaySound(".\\Bgm.wav", NULL, SND_ASYNC | SND_LOOP);

得分时:PlaySound(".\\Get.wav", NULL, SND_ASYNC | SND_NOSTOP);

按下空格 关闭 / 打开 音乐

if (input == ' ')
{
	if (isMusic)
	{
		PlaySound(NULL, NULL, NULL);
    	isMusic = false;
	}
	else
	{
		PlaySound(".\\Bgm.wav", NULL, SND_ASYNC | SND_LOOP);
		isMusic = true;
	}
}

背景

主函数:loadimage(&bk_img, ".\\Background.png", WIDTH, HEIGHT, true);

Draw函数:putimage(0, 0, &bk_img);

Main函数

int main()
{
	initgraph(WIDTH, HEIGHT);
	srand(time(NULL));
	loadimage(&bk_img, ".\\Background.png", WIDTH, HEIGHT, true);
	PlaySound(".\\Bgm.wav", NULL, SND_ASYNC | SND_LOOP);
	SetLetter();
	BeginBatchDraw();
	while (true)
	{
		Draw();
		MoveLetter();
		GetKey();
		FlushBatchDraw();
		Sleep(10);
	}
	EndBatchDraw();
	closegraph();
	return 0;
}

效果截图

完整代码

/*
* 项目名称:打字游戏
* 开发环境:vs2022 + easyx
* 作者:轩
* 代码长度:131 行
* 完成时间:2023.1.1
* 用时:1 小时
*/

#include <stdio.h>
#include <graphics.h>
#include <conio.h>
#include <time.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")
#define WIDTH 640
#define HEIGHT 480
#define MAX_LETTER 10
#define SPEED 2

struct Letter
{
	int x;
	int y;
	char ch;
};

IMAGE bk_img;
Letter letter[MAX_LETTER];
int score = 0; // 感谢 @ m0_74294396 提出的问题
bool isMusic = true;

// 初始化字母
void SetLetter()
{
	for (int i = 0; i < MAX_LETTER; i++)
	{
		letter[i].x = rand() % (WIDTH - 50) + 25;
		letter[i].y = rand() % HEIGHT - HEIGHT;
		letter[i].ch = rand() % 26 + 'A';
	}
}

// 绘制屏幕
void Draw()
{
	putimage(0, 0, &bk_img);

	for (int i = 0; i < MAX_LETTER; i++)
	{
		settextstyle(50, 20, "HandelGothic BT");
		setbkmode(TRANSPARENT);
		outtextxy(letter[i].x, letter[i].y, letter[i].ch);
	}

	char text[20];
	sprintf_s(text, "Score: %d", score);
	settextstyle(50, 20, "Arial");
	outtextxy(20, 20, text);
}

// 移动字母
void MoveLetter()
{
	for (int i = 0; i < MAX_LETTER; i++)
	{
		letter[i].y += SPEED;
		if (letter[i].y >= HEIGHT)
		{
			score--;
			letter[i].x = rand() % (WIDTH - 50) + 25;
			letter[i].y = rand() % HEIGHT - HEIGHT;
			letter[i].ch = rand() % 26 + 'A';
		}
	}
}

// 用户输入
void GetKey()
{
	if (_kbhit())
	{
		char input = _getch();
		if (input == ' ')
		{
			if (isMusic)
			{
				PlaySound(NULL, NULL, NULL);
				isMusic = false;
			}
			else
			{
				PlaySound(".\\Bgm.wav", NULL, SND_ASYNC | SND_LOOP);
				isMusic = true;
			}
		}
		input = input - 'a' + 'A';
		for (int i = 0; i < MAX_LETTER; i++)
		{
			if (input == letter[i].ch)
			{
				score++;
				PlaySound(".\\Get.wav", NULL, SND_ASYNC | SND_NOSTOP);
				letter[i].x = rand() % (WIDTH - 50) + 25;
				letter[i].y = rand() % HEIGHT - HEIGHT;
				letter[i].ch = rand() % 26 + 'A';
			}
		}
	}
}

int main()
{
	initgraph(WIDTH, HEIGHT);
	srand(time(NULL));
	loadimage(&bk_img, ".\\Background.png", WIDTH, HEIGHT, true);
	PlaySound(".\\Bgm.wav", NULL, SND_ASYNC | SND_LOOP);
	SetLetter();
	BeginBatchDraw();
	while (true)
	{
		Draw();
		MoveLetter();
		GetKey();
		FlushBatchDraw();
		Sleep(10);
	}
	EndBatchDraw();
	closegraph();
	return 0;
}

感谢 @ m0_74294396 提出的问题,已修改!

  • 6
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 9
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值