能帮到你的话,就给个赞吧 😘
文章目录
- 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关闭"));}
}