用C++实现简单的小游戏

采用面向对象的编程思想

在头文件中引入acllic图形库,实现c++控制图片以及生成可视化窗口

所需工具:

acllib图形库下载地址:acl图形库下载地址

 win32位项目的创建:通过visual studio创建win32项目

三张图片:tom.bmp,jerry.bmp,heart.bmp

游戏规则很简单,如下:

1.猫和老鼠游戏,其中包含可以加分的红心(heart)。

2.用户通过上下左右键控制老鼠jerry的移动,每当老鼠jerry与猫tom碰撞时,用户分数会下降,当老鼠jerry与红心heart碰撞时,用户分数增加。

3.tom猫的个数会随着时间增加,上限为5只,生成位置随机。

游戏没有设置获胜或者失败条件。

游戏效果图:

工程结构图:

注:

setup()函数为acllib库里的启动函数,相当于一般c++程序中的主函数。

游戏的重点在于图片碰撞的检测算法,要考虑两张图片的位置x,y与两张图片的宽高width,height之间的关系,用if语句进行判断,若猫鼠碰撞则减分,若鼠心碰撞则加分。

要考虑猫主动碰撞鼠、鼠主动碰撞猫以及鼠主动碰撞红心3种情况。

游戏的第二重点在于猫的自动生成与运行轨迹。代码中采用计时器实现tom猫的随机生成与移动,生成位置的随机性使用rand()函数实现 。用结构体数组和循环实现五只tom猫。   开头的srand((unsigned)time(NULL));语句让rand()函数与时间无关。

 

源码:

#include "acllib.h"
#include <time.h>
#include <string>
using namespace std;
typedef struct rect
{
	int x;
	int y;
	int width;
	int  height;
}rect;
ACL_Image tomimg, jerryimg,heartimg;//变量
ACL_Color red = RED;
void timerEvent(int id);
void keyEvent(int key, int e);
int winWidth = 700, winHeight = 480;
int moveid = 0, movetime = 60;
int creatid = 1, creattime = 6000;
const int maxnum = 5;
const char* tomm = "tom.bmp";
const char* jerryy = "jerry.bmp";
const char* heartt = "heart.bmp";
void paint();
int score=0;//分数
int collision(rect r1, rect r2);

struct sprite {
	char const* name;
	int x, y;
	int distx, disty;
	int width, height;
};
struct sprite tom[maxnum], jerry , heart[maxnum];
int num = 0;


int Setup()
{
	srand((unsigned)time(NULL));
	initWindow("happy game", DEFAULT, DEFAULT, winWidth, winHeight);
	loadImage(tomm, &tomimg);
	loadImage(jerryy, &jerryimg);//
	loadImage(heartt, &heartimg);//

	tom[0].width = 100;
	tom[0].height = 100;
	tom[0].x = rand() % (winWidth - tom[0].width);
	tom[0].y = rand() % (winHeight - tom[0].height);
	tom[0].distx = tom[0].disty = 3;

	//tom[num] = (struct sprite*)malloc(sizeof(struct sprite));//?


	jerry.x = 40;
	jerry.y = 50;


	registerTimerEvent(timerEvent);
	startTimer(moveid, movetime);
	startTimer(creatid, creattime);
	//paint();

	registerKeyboardEvent(keyEvent);
	//paint();
	return 0;
}//windows编程   消息处理机制
void timerEvent(int id)
{
	
	if (id == 0)
	{
		for (int i = 0; i < maxnum; i++)
		{
			tom[i].x += tom[i].distx;
			tom[i].y += tom[i].disty;
			if (tom[i].x > (winWidth - tom[i].width) || tom[i].x <= 0) tom[i].distx = tom[i].distx * -1;
			if (tom[i].y > (winHeight - tom[i].height) || tom[i].y <= 0) tom[i].disty = tom[i].disty * -1;
		}
		for (int i = 0; i < num; ++i)
		{
			rect r1, r2;
			r1.x = jerry.x;
			r1.y = jerry.y;
			r1.width = 80;
			r1.height = 70;

			r2.x = tom[i].x;
			r2.y = tom[i].y;
			r2.width = tom[i].width;
			r2.height = tom[i].height;
			int c = collision(r1, r2);
			if (c == 1) score--;

		}//判断于tom是否主动碰撞jerry

	}
	if (id == 1)
	{
		
		 if (num < maxnum-1)
		 {
			 num++;
			 tom[num].width = 100;
			 tom[num].height = 100;
			 tom[num].x = rand() % (winWidth - tom[num].width);
			 tom[num].y = rand() % (winHeight - tom[num].height);
			 tom[num].distx = tom[num].disty = 3;
			 
			 


		 }
		 heart[num].width = 40;
		 heart[num].height = 40;
		 heart[num].x = rand() % (winWidth - tom[num].width);
		 heart[num].y = rand() % (winHeight - tom[num].height);
		 heart[num].distx = heart[num].disty = 0;
		

	}
	paint();

}

void paint()
{
	beginPaint();
	//putImage(&img,0,0);//把图片数据绘制到指定位置
	clearDevice();
	setTextSize(40);
	setTextColor(BLACK);
	paintText(1, 1, "分数:");
	char score1[20];
	sprintf_s(score1, "%d", score);
	paintText(99, 1, score1);
	setTextSize(20);
	setTextColor(BLUE);
	paintText(490, 450, "使用键盘控制jerry");
	putImageScale(&jerryimg, jerry.x, jerry.y, 80, 70);
	for (int i = 0; i <= num; i++)
	{
		putImageScale(&tomimg, tom[i].x, tom[i].y, tom[i].width, tom[i].height);
		putImageScale(&heartimg, heart[i].x, heart[i].y, heart[i].width, heart[i].height);
	}
	

	endPaint();
}


void keyEvent(int key, int e)
{
	if (e != KEY_DOWN) return;
	switch (key)
	{
	case VK_UP:
		jerry.y = jerry.y - 11;
		break;
	case VK_DOWN:
		jerry.y = jerry.y + 11;
		break;
	case VK_LEFT:
		jerry.x = jerry.x - 11;
		break;
	case VK_RIGHT:
		jerry.x = jerry.x + 11;
		break;

	}
	for (int i = 0; i < num; ++i) 
	{
		rect r1, r2;
		r1.x = jerry.x;
		r1.y = jerry.y;
		r1.width =  80;
		r1.height = 70;
		
			r2.x = tom[i].x;
			r2.y = tom[i].y;
			r2.width = tom[i].width;
			r2.height = tom[i].height;
			int c = collision(r1, r2);
			if (c ==1) score--;

	}//判断于tom是否碰撞
	for (int i = 1; i <=num; ++i)
	{
		rect r1, r2;
		r1.x = jerry.x;
		r1.y = jerry.y;
		r1.width = 80;
		r1.height = 70;

		r2.x = heart[i].x;
		r2.y = heart[i].y;
		r2.width = heart[i].width;
		r2.height = heart[i].height;
		int c = collision(r1, r2);
		if (c == 1) { score = score + 5; heart[i].width = 0; heart[i].height = 0; heart[i].x = winWidth + 10000;  }
	}//判断是否与heart碰撞
	paint();
}
int collision(rect r1, rect r2)
{
	int c = 1;
if (r1.x<r2.x && r1.x + r1.width>r2.x) {
	if (r1.y > r2.y && r1.y < r2.y + r2.height) return c;
	if (r1.y<r2.y && r1.y + r1.height>r2.y)return c;
	else {
		if (r1.x > r2.x && r2.x + r2.width > r1.x) 
		{
			if (r1.y > r2.y && r1.y < r2.y + r2.height) return c;
			if (r1.y<  r2.y && r1.y + r1.height > r2.y)return c;

		}
		c = 0; return c;



	}

}

}

至此,游戏编写完成,但存在碰撞检测偶尔不敏感,jerry可以移动出可视化窗口等问题。

 

  • 16
    点赞
  • 73
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值