在此之前呢,和大家说明一下,因为这是一个比较大的项目了,所以展示所有代码会有些困难,从中还要数据库的参与,所以我裁剪了主要部分的代码,主要目的的让大家明白实现这个项目的难点以及逻辑思路,希望大家可以理解
好了,话不多说,开始了
enum ATTR { //图片对应的数组下标 i_gold=1, i_money=3, i_role=5, i_stone=9, i_bk= i_stone+1, //窗口尺寸 WIDTH = 1080, HEIGHT= 640, //物品数量 MINE_NUM=10, }; enum TYPE { //物品类型 GOLD, //金块 MONEY, //钱袋 STONE, //石头 //摆动方向 LEFT, RIGHT, //摆动状态 M_LONG, M_NORMAL, M_SHORT, };
struct Role { int x; //贴图的位置 int y; int width;//图片宽度和高度 int height; int coin;//金币 }; struct Mine //物品 { int x; int y; int size;//用来计算碰撞 int flag;//物品是否存在 int type;//物品类型,钱袋,石头,金块 int gold;//价值 }; //钩子 struct Hook { double x;//绳子开始坐标,固定不变的 double y; double endx;//末端变化的坐标 double endy; int len;//绳子长度 int dir;//摆动方向 double angle;//摆动角度 double speed;//速度 double vx;//速度分量 double vy; int swing;//是否在摆动 int state;//伸长状态,伸长,正常,缩短 int index;//抓到的物品下标 };
void GameInit() { //初始化随机数种子 srand(GetTickCount()); //初始化角色数据 role.coin = 0; role.width = 140; role.height = 120; role.x = WIDTH / 2 - role.width / 2;//让角色图片居中显示 role.y = 0; //加载图片 for (int i = 0; i < 10; i++) { char fileName[20]; sprintf(fileName, "./images/%d.jpg", i); if (i <= 1) { loadimage(&img[i], fileName,73,62); } else { loadimage(&img[i], fileName); } } loadimage(&img[i_bk], "./images/bk.jpg",WIDTH,HEIGHT-role.height); //初始化物品 for (int i = 0; i < MINE_NUM; i++) { mine[i].flag = 1; mine[i].size = 60; mine[i].type = rand() % 3; mine[i].x=rand()%(WIDTH-mine[i].size); mine[i].y=rand()%(HEIGHT-role.height-100)+ role.height+ 50; mine[i].gold = rand()%600+rand()%200; } //初始化钩子 hook.x = role.x+45; hook.y = role.y+100; hook.len = 50; hook.endx = hook.x; hook.endy=hook.y+hook.len; hook.angle = 0.0; hook.dir = RIGHT; hook.state = M_NORMAL; hook.vx = 0; hook.vy = 0; hook.speed = 5.0; hook.index = -1; }
void Gamedraw() { BeginBatchDraw(); //设置背景颜色 setbkcolor(GREEN); cleardevice(); putimage(0, role.height, &img[i_bk]); //透明贴图 两张图片,一张掩码图,一张原图 putimage(role.x, role.y, &img[i_role-1],SRCAND);//掩码图 putimage(role.x, role.y, &img[i_role],SRCPAINT);//原图 //绘制钩子 setlinestyle(PS_SOLID, 5); setlinecolor(BROWN); line(hook.x, hook.y, hook.endx, hook.endy); //绘制物品 for (int i = 0; i < MINE_NUM; i++) { if (mine[i].flag) { switch (mine[i].type) { case GOLD: putimage(mine[i].x, mine[i].y, &img[i_gold-1],SRCAND); putimage(mine[i].x, mine[i].y, &img[i_gold],SRCPAINT); break; case MONEY: putimage(mine[i].x, mine[i].y, &img[i_money-1], SRCAND); putimage(mine[i].x, mine[i].y, &img[i_money], SRCPAINT); break; case STONE: putimage(mine[i].x, mine[i].y, &img[i_stone-1], SRCAND); putimage(mine[i].x, mine[i].y, &img[i_stone], SRCPAINT); break; } } } //绘制分数 char s[30]; sprintf(s, "金币:%d", role.coin); settextstyle(50, 0, "黑体"); outtextxy(50, 50, s); EndBatchDraw(); }
//钩子摆动 void hookRock() { if (hook.state == M_NORMAL) { if (hook.dir == RIGHT) { hook.angle++; } else { hook.angle--; } if (hook.angle > 80) { hook.dir = LEFT; } else if (hook.angle < -80) { hook.dir = RIGHT; } hook.endx = hook.x + sin(π / 180 * hook.angle) * hook.len; hook.endy = hook.y + cos(π / 180 * hook.angle) * hook.len; } } int distance(struct Hook hook) { double dis=sqrt((hook.x-hook.endx)* (hook.x - hook.endx) + (hook.y-hook.endy) * (hook.y - hook.endy)); return dis <= hook.len; } void keyControl() { //按空格伸长 if (GetAsyncKeyState(VK_SPACE) && hook.state == M_NORMAL) { hook.state = M_LONG; hook.vx = sin(π / 180 * hook.angle) * hook.speed; hook.vy = cos(π / 180 * hook.angle) * hook.speed; } if (hook.endx <= 0 || hook.endx >= WIDTH || hook.endy >= HEIGHT) { hook.state = M_SHORT; } if (hook.state == M_LONG) { hook.endx += hook.vx; hook.endy += hook.vy; } else if (hook.state == M_SHORT) { hook.endx -= hook.vx; hook.endy -= hook.vy; //如果缩短到原来的长度,就停止缩短,判断起点和末端的距离是否等于,长度 if (distance(hook)) { hook.state = M_NORMAL; } } }
void grap() { //找到抓取的是哪个物品 for (int i = 0; i < MINE_NUM; i++) { if (mine[i].flag && hook.endx > mine[i].x && hook.endx<mine[i].x + mine[i].size && hook.endy>mine[i].y && hook.endy < mine[i].y + mine[i].size) { hook.index = i;//保存抓到的物品的下标 break; } } if (hook.index != -1) { hook.state = M_SHORT; mine[hook.index].x = hook.endx-mine[hook.index].size/2; mine[hook.index].y = hook.endy- mine[hook.index].size / 2; if (distance(hook)) { hook.state = M_NORMAL; mine[hook.index].flag = 0; role.coin += mine[hook.index].gold; hook.state = M_NORMAL; hook.index = -1; } } }
int main() { initgraph(WIDTH,HEIGHT,1); GameInit(); while (1) { printf("%lf,%lf vxy(%lf,%lf)\n", hook.endx, hook.endy,hook.vx,hook.vy); hookRock(); Gamedraw(); keyControl(); grap(); } closegraph(); return 0; }