Viens kuģis labi, divi vēl labāk. Lidinators v0.5

Kā minēju iepriekšējā “Lidinatora” sērijas rakstā, viena no tuvākajā laikā īstenojamajām lietām ir vairākspēlētāju režīms, kuru tad iesākšu realizēt šajā sērijā.

Kopš iepriekšējā raksta esmu nedaudz pārstrādājis kodu, izveidojot bāzes komponentu SpriteComponent, kurā ir iznestas LoadContent(), Draw() un GetBoundingSphere() metodes, kas bija kopīgas gan planētām, gan kuģim.  Līdz ar to, klasēs, kuras reprezentē minētos objektus ir palicis tikai stāvokļa izmaiņas kods. Detalizētāk to varēs apskatīt raksta beigās pievienotajā pirmkodā.

Atgriežoties pie vairākspēlētāju režīma varu pavēstīt priecīgu ziņu – pamatā kods jau uztur iespēju izmantot vairākus kuģus vienlaicīgi. Vienīgi viņi sāks vienā un tajā pašā punktā un vienādi reaģēs uz nospiestajiem taustiņiem un tādēļ nebūs atšķirami. Tātad, ir trīs risināmi jautājumi:

  1. Kuģa sākuma koordinātes
  2. Dažādi vadības taustiņi
  3. Kuģu atšķirības zīmes

Pirmo punktu var atrisināt, papildinot kuģa konstruktora metodi, piedāvājot iespēju norādīt sākumpunkta koordinātes.

        public Ship(Game game, Vector2 startLocation): base(game)
{
this.location = startLocation;
this.textureAsset = "ship_sprite";
}

public Ship(Game game)
:
this(game, new Vector2())
{
}

Kā redzams, ir atstāts arī vecais konstruktors, kurš inicializē kuģi ekrāna centrā. Papildināsim spēles klases konstruktoru, lai redzētu, kā izskatās vairāki kuģi uz viena ekrāna.

            ships = new List<Ship>();
for (int i = 0; i < 4; i++)
{
var shipLocation = new Vector2(
(
i + 1) * Window.ClientBounds.Width / 5 - Window.ClientBounds.Width / 2,
0);
var ship = new Ship(this, shipLocation);
ships.Add(ship);
Components.Add(ship);
}

Lai varētu paspēlēties, pagaidām atkal ir jāizkomentē sadursmju noteikšana. Toties, spriežot pēc attēla, ne vienai vien lidotāju vienībai skauž cik sinhroni šie puši prot lidot.

lidinators_8

Problēmu saraksts ir saīsināts par vienu punktu. Turpināšu ar trešo punktu, t.i. kuģu atšķiršanu. Ar šo punktu ne tikai tāpēc, ka to ir vieglāk realizēt, bet arī tādēļ, ka esmu ieplānojis to izmantot pārveidotajā sadursmju noteikšanā.

Lai atšķirtu kuģus, iekrāsosim tos dažādos toņos. Savukārt, lai varētu kuģus iekrāsot, nepieciešams papildināt bāzes komponentu ar īpašību toņa glabāšanai un jaunu konstruktoru, kuram var nodot toni.

        public Color Tint {get; set;}

public SpriteComponent(Game game, Color tint)
:
base(game)
{
this.Tint = tint;
}

Bāzes objektu papildināt nākas divu iemeslu pēc. Pirmkārt, tajā ir realizēta gariņa zīmēšana. Otrkārt, nākotnē varētu būt vēlme zīmēt tonētas planētas. Savukārt tonis ir publisks tikai tāpēc, lai pie sadursmju noteikšanas varētu mainīt fona krāsu uz vainīgā kuģa krāsu. 

Lai redzētu izmaiņas, nepieciešams izmainīt zīmēšanas metodi, un Color.White vietā izmantot iepriekš norādīto toņa vērtību. Jāņem vērā, ka norādītais tonis tiek lietots kā maska, tādēļ vēlams izmantot ļoti gaišas krāsas, lai saglabātu vismaz daļēju oriģinālo krāsojumu.

            spriteBatch.Draw(
sprite,
center + location - spriteCenter,
null,
Tint,
angle * (float)Math.PI / 180,
spriteCenter,
1,
SpriteEffects.None,
0);

Un atkal jāmaina kuģu inicializācija, tagad jau izmantojot krāsas:

            ships = new List<Ship>();
var colors = new[]
{
Color.White,
new Color(255,164,164),
new Color(164,255,164),
new Color(164,164,255)
};

for (int i = 0; i < 4; i++)
{
var shipLocation = new Vector2(
(
i + 1) * Window.ClientBounds.Width / 5 - Window.ClientBounds.Width / 2,
0);
var ship = new Ship(this, shipLocation, colors[i]);
ships.Add(ship);
Components.Add(ship);
}

Un sadursmju noteikšana:

            backgroundColor = Color.CornflowerBlue;
foreach (var ship in this.ships)
{
BoundingSphere shipSphere = ship.GetBoundingSphere();
foreach (var planet in planets)
{
if (shipSphere.Intersects(planet.GetBoundingSphere()))
{
backgroundColor = ship.Tint;
}
}
}

Domāju, ka ir pienācis brīdis, kad var papriecāties par rezultātu.

lidinators_9

Šobrīd no sākotnējā saraksta ir atlicis tikai viens punkts, dažādu vadības taustiņu definēšana. Vienkāršākajā variantā nepieciešams kuģa objektam nodefinēt četras īpašības, kur katra atbilst vienai no darbībām un atbilstoši izmainīt kuģa Update() metodes pārbaudes. Tas izskatās šādi:

        public Keys LeftKey { get; set; }
public Keys RightKey { get; set; }
public Keys DownKey { get; set; }
public Keys UpKey { get; set; }

tad ir nedaudz izlaista koda un pārbaudes bloks ir mainīts pēc šāda principa:

            if (currentState.IsKeyDown(UpKey))
{
speed += 3;
}

Atkal izmainam daudz cietušo kuģu inicializācijas bloku:

            ships = new List<Ship>();
var colors = new[]
{
Color.White,
new Color(255,164,164),
new Color(164,255,164),
new Color(164,164,255)
};

var shipLocation = new Vector2(
Window.ClientBounds.Width / (-4),
0);
var ship = new Ship(this, shipLocation, colors[0])
{
UpKey = Keys.Up,
DownKey = Keys.Down,
LeftKey = Keys.Left,
RightKey = Keys.Right
};
ships.Add(ship);
Components.Add(ship);

shipLocation = new Vector2(Window.ClientBounds.Width / 4, 0);
ship = new Ship(this, shipLocation, colors[2])
{
UpKey = Keys.I,
DownKey = Keys.K,
LeftKey = Keys.J,
RightKey = Keys.L
};
ships.Add(ship);
Components.Add(ship);

Un divspēlētāju “Lidinators” ir gatavs. Tagad divreiz labāks par to pašu cenu! :)

lidinators_A

Published 04 December 2008 08:33 AM by ivars.arins
Filed under: , , ,

Leave a Comment

(obligāts) 
(obligāts) 
(brīvizvēles)
(obligāts)