草稿111

peekmessage(用于接受信息)

exmessage(专门用于鼠标操作)

#include<graphics.h>
#include<string>
#include<vector>
using namespace std;
const int WINDOW_WIDTH = 1280;
const int WINDOW_HEIGHT = 720;

//封装了一个动画播放
class Animation
{
public:
	Animation(LPCTSTR path, int num, int interval)//图片所来源的路径,图片的数量,图片播放之间的间隔 LP的含义使长指针, C的含义是const ,
	{
		interval_ms = interval;

		TCHAR path_file[256];//TCHAR就是相当于根据我们系统在自己分配的字符串类型 这个自定义的含义是道路的文件
		for (int i = 0; i < num; i++)//通过一个for循环将所有我们下载的图片都加载到一个图片数组中
		{
			_stprintf_s(path_file, path, i);//将文件名字打印在loadimage中

			IMAGE* frame = new IMAGE();//定义一个图片指针 并且开辟这个图片指针
			loadimage(frame, path_file);//加载这个图片
			frame_list.push_back(frame);//有点类似于出队,或者出栈,就是数组向后移的意思
		}
	}

	~Animation()//析构函数
	{
		for (int i = 0; i < frame_list.size(); i++)
			delete frame_list[i];
	}

	void play(int x, int y, int delta)//动画播放
	{
		timer += delta;
		if (timer >= interval_ms)
		{
			idx_frame = (idx_frame + 1) % frame_list.size();
			timer = 0;
		}

		putimage_alpha(x, y, frame_list[idx_frame]);
	}
private:
	int timer = 0;     //动画计时器
	int idx_frame = 0; //动画帧索引
	int interval_ms = 0;
	vector<IMAGE*> frame_list;//frame是图形的意思,图形列表
};

//输出图片函数

#pragma comment(lib, "MSIMG32.LIB")
inline void putimage_alpha(int x, int y, IMAGE* img)
{
	int w = img->getheight();
	int h = img->getwidth();
	AlphaBlend(GetImageHDC(NULL), x, y, w, h,
		GetImageHDC(img), 0, 0, w, h, { AC_SRC_OVER,0,225,AC_SRC_ALPHA });
}

//敌人类
class Enemy
{
public:
	Enemy()
	{
		loadimage(&img_shadow, _T("img/shadow_enemy.png"));
		anim_left = new Animation(_T("img/enemy_left_%d.png"), 6, 45);
		anim_right = new Animation(_T("img/enemy_right_%d.png"), 6, 45);
		
		//生成敌人边界
		enum class SpawnEdge
		{
			Up = 0,
			Down,
			Left,
			Right
		};
	
		//将敌人放置在地图外边界出的随机位置
		SpawnEdge egde = (SpawnEdge)(rand() % 4);
		switch (egde)
		{
		case SpawnEdge::Up:
			position.x = rand() % WINDOW_WIDTH;
			position.y = -FRAME_HEIGHT;
			break;
		case SpawnEdge::Down:
			position.x = rand() % WINDOW_WIDTH;
			position.y = WINDOW_HEIGHT;
			break;
		case SpawnEdge::Left:
			position.x = -FRAME_WIDTH;
			position.y = rand() % WINDOW_HEIGHT;
			break;
		case SpawnEdge::Right:
			position.x = WINDOW_WIDTH;
			position.y = rand() % WINDOW_HEIGHT;
			break;
		default:
			break;
		}
	}

	bool CheckBulletCollison(const Bullet& bullet)
	{
		return false;
	}

	bool CheckPlayerCollison(const Player& player)
	{
		return false;
	}

	void move(const Player& player)
	{
		const POINT& player_position = player.GetPosition();
		int dir_x = player_position.x - position.x;
		int dir_y = player_position.y - position.y;
		double len_dir = sqrt(dir_x * dir_x + dir_y + dir_y);
		if (len_dir != 0)
		{
			double normalize_x = dir_x / len_dir;
			double normalize_y = dir_y / len_dir;
			position.x += (int)(SPEED * normalize_x);
			position.y += (int)(SPEED * normalize_y);
		}
		if (dir_x < 0)
			facing_left = true;
		else if (dir_x > 0)
			facing_left = false;
	}
	void Draw(int delta)
	{
		int pos_shadow_x = position.x + (FRAME_WIDTH / 2 - SHADOW_WIDTH / 2);
		int pos_shadow_y = position.y + FRAME_HEIGHT - 8;
		putimage_alpha(pos_shadow_x, pos_shadow_y, &img_shadow);

		if (facing_left)
			anim_left->play(position.x, position.y, delta);
		else
			anim_right->play(position.x, position.y, delta);
	}
	~Enemy()
	{
		delete anim_left;
		delete anim_right;
	}

private:
	const int SPEED = 2;
	const int FRAME_WIDTH = 80;
	const int FRAME_HEIGHT = 80;
	const int SHADOW_WIDTH = 48;
	bool is_move_right = false;
	bool is_move_left = false;
private:
	IMAGE img_shadow;
	Animation* anim_left;
	Animation* anim_right;
	POINT position = { 0, 0 };
	bool facing_left = false;
};


//子弹类
class Bullet
{
public:
	POINT position = { 0, 0 };

public:
	Bullet() = default;
	~Bullet() = default;

	void Draw() const
	{
		setlinecolor(RGB(255, 155, 50));
		setfillcolor(RGB(200, 75, 10));
		fillcircle(position.x, position.y, RADIUS);
	}

private:
	const int RADIUS = 10;//圆的半径
};
//玩家类
class Player
{
public:
	Player()
	{
		loadimage(&img_shadow, _T("img/shadow_player.png"));
		anim_left = new Animation(_T("img/player_left_%d.png"), 6, 45);
		anim_right = new Animation(_T("img/player_right_%d.png"), 6, 45);
	}
	~Player()
	{
		delete anim_left;//释放空间
		delete anim_right;
	}
	void ProcessEvent(const ExMessage& msg)//处理玩家的操作信息
	{
		switch (msg.message)
		{
		case WM_KEYDOWN:
			switch (msg.vkcode)
			{
			case VK_UP:
				is_move_up = true;
				break;
			case VK_DOWN:
				is_move_down = true;
				break;
			case VK_LEFT:
				is_move_left = true;
				break;
			case VK_RIGHT:
				is_move_right = true;
				break;
			}
			break;
		case WM_KEYUP:
			switch (msg.vkcode)
			{
			case VK_UP:
				is_move_up = false;
				break;
			case VK_DOWN:
				is_move_down = false;
				break;
			case VK_LEFT:
				is_move_left = false;
				break;
			case VK_RIGHT:
				is_move_right = false;
				break;
			}
			break;
		}
	}
	//处理玩家的移动
	void Move()
	{
		int dir_x = is_move_right - is_move_left;
		int dir_y = is_move_up - is_move_down;
		double len_dir = sqrt(dir_x * dir_x + dir_y + dir_y);
		if (len_dir != 0)
		{
			double normalize_x = dir_x / len_dir;
			double normalize_y = dir_y / len_dir;
			position.x += (int)(SPEED * normalize_x);
			position.y += (int)(SPEED * normalize_y);
		}
		//防止玩家走出迷宫
		if (position.x < 0)position.x = 0;
		if (position.y < 0)position.y = 00;
		if (position.x + FRAME_WIDTH > WINDOW_WIDTH) position.x = WINDOW_WIDTH - FRAME_WIDTH;
		if (position.y + FRAME_HEIGHT > WINDOW_HEIGHT) position.y = WINDOW_HEIGHT - FRAME_HEIGHT;
	}
	//处理玩家的图形输出
	void Draw(int delta)
	{
		int pos_shadow_x = position.x + (FRAME_WIDTH / 2 - SHADOW_WIDTH / 2);
		int pos_shadow_y = position.y + FRAME_HEIGHT - 8;
		putimage_alpha(pos_shadow_x, pos_shadow_y, &img_shadow);

		static bool facing_left = false;
		int dir_x = is_move_right - is_move_left;
		if (dir_x < 0)
			facing_left = true;
		else if (dir_x > 0)
			facing_left = false;
		
		if (facing_left)
			anim_left->play(position.x, position.y, delta);
		else
			anim_right->play(position.x, position.y, delta);
	}

private:
	const int SPEED = 3;
	const int FRAME_HEIGHT = 80;//玩家图片高度
	const int FRAME_WIDTH = 80;//玩家图片宽度
	const int SHADOW_WIDTH = 32;//阴影宽度
private:
	IMAGE img_shadow;
	Animation* anim_left;
	Animation* anim_right;
	POINT position = { 500,500 };//初始化玩家的位置
	bool is_move_up = false;
	bool is_move_down = false;
	bool is_move_left = false;
	bool is_move_right = false;
};
int main()
{
	initgraph(1280, 720);

	bool runing = true;
	
	Player player;
	ExMessage msg;
	IMAGE img_background;
	vector<Enemy*> enemy_list;

	loadimage(&img_background, _T("img/background.png"));

	BeginBatchDraw();
	while (runing)
	{
		DWORD start_time = GetTickCount();

		while (peekmessage(&msg))
		{
			player.ProcessEvent(msg);
		}

		player.Move();

		cleardevice();

		putimage(0, 0, &img_background);
		player.Draw(1000 / 144);

		FlushBatchDraw();

		DWORD end_time = GetTickCount();
		DWORD delta_time = end_time - start_time;
		if (delta_time < 1000 / 144)
		{
			Sleep(1000 / 144 - delta_time);
		}
	}

	bool is_move_up = false;
	bool is_move_down = false;
	bool is_move_left = false;
	bool is_move_right = false;

	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/437887.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

VNC 与 虚拟机 保姆级 快速入门图文指导

Time: 2024年3月5日22:31:49 By[ V ]: MemoryErHero 重要的事情先说三遍: 1 虚拟机内无需安装 VNC-Viewer-7.0.1-Windows 2 虚拟机内无需安装 VNC-Viewer-7.0.1-Windows 3 虚拟机内无需安装 VNC-Viewer-7.0.1-Windows 1 VNC 图文安装 流程 ① VNC-Viewer-7.0.1-Windows.e…

ROS 2基础概念#5:执行器(Executor)| ROS 2学习笔记

在ROS 2中&#xff0c;Executor是一个核心概念&#xff0c;负责管理节点&#xff08;Node&#xff09;中的回调函数&#xff0c;如订阅消息的回调、服务请求的回调、定时器回调等。Executor决定了何时以及如何执行这些回调&#xff0c;从而在ROS 2系统中实现异步编程。 ROS 2 …

AD20软件使用指南:拼板操作与Gerber文件生成详解

文章目录 一、前言二、拼板1.创建新的PCB&#xff0c;用于放置拼板文件2.放置拼板阵列3.设置阵列信息4.V割拼板&#xff0c;放置工艺边和定位孔和光点5.完成拼板 三、生成Gerber文件1.输出Gerber文件2.选择单位和格式3.选择输出的图层4.生成Gerber文件5.生成钻孔文件 四、上传嘉…

Mybatis-Plus Mapper映射文件使用

介绍 MyBatis 的真正强大在于它的语句映射&#xff0c;这是它的魔力所在。由于它的异常强大&#xff0c;映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比&#xff0c;你会立即发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本&#xff0…

使用Navicat连接阿里云服务器上的MySQL数据库

打开navicat&#xff0c;连接如下&#xff1a; 服务器的默认密码是 root 连接时出现 使用 ls 查找 /etc/my.cnf ls /etc/my.cnf 用vi打开my.cnf&#xff1a; vi /etc/my.cnf看看是否有绑定本地回环地址的配置&#xff0c;如果有&#xff0c;注释掉下面这段文字&#xff1a;…

几何工具的使用

Geometry - Creation 创建几何 CogCreateCircleTool&#xff1a;创建圆CogCreateEllipseTool:创建椭圆CogCreateLineBisectPointsTool&#xff1a;带有两个点的平行线CogCreateLineParallelTool:在某一点创建某条线的平行线CogCreateLinePerpendicularTool:在某一点创建某条线…

数据备份:守护你的数字资产,安全无忧!

一、数据备份&#xff1a;数字时代的“保险箱” 在数字化日益盛行的今天&#xff0c;我们的工作、学习和生活都离不开各种电子设备。无论是电脑中的文档、图片&#xff0c;还是手机里的联系人、短信&#xff0c;都承载着我们的重要信息和回忆。然而&#xff0c;电子设备并非永…

Vector Search和专用Search Nodes:现已正式发布

我们非常高兴地推出了 Atlas Vector Search 和 Search Nodes 的正式发布版本 (GA)&#xff0c;为 Atlas 平台增添了更多价值。 自从在公开预览版中发布 Atlas Vector Search 和带有 Search Nodes 的专用基础架构以来&#xff0c;我们注意到&#xff0c;对于使用向量优化搜索节…

WEB自动化测试----------Webdriver API 的使用

&#x1f525; 交流讨论&#xff1a;欢迎加入我们一起学习&#xff01; &#x1f525; 资源分享&#xff1a;耗时200小时精选的「软件测试」资料包 &#x1f525; 教程推荐&#xff1a;火遍全网的《软件测试》教程 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1…

0x04_数组_指针_字符串

数组 数组的定义与使用 数组是具有一定顺序关系的若干相同类型变量的集合体&#xff0c;组成数组的变量称为该数组的元素。 给出下面程序的输出&#xff1a; #include <iostream> using namespace std; int main() {int a[10], b[10];for(int i 0; i < 10; i) {a[…

LeetCode刷题---二叉树展开为链表

官方题解&#xff1a;LeetCode官方题解 解题思想&#xff1a; 当根节点不为空时&#xff0c;从二叉树根节点开始遍历 判断当前节点是否有左节点&#xff0c;如果不存在左节点&#xff0c;则当前节点向右移一位 如果存在左节点&#xff0c;创建辅助节点指向左节点&#xff0c;判…

万字长文讲解Golang pprof 的使用

往期好文推荐 ⭐️⭐️⭐️: # golang pprof 监控系列(1) —— go trace 统计原理与使用 # golang pprof监控系列&#xff08;2&#xff09; —— memory&#xff0c;block&#xff0c;mutex 使用 # golang pprof 监控系列(3) —— memory&#xff0c;block&#xff0c;mute…

第三百八十八回

文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了DateRangePickerDialog Widget相关的内容,本章回中将介绍Radio Widget.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在这里说的Radio Widget是指单选按钮&#xff0c;没有选中时是圆形边框&#x…

小白在VMware Workstation Pro上安装部署SinoDB V16.8

一、安装环境说明 CPU&#xff1a;2核或以上&#xff0c;内存&#xff1a;2G或以上&#xff1b;磁盘10G或以上&#xff1b;网卡&#xff1a;千兆 1.1检查服务器内存大小 命令&#xff1a;free -m 1.2检查服务器磁盘空间大小 命令&#xff1a;df -h 1.3检查服务器网络配置信息 命…

Python Tkinter GUI 基本概念

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd;如果停止&#xff0c;就是低谷&#xf…

VM内存结构和垃圾回收机制

引言 在计算机科学中&#xff0c;虚拟机&#xff08;VM&#xff09;是一个重要的概念&#xff0c;它允许程序在硬件平台之上运行。虚拟机模拟真实机器的行为&#xff0c;为程序提供了一个独立的运行环境。本文将深入探讨VM的内存结构和垃圾回收机制&#xff0c;以帮助读者更好…

“python -m experiments.cifar10_test“是什么意思

具体解释如下&#xff1a; "python" 是运行 Python 解释器的命令。"-m" 是一个选项&#xff0c;用于指定要运行的模块。"experiments.cifar10_test" 是要运行的 Python 模块的名称。 其中 虽说main.py文件在上一级目录中&#xff0c;仍然可以在…

计算阶梯数 Python

题目描述 爱因斯坦曾出过这样一道有趣的数学题&#xff1a; 有一个长阶梯&#xff0c; 若每步上2阶&#xff0c;最后剩1阶&#xff1b; 若每步上3阶&#xff0c;最后剩2阶&#xff1b; 若每步上5阶&#xff0c;最后剩4阶&#xff1b; 若每步上6阶&#xff0c;最后剩5阶&#xf…

一文教会你Jenkins 主从模式实现分布式自动化测试

背景 日常构建Jenkins任务中&#xff0c;会经常出现下面的情况&#xff1a; &#xff08;1&#xff09;自动化测试执行需要消耗大量的 CPU 和内存资源&#xff0c;如果服务器上还有其他的服务&#xff0c;可能会造成卡顿或者宕机这样的情况&#xff1b; &#xff08;2&#…

基于R语言lavaan的SEM在复杂统计建模中的科研技术新突破

此外&#xff0c;我们还将深入探讨R语言的基础知识、结构方程模型的基本原理、lavaan程序包的使用方法等内容。无论是潜变量分析、复合变量分析&#xff0c;还是非线性/非正态/缺失数据处理、分类变量分析、分组数据处理等复杂问题&#xff0c;我们都将一一为您解析。 希望通过…