第13章 祖玛(《C和C++游戏趣味编程》配套教学视频)

本章介绍如何使用C++开发祖玛游戏,涉及链表、STL、面向对象编程等技术,讲解了炮台旋转、小球消除等关键功能。读者可以学习并尝试增加道具、实现小球回吸等高级功能。
摘要由CSDN通过智能技术生成

(图书介绍:童晶:《C和C++游戏趣味编程》新书预告

本章我们将编写祖玛游戏,各种颜色的小球沿着轨道移动,玩家必须阻止小球进入轨道终点的城堡。鼠标可以移动控制炮台旋转、鼠标右键更换小球颜色、按下鼠标左键发射小球。发射的小球进入轨道,如果周围有连续三个相同颜色的小球即可消除,效果如图所示。

为了实现动态数据结构,首先学习了链表和C++标准模板库。然后利用面向对象知识和STL的vector,依次实现了顶点类、轨迹类和小球类;接着实现了炮台类,完成炮台旋转、发射小球和胜负判断的功能。

13 祖玛

讲解视频:

最终代码:

#include <graphics.h>  
#include <conio.h>
#include <time.h>
#include <vector>
#include <algorithm>
#pragma comment(lib,"Winmm.lib")
using namespace std;
#define  WIDTH 1000 // 窗口宽度
#define  HEIGHT 700 // 窗口高度
#define  Radius 25 //  小球半径
#define  ColorNum 5 //  小球颜色种类数目
COLORREF  colors[ColorNum] = {RED,BLUE,GREEN,YELLOW,MAGENTA}; // 定义数组保存所有的颜色

// 求两点之间的距离函数
float Distance(float x1,float y1,float x2,float y2)
{
	float xd = x1 - x2;
	float yd = y1 - y2;
	float length = sqrt(xd*xd+yd*yd); 
	return length;
}

void sleep(DWORD ms)  // 精确延时函数
{
	static DWORD oldtime = GetTickCount();
	while(GetTickCount() - oldtime < ms)
		Sleep(1);
	oldtime = GetTickCount();
}

void PlayMusicOnce(TCHAR fileName[80]) // 播放一次音乐函数
{
	TCHAR cmdString1[50];
	_stprintf(cmdString1, _T("open %s alias tmpmusic"), fileName); // 生成命令字符串
	mciSendString(_T("close tmpmusic"), NULL, 0, NULL); // 先把前面一次的音乐关闭
	mciSendString(cmdString1, NULL, 0, NULL); // 打开音乐
	mciSendString(_T("play tmpmusic"), NULL, 0, NULL); // 仅播放一次
}

class Point // 定义顶点类
{
public:
	float x,y; // 记录(x,y)坐标
	Point() // 无参数的构造函数
	{
	}
	Point (float ix,float iy) // 有参数的构造函数
	{
		x = ix;
		y = iy;
	}
};

class Path  // 定义轨迹类
{
public:
	vector<Point> keyPoints; //  记录轨迹上的一些关键点,关键点之间以直线相连
	float sampleInterval; // 对特征点连成的轨迹线,进行均匀采样的间隔
	vector<Point> allPoints; //  所有以采样间隔得到的采样点

	void getAllPoints() // 以采样间隔进行采样,得到所有的采样点
	{
		int i;
		// 对关键点依次连接形成的多条线段进行遍历
		for (i=0;i<keyPoints.size()-1;i++)
		{
			float xd = keyPoints[i+1].x - keyPoints[i].x;
			float yd = keyPoints[i+1].y - keyPoints[i].y;
			float length = sqrt(xd*xd+yd*yd); // 这一段直线段的长度

			int num = length/sampleInterval; // 这一段直线段要被采样的个数
			for (int j=0;j<num;j++)
			{
				float x_sample = keyPoints[i].x + j*xd/num;
				float y_sample = keyPoints[i].y + j*yd/num;
				allPoints.push_back(Point(x_sample,y_sample)); // 添加进去所有的采样点
			}
		}
		// 还有最后一个关键点
		allPoints.push_back(Point(keyPoints[i].x,keyPoints[i].y)
  • 6
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
下面是一个简单的 C 语言链表祖玛游戏的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <time.h> #define ROW 5 #define COL 6 #define COLOR_NUM 3 typedef struct ball { int color; struct ball *next; } Ball; void init_board(int board[ROW][COL]) { int i, j; srand(time(NULL)); for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { board[i][j] = rand() % COLOR_NUM; } } } void print_board(int board[ROW][COL]) { int i, j; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { printf("%d ", board[i][j]); } printf("\n"); } } Ball *create_ball(int color) { Ball *ball = (Ball *)malloc(sizeof(Ball)); ball->color = color; ball->next = NULL; return ball; } void add_ball(Ball **head, int color) { Ball *ball = create_ball(color); if (*head == NULL) { *head = ball; } else { Ball *p = *head; while (p->next != NULL) { p = p->next; } p->next = ball; } } void init_balls(Ball **head, int board[ROW][COL], int row, int col) { int i, j; for (i = 0; i < ROW; i++) { for (j = 0; j < COL; j++) { if (i == row && j == col) { continue; } add_ball(head, board[i][j]); } } } void print_balls(Ball *head) { while (head != NULL) { printf("%d ", head->color); head = head->next; } printf("\n"); } Ball *remove_balls(int board[ROW][COL], int row, int col) { Ball *head = NULL; int color = board[row][col]; int i, j; // check left for (i = col - 1; i >= 0; i--) { if (board[row][i] != color) { break; } } if (col - i >= 3) { for (j = i + 1; j <= col; j++) { init_balls(&head, board, row, j); board[row][j] = -1; } } // check right for (i = col + 1; i < COL; i++) { if (board[row][i] != color) { break; } } if (i - col >= 3) { for (j = col; j < i; j++) { init_balls(&head, board, row, j); board[row][j] = -1; } } // check up for (i = row - 1; i >= 0; i--) { if (board[i][col] != color) { break; } } if (row - i >= 3) { for (j = i + 1; j <= row; j++) { init_balls(&head, board, j, col); board[j][col] = -1; } } // check down for (i = row + 1; i < ROW; i++) { if (board[i][col] != color) { break; } } if (i - row >= 3) { for (j = row; j < i; j++) { init_balls(&head, board, j, col); board[j][col] = -1; } } return head; } void drop_balls(int board[ROW][COL]) { int i, j, k; for (j = 0; j < COL; j++) { for (i = ROW - 1; i >= 0; i--) { if (board[i][j] == -1) { for (k = i - 1; k >= 0; k--) { if (board[k][j] != -1) { board[i][j] = board[k][j]; board[k][j] = -1; break; } } if (k == -1) { board[i][j] = rand() % COLOR_NUM; } } } } } int main() { int board[ROW][COL]; Ball *balls = NULL; int row, col; init_board(board); print_board(board); while (1) { printf("Input row and col: "); scanf("%d %d", &row, &col); if (row < 0 || row >= ROW || col < 0 || col >= COL) { printf("Invalid input!\n"); continue; } if (board[row][col] == -1) { printf("This ball has been removed!\n"); continue; } balls = remove_balls(board, row, col); if (balls == NULL) { printf("No balls can be removed!\n"); continue; } printf("Removed balls: "); print_balls(balls); free(balls); drop_balls(board); print_board(board); } return 0; } ``` 该代码使用了链表来存储被移除的小球,移除过程使用了递归函数,下落过程使用了嵌套循环。运行该代码可以与用户交互进行祖玛游戏
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值