第十章 俄罗斯方块(基本完成 留档)

main.h

#include "Game.h"

int main()
{
	Game tetris;
	while (tetris.window.isOpen())
	{
		tetris.gameRun();
	}
	return 0;
}

Game.h

#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <windows.h>
#include <iostream>
#include <sstream>
#include "Tetris.h"
using namespace sf;

class Game
{
public:
	Game();
	~Game();
	sf::RenderWindow window;

	Tetris player1, player2;
	bool gameOver, gameQuit;
	Clock clock;
	int Window_width, Window_height, stageWidth, stageHeight;
	bool isGameBegin;   //--------->游戏是否开始
	int isGameOverState; //--------->游戏结束的状态 
	Vector2i mCornPoint;     //游戏区域位置
	int gridSize;     //块的大小
	int imgBGno, imgSkinNo;
	Texture tTiles;
	Texture tBackground, tButtons, tSwitcher, tFrame, tCover, tScore, tGameOver; //创建纹理对象
	Sprite sTiles;
	Sprite  sBackground, sButtons, sSwitcher, sFrame, sCover, sScore, sGameOver; //创建精灵对象
	IntRect ButtonRectStart, ButtonRectHold, ButtonRectLeft, ButtonRectRight;
	int ButtonState_Start, ButtonState_Hold;
	SoundBuffer sbWin;
	Sound soundWin;
	Music bgMusic;

	Clock gameClock;

	void gameInitial();
	void LoadMediaData();

	void gameInput();
	void gameLogic();
	void gameDraw();
	void gameRun();
};

Game.cpp

#include "Game.h"
Game::Game()
{
	Window_width = 1350;
	Window_height = 1000;

	imgBGno = 1;
	imgSkinNo = 1;
	window.create(sf::VideoMode(Window_width, Window_height), L"Tetris");
}

Game::~Game()
{

}

void Game::gameInitial()
{
	window.setFramerateLimit(15);  //设置游戏帧频
	LoadMediaData();

	player1.role = rolePLAYER1;     //定义Tetris对象为player1
	player2.role = rolePLAYER2;     //定义Tetris对象为player2
	player1.Initial(&tTiles);       //将方块的素材传给Tetris对象, 由Tetris对象绘制方块
	player2.Initial(&tTiles);
}
void Game::LoadMediaData()
{
	std::stringstream ss;
	ss << "data/images/bg" << imgBGno << ".jpg";
	if (!tBackground.loadFromFile(ss.str()))//加载纹理图片
		std::cout << "BK image 没有找到" << std::endl;
	ss.str("");//清空字符串

	ss << "data/images/tiles" << imgSkinNo << ".jpg";
	if (!tTiles.loadFromFile(ss.str()))//加载纹理图片
		std::cout << "tiles image 没有找到" << std::endl;
	if (!tFrame.loadFromFile("data/images/frame.png"))//加载纹理照片
		std::cout << "tFrame image 没有找到" << std::endl;
	if (!tCover.loadFromFile("data/images/cover.png"))//加载纹理照片
		std::cout << "tCover image 没有找到" << std::endl;
	if (!tGameOver.loadFromFile("data/images/end.png"))//加载纹理照片
		std::cout << "tGameOver image 没有找到" << std::endl;

	sBackground.setTexture(tBackground);//设置精灵对象的纹理
	//sTiles.setTexture(tTiles);     //由Tetris对象绘制方块,两个玩家各自绘自己的方块
	sFrame.setTexture(tFrame);
	sCover.setTexture(tCover);
	sGameOver.setTexture(tGameOver);
}

void Game::gameInput()
{
	sf::Event event;
	window.setKeyRepeatEnabled(false);//按键按下只相应一次
	while (window.pollEvent(event))
	{
		if (event.type == sf::Event::Closed)
		{
			window.close();
			gameQuit = true;
		}

		player1.Iuput(event);
		player2.Iuput(event);

	}
}
void Game::gameLogic()
{
	float time = clock.getElapsedTime().asSeconds();
	clock.restart();
	player1.timer += time;
	player2.timer += time;

	player1.Logic();
	player2.Logic();
}
void Game::gameDraw()
{
	window.clear();//	清屏
	//绘制背景
	sBackground.setPosition(0, 0);
	window.draw(sBackground);
	window.draw(sFrame);
	player1.Draw(&window);
	player2.Draw(&window);

	window.display();
}
void Game::gameRun()
{
	do 
	{
		gameInitial();
		while (window.isOpen() && gameOver == false)
		{
			gameInput();
			gameLogic();
			gameDraw();
		}
	} while (!gameQuit);
}

Tetris.h

#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include <windows.h>
#include <iostream>
#include <sstream>
#define  GRIDSIZE    35
#define STAGE_WIDTH  10
#define STAGE_HEIGHT 20
#define P1_STAGE_CORNER_X   156
#define P1_STAGE_CORNER_Y   174
#define P2_STAGE_CORNER_X   844
#define P2_STAGE_CORNER_Y   174
typedef enum PLAYROLE {
	roleNONE,    //空
	rolePLAYER1, //玩家1
	rolePLAYER2, //玩家2
};
using namespace sf;

class Tetris
{
public:
	Tetris();
	~Tetris();
	Vector2i mCornPoint;  //游戏区域位置
	int role;
	int gridSize;     //块的大小
	int imgBGno, imgSkinNo;
	Texture *tTiles;
	Texture tBackground, tButtons, tNum, tTimer, tCounter, tGameOver; //创建纹理对象
	Sprite  sBackground, sTiles, sButtons, sNum, sTimer, sCounter, sGameOver;   //创建精灵对象

	int Field[STAGE_HEIGHT][STAGE_HEIGHT] = { 0 };
	Vector2i currentSquare[4], nextSquare[4], holdSquare[4], tempSquare[4];
	int Figures[7][4] =
	{
		3,5,1,7, //I
		4,5,2,7, //S
		4,5,3,6, //Z
		5,3,4,7, //T
		3,5,2,7, //L
		7,5,3,6, //J
		2,3,4,5, //O
	};
	int dx;
	bool rotate;
	int colorNum;
	float timer, delay;

	void Initial(Texture *tex);
	void Iuput(sf::Event event);
	void Logic();
	void Draw(sf::RenderWindow* window);
	bool hitTest();



};

Tetris.cpp

#include "Tetris.h"

Tetris::Tetris()
{
	dx = 0; //  X方向偏移量 
	rotate = false;  //是否旋转
	colorNum = 1;    //色块的颜色
	timer = 0;       //计时间隔
	delay = 0.3;      //方块下落的速度
}

Tetris::~Tetris()
{

}


void Tetris::Initial(Texture *tex)
{
	tTiles = tex;
	if (role == rolePLAYER1)
	{
		mCornPoint = { P1_STAGE_CORNER_X,P1_STAGE_CORNER_Y };
	}
	if (role == rolePLAYER2)
	{
		mCornPoint = { P2_STAGE_CORNER_X,P2_STAGE_CORNER_Y };
	}
	sTiles.setTexture(*tTiles);
	//初始化方块图形
	colorNum = 1 + rand() % 7;
	int n = rand() % 7;
	for (int i = 0; i < 4; i++)
	{
		currentSquare[i].x = Figures[n][i] % 2;
		currentSquare[i].y = Figures[n][i] / 2;
	}
}
void Tetris::Iuput(sf::Event event)
{
	if (role == rolePLAYER1)//玩家1的按键响应
	{
		if (event.type == Event::KeyPressed)
		{
			if (event.key.code == Keyboard::W)
				rotate = true;
			if (event.key.code == Keyboard::A)
				dx = -1;
			else if (event.key.code == Keyboard::D)
				dx = 1;
			if (event.key.code == Keyboard::S)
				delay = 0.05;
		}
		if (event.type == Event::KeyReleased)
		{
			if (event.key.code == Keyboard::A || event.key.code == Keyboard::D)
				dx = 0;
			if (event.key.code == Keyboard::S)
				delay = 0.3;
		}
	}
	if (role == rolePLAYER2)
	{
		if (event.type == Event::KeyPressed)
		{
			if (event.key.code == Keyboard::Up)
				rotate = true;
			if (event.key.code == Keyboard::Left)
				dx = -1;
			else if (event.key.code == Keyboard::Right)
				dx = 1;
			if (event.key.code == Keyboard::Down)
				delay = 0.05;
		}
		if (event.type == Event::KeyReleased)
		{
			if (event.key.code == Keyboard::Left || event.key.code == Keyboard::Right)
				dx = 0;
			if (event.key.code == Keyboard::Down)
				delay = 0.3;   //时间响应间隔变大,方块下降速度变慢
		}
	}
}
void Tetris::Logic()
{
	///<- 水平 Move ->///
	for (int i = 0; i < 4; i++)
	{
		tempSquare[i] = currentSquare[i];
		currentSquare[i].x += dx;
	}
	if (!hitTest())//如果撞上了
		for (int i = 0; i < 4; i++)
			currentSquare[i] = tempSquare[i];//方块左右如果有障碍,则不能向障碍方向移动
	///<- 旋转 rotate ->///
	if (rotate)
	{
		Vector2i p = currentSquare[1];  //设置旋转中心点
		for (int i = 0; i < 4; i++)
		{//顺时针旋转90度
			int x = currentSquare[i].y - p.y;//原Y方向距离中心点的差值,作为新的差值, 传递给X方向
			int y = currentSquare[i].x - p.x;//原X方向距离中心点的差值,作为新的差值, 传递给Y方向
			currentSquare[i].x = p.x - x;//新坐标X=中心点坐标-新的X方向差值
			currentSquare[i].y = p.y - y;//新坐标Y=中心点坐标-新的Y方向差值
		}
		if (!hitTest())//如果撞上了
			for (int i = 0; i < 4; i++)
				currentSquare[i] = tempSquare[i];
	}
	///<- Tick 下落 ->///
	if (timer > delay)
	{
		for (int i = 0; i < 4; i++)
		{
			tempSquare[i] = currentSquare[i];
			currentSquare[i].y += 1;
		}
		if (!hitTest())//如果撞上了
		{
			for (int i = 0; i < 4; i++)
				Field[tempSquare[i].y][tempSquare[i].x] = colorNum;

			colorNum = 1 + rand() % 7;
			int n = rand() % 7;
			for (int i = 0; i < 4; i++ )
			{
				currentSquare[i].x = Figures[n][i] % 2;
				currentSquare[i].y = Figures[n][i] / 2;
			}
		}
		timer = 0;
	}	
    ///<- check lines 消行 ->///
	int k = STAGE_HEIGHT - 1;
	for (int i = STAGE_HEIGHT - 1; i>0;i--)
	{
		int count = 0;
		for (int j= 0; j < STAGE_WIDTH; j++)
		{
			if (Field[i][j])
				count++;
			Field[k][j] = Field[i][j];
		}
		if (count < STAGE_WIDTH)
			k--;
	}
	rotate = 0;
}
void Tetris::Draw(sf::RenderWindow* window)
{
	//绘制固定的方块
	for (int i = 0; i < STAGE_HEIGHT; i++)
		for (int j = 0; j < STAGE_WIDTH; j++)
		{
			if (Field[i][j] == 0)
			     continue;   //无方块的地方,即空地,则略过
			sTiles.setTextureRect(IntRect(Field[i][j] * GRIDSIZE, 0, GRIDSIZE, GRIDSIZE));
			sTiles.setPosition(j * GRIDSIZE, i * GRIDSIZE);
			sTiles.move(mCornPoint.x, mCornPoint.y);   //offset设置偏移量
			window->draw(sTiles);
		 }
	//绘制活动的方块
	for (int i = 0; i < 4; i++)
	{
			sTiles.setTextureRect(IntRect(colorNum * GRIDSIZE, 0, GRIDSIZE, GRIDSIZE));
			sTiles.setPosition(currentSquare[i].x * GRIDSIZE, currentSquare[i].y * GRIDSIZE);
			sTiles.move(mCornPoint.x, mCornPoint.y);   //offset设置偏移量
			window->draw(sTiles);
	}
}
bool  Tetris::hitTest()
{
	for (int i = 0; i < 4; i++)
		if (currentSquare[i].x < 0 || currentSquare[i].x >= STAGE_WIDTH || currentSquare[i].y >= STAGE_HEIGHT)
			return false;
		else if (Field[currentSquare[i].y][currentSquare[i].x])
			return false;

	return true;
}

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值