植物明星大乱斗8


能帮到你的话,就给个赞吧 😘


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")		//AlphaBlend

void 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")	//mciSendString

bool 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();

	//hertz
		auto 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);

	//large
	auto& 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;

	//small1
	auto& 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;

	//small2
	auto& 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;

	//small3
	auto& 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:
		//q
		if (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关闭"));
	}
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值