能帮到你的话,就给个赞吧 😘
文章目录
- util.h
- util.cpp
- platform.h
- platform.cpp
- main.cpp
- gameScene.h
- gameScene.cpp
util.h
#pragma once
#include <graphics.h>
#include "camera.h"void flipImage(IMAGE* src, IMAGE* dst);void putImageAlpha(int x, int y, IMAGE* img);		//图像绘制(透明度)//裁剪任意位置的图并显示//在(dst_x, dst_y) 处 显示 (src_x, src_y), w, h 的 图
void putImageAlpha(int dst_x, int dst_y, int width, int height, IMAGE* img, int src_x, int src_y);void putLine(int x1, int y1, int x2, int y2);
util.cpp
#include "util.h"
#pragma comment(lib, "MSIMG32.LIB")		//AlphaBlendvoid flipImage(IMAGE* src, IMAGE* dst){int height = src->getheight();int width = src->getwidth();Resize(dst, width, height);auto srcPixels = GetImageBuffer(src);auto dstPixels = GetImageBuffer(dst);for (int h = 0; h < height; h++)for (int w = 0; w < width; w++)dstPixels[h * width + w] = srcPixels[h * width + width - 1 - w];
}void putImageAlpha(int x, int y, IMAGE* img) {int w = img->getwidth();int h = img->getheight();auto cameraX = Camera::getCamera().getPostion().x;auto cameraY = Camera::getCamera().getPostion().y;AlphaBlend(GetImageHDC(nullptr), x - cameraX, y - cameraY, w, h,GetImageHDC(img), 0, 0, w, h, { AC_SRC_OVER,0,255, AC_SRC_ALPHA });
}//在(dst_x, dst_y) 处 显示 (src_x, src_y), w, h 的 图
void putImageAlpha(int dst_x, int dst_y, int width, int height, IMAGE* img,int src_x, int src_y){int w = width;int h = height;//将(src_x, src_y), w, h 的图像 复制到 (dst_x, dst_y)处AlphaBlend(GetImageHDC(GetWorkingImage()), dst_x, dst_y, w, h,GetImageHDC(img), src_x, src_y, w, h, { AC_SRC_OVER, 0, 255, AC_SRC_ALPHA });
}void putLine(int x1, int y1, int x2, int y2){auto cameraX = Camera::getCamera().getPostion().x;auto cameraY = Camera::getCamera().getPostion().y;line(x1 - cameraX, y1 - cameraY, x2 - cameraX, y2 - cameraY);
}platform.h
#pragma once
#include <graphics.h>
#include "camera.h"
#include "util.h"extern bool isDebug;class Platform {//碰撞箱为一条直线struct CollisionShape{float y;			//线的高度float left, right;	//线的左右端点};public://渲染数据IMAGE* img = nullptr;POINT renderPos = { 0 };//碰撞数据CollisionShape shape;	//平台碰撞箱
public:void render() const;
};
platform.cpp
#include "platform.h"void Platform::render() const{putImageAlpha(renderPos.x, renderPos.y, img);if (isDebug) {setlinecolor(RGB(255, 0, 0));putLine(shape.left, shape.y, shape.right, shape.y);}
}main.cpp
#include <Windows.h>		//windows要放在graphics之前
#include <graphics.h>
#include "menuScene.h"
#include "gameScene.h"
#include "selectorScene.h"
#include "sceneManager.h"
#include "util.h"
#include "atlas.h"
#include "platform.h"
#include <iostream>
using namespace std;#pragma comment(lib, "Winmm.lib")	//mciSendStringbool isDebug = false;IMAGE	imgMenuBackground;IMAGE	imgVS;										//VS艺术字IMAGE	img1P;										//文本
IMAGE	img2P;
IMAGE	img1PDesc;									//键位描述
IMAGE	img2PDesc;IMAGE	imgGraveStoneLeft;							//向左墓碑
IMAGE	imgGraveStoneRight;
IMAGE	imgSelectorTip;								//选择提示
IMAGE	imgSelectorBackground;IMAGE	img1PSelectorButtonIdleLeft;				//1P向左选择按钮默认
IMAGE	img1PSelectorButtonIdleRight;
IMAGE	img1PSelectorButtonDownLeft;
IMAGE	img1PSelectorButtonDownRight;				//1P向左选择按钮按下IMAGE	img2PSelectorButtonIdleLeft;
IMAGE	img2PSelectorButtonIdleRight;
IMAGE	img2PSelectorButtonDownLeft;
IMAGE	img2PSelectorButtonDownRight;IMAGE	imgPeaShooterSelectorBackgroundLeft;		//豌豆向左选择界面
IMAGE	imgPeaShooterSelectorBackgroundRight;
IMAGE	imgSunFlowerSelectorBackgroundLeft;			//向日葵向左选择界面
IMAGE	imgSunFlowerSelectorBackgroundRight;IMAGE	imgSky;										//天空
IMAGE	imgHills;									//山脉
IMAGE	imgLargePlatform;							//平台
IMAGE	imgSmallPlatform;IMAGE	img1PCursor;
IMAGE	img2PCursor;Atlas	atlasPeaShooterIdleLeft;			//豌豆向左
Atlas	atlasPeaShooterIdleRight;
Atlas	atlasPeaShooterRunLeft;
Atlas	atlasPeaShooterRunRight;
Atlas	atlasPeaShooterAttackExLeft;		//豌豆向左特殊攻击
Atlas	atlasPeaShooterAttackExRight;
Atlas	atlasPeaShooterDieLeft;				//向左死亡
Atlas	atlasPeaShooterDieRight;Atlas	atlasSunFlowerIdleLeft;				//向日葵
Atlas	atlasSunFlowerIdleRight;
Atlas	atlasSunFlowerRunLeft;
Atlas	atlasSunFlowerRunRight;
Atlas	atlasSunFlowerAttackExLeft;
Atlas	atlasSunFlowerAttackExRight;
Atlas	atlasSunFlowerDieLeft;
Atlas	atlasSunFlowerDieRight;IMAGE	imgPea;								//豌豆
Atlas	atlasPeaBreak;
Atlas	atlasSun;
Atlas	atlasSunExplode;					//太阳爆炸
Atlas	atlasSunEX;							//特殊动画
Atlas	atlasSunEXExplode;					//特殊爆炸
Atlas	atlasSunText;						//文本动画Atlas	atlasRunEffect;						//奔跑特效
Atlas	atlasJumpEffect;
Atlas	atlasLandEffect;IMAGE	img1PWinner;						//1P获胜文本
IMAGE	img2PWinner;
IMAGE	imgWinnerBar;						//获胜背景IMAGE	imgPeaShooterAvatar;				//豌豆头像
IMAGE	imgSunFlowerAvatar;					//向日葵头像//场景与场景管理器互相引用
Scene* menuScene = new MenuScene;
Scene* gameScene = new GameScene;
Scene* selectorScene = new SelectorScene;SceneManager sceneManager;vector<Platform> platforms;void flipAtlas(Atlas& src, Atlas& dst) {dst.clear();for (int i = 0; i < src.getSize(); i++) {IMAGE img;flipImage(src.getImage(i), &img);dst.addImage(img);}}void loadResources() {//加载字体//将 IPix.ttf" 加载到系统字体中,并将其设置为私有字体。AddFontResourceEx(_T("resources/IPix.ttf"), FR_PRIVATE, nullptr);//加载图片loadimage(&imgMenuBackground, _T("resources/menu_background.png"));loadimage(&imgVS, _T("resources/VS.png"));loadimage(&img1P, _T("resources/1P.png"));loadimage(&img2P, _T("resources/2P.png"));loadimage(&img1PDesc, _T("resources/1P_desc.png"));loadimage(&img2PDesc, _T("resources/2P_desc.png"));loadimage(&imgGraveStoneRight, _T("resources/gravestone.png"));flipImage(&imgGraveStoneRight, &imgGraveStoneLeft);loadimage(&imgSelectorTip, _T("resources/selector_tip.png"));loadimage(&imgSelectorBackground, _T("resources/selector_background.png"));loadimage(&img1PSelectorButtonIdleRight, _T("resources/1P_selector_btn_idle.png"));flipImage(&img1PSelectorButtonIdleRight, &img1PSelectorButtonIdleLeft);loadimage(&img1PSelectorButtonDownRight, _T("resources/1P_selector_btn_down.png"));flipImage(&img1PSelectorButtonDownRight, &img1PSelectorButtonDownLeft);loadimage(&img2PSelectorButtonIdleRight, _T("resources/2P_selector_btn_idle.png"));flipImage(&img2PSelectorButtonIdleRight, &img2PSelectorButtonIdleLeft);loadimage(&img2PSelectorButtonDownRight, _T("resources/2P_selector_btn_down.png"));flipImage(&img2PSelectorButtonDownRight, &img2PSelectorButtonDownLeft);loadimage(&imgPeaShooterSelectorBackgroundRight, _T("resources/peashooter_selector_background.png"));flipImage(&imgPeaShooterSelectorBackgroundRight, &imgPeaShooterSelectorBackgroundLeft);loadimage(&imgSunFlowerSelectorBackgroundRight, _T("resources/sunflower_selector_background.png"));flipImage(&imgSunFlowerSelectorBackgroundRight, &imgSunFlowerSelectorBackgroundLeft);loadimage(&imgSky, _T("resources/sky.png"));loadimage(&imgHills, _T("resources/hills.png"));loadimage(&imgLargePlatform, _T("resources/platform_large.png"));loadimage(&imgSmallPlatform, _T("resources/platform_small.png"));loadimage(&img1PCursor, _T("resources/1P_cursor.png"));loadimage(&img2PCursor, _T("resources/2P_cursor.png"));//豌豆射手atlasPeaShooterIdleRight.loadImages(_T("resources/peashooter_idle_%d.png"), 9);flipAtlas(atlasPeaShooterIdleRight, atlasPeaShooterIdleLeft);atlasPeaShooterRunRight.loadImages(_T("resources/peashooter_run_%d.png"), 5);flipAtlas(atlasPeaShooterRunRight, atlasPeaShooterRunLeft);atlasPeaShooterAttackExRight.loadImages(_T("resources/peashooter_attack_ex_%d.png"), 3);flipAtlas(atlasPeaShooterAttackExRight, atlasPeaShooterAttackExLeft);atlasPeaShooterDieRight.loadImages(_T("resources/peashooter_die_%d.png"), 4);flipAtlas(atlasPeaShooterDieRight, atlasPeaShooterDieLeft);//向日葵atlasSunFlowerIdleRight.loadImages(_T("resources/sunflower_idle_%d.png"), 8);flipAtlas(atlasSunFlowerIdleRight, atlasSunFlowerIdleLeft);atlasSunFlowerRunRight.loadImages(_T("resources/sunflower_run_%d.png"), 5);flipAtlas(atlasSunFlowerRunRight, atlasSunFlowerRunLeft);atlasSunFlowerAttackExRight.loadImages(_T("resources/sunflower_attack_ex_%d.png"), 9);flipAtlas(atlasSunFlowerAttackExRight, atlasSunFlowerAttackExLeft);atlasSunFlowerDieRight.loadImages(_T("resources/sunflower_die_%d.png"), 2);flipAtlas(atlasSunFlowerDieRight, atlasSunFlowerDieLeft);loadimage(&imgPea, _T("resources/pea.png"));atlasPeaBreak.loadImages(_T("resources/pea_break_%d.png"), 3);atlasSun.loadImages(_T("resources/sun_%d.png"), 5);atlasSunExplode.loadImages(_T("resources/sun_explode_%d.png"), 5);atlasSunEX.loadImages(_T("resources/sun_ex_%d.png"), 5);atlasSunEXExplode.loadImages(_T("resources/sun_ex_explode_%d.png"), 5);atlasSunText.loadImages(_T("resources/sun_text_%d.png"), 6);atlasRunEffect.loadImages(_T("resources/run_effect_%d.png"), 4);atlasJumpEffect.loadImages(_T("resources/jump_effect_%d.png"), 5);atlasLandEffect.loadImages(_T("resources/land_effect_%d.png"), 2);loadimage(&img1PWinner, _T("resources/1P_winner.png"));loadimage(&img2PWinner, _T("resources/2P_winner.png"));loadimage(&imgWinnerBar, _T("resources/winnner_bar.png"));loadimage(&imgPeaShooterAvatar, _T("resources/avatar_peashooter.png"));loadimage(&imgSunFlowerAvatar, _T("resources/avatar_sunflower.png"));
//加载音乐mciSendString(_T("open resources/bgm_game.mp3 alias bgmGame"), nullptr, 0, nullptr);mciSendString(_T("open resources/bgm_menu.mp3 alias bgmMenu"), nullptr, 0, nullptr);mciSendString(_T("open resources/pea_break_1.mp3 alias peaBreak1"), nullptr, 0, nullptr);mciSendString(_T("open resources/pea_break_2.mp3 alias peaBreak2"), nullptr, 0, nullptr);mciSendString(_T("open resources/pea_break_3.mp3 alias peaBreak3"), nullptr, 0, nullptr);mciSendString(_T("open resources/pea_shoot_1.mp3 alias peaShoot1"), nullptr, 0, nullptr);mciSendString(_T("open resources/pea_shoot_2.mp3 alias peaShoot2"), nullptr, 0, nullptr);mciSendString(_T("open resources/pea_shoot_ex.mp3 alias peaShootEx"), nullptr, 0, nullptr);mciSendString(_T("open resources/sun_explode.mp3 alias sunExplode"), nullptr, 0, nullptr);mciSendString(_T("open resources/sun_explode_ex.mp3 alias sunExplodeEx"), nullptr, 0, nullptr);mciSendString(_T("open resources/sun_text.mp3 alias sunText"), nullptr, 0, nullptr);mciSendString(_T("open resources/ui_confirm.wav alias uiConfirm"), nullptr, 0, nullptr);mciSendString(_T("open resources/ui_switch.wav alias uiSwitch"), nullptr, 0, nullptr);mciSendString(_T("open resources/ui_win.wav alias uiWin"), nullptr, 0, nullptr);
}int main() {//加载资源loadResources();//初始化管理器	sceneManager.setSceneManager(menuScene);ExMessage msg;const int FPS = 1000 / 60;initgraph(1280, 720, EW_SHOWCONSOLE);	//EW_SHOWCONSOLE//设置文本样式//要在initgraph才能设置settextstyle(28, 0, _T("IPix"));setbkmode(TRANSPARENT);BeginBatchDraw();while (1) {	auto startTime = GetTickCount64();//接收消息if(peekmessage(&msg))sceneManager.receiveInput(msg);//管理器运行的时间static auto managerLastTime = GetTickCount64();auto managerCurrentTime = GetTickCount64();sceneManager.update(managerCurrentTime - managerLastTime);managerLastTime = managerCurrentTime;cleardevice();//渲染sceneManager.render();FlushBatchDraw();//hertzauto excutionTime = GetTickCount64() - startTime;if (excutionTime < FPS)Sleep(FPS - excutionTime);}EndBatchDraw();//释放资源delete menuScene;delete gameScene;	}
gameScene.h
#pragma once
#include "scene.h"
#include "sceneManager.h"
#include "util.h"
#include "platform.h"extern IMAGE imgSky;									//天空
extern IMAGE imgHills;									//山脉
extern IMAGE imgLargePlatform;							//平台
extern IMAGE imgSmallPlatform;extern SceneManager sceneManager;
extern std::vector<Platform> platforms;class GameScene :public Scene {public:virtual void enter();								//场景进入——初始化所有场景对象virtual void exit();								//退出virtual void receiveInput(const ExMessage& msg);	//输入virtual void update(int runTimeMs);					//场景更新——让场景运行的时间virtual void render();								//渲染private://天空山脉 世界坐标POINT posImgSky = { 0 };						POINT posImgHills = { 0 };
};
gameScene.cpp
#include "gameScene.h"
#include <iostream>
#include "sceneManager.h"void GameScene::enter(){int xWindow = getwidth(), yWindow = getheight();//窗口居中posImgSky.x = (xWindow - imgSky.getwidth()) / 2,posImgSky.y = (yWindow - imgSky.getheight()) / 2;posImgHills.x = (xWindow - imgHills.getwidth()) / 2,posImgHills.y = (yWindow - imgHills.getheight()) / 2;//初始化平台platforms.resize(4);//largeauto& largePlatform = platforms[0];largePlatform.img = &imgLargePlatform;largePlatform.renderPos.x = 122, largePlatform.renderPos.y = 455;//碰撞箱 一般 位于 渲染图内部偏上largePlatform.shape.left = largePlatform.renderPos.x + 30,largePlatform.shape.right = largePlatform.renderPos.x + largePlatform.img->getwidth() - 30,largePlatform.shape.y = largePlatform.renderPos.y + 60;//small1auto& smallPlatform1 = platforms[1];smallPlatform1.img = &imgSmallPlatform;smallPlatform1.renderPos.x = 175, smallPlatform1.renderPos.y = 360;smallPlatform1.shape.left = smallPlatform1.renderPos.x + 40,smallPlatform1.shape.right = smallPlatform1.renderPos.x + smallPlatform1.img->getwidth() - 40,smallPlatform1.shape.y = smallPlatform1.renderPos.y + smallPlatform1.img->getheight() / 2;//small2auto& smallPlatform2 = platforms[2];smallPlatform2.img = &imgSmallPlatform;smallPlatform2.renderPos.x = 855, smallPlatform2.renderPos.y = 360;smallPlatform2.shape.left = smallPlatform2.renderPos.x + 40,smallPlatform2.shape.right = smallPlatform2.renderPos.x + smallPlatform2.img->getwidth() - 40,smallPlatform2.shape.y = smallPlatform2.renderPos.y + smallPlatform2.img->getheight() / 2;//small3auto& smallPlatform3 = platforms[3];smallPlatform3.img = &imgSmallPlatform;smallPlatform3.renderPos.x = 515, smallPlatform3.renderPos.y = 225;smallPlatform3.shape.left = smallPlatform3.renderPos.x + 40,smallPlatform3.shape.right = smallPlatform3.renderPos.x + smallPlatform3.img->getwidth() - 40,smallPlatform3.shape.y = smallPlatform3.renderPos.y + smallPlatform3.img->getheight() / 2;
}void GameScene::exit() {}void GameScene::receiveInput(const ExMessage& msg){switch (msg.message){case WM_KEYUP://qif (msg.vkcode == 0x51)isDebug = !isDebug;break;default:break;}
}void GameScene::update(int runTimeMs){}void GameScene::render(){putImageAlpha(posImgSky.x, posImgSky.y, &imgSky);putImageAlpha(posImgHills.x, posImgHills.y, &imgHills);for (const auto& platform : platforms)platform.render();if (isDebug) {settextcolor(RGB(255, 0, 0));outtextxy(15, 15, _T("调试模式已开启,按q关闭"));}
}