loadimage();
第1个参数为IMAGE变量的地址。
第2个参数为图片资源的位置即路径。
关于图片资源的路径问题,这里有相对引用和绝对引用两种。
已经将项目属性改为多字节(关于这个问题参见:图形的可视化编程(一))
相对引用:
当图片资源与.cpp文件在同一目录下时我们可以用其相对路径进行引用。例如我们将图片:1.jpg与该.cpp文件放在同一目录下。我们就可以用相对引用,这时只需要用到图片资源的名称即可。
如:
这种引用方法。
绝对引用:
绝对引用适用的范围更加广阔,当图片资源和.cpp文件不在同一目录下,比如图片资源在与.cpp同目录的一个文件夹中或者在计算机某个盘的某个文件夹下面时。那么我们就无法用相对引用了。此时我们必须要用到其绝对位置了。
如下面这种情况:
获取绝对路径的方法:
这里的对象名称就是其绝对位置了。我们可以将其复制粘贴到代码中了。
注意:由于\字符转义的问题,我们在使用时要讲单反斜杠\改为\\ 双反斜杠,或者改为/单斜杠
另外:使用loadimage()加载图片时可以用第三第四个参数进行图片的缩放。
示例:
#include
#include
#include
#include
int main(void)
{
initgraph(800, 600);
IMAGE m;
//loadimage(&m, "C:\\Users\\付河林\\Desktop\\图片坐标\\images\\1.jpg");绝对引用
loadimage(&m, "1.jpg");
putimage(0, 0, &m);
_getch();
closegraph();
return 0;
}
我们可以用m.getwidth()和m.getheight()来获取图片的长和宽,如果我们将获取的图片的尺寸传给initgraph()来创建窗口,那么就可以避免创建的窗口大小和图片的大小不一致的问题了。
如:
基本框架
#include
#include
#include
#include
int main(void)
{
initgraph(800, 600);
MOUSEMSG m;
while (1)
{
m = GetMouseMsg();
switch (m.uMsg)
{
case WM_LBUTTONDOWN: //L:left
setfillcolor(RED);
solidcircle(m.x, m.y, 50);
break;
case WM_RBUTTONDOWN: //R:right button: 按钮 down:向下
setfillcolor(WHITE);
solidcircle(m.x, m.y, 50);
break;
case WM_MOUSEMOVE: //W:Windows M:message mouse:鼠标 move:移动
circle(m.x, m.y, 10);
break;
default:
break;
}
}
closegraph();
return 0;
}
按下鼠标左键,在当前位置画一个半径50的红色填充圆,右键,在当前位置画一个半径为50的白色填充圆。
鼠标操作的菜单模型:
#include
#include
#include
#include
void makeMenu()
{
setfillcolor(RGB(192,192,192));
fillrectangle(300, 200, 500, 250);
fillrectangle(300, 250 + 10, 500, 250 + 10 + 50);
settextstyle(35, 0, "黑体");
settextcolor(BLUE);
setbkmode(TRANSPARENT);
outtextxy(300 + 25, 200 + 10, "开始游戏");
outtextxy(300 + 25, 250 + 10 + 10, "结束游戏");
MOUSEMSG m;
while (1)//监视鼠标
{
m = GetMouseMsg();
if (m.x >= 300 && m.x <= 500 && m.y >= 200 && m.y <= 250)
{
setfillcolor(YELLOW);
fillrectangle(300, 200, 500, 250);
outtextxy(300 + 25, 200 + 10, "开始游戏");
if (m.uMsg == WM_LBUTTONDOWN)
{
break;
}
}
else if (m.x >= 300 && m.x <= 500 && m.y >= 260 && m.y <= 310)
{
setfillcolor(YELLOW);
fillrectangle(300, 250 + 10, 500, 250 + 10 + 50);
outtextxy(300 + 25, 250 + 10 + 10, "结束游戏");
if (m.uMsg == WM_LBUTTONDOWN)
{
Sleep(3000);//休眠3000毫秒后关闭程序
exit(0);
}
}
else
{
setfillcolor(RGB(192,192,192));
fillrectangle(300, 200, 500, 250);
fillrectangle(300, 250 + 10, 500, 250 + 10 + 50);
outtextxy(300 + 25, 200 + 10, "开始游戏");
outtextxy(300 + 25, 250 + 10 + 10, "结束游戏");
}
}
}
int main(void)
{
initgraph(800, 600);
makeMenu();
//game(); 当点击开始游戏后break;退出循环执行下一条语句game();我们将鼠标操作菜单放在游戏模块之前就行了
closegraph();
return 0;
}
示例:
#include
#include
#include
#include
#include
#pragma comment(lib,"winmm.lib")
int main()
{
mciSendString("open 说好不哭.mp3 alias music", 0, 0, 0);
mciSendString("play music repeat", 0, 0, 0);
_getch();
return 0;
}
二维数组与推箱子:
#include
#include
#include
#include
//模块设计理念:尽量避免功能交叉,做到高内聚,底耦合。
///*
// //1.墙: ■
// //0.空地 :两个空格
// //3.目的地 ☆
// //4.箱子 ★
// //5:人 ※
// //3+4:箱子到达目的地 ●
//*/
int cas = 0;
int map[3][8][8] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 3, 4, 0, 0, 1,
1, 0, 1, 0, 5, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 4, 3, 0, 4, 1,
1, 4, 1, 0, 0, 1, 3, 1,
1, 3, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 0, 0, 0, 1,
1, 0, 1, 0, 5, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 4, 3, 0, 4, 1,
1, 4, 1, 0, 0, 1, 3, 1,
1, 3, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 3, 0, 0, 0, 4, 3, 1,
1, 4, 1, 0, 5, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 4, 3, 0, 4, 1,
1, 0, 4, 0, 0, 1, 3, 1,
1, 0, 3, 1, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1
};
void gotoxy(int x, int y) //光标移动到(x,y)位置,在游戏中打印一张画面后将光标拉到(x,y)处进行打印。
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void drawGraph()
{
printf("推箱子第%d关\n", cas+1);
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
switch (map[cas][i][j])
{
case 0:
printf(" ");//打印空地
break;
case 1:
printf("■");//打印墙
break;
case 3:
printf("☆");//打印目的地
break;
case 4:
printf("★");//打印箱子
break;
case 5:
case 8://人到达目的地
printf("※");//打印人
break;
case 7:
printf("●");//箱子到达目的地
break;
}
}
printf("\n");
}
}
void keyDown()
{
//定位
int i;
int j;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
if (map[cas][i][j] == 5 || map[cas][i][j] == 8)
{
break;
}
}
if (map[cas][i][j] == 5 || map[cas][i][j] == 8)
{
break;
}
}
printf("%d%d", i, j);
char userKey = _getch();
switch (userKey)
{
case 'W':
case 'w':
case 72:
if (map[cas][i - 1][j] == 0 || map[cas][i - 1][j] == 3)
{
map[cas][i - 1][j] += 5;
map[cas][i][j] -= 5;
}
else if (map[cas][i - 1][j] == 4 || map[cas][i - 1][j] == 7)
{
if (map[cas][i - 2][j] == 0 || map[cas][i - 2][j] == 3)
{
map[cas][i][j] -= 5;
map[cas][i - 1][j] += 1;
map[cas][i - 2][j] += 4;
}
}
break;
case 'S':
case 's':
case 80:
if (map[cas][i + 1][j] == 0 || map[cas][i + 1][j] == 3)
{
map[cas][i + 1][j] += 5;
map[cas][i][j] -= 5;
}
else if (map[cas][i + 1][j] == 4 || map[cas][i + 1][j] == 7)
{
if (map[cas][i + 2][j] == 0 || map[cas][i + 2][j] == 3)
{
map[cas][i][j] -= 5;
map[cas][i + 1][j] += 1;
map[cas][i + 2][j] += 4;
}
}
break;
case 'A':
case 'a':
case 75:
if (map[cas][i][j - 1] == 0 || map[cas][i][j - 1] == 3)
{
map[cas][i][j - 1] += 5;
map[cas][i][j] -= 5;
}
else if (map[cas][i][j - 1] == 4 || map[cas][i][j - 1] == 7)
{
if (map[cas][i][j - 2] == 0 || map[cas][i][j - 2] == 3)
{
map[cas][i][j] -= 5;
map[cas][i][j - 1] += 1;
map[cas][i][j - 2] += 4;
}
}
break;
case 'D':
case 'd':
case 77:
if (map[cas][i][j + 1] == 0 || map[cas][i][j + 1] == 3)
{
map[cas][i][j + 1] += 5;
map[cas][i][j] -= 5;
}
else if (map[cas][i][j + 1] == 4 || map[cas][i][j + 1] == 7)
{
if (map[cas][i][j + 2] == 0 || map[cas][i][j + 2] == 3)
{
map[cas][i][j] -= 5;
map[cas][i][j + 1] += 1;
map[cas][i][j + 2] += 4;
}
}
break;
}
}
int gameOver()
{
int flag = 1;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if (map[cas][i][j] == 4)
{
flag = 0;
}
}
}
return flag;
}
int main(void)
{
while (1)
{
gotoxy(0, 0);
drawGraph();
keyDown();
if (gameOver() == 1)
{
cas++;
if (cas == 3)
{
//drawGraph();
break;
}
}
}
system("cls");
printf("Victory\n");
return 0;
}
图形化优化:
#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include
#include
int cas = 0;
int map[3][8][8] = {
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 0, 3, 4, 0, 0, 1,
1, 0, 1, 0, 5, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 4, 3, 0, 4, 1,
1, 4, 1, 0, 0, 1, 3, 1,
1, 3, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 0, 1, 0, 0, 0, 0, 1,
1, 0, 1, 0, 5, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 4, 3, 0, 4, 1,
1, 4, 1, 0, 0, 1, 3, 1,
1, 3, 0, 0, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 3, 0, 0, 0, 4, 3, 1,
1, 4, 1, 0, 5, 1, 0, 1,
1, 0, 0, 0, 0, 0, 0, 1,
1, 1, 0, 4, 3, 0, 4, 1,
1, 0, 4, 0, 0, 1, 3, 1,
1, 0, 3, 1, 0, 0, 0, 1,
1, 1, 1, 1, 1, 1, 1, 1
};
IMAGE img[6];
int imgIndex[6] = { 0,1,3,4,5,7 };
void loadResource()
{
for (int i = 0; i < 6; i++)
{
char fileName[20] = "";
sprintf(fileName, "%d.bmp", imgIndex[i]);
loadimage(&img[i], fileName);
}
}
void gotoxy(int x, int y) //光标移动到(x,y)位置,在游戏中打印一张画面后将光标拉到(x,y)处进行打印。
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void drawGraph()
{
//printf("推箱子第%d关\n", cas + 1);
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
int x = 60 * j;
int y = 60 * i;
switch (map[cas][i][j])
{
case 0:
putimage(x, y, &img[0]);
//printf(" ");//打印空地
break;
case 1:
putimage(x, y, &img[1]);
//printf("■");//打印墙
break;
case 3:
putimage(x, y, &img[2]);
//printf("☆");//打印目的地
break;
case 4:
putimage(x, y, &img[3]);
//printf("★");//打印箱子
break;
case 5:
case 8://人到达目的地
//printf("※");//打印人
putimage(x, y, &img[4]);
break;
case 7:
putimage(x, y, &img[5]);
//printf("●");//箱子到达目的地
break;
}
}
//printf("\n");
}
}
void keyDown()
{
//定位
int i;
int j;
for (i = 0; i < 8; i++)
{
for (j = 0; j < 8; j++)
{
if (map[cas][i][j] == 5 || map[cas][i][j] == 8)
{
break;
}
}
if (map[cas][i][j] == 5 || map[cas][i][j] == 8)
{
break;
}
}
//printf("%d%d", i, j);
char userKey = _getch();
switch (userKey)
{
case 'W':
case 'w':
case 72:
if (map[cas][i - 1][j] == 0 || map[cas][i - 1][j] == 3)
{
map[cas][i - 1][j] += 5;
map[cas][i][j] -= 5;
}
else if (map[cas][i - 1][j] == 4 || map[cas][i - 1][j] == 7)
{
if (map[cas][i - 2][j] == 0 || map[cas][i - 2][j] == 3)
{
map[cas][i][j] -= 5;
map[cas][i - 1][j] += 1;
map[cas][i - 2][j] += 4;
}
}
break;
case 'S':
case 's':
case 80:
if (map[cas][i + 1][j] == 0 || map[cas][i + 1][j] == 3)
{
map[cas][i + 1][j] += 5;
map[cas][i][j] -= 5;
}
else if (map[cas][i + 1][j] == 4 || map[cas][i + 1][j] == 7)
{
if (map[cas][i + 2][j] == 0 || map[cas][i + 2][j] == 3)
{
map[cas][i][j] -= 5;
map[cas][i + 1][j] += 1;
map[cas][i + 2][j] += 4;
}
}
break;
case 'A':
case 'a':
case 75:
if (map[cas][i][j - 1] == 0 || map[cas][i][j - 1] == 3)
{
map[cas][i][j - 1] += 5;
map[cas][i][j] -= 5;
}
else if (map[cas][i][j - 1] == 4 || map[cas][i][j - 1] == 7)
{
if (map[cas][i][j - 2] == 0 || map[cas][i][j - 2] == 3)
{
map[cas][i][j] -= 5;
map[cas][i][j - 1] += 1;
map[cas][i][j - 2] += 4;
}
}
break;
case 'D':
case 'd':
case 77:
if (map[cas][i][j + 1] == 0 || map[cas][i][j + 1] == 3)
{
map[cas][i][j + 1] += 5;
map[cas][i][j] -= 5;
}
else if (map[cas][i][j + 1] == 4 || map[cas][i][j + 1] == 7)
{
if (map[cas][i][j + 2] == 0 || map[cas][i][j + 2] == 3)
{
map[cas][i][j] -= 5;
map[cas][i][j + 1] += 1;
map[cas][i][j + 2] += 4;
}
}
break;
}
}
int gameOver()
{
int flag = 1;
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 8; j++)
{
if (map[cas][i][j] == 4)
{
flag = 0;
}
}
}
return flag;
}
void makeMenu()
{
initgraph(800, 600);
setfillcolor(RGB(192, 192, 192));
fillrectangle(300, 200, 500, 250);
fillrectangle(300, 250 + 10, 500, 250 + 10 + 50);
settextstyle(35, 0, "黑体");
settextcolor(BLUE);
setbkmode(TRANSPARENT);
outtextxy(300 + 25, 200 + 10, "开始游戏");
outtextxy(300 + 25, 250 + 10 + 10, "结束游戏");
MOUSEMSG m;
while (1)//监视鼠标
{
m = GetMouseMsg();
if (m.x >= 300 && m.x <= 500 && m.y >= 200 && m.y <= 250)
{
setfillcolor(YELLOW);
fillrectangle(300, 200, 500, 250);
outtextxy(300 + 25, 200 + 10, "开始游戏");
if (m.uMsg == WM_LBUTTONDOWN)
{
break;
}
}
else if (m.x >= 300 && m.x <= 500 && m.y >= 260 && m.y <= 310)
{
setfillcolor(YELLOW);
fillrectangle(300, 250 + 10, 500, 250 + 10 + 50);
outtextxy(300 + 25, 250 + 10 + 10, "结束游戏");
if (m.uMsg == WM_LBUTTONDOWN)
{
Sleep(3000);//休眠3000毫秒后关闭程序
exit(0);
}
}
else
{
setfillcolor(RGB(192, 192, 192));
fillrectangle(300, 200, 500, 250);
fillrectangle(300, 250 + 10, 500, 250 + 10 + 50);
outtextxy(300 + 25, 200 + 10, "开始游戏");
outtextxy(300 + 25, 250 + 10 + 10, "结束游戏");
}
}
closegraph();
}
int main(void)
{
loadResource();
makeMenu();
initgraph(8 * 60, 8 * 60);
while (1)
{
//gotoxy(0, 0);
//initgraph(8 * 60, 8 * 60);
drawGraph();
keyDown();
if (gameOver() == 1)
{
cas++;
if (cas == 3)
{
break;
}
}
//closegraph();
}
closegraph();
return 0;
}
这里我们加上了前面用鼠标操作写的makeMenu()菜单