运行页面
视频展示
说明
有空的时候会录视频教各位怎么实现这个小游戏。
视频长度为半小时左右。
源码
main.cpp
#include<graphics.h>
#include <cstdio>
#include <ctime>
#include "Bean.h"
#define WIDTH 640
#define HEIGHT 960
static IMAGE background, mouseA, mouseB, mouseC;
static IMAGE HitMouseA, HitMouseB, HitMouseC;
static IMAGE bucket, water_full;
static Mouse mouses[3][3];
static int num;
clock_t start;
void initImage() {
loadimage(&background, "image/background.jpg");
loadimage(&mouseA, "image/A.png");
loadimage(&mouseB, "image/B.png");
loadimage(&mouseC, "image/C.png");
loadimage(&HitMouseA, "image/hitA.png");
loadimage(&HitMouseB, "image/hitB.png");
loadimage(&HitMouseC, "image/hitC.png");
loadimage(&bucket, "image/bucket.png");
loadimage(&water_full, _T("image/water-full.png"));
}
void drawAlpha(IMAGE *picture, int picture_x, int picture_y); //x为要载入图片的X坐标,y为Y坐标
void drawBoard() {// 绘制棋盘底色
putimage(0, 0, &background);
}
void createMouse() {
int newX = rand() % 3;
int newY = rand() % 3;
if (mouses[newX][newY].character != NONE)
createMouse();
else
mouses[newX][newY].randomCharacter();
}
void HandleMouse() {
static int time = 0;
int mouseNum = 0;
for (int i = 0; i < 3; ++i) //获得当前有几个地鼠露头
for (int j = 0; j < 3; ++j)
if (mouses[i][j].character != NONE)
mouseNum++;
if (mouseNum < 2 && time++ == 10) {
createMouse();
time = 0;
}
}
void drawMouseByCharacter(Character character, int x, int y) {
int imgX, imgY;
imgY = 165 * y + 350;
imgX = 213 * x + 40;
switch (character) {
case A: {
drawAlpha(&mouseA, imgX, imgY);
break;
}
case B: {
drawAlpha(&mouseB, imgX, imgY);
break;
}
case C: {
drawAlpha(&mouseC, imgX, imgY);
break;
}
default:
break;
}
}
void drawMouseHitByCharacter(Character character, int x, int y) {
int imgX, imgY;
imgY = 165 * y + 400;
imgX = 213 * x + 40;
if (mouses[x][y].time >= 20)
drawAlpha(&water_full, imgX, imgY - 100);
switch (character) {
case A: {
drawAlpha(&HitMouseA, imgX, imgY);
break;
}
case B: {
drawAlpha(&HitMouseB, imgX, imgY);
break;
}
case C: {
drawAlpha(&HitMouseC, imgX, imgY);
break;
}
default:
break;
}
}
void drawMouse() {
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
if (mouses[i][j].character != NONE) {
if (!mouses[i][j].isHit) {
drawMouseByCharacter(mouses[i][j].character, i, j);
} else {
mouses[i][j].timeDown();
if (mouses[i][j].time == 0) {
mouses[i][j].character = NONE;
continue;
}
drawMouseHitByCharacter(mouses[i][j].character, i, j);
}
}
}
void observeMouse() {
static int mouseX = 0, mouseY = 0;
if (MouseHit()) {//如果鼠标没有点击,则不交互
MOUSEMSG msg = GetMouseMsg();
mouseX = msg.x - 50;
mouseY = msg.y - 50;
if (msg.mkLButton && msg.uMsg != WM_MOUSEMOVE) {
int mouseI = 3, mouseJ = 3;
for (int i = 0; i < 3; ++i) {
if ((213 * i + 40) < mouseX && mouseX < (213 * (i + 1) + 40)) {
mouseI = i;
}
}
if (mouseY < 350)goto doNo;
for (int i = 0; i < 3; ++i) {
if ((165 * i + 330) < mouseY && mouseY < (165 * (i + 1) + 330)) {
mouseJ = i;
}
}
if (mouseI == 3 || mouseJ == 3)
goto doNo;
if (mouses[mouseI][mouseJ].character != NONE)
mouses[mouseI][mouseJ].isHit = true;
num++;
}
doNo:
FlushMouseMsgBuffer();
}
if (mouseX < 0)mouseX = 0;
if (mouseY < 0)mouseY = 0;
if (mouseY + 200 > HEIGHT)mouseY = HEIGHT - 200;
drawAlpha(&bucket, mouseX, mouseY);
}
void drawScoreAndTime() {
setbkmode(TRANSPARENT);
settextcolor(BLUE);
settextstyle(100, 0, nullptr, 0, 0, 100, false, false, false);
char charValue[5];
sprintf(charValue, "%d ", num);
outtextxy(466 - strlen(charValue) * 20, 60, charValue);
int time=(int)(clock()-start)/CLOCKS_PER_SEC;
char TimeValue[5];
sprintf(TimeValue, "%d ", time);
settextcolor(GREEN);
settextstyle(80, 0, nullptr, 0, 0, 70, false, false, false);
outtextxy(100, 15, TimeValue);
}
int main() {
initgraph(WIDTH, HEIGHT);
initImage();
num = 0;
start=clock();
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
mouses[i][j].character = NONE;
while (true) {
srand((unsigned) time(NULL));
Sleep(UNIT);
BeginBatchDraw();
cleardevice();
drawBoard();
HandleMouse();
drawMouse();
observeMouse();
drawScoreAndTime();
EndBatchDraw();
}
closegraph();
system("pause");
return 0;
}
// 载入PNG图并去透明部分
void drawAlpha(IMAGE *picture, int picture_x, int picture_y) {
DWORD *dst = GetImageBuffer();
DWORD *draw = GetImageBuffer();
DWORD *src = GetImageBuffer(picture);
int picture_width = picture->getwidth();
int picture_height = picture->getheight();
int graphWidth = getwidth();
int graphHeight = getheight();
int dstX = 0;
for (int iy = 0; iy < picture_height; iy++) {
for (int ix = 0; ix < picture_width; ix++) {
int srcX = ix + iy * picture_width;
int sa = ((src[srcX] & 0xff000000) >> 24);
int sr = ((src[srcX] & 0xff0000) >> 16);
int sg = ((src[srcX] & 0xff00) >> 8);
int sb = src[srcX] & 0xff;
if (ix >= 0 && ix <= graphWidth && iy >= 0 && iy <= graphHeight && dstX <= graphWidth * graphHeight) {
dstX = (ix + picture_x) + (iy + picture_y) * graphWidth;
int dr = ((dst[dstX] & 0xff0000) >> 16);
int dg = ((dst[dstX] & 0xff00) >> 8);
int db = dst[dstX] & 0xff;
draw[dstX] = ((sr * sa / 255 + dr * (255 - sa) / 255) << 16)
| ((sg * sa / 255 + dg * (255 - sa) / 255) << 8)
| (sb * sa / 255 + db * (255 - sa) / 255);
}
}
}
}
Button.h
#ifndef NANI_BEAN_H
#define NANI_BEAN_H
#define UNIT 13
enum Character{
A,B,C
,NONE
};
class Mouse{
public:
Character character;
bool isHit;
int time;
void timeDown(){
time--;
}
void randomCharacter(){
character=static_cast<Character>(rand()%3);
isHit= false;
time=25;
};
};
#endif //NANI_BEAN_H
其他资源
A.png
B.png
C.png
bucket.png
backgrond.jpg
hitA.png
hitB.png
hitC.png
water-full.png
总结
整体代码比较简单,思路也比较清晰,唯一难的也就是注意一下图片摆放位置,以及小锤子的图标不能直接左上角对齐