C++入门之实现十步万度游戏

参考

《C和C++游戏趣味编程》 童晶

十步万度游戏

用鼠标点击任意一个小圆圈,其指针顺时针旋转90度,后续被指向的圆圈指针也依次旋转,所有圆圈的旋转度数累积。玩家点击10次,尝试得到尽量高的旋转度数

绘制圆圈和指针

定义一个结构体Round,用于保存圆圈的信息,成员变量有圆圈的圆心坐标、半径和角度。进一步,定义一个Round类型的二维数组,保存所有圆圈的信息

#include <graphics.h>
#include <conio.h>
#include <math.h>
#define PI 3.14159

struct Round        // 定义结构体,用来表示带角度指示的小圆圈
{
	float x, y;     // 圆心坐标
	float r;        // 圆圈半径
	int angleNum;   // 对应的角度,取0、1、2、3。表示乘以PI/2后对应的4个角度值
};

// 全局变量定义
Round rounds[5][5];

void startup()      // 初始化函数
{
	initgraph(600, 700);
	setbkcolor(RGB(50, 50, 50));
	setlinestyle(PS_SOLID, 3);    // 设置线条样式、线宽
	cleardevice();
	BeginBatchDraw();

	int i, j;
	for (i = 0; i < 5; i++)                // 初始化5*5个圆圈
	{
		for (j = 0; j < 5; j++)
		{
			rounds[i][j].x = 100 + j * 100;
			rounds[i][j].y = 200 + i * 100;
			rounds[i][j].r = 30;
			rounds[i][j].angleNum = 1;      // 开始都是PI/2
		}
	}
}

void show()          // 绘制函数
{
	int i, j;
	float angle;
	cleardevice();
	for (i = 0; i < 5; i++)
	{
		for (j = 0; j < 5; j++)
		{
			setlinecolor(RGB(200, 200, 200));// 圆圈的颜色为白灰色
			circle(rounds[i][j].x, rounds[i][j].y, rounds[i][j].r);
			setlinecolor(RGB(255, 0, 0));    // 角度指示线颜色为红色
			angle = rounds[i][j].angleNum * PI / 2;
			line(rounds[i][j].x, rounds[i][j].y, rounds[i][j].x + rounds[i][j].r * cos(-angle), rounds[i][j].y + rounds[i][j].r * sin(-angle));
		}
	}
	FlushBatchDraw();
}

void update()         // 更新函数
{

}

int main()
{
	startup();
	while (1)
	{
		show();
		update();
	}
	return 0;
}

鼠标互动

和键盘交互代码结构类似,实现基于鼠标的交互处理:

void update()
{
	ExMessage e;            // 定义鼠标消息
	if (peekmessage(&e))             // 如果有鼠标消息
	{
		if (e.message == WM_LBUTTONDOWN) // 如果点击鼠标左键
		{
			// 执行相应操作
			// m.x为当前鼠标的x坐标,m.y为当前鼠标的y坐标
		}
	}
}

被鼠标点击后旋转

鼠标点击位置的坐标为(m.x, m.y),被点击的小圆圈在二维数组rounds中的行、列序号为:

int clicked_i = int(m.y - 150) / 100;
int clicked_j = int(m.x - 50) / 100;

被点击的小圆圈需要顺时针旋转90度,需要将angleNum值依次减小:

rounds[clicked_i][clicked_j].angleNum -= 1;
if (rounds[clicked_i][clicked_j].angleNum < 0)
{
	rounds[clicked_i][clicked_j].angleNum = 3;
}

将小圆圈顺时针旋转的功能封装在rotateRound()中:

void rotateRound(int i, int j)
{
	rounds[i][j].angleNum -= 1;
	if (rounds[i][j].angleNum < 0)
	{
		rounds[i][j].angleNum = 3;
	}
}
void update()         // 更新函数
{
	ExMessage e;
	if (peekmessage(&e))
	{
		if (e.message == WM_LBUTTONDOWN)              // 如果点击鼠标左键
		{
			int clicked_i = int(e.y - 150) / 100;  // 获取当前点击圆圈的序号
			int clicked_j = int(e.x - 50) / 100;
			rotateRound(clicked_i, clicked_j);
			show();
		}
	}
}

旋转的传播

当鼠标点击一个小圆圈时,小圆圈顺时针旋转90度,然后其指向的下一个圆圈继续旋转90度,如此迭代,直到不指向任何小圆圈为止

首先,定义一维数组indexes,存储被鼠标点中的小圆圈在二维数组rounds中的行列序号:

int index[2] = {clicked_i, clicked_j};

定义函数int GetNextIndexes(int indexes[2]),根据当前小圆圈的序号indexes[0]、indexes[1]和当前小圆圈的角度angleNum,首先求出其指向小圆圈的序号。如果指向的小圆圈超出边界,函数返回0;如果指向一个有效的小圆圈,就把其序号更新到数组indexes中,函数返回1

int GetNextIndexes(int indexes[2])
{
	int i = indexes[0];
	int j = indexes[1];

	// 根据当前圆圈的角度,获得下一个小圆圈的序号
	if (rounds[i][j].angleNum == 0)                // 指向右边的
	{
		j++;
	}
	else if (rounds[i][j].angleNum == 3)           // 指向下边
	{
		i++;
	}
	else if (rounds[i][j].angleNum == 2)           // 指向左边
	{
		j--;
	}
	else if (rounds[i][j].angleNum == 1)           // 指向上边
	{
		i--;
	}

	indexes[0] = i;
	indexes[1] = j;

	if (i >= 0 && i < 5 && j >= 0 && j < 5)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

得分显示

定义全局变量step和score记录剩下的操作步数和一共旋转的度数:

int step;
int score;

在show()函数中输出相关的文字信息:

void show()          // 绘制函数
{
	TCHAR s[20];                             // 要输出的字符串
	setbkmode(TRANSPARENT);                  // 透明显示文字
	swprintf_s(s, _T("%d 步   %d 度"), step, score); // 把整数转换为字符串
	settextstyle(50, 0, _T("宋体"));
	outtextxy(150, 30, s);                          // 在xy位置输出字符串文字
	settextstyle(20, 0, _T("宋体"));
	outtextxy(15, 100, _T("点击一个圆圈 其指针顺时针旋转90度之后 指向的指针依次旋转"));
	FlushBatchDraw();
	FlushBatchDraw();
}

每旋转一次,得分增加90度:

void rotateRound(int i, int j)
{
	score += 90;
}

鼠标每操作一次,step减1:

if (e.message == WM_LBUTTONDOWN && step > 0)
{
	step--;
}

完整代码

#include <graphics.h>
#include <conio.h>
#include <math.h>
#define PI 3.14159

struct Round        // 定义结构体,用来表示带角度指示的小圆圈
{
	float x, y;     // 圆心坐标
	float r;        // 圆圈半径
	int angleNum;   // 对应的角度,取0、1、2、3。表示乘以PI/2后对应的4个角度值
};

// 全局变量定义
Round rounds[5][5];
int step;
int score;

void startup()      // 初始化函数
{
	initgraph(600, 700);
	setbkcolor(RGB(50, 50, 50));
	setlinestyle(PS_SOLID, 3);    // 设置线条样式、线宽
	cleardevice();
	BeginBatchDraw();
	step = 10;
	score = 0;
	int i, j;
	for (i = 0; i < 5; i++)                // 初始化5*5个圆圈
	{
		for (j = 0; j < 5; j++)
		{
			rounds[i][j].x = 100 + j * 100;
			rounds[i][j].y = 200 + i * 100;
			rounds[i][j].r = 30;
			rounds[i][j].angleNum = 1;      // 开始都是PI/2
		}
	}
}

void show()          // 绘制函数
{
	int i, j;
	float angle;
	cleardevice();
	for (i = 0; i < 5; i++)
	{
		for (j = 0; j < 5; j++)
		{
			setlinecolor(RGB(200, 200, 200));// 圆圈的颜色为白灰色
			circle(rounds[i][j].x, rounds[i][j].y, rounds[i][j].r);
			setlinecolor(RGB(255, 0, 0));    // 角度指示线颜色为红色
			angle = rounds[i][j].angleNum * PI / 2;
			line(rounds[i][j].x, rounds[i][j].y, rounds[i][j].x + rounds[i][j].r * cos(-angle), rounds[i][j].y + rounds[i][j].r * sin(-angle));
		}
	}
	TCHAR s[20];                             // 要输出的字符串
	setbkmode(TRANSPARENT);                  // 透明显示文字
	swprintf_s(s, _T("%d 步   %d 度"), step, score); // 把整数转换为字符串
	settextstyle(50, 0, _T("宋体"));
	outtextxy(150, 30, s);                          // 在xy位置输出字符串文字
	settextstyle(20, 0, _T("宋体"));
	outtextxy(15, 100, _T("点击一个圆圈 其指针顺时针旋转90度之后 指向的指针依次旋转"));
	FlushBatchDraw();
}

void rotateRound(int i, int j)
{
	rounds[i][j].angleNum -= 1;
	if (rounds[i][j].angleNum < 0)
	{
		rounds[i][j].angleNum = 3;
	}
	score += 90;
}

int GetNextIndexes(int indexes[2])
{
	int i = indexes[0];
	int j = indexes[1];

	// 根据当前圆圈的角度,获得下一个小圆圈的序号
	if (rounds[i][j].angleNum == 0)                // 指向右边的
	{
		j++;
	}
	else if (rounds[i][j].angleNum == 3)           // 指向下边
	{
		i++;
	}
	else if (rounds[i][j].angleNum == 2)           // 指向左边
	{
		j--;
	}
	else if (rounds[i][j].angleNum == 1)           // 指向上边
	{
		i--;
	}

	indexes[0] = i;
	indexes[1] = j;

	if (i >= 0 && i < 5 && j >= 0 && j < 5)
	{
		return 1;
	}
	else
	{
		return 0;
	}
}

void update()         // 更新函数
{
	ExMessage e;
	if (peekmessage(&e))
	{
		if (e.message == WM_LBUTTONDOWN && step > 0)              // 如果点击鼠标左键
		{
			int clicked_i = int(e.y - 150) / 100;              // 获取当前点击圆圈的序号
			int clicked_j = int(e.x - 50) / 100;
			rotateRound(clicked_i, clicked_j);
			show();
			Sleep(300);

			int indexes[2] = { clicked_i, clicked_j };         // 存储当前点击圆圈的序号
			while (GetNextIndexes(indexes))                    // 依次获取指向的下一个圆圈
			{
				rotateRound(indexes[0], indexes[1]);
				show();
				Sleep(300);
			}
		}
	}
}

int main()
{
	startup();
	while (1)
	{
		show();
		update();
	}
	return 0;
}

到此这篇关于C++入门实现十步万度游戏的文章就介绍到这了,更多相关C++十步万度游戏内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++实现俄罗斯方块小游戏

    本文实例为大家分享了C++实现俄罗斯方块小游戏的具体代码,供大家参考,具体内容如下 操作说明: D F:左右旋转 J  L:左右移动 E(一堆键都行): 加快下落速度 空格: 开始游戏 与 一落到底 上代码! #include <cstdio> #include <cstdlib> #include <cstring> #include <windows.h> #include <ctime> #include <conio.h> #

  • C++实现简易的弹球小游戏

    本文实例为大家分享了C++实现弹球小游戏的具体代码,供大家参考,具体内容如下 操作说明:键盘A和D键控制左右移动,让球不要落下. #include <graphics.h> #include <conio.h> #include <time.h> int i; int xx=0; int yy = 0; class Ball { public: int x, y; clock_t b; void draw() { setfillcolor(RGB(200, 399, 1

  • C++语言实现拼图游戏详解

    目录 开发环境:Visual Studio 2019,easyx图形库. 游戏功能列表: 游戏效果 一.头文件和基本量 二.封面 三.数据初始化 四.封面规则按钮 五.构造拼图 六.绘图函数 七.背景音乐 八.数据更新 九.通关判断 十.完整程序 总结 开发环境:Visual Studio 2019,easyx图形库. easyx下载官网: EasyX Graphics Library for C++ https://easyx.cn/ easyx使用文档: EasyX 文档 - 函数说明 ht

  • 利用C/C++实现贪吃蛇游戏

    利用C/C++实现贪吃蛇 (注意:本文章仅供参考,第一次写博客还请多多指教.理解本文章需要easyx和c++等基础知识,并且需要了解贪吃蛇游戏机制) 贪吃蛇机制介绍 相信绝大多数人都曾玩过或者了解过贪吃蛇这款经典的游戏.贪吃蛇顾名思义,就是让蛇尽可能的吃食物.玩家可通过方向键或自定义键来控制蛇头的方向,使它吃到地图出现的随机食物.蛇每吃到一个食物,自身便会增长.当蛇碰到地图的边界或是蛇碰到自身,蛇便会死亡,游戏便结束. 机制大概了解过后,我们将考虑如何实现这类游戏. 设计与分析 首先,我们分析游

  • C++ 实战开发一个猜单词的小游戏

    目录 前言 效果展示 一.函数接口 二.重要函数接口详解 1.菜单内容 2.退出程序 3.打开单词文件 4.开始游戏 5.查看玩家排名 6.清空玩家排名 7.玩家排名 全部代码展示 前言 程序内的单词全部保存于word.txt的文本文档中,玩家排名保存在rand.txt文本文档中.运行程序时,会自动读取文本中的内容. 游戏规则:①先请用户输入猜的单词数量,可以有一个默认值.②随机抽取单词,对每个单词,系统根据谜底单词长度在屏幕上显示相应个数'#',假设谜底单词为"hello",则在屏幕

  • C++入门指南之贪吃蛇游戏的实现

    目录 参考 贪吃蛇游戏 程序框架 绘制游戏地图和蛇 小蛇向右移动 控制小蛇4个方向移动 时间控制的改进 失败判断与显示 添加食物 完整代码 总结 参考 <C和C++游戏趣味编程> 贪吃蛇游戏 键盘控制小蛇上.下.左.右移动,迟到食物后长度加1:蛇头碰到自身或窗口边缘,游戏失败 程序框架 #include <graphics.h> #include <conio.h> #include <stdio.h> // 全局变量定义 void startup() //

  • 用C++实现推箱子小游戏

    前言 推箱子小游戏相信是很多人的同年记忆了,今天用c++语言来尝试下,用的是vs编译器. 代码还有很多可以优化的地方,为了更直观了解函数的形参和实参,所以地图没有用全局变量声明了,其实用全局变量声明会简洁很多. 头文件和main函数分享在最下面了. 提示:以下是本篇文章正文内容,下面案例可供参考 一.初始化游戏数据 void GameInit(int(*&pMap)[10][10], int index)//两张地图数据 { // static:返回静态全局区变量 static int loca

  • C++实现简易贪吃蛇游戏

    C++实现建议贪吃蛇(不会闪屏幕) 使用vs2013完成.记录踏上游戏开发的道路. 效果图 代码 // 2021.7.24.1贪吃蛇.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include <list> #include <numeric> #include <algorithm> #include <Windows.h> #includ

  • 使用c++编程实现简单的打字小游戏

    目录 你是否对键盘熟悉? "qwertyuiopasdfghjklzxcvbnm"是否已经印在你的脑海里? NO? 没有关系,今天,让我来帮你对键盘有一个更深一步的了解吧! #include"stdio.h" #include"stdlib.h" #include"windows.h" #include"conio.h" void entry_place(int num) { for(int i;i<

  • C++入门之实现十步万度游戏

    参考 <C和C++游戏趣味编程> 童晶 十步万度游戏 用鼠标点击任意一个小圆圈,其指针顺时针旋转90度,后续被指向的圆圈指针也依次旋转,所有圆圈的旋转度数累积.玩家点击10次,尝试得到尽量高的旋转度数 绘制圆圈和指针 定义一个结构体Round,用于保存圆圈的信息,成员变量有圆圈的圆心坐标.半径和角度.进一步,定义一个Round类型的二维数组,保存所有圆圈的信息 #include <graphics.h> #include <conio.h> #include <m

  • Python装饰器入门学习教程(九步学习)

    装饰器(decorator)是一种高级Python语法.装饰器可以对一个函数.方法或者类进行加工.在Python中,我们有多种方法对函数和类进行加工,比如在Python闭包中,我们见到函数对象作为某一个函数的返回结果.相对于其它方式,装饰器语法简单,代码可读性高.因此,装饰器在Python项目中有广泛的应用. 这是在Python学习小组上介绍的内容,现学现卖.多练习是好的学习方式. 第一步:最简单的函数,准备附加额外功能 # -*- coding:gbk -*- '''示例1: 最简单的函数,表

  • 十步搞定uni-app使用字体图标的方法

    uni-app简介 uni-app是一个使用Vue.js开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS.Android.H5.小程序等多个平台.   uni-app框架由Dcloud即数字天堂(北京)网络技术有限公司推出,该公司主要产品有Web开发IDE Hbuiler.HbuilderX,前端框架mui.uni-app,增强版的手机浏览器引擎H5plus等. uni-app中使用字体图标图标的下载 首先去阿里图标库选择要用的图标,并且打包下载下来,步骤如下 1. 2. 3. 4.

  • 入门java的第一步HelloWorld

    踏过JDK开发环境安装这所大门,我们正式走进了Java的世界.Java是一门面向对象的编程语言,不仅吸收了c++语言的各种有点,还摒弃了c++里难以理解的多继承,指针等概念,因此它具有功能强大和简单易用两个特征,它的语法比c/c++都更加简单,它最大的优点就是可移植性很高,一次编写,到处执行,今天我们就来练习一下Java入行的第一段代码. public class HelloWorld { //HelloWorld叫做类名 public static void main(String[]args

  • Python入门教程(二十九)Python的RegEx正则表达式

    RegEx 或正则表达式是形成搜索模式的字符序列. RegEx 可用于检查字符串是否包含指定的搜索模式. RegEx 模块 Python 提供名为 re 的内置包,可用于处理正则表达式. 导入 re 模块: import re Python 中的 RegEx 导入 re 模块后,就可以开始使用正则表达式了: 实例 检索字符串以查看它是否以 “China” 开头并以 “country” 结尾: import re txt = "China is a great country" x =

  • Python入门教程(二十八)Python中的JSON

    JSON 是用于存储和交换数据的语法. JSON 是用 JavaScript 对象表示法(JavaScript object notation)编写的文本. Python 中的 JSON Python 有一个名为 json 的内置包,可用于处理 JSON 数据. 实例 导入 json 模块: import json 解析 JSON - 把 JSON 转换为 Python 若有 JSON 字符串,则可以使用 json.loads() 方法对其进行解析. 结果将是 Python 字典 实例 把 JS

  • Python入门教程(二十五)Python的作用域

    目录 局部作用域 函数内部的函数 全局作用域 命名变量 Global 关键字 变量仅在创建区域内可用.这称为作用域. 局部作用域 在函数内部创建的变量属于该函数的局部作用域,并且只能在该函数内部使用. 实例 在函数内部创建的变量在该函数内部可用: def myfunc(): x = 100 print(x) myfunc() 运行实例 100 函数内部的函数 如上例中所示,变量 x 在函数外部不可用,但对于函数内部的任何函数均可用: 实例 能够从函数内的一个函数访问局部变量: def myfun

  • Python入门教程(二十二)Python的类和对象

    目录 Python 类/对象 创建类 创建对象 init() 函数 对象方法 self 参数 修改对象属性 删除对象属性 删除对象 pass 语句 Python 类/对象 Python 是一种面向对象的编程语言. Python 中的几乎所有东西都是对象,拥有属性和方法. 类(Class)类似对象构造函数,或者是用于创建对象的“蓝图”. 创建类 如需创建类,请使用 class 关键字: 实例 使用名为 x 的属性,创建一个名为 MyClass 的类: class MyClass: x = 5 运行

  • Python入门教程(二十)Python的Lambda表达式

    目录 语法 lambda 函数可接受任意数量的参数: 为何使用 Lambda 函数? lambda 函数是一种小的匿名函数. lambda 函数可接受任意数量的参数,但只能有一个表达式. 语法 lambda arguments : expression 执行表达式并返回结果: 实例 一个 lambda 函数,它把作为参数传入的数字加 10,然后打印结果: x = lambda a : a + 10 print(x(5)) 运行实例 17 lambda 函数可接受任意数量的参数: 实例 一个 la

  • ASP编程入门进阶(十四):Browser & Linking

    一.Browser Capabilities组件 该组件最主要的作用是:提取识别客户端浏览器的版本信息. 其原理是这样的:当客户端浏览器向服务器发送页面请求时,同时会自动发送一个User Agent HTTP标题,而该标题是一个声明浏览器及其版本的 ASCII 字符串.而Browser Capabilities组件就将User Agent映射到在文件Browscap.ini中所注明的浏览器 , 并通过BrowserType对象的属性来识别客户浏览器. 若该对象在 browscap.ini 文件中

随机推荐