VC绘图/游戏简易教程--12:数组
2010-5-28 ~ 2021-5-28
(8)
教程总目录:https://codebus.cn/bestans/post/concise-lesson-contents(里面包括VC下的graphics.h的配置方法)
课程要求:先复习下课本上对数组的讲解(随便一本教材都行)
一维数组
数组可以实现批量操作。比如,我们产生 10 个随机数,产生后先保存起来,然后输出最大的:
int n[10];
int i;
for (i = 0; i < 10; i++)
n[i] = rand() % 1000;
// 按生成的顺序,逆序输出
for (i = 9; i >= 0; i--)
printf("%d\n", n[i]);
// 找出最大的
int max = -1;
for (i = 0; i < 10; i++)
{
if (n[i] > max)
max = n[i];
}
printf("最大的数字是:%d\n", max);
看明白这个程序后,我们继续。
下面,我们绘制一个从屏幕上边任意位置往下落的白色点:
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
int main()
{
srand( (unsigned)time(NULL) );
initgraph(640, 480);
int x = rand() % 640; // 点的 x 坐标
int y = 0; // 点的 y 坐标
while(!_kbhit())
{
// 擦掉前一个点
putpixel(x, y, BLACK);
// 计算新坐标
y+=3;
if (y >= 480) break;
// 绘制新点
putpixel(x, y, WHITE);
Sleep(10);
}
closegraph();
return 0;
}
现在利用数组,来产生 100 个随机下落的点。并且每个点落到底部后,就回到顶部重新往下落:
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <time.h>
int main()
{
srand( (unsigned)time(NULL) );
initgraph(640, 480);
// 定义点的坐标数组
int x[100]; // 点的 x 坐标
int y[100]; // 点的 y 坐标
int i;
// 初始化点的初始坐标
for (i = 0; i < 100; i++)
{
x[i] = rand() % 640;
y[i] = rand() % 480;
}
while(!_kbhit())
{
for(i = 0; i < 100; i++)
{
// 擦掉前一个点
putpixel(x[i], y[i], BLACK);
// 计算新坐标
y[i] += 3;
if (y[i] >= 480) y[i] = 0;
// 绘制新点
putpixel(x[i], y[i], WHITE);
}
Sleep(10);
}
closegraph();
return 0;
}
二维数组
理解了一维数组,再看二维数组甚至多维数组,就简单多了,看下面程序理解一下二维数组:
程序要求:屏幕上有 16x8 的方格,按随机顺序在将 1~128 的数字写到每个格子上。
考虑:我们需要记录这些格子,哪些写过数字,哪些没写数字。
我们用一个二维数组来记录:
bool cell[16][8];
写过数字后,我们将相应数组的值设置为 true,看程序:
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <stdio.h>
#include <time.h>
int main()
{
int x, y;
wchar_t num[4];
srand( (unsigned)time(NULL) );
initgraph(640, 480);
// 画格子
for (x = 0; x < 480; x += 30)
for (y = 0; y < 240; y += 30)
rectangle(x, y, x + 28, y + 28);
// 定义二维数组
bool cell[16][8];
// 初始化二维数组
for (x = 0; x < 16; x++)
for (y = 0; y < 8; y++)
cell[x][y] = false;
// 在每个格子上写数字
for (int i = 1; i <= 128; i++)
{
// 找到一个没有写数字的随机格子
do
{
x = rand() % 16;
y = rand() % 8;
}while(cell[x][y] == true);
// 标记该格子已用
cell[x][y] = true;
// 在格子上写数字
swprintf_s(num, 4, L"%d", i);
outtextxy(x * 30 + 2, y * 30 + 6, num);
}
_getch();
closegraph();
return 0;
}
以上几个范例,无论从实用上还是美观上都很差,我只是希望大家能举一反三,写出更多漂亮的程序。
作业
- 回顾一下上一节课的作业,绘制一个任意反弹的球。这次,将程序修改成屏幕上有 10 个任意反弹的球。
- 如果反弹的不是球,而是点呢?再将某些点之间用线连起来,就可以做一个屏保“变幻线”的程序了。试试做一个。
- 写“涂格子(也叫点灯)”的游戏。详细规则可以试玩网上的各种版本。
以下作业,有时间就写。因为讲完这 12 节课,可以写出很多游戏了,所以可能会感觉作业一下子多了许多。
4. 写个俄罗斯方块。
5. 写贪吃蛇、扫雷。这两个稍微复杂一些,如果遇到问题,贴吧里贴出来,大家一起讨论。
后面还会有更精彩的课程,敬请期待。
#include<stdio.h>
#include<graphics.h>
#include<conio.h>
#include<time.h>
int main()
{
srand((unsigned)time(NULL));
initgraph(640, 480);
int x[10][2];
int y[10][2] ;
int i;
int n;//随机数1-4
for (i = 0; i < 10; i++)
{
//初始化10个点的位置
x[i][0] = rand() % 640;
y[i][0] = rand() % 480;
//初始化10个点坐标变化量
x[i][1] = rand() % 4+1;
y[i][1] = rand() % 4+1;
}
while (!_kbhit())
{
for (i = 0; i < 10; i++)
{
n = rand() % 4 + 1;
putpixel(x[i][0], y[i][0], BLACK);//删掉上一次的点
setlinecolor(BLACK);
line(x[i][0], y[i][0], x[9 - i][0], y[9 - i][0]);//删掉上次的线
if (x[i][0] >= 640 || x[i][0] <= 0) //判断点是否在窗口内,使点碰到窗口后反向
x[i][1] = x[i][1] > 0 ? (-n) : n;
if (y[i][0] >= 480 || y[i][0] <=0)
y[i][1] = y[i][1] > 0 ? (-n) : n;
x[i][0] += x[i][1];
y[i][0] += y[i][1];
putpixel(x[i][0], y[i][0], WHITE);//画点
setlinecolor(WHITE);
line(x[i][0], y[i][0], x[9 - i][0], y[9 - i][0]);//画线
}
Sleep(10);
}
closegraph();
return 0;
}
D:\编程\easy X practice\demo.cpp(43) : error C2665: 'outtextxy' : none of the 2 overloads can convert parameter 3 from type 'unsigned short [4]'
执行 cl.exe 时出错.
这是啥意思啊…………
wchar_t num[4]; -> char num[4];
swprintf_s(num, 4, L"%d", i); -> sprintf_s(num, 4, "%d", i);