Peršokti į turinį
  • ŽAIDIMAI
  • , ŽAIDIMAI
  • ŽAIDIMAI

Objektinis programavimas


Ši tema yra neaktyvi. Paskutinis pranešimas šioje temoje buvo prieš 2730 dienas (-ų). Patariame sukurti naują temą, o ne rašyti naują pranešimą.

Už neaktyvių temų prikėlimą galite sulaukti įspėjimo ir pranešimo pašalinimo!

Recommended Posts

(redaguota)

Zodziu programuoju dabar Zaidejo objekta su state machine viskas kaip ir veikia bet seip man nelabai patinka kaip viskas atrodo ir kaip viska padariau nes tikrai zinau jog yra geresniu budu viska padaryt .Turiu pasidares 3 Pagrindines klases zaidejui :

 

PlayerSprite.h // zaidejo info x, y ,speed...

#pragma once
#include "Keyboard.h"
#include "PlayerState.h"
#include "PlayerControls.h"

class PlayerSprite{
public:
	PlayerSprite(float x, float y, float speed)
		:
		x(x),
		y(y),
		speed(speed),
		PlayerControl(new PlayerControls(this))
		
	{
		pCurrentState = new StateStand(PlayerControl->GetDirection(),this);
	}
	~PlayerSprite() {
		delete pCurrentState;
	}
	void Draw(Graphics& gfx) const {
		pCurrentState->Draw(x, y, gfx);
	}
	void Update(Keyboard& kbd) {
		PlayerControl->CheckControls(kbd);
		pCurrentState->Update();
	}
	float GetX() const { return x; }
	float GetY() const { return y; }
	float GetSpeed() const { return speed; }
	void SetX(float newx) { x = newx; }
	void SetY(float newy) { y = newy; }
	void SetSpeed(float newspd) { speed = newspd; }
	void SetState(PlayerState* state) { pCurrentState = state; }
private:
	float x, y,speed;
	PlayerState* pCurrentState;
	PlayerControls* PlayerControl;
};

PlayerState.h // state machine

#pragma once
#include "SurfaceAnimation.h"
#include "LoadPlayerRes.h"
#include "PlayerDirection.h"

class PlayerSprite;

class PlayerState:public LoadPlayerRes {
public:
	PlayerState(SurfaceAnimation* pSprite,PlayerDirection* dir,PlayerSprite* pplay)
		:
		pSprite(pSprite),
		pPlayerDir(dir),
		pPlayer(pplay)
	{}
	virtual void Update(){}
	virtual void Draw(float xoff, float yoff, Graphics&gfx) const {
		if (pPlayerDir->IsRight()) {
			pSprite->Draw(xoff, yoff, gfx);
		}
		else if (pPlayerDir->IsLeft()) {
			pSprite->DrawFlipY(xoff, yoff, gfx);
		}
	}
protected:
	SurfaceAnimation* pSprite;
	PlayerDirection* pPlayerDir;
	PlayerSprite* pPlayer;
};

class StateRun:public PlayerState {
public:
	StateRun(PlayerDirection* dir,PlayerSprite* player)
		:
		PlayerState(&Run,dir,player)
	{}
	virtual void Update();
};

class StateStand :public PlayerState {
public:
	StateStand(PlayerDirection* dir,PlayerSprite* player)
		:
		PlayerState(&Stand,dir,player)
	{}
};

class StateJump :public PlayerState {
public:
	StateJump(PlayerDirection* dir, PlayerSprite* player)
		:
		PlayerState(&Jump,dir,player)
	{}
};

PlayerControls.h // valdymas ir State trigerinimas

#pragma once
#include "ChiliWin.h"
#include "Keyboard.h"
#include "PlayerState.h"
#include "PlayerDirection.h"

class PlayerSprite;

class PlayerControls {
public:
	PlayerControls(PlayerSprite* player)
		:
		pPlayer(player),
		PlayerDir(PlayerDirection::MakeRight())
	{}
	void CheckControls(Keyboard& kbd);
	PlayerDirection* GetDirection() { return &PlayerDir; }
private:
	PlayerSprite* pPlayer;
	PlayerDirection PlayerDir;
};

Taigi viskas veikia mazdauk taip , PlayerControls clase yra zaidejo valdymui jinai ir nustato zaidejo busena priklausomai nuo to kuris mygtukas buvo paspaustas , PlayerState clase vygdo koda kuris priklauso jai vygdyt (priklausomai nuo zaidejo busenos) Pagrindine PlayerSprite clase tiesiog turi visus duomenis ir objektus arba pointerius y State clase ir control clase. viskas veikia kaip priklauso , taciau yra dalyku kurie man nlb patinka pats pagrindinis yra tai jog PlayerState clase paveldi is LoadPlayerRes clases kuri tiesiog uzkrauna visus zaidejui reikalingus failus (texturas ir panasei) kadangi PlayerState paveldi sita klase tai kiekviena kartai kai sukuriama nauja busena sukuriami ir uzkraunami tie objektai is LoadPlayerRes clases , kas yra visiska nesamone , kjp atrodo LoadPlayerRes clase :

#pragma once
#include "SurfaceAnimation.h"

class LoadPlayerRes {
public:
	LoadPlayerRes()
		:
		Stand("StickMan\\Stand\\stand", 1, 60, 255, 255, 255),
		Run("StickMan\\Run\\run", 13, 4, 255, 255, 255),
		Jump("StickMan\\Jump\\jump", 1, 60, 255, 255, 255),
		Fall("StickMan\\Fall\\fall",1,60,255,255,255)
	{}
protected:
	SurfaceAnimation Stand;
	SurfaceAnimation Run;
	SurfaceAnimation Jump;
	SurfaceAnimation Fall;
};

Realiai jinai tik uzkrauna visus reikiamus failus . Bet kadangi kiekviena zaidejobusena paveldi ja tai keikvienai klasei jie ir uzkraunami . Galvojau tiesiog sukuri LoadPlayerRes objekta PlayerControls claseje ir sukuriant nauja zaidejo busena persiusti referencus tam tikros animacijos , bet atsiranda problema jog PlayerSprite clase turi initializuoti Pradine busena konstruktoriuje . Nelabai gerai moku viska aiskint bet tikiuosi supratot ka turiu omeny :D

Redaguota , nario yahoo5000
Nuoroda į komentarą
Dalintis per kitą puslapį

Na, nemanau, kad kažkas turės laiko gilintis į visas tavo įdėto kodo smulkmenas, tačiau jei nori efektyviai objektiškai programuoti, turi būti susipažinęs su 3 pagrindiniais OOP principais:

1) encapsulation

2) inheritance

3) polymorphism

 

Pas tave, bent jau man toks jausmas, kad viskas per daug sumalta ir gana sunku skaityti kodą. Ir kaip pats rašei, tą paveldimumą reikėtų optimizuoti, kur LoadPlayerRes yra užkraunamas.

 

Beje, čia C++ objektinis? Aš tik su Java ir C# kol kas esu praktikavęsis, tai sunku labiau pasigilinti į tavo kodą.

Nuoroda į komentarą
Dalintis per kitą puslapį

(redaguota)

Jo ce C++ . encapsulation , sita pirma kart girdziu apsidomesiu kas ce per tokio, seip dauk kodo neydejau tai neturetu but sudetinga ir nlb yra ce y ka gilintis :D ce trys paprasto klases nera kazko prikista , paprastos funkcijos Su normaliais pavadinimais nemanau jog yra kazkokiu problemu suprast kas ten parasyta . As ipradziu buvau LoadPlayerRes clases priskyres PlayerSprite clasei , bet velgi PlayerSprite jinai kjp ir nereikalinga (iskyrus inicializuoti pradine busena) , todel tokiu atveju reiketu objekto arba PlayerControls arba PlayerState . Ispradziu as isviso nenorejau permest okios info kaip uz parametra del to ir priskyriau ja prie State machine tam kad todel kad apie tai niekam kitiem nereikia nieko zinoti , tai arba man reiktu tas animacijas daryt public kad butu galima prieit prie ju paprastai arba kazka kito galvot.


Realiai gal netgi galeciau padaryt taip pat kaip padariau su PlayerDirection , sukurti objekta  ir padaryti public funcija kad grazintu pointery i ta objekta . Tokiu atveju viskas atrodytu graziau ir prieit visi kam reiketu galetu per pointery i objekta :huh:.

 

Manau sugalvojau sioky toky sprendima , kjp ir pradzioj buvau padares visus reikalingus resursus turetu saugoti arba buti priskirta prie Player clases , ir tada galeciau tiesiog padaryt public funkcija y Animacijas tokiu atveju tiem kam reiketu galetu pasiekti per funkcija , o Player klasej nereiketu man sukt galvos kaip sukonstruotpradine busena nes Player clase turetu viska ko jai reiketu kad padarytu tai pati

Redaguota , nario yahoo5000
Nuoroda į komentarą
Dalintis per kitą puslapį

Jeigu kazkas domisi programavimu tai stai kaip viska isprendziua :

LoadPlayerRes nebepaveldi PlayerState clases , dabar LoadPlayerRes sukuriau objekta PlayerSprite claseja  ir sukurriau public funkcija kad pasiekti visas animacijas :

SurfaceAnimation* GetSurfaceP(std::string name) { 
		if (name == "Stand") {
			return &res.Stand;
		}
		else if (name == "Run") {
			return &res.Run;
		}
		else if (name == "Jump") {
			return &res.Jump;
		}
		else if (name == "Fall") {
			return &res.Fall;
		}
	}

tada PlayerState clases konstruktorius reikalauja 3 parametru 2 is ju duoda Betkuri State clase (krypty ir pointery i playerSprite clase ) 3 parametra perduodu pasijemes viena jau duota parametra (pointery i playerSPrite clase) ir kvieciu funkcija kuria auksciau papastinau kad gauti 3 parametra (pointery i  animacijas) viskas atrodo taip :

PlayerState::PlayerState(SurfaceAnimation* pSprite, PlayerDirection* dir, PlayerSprite* pplay)
	:
	pSprite(pSprite),
	pPlayerDir(dir),
	pPlayer(pplay)
{}


StateRun::StateRun(PlayerDirection* dir, PlayerSprite* player)
	:
	PlayerState(player->GetSurfaceP("Run"), dir, player)
{}

tokiu budu apie animacijas zino tik State clasees o inicializuojant Status nereikia perleist animaciju kaip uz parametra nes klase pati zino ko jai reik

Nuoroda į komentarą
Dalintis per kitą puslapį

Dabar vietoj std::string naudok enumeracijas. o vietoj salygos switch cikla. Ir viskas bus perfect :)

kaip pavizdi:

typedef enum {
	PLAYER_STATE_UNDEFINED = 0,
	PLAYER_STATE_STAND,
	PLAYER_STATE_RUN,
	PLAYER_STATE_JUMP,
	PLAYER_STATE_FALL
} PLAYER_STATE;

Ir:

SurfaceAnimation* GetSurfaceP(PLAYER_STATE state)
{
	switch (state)
	{
		case PLAYER_STATE_STAND:
			return &res.Stand;
		case PLAYER_STATE_RUN:
			return &res.Run;
		case PLAYER_STATE_JUMP:
			return &res.Jump;
		case PLAYER_STATE_FALL:
			return &res.Fall;
	}
	return PLAYER_STATE_UNDEFINED;
}

Redaguota , nario Amxxl
Nuoroda į komentarą
Dalintis per kitą puslapį

(redaguota)

nematau tikslo tai daryt ? i koda tokiu budu isimaiso tik daugiau painiavos , tos enumeracijos pradetusy maisytis su State clasem , nera tikslo kurt tuos enumus del vienos funkcijos , enumeracijas kuri kj nori pasidaryti nauja duomenu tipa , situ atveju as to daryt tikrai nenoriu

Redaguota , nario yahoo5000
Nuoroda į komentarą
Dalintis per kitą puslapį

nematau tikslo tai daryt ? i koda tokiu budu isimaiso tik daugiau painiavos , tos enumeracijos pradetusy maisytis su State clasem , nera tikslo kurt tuos enumus del vienos funkcijos , enumeracijas kuri kj nori pasidaryti nauja duomenu tipa , situ atveju as to daryt tikrai nenoriu

Nu cia tavo pasirinkimas. Nezinau apie kokia painiava tu sneki kaip tik kodas atrodytu more clearly. Enumeracijos niekaip negali masytis su state clasem tik tinkamai uzvadinti reikia. Del tikslo tai tikrai gal ir nera nebent nori sutaupyti programos apimties dydi :D. Enumeracijas kuri ne vien kad pasidaryti duomenu tipa bet jos puikiai tinka Flagams / Steitams (siuo atveju) (ipac kai prireikia GetState() funkcijos tikrinimams).

Redaguota , nario Amxxl
Nuoroda į komentarą
Dalintis per kitą puslapį

Nu ne siuo atveju naudot Enumeracijas ;d tiesiog nera geras sprendimas . Zodziu nlb moku paaiskint bet tikrai nemanau jog tureciau ce naudoti enumeracijas

Ne nu tai viskas gerai palei kolkas kol neprireiks GetPlayerState() :D

 tai arba man reiktu tas animacijas daryt public kad butu galima prieit prie ju paprastai arba kazka kito galvot.

Teko apie friend class girdet ? ;D ko gero galetum tai panaudot ;D Tai leidzia friend classei priet prie visu

bloku taipat ir private.

Redaguota , nario Amxxl
Nuoroda į komentarą
Dalintis per kitą puslapį

(redaguota)

Jeigu ir reikes man GetPlayerState() funkcijos visa funkcija neuzims daugiaunei vienos eilutes. Friend clase yra pats blogiauses sprendimas is visu , nezinau kiek nusimanai apie programavima bet friend clase yra devil , paklausk pas betkury rimta programuotoja StackOverflowe ar dar kur nors pasakys ta paty , "Blogiauses sprendimo budas yra friend clase "

stai kjp atrodo getplayer state funkcija :

PlayerState* GetPlayerState() { return pCurrentState; }
Redaguota , nario yahoo5000
Nuoroda į komentarą
Dalintis per kitą puslapį

 

Jeigu ir reikes man GetPlayerState() funkcijos visa funkcija neuzims daugiaunei vienos eilutes. Friend clase yra pats blogiauses sprendimas is visu , nezinau kiek nusimanai apie programavima bet friend clase yra devil , paklausk pas betkury rimta programuotoja StackOverflowe ar dar kur nors pasakys ta paty , "Blogiauses sprendimo budas yra friend clase "

stai kjp atrodo getplayer state funkcija :

PlayerState* GetPlayerState() { return pCurrentState; }

Friend klase naudojama paskutiniu atveju kai kito varianto nera. nezinau kodel uzsiminiau. O del GetPlayerState() tai as turejau galvoje player state type pvz: GetPlayerStateType() == PLAYER_STATE_IDLE. Bet sita galima lengvai padaryt su Derived klasiu konstruktoriais kai base klases konstruktorius nustato tipa. Bet gali buti kad tau to isvis nereikia cia priklauso nuo to koki zaidima darai.

Pas mane tai viskas kitaip pacio parasytas Engine ir dar Directxa sena naudoju t.y 9. :D Pilna singleton patternu ir visokio "s".

Kazkada bandziau Chilli frameworka senais laikais tai del kazkokiu priezaciu nepatiko man :D.

 

Kodo pavidalu mano mintis buvo:

#pragma once
#include "SurfaceAnimation.h"
#include "LoadPlayerRes.h"
#include "PlayerDirection.h"

class PlayerSprite;

class PlayerState : public LoadPlayerRes {
public:
	typedef enum {
		UNDEFINED_PLAYER_STATE = 0,
		PLAYER_STATE_RUN,
		PLAYER_STATE_STAND,
		PLAYER_STATE_JUMP,
		PLAYER_STATE_FALL
	} PLAYER_STATE_TYPE;

	PlayerState(PLAYER_STATE_TYPE type, SurfaceAnimation* pSprite, PlayerDirection* dir, PlayerSprite* pplay)
		:
		pSprite(pSprite),
		pPlayerDir(dir),
		pPlayer(pplay),
		state_type(type)
	{}
	virtual void Update() {}
	virtual void Draw(float xoff, float yoff, Graphics&gfx) const {
		if (pPlayerDir->IsRight()) {
			pSprite->Draw(xoff, yoff, gfx);
		}
		else if (pPlayerDir->IsLeft()) {
			pSprite->DrawFlipY(xoff, yoff, gfx);
		}
	}

	PLAYER_STATE_TYPE GetPlayerStateType() const { return state_type; }

protected:
	SurfaceAnimation* pSprite;
	PlayerDirection* pPlayerDir;
	PlayerSprite* pPlayer;

private:
	PLAYER_STATE_TYPE state_type;
};

class StateRun :public PlayerState {
public:
	StateRun(PlayerDirection* dir, PlayerSprite* player)
		:
		PlayerState(PLAYER_STATE_RUN, &Run, dir, player)
	{}
	virtual void Update();
};

class StateStand :public PlayerState {
public:
	StateStand(PlayerDirection* dir, PlayerSprite* player)
		:
		PlayerState(PLAYER_STATE_STAND, &Stand, dir, player)
	{}
};

class StateJump :public PlayerState {
public:
	StateJump(PlayerDirection* dir, PlayerSprite* player)
		:
		PlayerState(PLAYER_STATE_JUMP, &Jump, dir, player)
	{}
};

class StateFall : public PlayerState {
public:
	StateFall(PlayerDirection* dir, PlayerSprite* player)
		:
		PlayerState(PLAYER_STATE_FALL, &Fall, dir, player)
	{}
};
Redaguota , nario Amxxl
Nuoroda į komentarą
Dalintis per kitą puslapį

(redaguota)

Kitas varijantas visada yra tik klausimas kjp labai tyngi nori kazka perdarinet ar keist friend clase gal itik sumazint darba kj labai tyngi bet kita varijanta visada galima rast manau .As rialiai dabar nedarau jokio zaidimo tiesiog mokausi ir ruosiuosi ateinanciam projektui kyru galvoju pradet po poros menesiu jei netyngesiu kas yra Online zaidimai dabar domiuosi ir studijuoju visa client ir server stuffa kas nera sudetinga , ir taip pat toliau gilinuosi i c++ programavima . Dabartinis kodas nera visiskai panasus y sena mano ar sita kur tu pateikei , perdariau viska beveik , dabar State construktoriuj reikia tik vieno parametro pointerio i player clase o visa kita jisai pasidaro pats , rytoj manau busiu perderes viska jau galesiu i kelt jeigu domiesi pasiziuresi kjp atrodo viskas :) Chili frameworkas buvo atnaujintas seis metais ir visiskai kitoks nei anksciau buvo , plius ce tik frameworkas visada gali jy persidaryt pagal save

Redaguota , nario yahoo5000
  • Teigiamai 1
Nuoroda į komentarą
Dalintis per kitą puslapį

Na realiai as jau esu pasidares pagal save and DirectX 9 dabar tik reiketu atnaujinti ant 11 / 12. Beda ta kad ant DirectX 9

Geriausias spritu drawinimas buvo batchingas. O ant 11 instancingas. Beda kad mano variklio struktura tektu kardinaliai keisti.

Norint atnaujinti. O del networko tai pirma ka reikia moketi tai pasirasyti ByteBuffer klase. Pirma baita (ar kelis) naudoji kaip message id.

Sekancius persiuntinet duomenims. taip identifikuoji paketus ir synhronizuoji duomenis. As naudoju WinSock2 duomenu persiuntimui (bet nepatarciau) veikia tik ant windows'u o serverius laikyti reikia ant linux (nebutinai bet geriausiai). Del to Chilli frameworko tai man kas patiko kad nereikia naudoti DirectX SDK (Kurio nebenaujina microsoftas) ir yra geras pavizdys kaip nuskaityt BMP faila (Biski perkeiti duomenis ir gali pasidaryti savo paveikslelio formata kas visai aktualu (bent man)). Jo butu gerai kad ikeltum visai noriu paziuret kaip tu ten padares.

 

P.S.: Neuzkalnu C++ 17 standartas tures networko liba kazkoki based on ace Ciuju perkodinsiu ant jo. :D

Redaguota , nario Amxxl
Nuoroda į komentarą
Dalintis per kitą puslapį

(redaguota)

Kiek teko girdet Winstoka naudoja dauguma siuolaikiniu zaidimu


Stai kaip viska perdariau :

https://github.com/egizz983/C--/

Zinoma pries ikeldamas i GitHub sumeciau viska i atskirus folderius todel nemanau jog veiks , reiktu pazaist su includais visais ir file path

 

BMP loadery pasidariau su vectoriais bet kai netingesiu perdarysiu tikriausei i queue nes jei veikia dauk greiciau nei vectoriai

Redaguota , nario yahoo5000
Nuoroda į komentarą
Dalintis per kitą puslapį

Ši tema yra neaktyvi. Paskutinis pranešimas šioje temoje buvo prieš 2730 dienas (-ų). Patariame sukurti naują temą, o ne rašyti naują pranešimą.

Už neaktyvių temų prikėlimą galite sulaukti įspėjimo ir pranešimo pašalinimo!

Svečias
Ši tema yra užrakinta.
  • Šiame puslapyje naršo:   0 nariai

    • Nėra registruotų narių peržiūrinčių šį forumą.

Skelbimai


×
×
  • Sukurti naują...