亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

C++游戲編程教程(五)——項(xiàng)目實(shí)戰(zhàn)

phpmatt / 2243人閱讀

摘要:代碼下載點(diǎn)擊此處下載游戲截圖游戲編寫(xiě)項(xiàng)目框架這個(gè)游戲主要的框架是這樣的其中有三個(gè)類派生自類,兩個(gè)派生自類。用于控制時(shí)間間隔。更新角色位置,并判斷是否與飛機(jī)或子彈碰撞。構(gòu)造函數(shù)初始化成員。

今天,我們來(lái)用所學(xué)知識(shí)做一個(gè)簡(jiǎn)易的飛機(jī)大戰(zhàn)游戲。

游戲介紹

游戲功能

玩家駕駛飛機(jī)在窗口下方左右移動(dòng),按下空格發(fā)射子彈(0.3秒一個(gè)),而上方會(huì)有石塊落下,打中飛機(jī)會(huì)死亡,玩家可以使用子彈攻擊石塊,如果打到了石塊就消失,同時(shí)之后的石塊下落會(huì)加速。屏幕上方還會(huì)有敵人的飛機(jī)出現(xiàn),會(huì)隨機(jī)發(fā)射子彈,還會(huì)隨機(jī)移動(dòng),玩家碰到敵人發(fā)來(lái)的子彈會(huì)死亡,敵人碰到玩家的子彈也會(huì)消失。敵人有20個(gè),隨機(jī)出現(xiàn),同一時(shí)刻屏幕上最多有5個(gè)敵人。玩家消滅所有的敵人就勝利了。

代碼下載

點(diǎn)擊此處下載

游戲截圖


游戲編寫(xiě)

項(xiàng)目框架

這個(gè)游戲主要的框架是這樣的:

其中有三個(gè)類派生自Actor類,兩個(gè)派生自DrawComponent類。

創(chuàng)建項(xiàng)目

首先,用我們的項(xiàng)目模板創(chuàng)建一個(gè)項(xiàng)目。
注意:在所有出現(xiàn)顯示中文內(nèi)容的文件中都應(yīng)該加入一行#pragma execution_character_set("utf-8"),否則是亂碼。

Plane類

這個(gè)類是玩家控制的飛機(jī)類,功能主要有移動(dòng)和發(fā)射子彈。

代碼

Plane.h:

#pragma once#include"Actor.h"class Plane :    public Actor{public:    Plane(class Game* game, const Vector2& pos);    virtual void ActorInput(const uint8_t* keyState);    virtual void UpdateActor(float deltaTime);private:    short mPlaneDir;    Uint32 mTick;};

Plane.cpp:

#include "Plane.h"#include "Bullet.h"#include "DrawRectangleComponent.h"Plane::Plane(Game* game, const Vector2& pos) :Actor(game), mPlaneDir(0){	SetPosition(pos);	mTick = SDL_GetTicks();}void Plane::ActorInput(const uint8_t* keyState){	mPlaneDir = 0;	if (keyState[SDL_SCANCODE_RIGHT])		mPlaneDir += 1;	if (keyState[SDL_SCANCODE_LEFT])		mPlaneDir -= 1;	if (keyState[SDL_SCANCODE_SPACE] && SDL_TICKS_PASSED(SDL_GetTicks(), mTick + 300))//0.3秒發(fā)射一顆子彈	{		mTick = SDL_GetTicks();		Vector2 pos = GetPosition();		pos.x += 20;		pos.y -= 40;		new DrawRectangleComponent(new Bullet(GetGame(), pos, -700), Vector2(10, 20), 255, 0, 0, 0);	}}void Plane::UpdateActor(float deltaTime){	Vector2 pos = GetPosition();	pos.x += mPlaneDir * 300 * deltaTime;	if (pos.x < 0)		pos.x = 0;	if (pos.x > 1024 - 50)		pos.x = 1024 - 50;	SetPosition(pos);}

代碼分析

成員變量

mTick:上次發(fā)射子彈的時(shí)間。用于控制時(shí)間間隔。
mPlaneDir:飛機(jī)移動(dòng)方向。

構(gòu)造函數(shù)

初始化變量。

ActorInput

重寫(xiě)的虛函數(shù)。首先設(shè)置移動(dòng)方向,然后判斷是否按下空格,如果按下就new一個(gè)子彈。

UpdateActor

更新位置。

Stone類

這個(gè)類是石頭類。

代碼

Stone.h:

#pragma once#include"Actor.h"class Stone	:public Actor{public:	Stone(Game* game, const Vector2& pos, float speed);	virtual void UpdateActor(float deltaTime);private:	float mSpeed;};

Stone.cpp:

#include "Stone.h"#include"Bullet.h"#include"Plane.h"#include#pragma execution_character_set("utf-8")Stone::Stone(Game* game, const Vector2& pos, float speed):Actor(game),mSpeed(speed){	SetPosition(pos);}void Stone::UpdateActor(float deltaTime){	Vector2 pos = GetPosition();	pos.y += deltaTime * mSpeed;	if (pos.y > 768)		SetState(EDead);	SetPosition(pos);	for (auto i : GetGame()->mActors)	{		if (typeid(*i) == typeid(Bullet))//運(yùn)行時(shí)類型檢查		{			Vector2 bPos = i->GetPosition();			if (bPos.x + 20 > pos.x && bPos.x < pos.x + 50 && bPos.y < pos.y + 50)			{				SetState(EDead);				i->SetState(EDead);				GetGame()->mStoneSpeed *= 1.02;			}		}		else if (typeid(*i) == typeid(Plane))		{			Vector2 bPos = i->GetPosition();			if (bPos.x + 50 > pos.x && bPos.x < pos.x + 50 && bPos.y < pos.y + 50 && bPos.y + 30>pos.y)			{				SetState(EDead);				i->SetState(EDead);				SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "游戲結(jié)束", "游戲結(jié)束,你輸了!", GetGame()->mWindow);				GetGame()->mIsRunning = false;			}		}	}}

代碼分析

成員變量

mSpeed:速度。

構(gòu)造函數(shù)

初始化變量。

UpdateActor

更新角色位置,并判斷是否與飛機(jī)或子彈碰撞。
其實(shí),這里的代碼我寫(xiě)得非常非常非常非常非常非常非常非常非常非常(注:此處省略 1 0 1000000 10^{1000000} 101000000個(gè)非常)不規(guī)范。為什么呢?因?yàn)榘凑瘴覀兊拇a規(guī)范來(lái)說(shuō),這里應(yīng)該建立一個(gè)專門(mén)的碰撞檢測(cè)組件,并把它加到Actor里,如果簡(jiǎn)單地寫(xiě)在UpdateActor里面,會(huì)使代碼混亂,非常非常非常
(注:此處省略 1 0 1000000 10^{1000000} 101000000個(gè)非常)不便于閱讀和后續(xù)添加代碼。不過(guò)這里比較簡(jiǎn)單 (其實(shí)是我偷懶) ,就將就看吧。

Enemy類

這個(gè)類是敵方飛機(jī)類,它可以自動(dòng)移動(dòng),并且隨機(jī)發(fā)射子彈。其實(shí)這里也寫(xiě)得不太規(guī)范,其實(shí)我們大可不必建這個(gè)類,只需要建立Plane類,并不添加任何代碼,然后建兩個(gè)組件InputComponent和AutoMoveComponent,new對(duì)象的時(shí)候分別加上,這樣可以提高代碼復(fù)用率。在本例中,這個(gè)功能的好處并不明顯,但設(shè)想一下,如果飛機(jī)除了用戶控制和電腦控制之外,還有很多很多其它功能(比如為飛機(jī)添加彈夾和油量屬性),這樣專門(mén)寫(xiě)兩個(gè)類就太麻煩了,不如使用組件。

代碼

Enemy.h:

#pragma once#include "Actor.h"class Enemy :    public Actor{public:    Enemy(Game* game, const Vector2& pos);    virtual void UpdateActor(float deltatime);private:    Uint32 mTicks;    Uint32 mMoveTicks;    short mMove;};

Enemy.cpp:

#include "Enemy.h"#include"Bullet.h"#include"DrawRectangleComponent.h"Enemy::Enemy(Game* game, const Vector2& pos) :Actor(game), mTicks(SDL_GetTicks()), mMoveTicks(SDL_GetTicks()){	SetPosition(pos);	mMove = 200 + rand() % 100;	if (rand() % 2)		mMove = -mMove;}void Enemy::UpdateActor(float deltatime){	Vector2 pos = GetPosition();	if (SDL_TICKS_PASSED(SDL_GetTicks(), mMoveTicks + 1000))//隨機(jī)移動(dòng)位置	{		mMoveTicks = SDL_GetTicks();		mMove = 100 + rand() % 100;		if (rand() % 2)			mMove = -mMove;	}	pos.x += deltatime * mMove;	if (pos.x > 1024 - 50)		pos.x = 1024 - 50;	if (pos.x < 0)		pos.x = 0;	SetPosition(pos);	if (SDL_TICKS_PASSED(SDL_GetTicks(), mTicks + 1000)&&!(rand()%25))//1秒發(fā)射子彈	{		mTicks = SDL_GetTicks();		pos.x += 20;		pos.y += 40;		new DrawRectangleComponent(new Bullet(GetGame(), pos, 700), Vector2(10, 20), 255, 0, 0, 0);	}}

代碼分析

成員變量

mTicks:記錄上一次射擊的時(shí)間。
mMoveTicks:記錄以這個(gè)速度移動(dòng)的時(shí)間(因?yàn)橐S機(jī)移動(dòng),所以需要頻繁更新移動(dòng)速度和方向)。
mMove:移動(dòng)速度。

構(gòu)造函數(shù)

初始化成員。

UpdateActor

先更新隨機(jī)移動(dòng)的速度,然后隨機(jī)移動(dòng)位置,最后發(fā)射子彈(1秒后,每幀有 1 25 /frac{1}{25} 251?幾率發(fā)射子彈)。

Bullet類

這個(gè)類是子彈類。

代碼

Bullet.h:

#pragma once#include "Actor.h"class Bullet :    public Actor{public:    Bullet(class Game* game, const Vector2& pos, float speed);    virtual void UpdateActor(float deltaTime);private:    float mSpeed;};

Bullet.cpp:

#include "Bullet.h"#include"Plane.h"#include"Enemy.h"#include#pragma execution_character_set("utf-8")Bullet::Bullet(Game* game, const Vector2& pos, float speed) :Actor(game), mSpeed(speed){	SetPosition(pos);}void Bullet::UpdateActor(float deltaTime){	Vector2 pos = GetPosition();	pos.y += mSpeed * deltaTime;	SetPosition(pos);	if (pos.y > 768 || pos.y < 0)		SetState(EDead);	for (auto i : GetGame()->mActors)	{		if (typeid(*i) == typeid(Enemy))//運(yùn)行時(shí)類型檢查		{			Vector2 bPos = i->GetPosition();			if (bPos.x - 10 < pos.x && bPos.x + 50 > pos.x && bPos.y + 50 > pos.y)			{				SetState(EDead);				i->SetState(EDead);			}		}		else if (typeid(*i) == typeid(Plane))		{			Vector2 bPos = i->GetPosition();			if (bPos.x - 10 < pos.x && bPos.x + 50 > pos.x && bPos.y < pos.y + 20 && bPos.y + 30 > pos.y)			{				SetState(EDead);				i->SetState(EDead);				SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "游戲結(jié)束", "游戲結(jié)束,你輸了!", GetGame()->mWindow);				GetGame()->mIsRunning = false;			}		}	}}

代碼分析

Bullet類的代碼和Stone類的代碼基本相同,此處不再介紹。

Game類

最后,我們的任務(wù)是修改Game類。
首先,要在Game.cpp中包含所有自定義類的頭文件:

#include "Game.h"#include "SDL_image.h"#include #include "Actor.h"#include"Plane.h"#include"DrawPlaneComponent.h"#include"DrawRectangleComponent.h"#include"Stone.h"#include"Enemy.h"#include #include

接著,在Game.h中加入:

	float mStoneSpeed;//石頭的速度	unsigned short mEnemyCount;//屏幕上敵人數(shù)量	unsigned short mAllEnemyCount;//剩余敵人數(shù)量

并在構(gòu)造函數(shù)里初始化這幾個(gè)變量。
然后,在LoadData函數(shù)里添加:

new DrawPlaneComponent(new Plane(this, Vector2(492, 700)));

new出飛機(jī)對(duì)象。
然后在UpdateGame里添加:

if (!(rand() % 100))	{		new DrawRectangleComponent(new Stone(this, Vector2(rand() % (1024 - 50), 0), mStoneSpeed + rand() % 10), Vector2(50, 50), 255, 255, 0, 0);	}	if (mEnemyCount < 5 && mAllEnemyCount)	{		new DrawPlaneComponent(new Enemy(this, Vector2(rand() % 984, 10)), true);		--mAllEnemyCount;		++mEnemyCount;	}

用來(lái)new出敵人和石頭。
最后,在GenerateOutput函數(shù)里添加:

if (!mAllEnemyCount && !mEnemyCount)	{		SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_INFORMATION, "游戲結(jié)束", "游戲結(jié)束,你贏了!", mWindow);		mIsRunning = false;	}

用來(lái)提示勝利。注:最好添加在SDL_RenderPresent后面,這樣能顯示最后一個(gè)敵人消失的場(chǎng)景,要不然提示結(jié)束的時(shí)候屏幕上還有一個(gè)敵人。

總結(jié)

到現(xiàn)在,整個(gè)的游戲就編寫(xiě)完畢了,效果也就是開(kāi)頭出示的那樣。通過(guò)這個(gè)項(xiàng)目,我們真正體會(huì)到了面向?qū)ο蟮暮锰帲约皩⒊绦蚰K化的重要性。最后,祝大家編程順利,代碼無(wú)bug!
注:博主馬上就要開(kāi)學(xué)了,可能最近無(wú)法更新。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/121856.html

相關(guān)文章

  • SegmentFault 技術(shù)周刊 Vol.40 - 2018,來(lái)學(xué)習(xí)一門(mén)新的編程語(yǔ)言吧!

    摘要:入門(mén),第一個(gè)這是一門(mén)很新的語(yǔ)言,年前后正式公布,算起來(lái)是比較年輕的編程語(yǔ)言了,更重要的是它是面向程序員的函數(shù)式編程語(yǔ)言,它的代碼運(yùn)行在之上。它通過(guò)編輯類工具,帶來(lái)了先進(jìn)的編輯體驗(yàn),增強(qiáng)了語(yǔ)言服務(wù)。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺(jué)已經(jīng)到來(lái)了,總結(jié)過(guò)去的 2017,相信小伙們一定有很多收獲...

    caspar 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.40 - 2018,來(lái)學(xué)習(xí)一門(mén)新的編程語(yǔ)言吧!

    摘要:入門(mén),第一個(gè)這是一門(mén)很新的語(yǔ)言,年前后正式公布,算起來(lái)是比較年輕的編程語(yǔ)言了,更重要的是它是面向程序員的函數(shù)式編程語(yǔ)言,它的代碼運(yùn)行在之上。它通過(guò)編輯類工具,帶來(lái)了先進(jìn)的編輯體驗(yàn),增強(qiáng)了語(yǔ)言服務(wù)。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺(jué)已經(jīng)到來(lái)了,總結(jié)過(guò)去的 2017,相信小伙們一定有很多收獲...

    nihao 評(píng)論0 收藏0
  • SegmentFault 技術(shù)周刊 Vol.40 - 2018,來(lái)學(xué)習(xí)一門(mén)新的編程語(yǔ)言吧!

    摘要:入門(mén),第一個(gè)這是一門(mén)很新的語(yǔ)言,年前后正式公布,算起來(lái)是比較年輕的編程語(yǔ)言了,更重要的是它是面向程序員的函數(shù)式編程語(yǔ)言,它的代碼運(yùn)行在之上。它通過(guò)編輯類工具,帶來(lái)了先進(jìn)的編輯體驗(yàn),增強(qiáng)了語(yǔ)言服務(wù)。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺(jué)已經(jīng)到來(lái)了,總結(jié)過(guò)去的 2017,相信小伙們一定有很多收獲...

    Drummor 評(píng)論0 收藏0
  • 系統(tǒng)地學(xué)習(xí)C++

    摘要:本書(shū)主要圍繞一系列逐漸復(fù)雜的程序問(wèn)題,以及用以解決這些問(wèn)題的語(yǔ)言特性展開(kāi)講解。你不只學(xué)到的函數(shù)和結(jié)構(gòu),也會(huì)學(xué)習(xí)到它們的設(shè)計(jì)目的和基本原理。因此我們把精力集中在最有價(jià)值的地方。本書(shū)不僅是對(duì)模板的權(quán)威解釋,而且本書(shū)還深入地介紹了其他一般的思想。 C++ 入門(mén)教程(41課時(shí)) - 阿里云大學(xué) C+...

    joyqi 評(píng)論0 收藏0
  • 區(qū)塊鏈開(kāi)發(fā)中使用的最流行的編程語(yǔ)言

    摘要:我們目前正處于一個(gè)新興的區(qū)塊鏈開(kāi)發(fā)行業(yè)中。,一種在以太坊開(kāi)發(fā)人員中流行的新的簡(jiǎn)單編程語(yǔ)言,因?yàn)樗怯糜陂_(kāi)發(fā)以太坊智能合約的語(yǔ)言。它是全球至少萬(wàn)開(kāi)發(fā)人員使用的世界上最流行的編程語(yǔ)言之一。以太坊,主要是針對(duì)工程師使用進(jìn)行區(qū)塊鏈以太坊開(kāi)發(fā)的詳解。 我們目前正處于一個(gè)新興的區(qū)塊鏈開(kāi)發(fā)行業(yè)中。區(qū)塊鏈技術(shù)處于初期階段,然而這種顛覆性技術(shù)已經(jīng)成功地風(fēng)靡全球,并且最近經(jīng)歷了一場(chǎng)與眾不同的繁榮。由于許多...

    2shou 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<