November 2008 - Posts

Tīmekļa platformas uzstādītājs
Aizrāvies ar "Lidinatora"  sērijas rakstīšanu, tā arī līdz šim brīdim nebiju atradis laiku pastāstīt par Microsoft Web Platform Installer, kuram pagājušās nedēļas beigās ir iznākusi "Release Candidate"  versija.

Tīmekļa platformas uzstādītājs ir programma, kas ļauj vienkārši uzstādīt tīmekļa izstrādei nepieciešamās programmas t.i, web serveri, Visual Studio 2008 ekspress variantu, kā arī dažādus papildinājumus, piemēram, ASP.NET MVC vai arī SQL PHP draiveri. Nelielu vilšanos sagādāja tas, ka lai gan mājaslapā esošajā aprakstā ir teikts, ka instalē IIS 7, uz Windows XP tiks uzinstalēta sestā versija. Lai gan tas bija gaidāms, manī mājoja neliela cerība, ka izdosies iegūt jauno web serveri, nemainot operētājsistēmu.

Domāju, ka noderēs tiem, kas vēlas uzsākt izstrādi ar ASP.NET un saistītajām platformām, lai ātri un vienkārši iegūtu nepieciešamos rīkus.

wpi

Kur planētām nav vietas. Lidinators v0.3

Nupat sapratu, ka lidināšanās apkārt nav nemaz tik interesanta. Tāpēc, turpinot lidinatora attīstību, nāksies to papildināt ar ko jaunu. Pirmais, kas man jau sākotnēji nepatika, ir tas, ka ļoti viegli nomaldīties un pazaudēt raķeti. Šo var risināt divejādi:

  1. Izdarīt tā, lai pie kāda taustiņa nospiešanas kuģis atgrieztos sākotnējā stāvoklī. Neforši, bet ļoti vienkārši.
  2. Neļaut kuģim izlidot ārpus ekrāna robežām. Nedaudz sarežģītāk, toties Īstu vīru solution™.

Lieki nedomājot izvēlējos otro variantu. Tā kā visa dzīve ir izvēlēšanās starp variantiem, tad arī šeit ir divi varianti, kā rīkoties gadījumā, ja kuģis sasniedz ekrāna malu. Viens būtu to "atsist" pret malu, kā biljarda bumbiņu, savukārt otrs veido "bezgalīgu" telpu, kad kuģis sasniedzot vienu malu parādās otrā. Ieraduma pēc atkal nolēmu, ka ir jāizvēlas otrais variants.

Nekas daudz jau šeit nav jādara, tik vien, kā jāizmaina kuģa koordinātes gadījumā, ja tā centrs ir aiz kādas no ekrāna robežām. Nedaudz jāpapildina Update() metode un lieta darīta

            if (Math.Abs(shipLocation.X) > Window.ClientBounds.Width / 2)
{
shipLocation.X *= -1;
}
if (Math.Abs(shipLocation.Y) > Window.ClientBounds.Height /2 )
{
shipLocation.Y *= -1;
}

Tā, kā koordinātu sākumpunkts ir ekrāna centrā, tad pārbaude un koordināšu maiņa ir ļoti vienkārša. Pārbaudam, vai kādas koordinātes absolūtā vērtība nepārsniedz pusi atbilstošā ekrāna izmēra. Gadījumā, ja pārsniedz, tad šo koordināti pareizinot ar -1 kuģis tiek pārvietots uz otru ekrāna malu.

Šāda metode gan ir vienkāršota un gadījumā, ja kuģis apstājas tieši uz ekrāna malas, tad dabū diezgan nejauku mirgošanas efektu, tāpēc nākas to pārrakstīt nedaudz "gudrāk".

            if (Math.Abs(shipLocation.X) > Window.ClientBounds.Width / 2)
{
float sign = Math.Abs(shipLocation.X) / shipLocation.X;
shipLocation.X = - 1 * sign *
Math
.Min(Math.Abs(shipLocation.X), Window.ClientBounds.Width / 2 - 1);
}
if (Math.Abs(shipLocation.Y) > Window.ClientBounds.Height /2 )
{
float sign = Math.Abs(shipLocation.Y) / shipLocation.Y;
shipLocation.Y = -1 * sign *
Math
.Min(Math.Abs(shipLocation.Y), Window.ClientBounds.Height / 2 - 1);
}

Nav tik saprotami, bet dara ko ļoti līdzīgu. Gadījumā, ja kuģis jāpārvieto uz otru ekrāna malu, tad izvēlas ekrāna centram tuvāko vērtību no kuģa koordinātes un punkta, kas ir par vienu vienību nost no ekrāna malas.

Tagad kuģi pazaudēt ir grūtāk, bet lidināšanās īpaši interesantāka nav palikusi. Lai nebūtu tik vientuļi, papildināsim pieejamo kosmosu ar kādu planētu.

planet

Atkārtojot pirmajā rakstā minētās darbības, jāpievieno planētas gariņgrafiku projekta saturam. Tālāk nepieciešams izveidot mainīgos koordināšu un gariņa glabāšanai, spēles sākumā inicializēt planētas koordinātes un attēlot to uz ekrāna Draw() metodē. Tās visas ir jau apskatītas lietas, tāpēc detalizēti to neapskatīšu. Jebkurā gadījumā to var apskatīt pievienotajā pirmkodā.

Bet ja jau ir planēta, tad vajadzētu ļaut tajā ietriekties kuģim, lai lidošanai piedotu "briesmu elementu".  Ja šajā spēles posmā kuģis "saduras" ar planētu, tad tas vienkārši pārlido pāri tā, it kā planēta atrastos tālumā. Šeit ir nepieciešams izmantot kādu sadursmju noteikšanas mehānismu, lai konstatētu, ka abi objekti ir sadūrušies.

XNA piedāvā vairākas struktūra, kuras var izmantot sadursmju noteikšanai. Lai gan šīs klases ir paredzētas izmantošanai 3D telpā, tās mierīgi var izmantot arī 2D spēlēs. Lidinatora piemērā tiek izmantota BoundingSphere struktūra, kas izmanto objektu aptverošu lodi. Tas gan nav precīzākais sadursmju noteikšanas veids, bet sākumā noderēs.

Update() metodē izveido divas jaunas BoundingSphere lodes, kas atbilst katram no objektiem (planētai un kuģim):

            BoundingSphere shipSphere = new BoundingSphere(
new Vector3(shipLocation, 0),
(
float)(shipSprite.Width / 2.5));
BoundingSphere planetSphere = new BoundingSphere(
new
Vector3(planetLocation, 0),
(
float)(planetSprite.Width / 2.5));

Lai pārbaudītu, vai lodes nepārklājas, jāizmanto Intersects() metode. Lai uzskatāmāk varētu redzēt kurā brīdī lodes pārklājas, nedaudz izmainīšu zīmēšanas metodi lai pārklāšanās gadījumā izmantotu sarkanu fonu. Šim nolūkam tiek izveidots jauns klases lauks kurā glabā pārbaudes rezultātu un Update() metodē to aizpilda ar pārbaudes rezultātu:

crashed = shipSphere.Intersects(planetSphere);

Un zīmēšanas izmaiņas:

GraphicsDevice.Clear(crashed ? Color.Red : Color.CornflowerBlue);

Kā rezultātā ir iespējams vērot nākošajā attēlā redzamo ainu.

lidinators_6

 

Tas pirmajā tuvinājumā arī būtu viss par sadursmju noteikšanu. Katrā ziņā nākošajās sērijās ar to vēl nāksies saskarties ne vienu vien reizi.

Apsolītais pirmkods

I like to move it, move it! Lidinators v0.2

Sveiki! Ir jauna diena un "Lidinators" turpina savu lidojumu. Domāju, ka vakardienas rezultāts nav pārāk iespaidīgs. Jā, varam ar dažām koda rindiņām parādīt kuģīti uz ekrāna, bet ko tas dod? Neko daudz, tikai sākumu jaunai spēlei. Turpinot tādiem pašiem maziem solīšiem, šodien pievienosim iespējas pārvietot kuģi.

Lai varētu ko pārvietot, nepieciešams zināt tā atrašanās vietu. Tāpēc papildināsim kodu ar mainīgajiem, kuros glabāt kuģa koordinātes un ātrumus. Ātrumi ir daudzskaitlī, tādēļ, ka vēlos atseviški izdalīt pārvietošanās ātrumu uz priekšu un rotācijas ātrumu. Līdz ar to pašreizējās mainīgo definīcijas būs šādas:

        GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
Texture2D shipSprite;
Vector2 shipLocation;
float speed, rotationSpeed;

Tāpat derētu nodefinēt konstantes ātruma ierobežojumiem, lai kuģis neieskrietos pārāk ātri un neizsistu caurumu monitora sānos.

        const float MaxSpeed = 10;
const float MaxRotationSpeed = 3;

Spēles inicializācijas metodē jānovieto kuģi koordinātu sākumpunktā:

        /// <summary>
///
Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
shipLocation = new Vector2(0, 0);
base.Initialize();
}

Un jāpārveido zīmēšanas metodi, lai tā zīmētu kuģi, ņemot vērā tā atrašanās vietu.

        protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();
spriteBatch.Draw(
shipSprite,
shipLocation,
Color.White);
spriteBatch.End();

base.Draw(gameTime);
}

Palaižot spēli var redzēt, kas ir sanācis.

Lidinators stūrī

Domāju, ka nevienam nav pārsteigums, ka datoriem koordinātu sistēma parasti atšķiras no tās, ko mācīja skolā. T.i. koordinātu sākumpunkts ir ekrāna labajā augšējā stūrī, nevis ekrāna centrā. Līdz ar to ir nepieciešams kompensēt divas lietas:

  • Atšķirīgu koordinātu sākumpunktu
  • To, ka gariņu zīmē no stūra, nevis no centra

Lai neitralizētu pirmo punktu, pietiek izrēķināt sākuma koordinātes pēc ekrāna izmēriem. Un arī otru problēmu atrisina līdzīgi - atņemot no zīmēšanas koordinātēm kuģa centra koordinātes.  Izmainītā zīmēšanas metode:

protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

Vector2 center = new Vector2(
Window.ClientBounds.Width / 2,
Window.ClientBounds.Height / 2);
Vector2 shipCenter = new Vector2(shipSprite.Width / 2, shipSprite.Height / 2);

spriteBatch.Begin();
spriteBatch.Draw(
shipSprite,
center + shipLocation - shipCenter,
Color.White);
spriteBatch.End();

base.Draw(gameTime);
}

Un ekrānšāviņš, lai pārliecinātos, ka tas darbojas

Lidinators centrā

Sagatavošanās darbi ir pabeigti, jāsāk kustināt kuģi. Spēles stāvokļa pārrēķināšanai un lietotāja ievades saņemšanai ir paredzēta spēles Update() metode, kuru tad arī ir jāpapildina ar nepieciešamo loģiku. "Lidinatora" gadījumā algoritms ir vienkāršs:

  • Ja ir nospiests taustiņš "uz augšu", tad palielina kuģa ātrumu par 3, bet nepārsniedzot maksimālo ātrumu;
  • Ja ir nospiests taustiņs "uz leju", tad samazina kuģa ātrumu par 3, bet kuģa ātrums nedrīkst būt negatīvs;
  • Ja ir nospiests taustiņš "pa kreisi", tad palielina kuģa rotācijas ātrumu par 2, bet tas nedrīkst pārsniegt maksimālo rotācijas ātrumu;
  • Ja ir nospiests taustiņš "pa labi", tad samazina kuģa rotācijas ātrumu par 2, bet tas nedrīkst būt mazāks par negatīvu maksimālo rotācijas ātrumu;

Lai uzzinātu par nospiestajiem taustiņiem, nepieciešams izmantot Keyboard klases metodi GetState(), kas atgriež KeyboardState struktūru. Savukārt KeyboardState satur metodi IsKeyDown(), ar kuras palīdzību var pārliecināties vai konkrēts taustiņš ir nospiests. Iepriekš aprakstītajam algoritmam atbilst šāds kods:

            KeyboardState currentState = Keyboard.GetState();
if (currentState.IsKeyDown(Keys.Up))
{
speed += 3;
}
if (currentState.IsKeyDown(Keys.Down))
{
speed -= 3;
}
if (currentState.IsKeyDown(Keys.Left))
{
rotationSpeed += 2;
}
if (currentState.IsKeyDown(Keys.Right))
{
rotationSpeed -= 2;
}
if (speed < 0)
{
speed = 0;
}
if (speed > MaxSpeed)
{
speed = MaxSpeed;
}
if (rotationSpeed > MaxRotationSpeed)
{
rotationSpeed = MaxRotationSpeed;
}
if (rotationSpeed < -MaxRotationSpeed)
{
rotationSpeed = MaxRotationSpeed;
}

Protams, ar ātruma rēķināšanu nepietiks, lai kuģis tiešām pārvietotos. Šajā pašā metodē ir nepieciešams uzrakstīt arī stāvokļa izmaiņu loģiku. Šajā brīdī es sapratu, ka kodā pietrūkst kuģa šābrīža leņķis un tā attēlošana. Ja pirmo trūkumu var atrisināt ar jauna mainīgā ieviešanu, tad ar otro būs nedaudz sarežģītāk, jo nāksies izmantot citu zīmēšanas metodi, kurai ir stipri vairāk parametri. Ja pirmā problēma (trūkstošais leņķis) ir atrisināta,  pārvietošanās loģiku var uzrakstīt salīdzinoši vienkārši, ja neskaita, ka nepieciešams atcerēties ģeometrijas kursu. Sākumā izmainam kuģa leņķi atbilstoši rotācijas ātrumam, savukārt pēc tam izmainam kuģa koordinātes atbilstoši tā ātrumam un leņķim. Pieņemot, ka kuģa leņķis tiek glabāts grādos, tas izskatītos šādi:

            shipAngle = shipAngle - rotationSpeed;
shipLocation.X += speed * (float)Math.Sin(shipAngle / 180 * Math.PI);
shipLocation.Y -= speed * (float)Math.Cos(shipAngle / 180 * Math.PI);

Lai kuģis neizlidotu tālēs zilajās (vārda tiešā nozīmē), vajadzētu arī ātrumu samazināt, tāpēc metodes beigās ātrumu samazina par vienu vienību, bet rotācijas ātrumu - uz pusi:

            speed--;
rotationSpeed /= 2;

Kad kuģis, vismaz teorētiski, ir spējīgs pārvietoties, nepieciešams izmainīt zīmēšanas kodu, lai arī leņķis būtu redzams:

            spriteBatch.Draw(
shipSprite, //1
center + shipLocation - shipCenter, //2
null, //3
Color.White, //4
shipAngle * (float)Math.PI / 180, //5
shipCenter, //6
1, //7
SpriteEffects.None, //8
0 //9
);

Kā redzams, klāt ir nākuši vairāki parametri, tāpēc paskaidrošu, ko nozīmē katrs no parametriem:

  1. gariņš kuru zīmēt;
  2. koordinātes, kurās zīmēt gariņu;
  3. taisnstūra struktūra, kas nosaka, kuru daļu no gariņa zīmēt (ja norādīta null vērtībā, tad zīmē visu)
  4. tonis, kas tiek lietots zīmēšanai (baltā krāsa nozīmē - zīmēt netonētu)
  5. rotācijas leņķis
  6. rotācijas centrs
  7. mērogmaiņas koeficients
  8. efekts (nekāds, apvēršana horizontāli, apvēršana vertikāli)
  9. z koordināte

Domāju, ka šeit nav nekāda raķešzinātne (hmm, varbūt tomēr ir?), tāpēc vajadzētu būt skaidram. Neskaidros jautājumus droši varat uzdot komentāros, centīšos atbildēt.

Viens jautājums, kurš droši vien parādīsies, ir - kāpēc nepieciešami tik sarežģīti ātruma aprēķini, ja kuģis vienalga kustās samērā saraustīti? Patiesībā kuģim vajadzētu kustēties ar zināmu inerci, bet tas tā nenotiek tādēļ, ka Update metode notiek parāk bieži. Lai padarītu kuģa ātrumu atkarīgu no laika, izmantosim Update() metodes parametru gameTime, kuram ir tāda paša nosaukuma tips GameTime. Izmantojot dažādus šī tipa parametrus var iegūt informāciju par spēles stāvokli laikā. Nedaudz pārveidojot ātrumu izmaiņas tā, lai tās būtu atkarīgas no laika, nevis atjaunošanas biežuma, "spēle" paliek interesantāka.

            var elapsed = (float)gameTime.ElapsedGameTime.Ticks / 1000000;

if (elapsed > 0)
{
speed -= elapsed;
rotationSpeed -= (rotationSpeed / 4) * elapsed;
}

Tas nu pagaidām būs viss. Gaidu ierosinājumus nākošajai sērijai.

Tā kā šobrīd kods jau ir nedaudz izaudzis, pievienoju pirmkodu.

Paspēlēsimies? Lidinators 0.1

Kādu laiku atpakaļ rakstīju, ka ir iznākusi trešā versija XNA spēļu studijai un, ka es vēlētos par to pastāstīt sīkāk. Tas laiks nu ir pienācis un tuvākajās dienās (nedēļās? mēnešos?) centīšos pastāstīt par spēļu veidošanu izmantojot XNA.

Lai sāktu izstrādi nepieciešama Microsoft Visual Studio izstrādes vide (ekspress variants šeit) un XNA platforma (šeit). Pēc XNA uzstādīšanas, vizuālajā studijā veidojot jaunu projektu būs pieejama jauna sadaļa "XNA Game Studio 3.0".

Jauns XNA projekts

Šīs ierakstu sērijas gaitā mēģināšu izveidot vienkāršu spēli, kurā lidināsies un šaudīsies kosmosa kuģīši, tādēļ nosaucu projektu par "Lidinatoru". Nosaukums ir par godu kādai spēlei, kuras izveidē, lai gan ļoti minimāli iznāca piedalīties laikā, kad mācījos vidusskolā (tas bija tik sen, ka datoriem operatīvās atmiņas un cieto disku apjomu vēl mērīja megabaitos).

Jaunizveidotajā projektā jau ir iekļauts "spēles" skelets, kuru tālāk ir tikai jāpapildina. Sākotnēji tas tikai attēlo rudzupuķu1 zilu logu, kurš var tikt aizvērts ar loga aizvēršanas standarta "krustiņu", vai nospiežot "back" pogu uz XBox kontroliera.

lidinatora pirmais ekrāns - rudzupuķu zils

Lai gan XNA piedāvā dažādas 3D grafikas iespējas, sākumā iemēģināšu roku 2D gariņgrafikā2. Izmantojot visas savas necilās zīmēšanas spējas uzzīmēju kaut ko attāli līdzīgu kosmiskajam kuģim

Kosmosa kuģa "sprite"

Lai pievienotu bildi projekta resursiem, jāspiež ar peles labo taustiņu uz "Content" sadaļas "Solution explorer" logā un jāizvēlas "Add Existing Item" punkts no uznirstošās izvēlnes. Pēc resursa pievienošanas var pamainīt dažādus parametrus, bet šobrīd tas nav aktuāli. Vienīgais, ko vajadzētu ievērot ir resursa identifikators "Asset Name".

Lai varētu spēlē izmantot resursu, to ir nepieciešams ielādēt atmiņā. Lai to izdarītu ir nepieciešams papildināt LoadContent() metodi spēles skeletā. Sākotnēji šī metode izskatās šādi:

        /// <summary>
///
LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

// TODO: use this.Content to load your game content here
}

Lai ielādētu jaunizveidoto resursu ir jāizmanto satura menedžeris, kurš ir inicalizēts Game klases Content īpašībā. Satura menedžeris satur "generic" metodi Load() resursu ielādēšanai.

Papildinātais LoadContent() kods:

        protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);

shipSprite = Content.Load<Texture2D>("ship_sprite");
}

Spēles skeletā jau ir paredzēta metode ekrāna atjaunošana, tādēļ atliek tikai to papildināt, lai parādītu kosmosa kuģi uz ekrāna. Gariņu zīmēšana jāizmanto SpriteBatch klase, kas ir paredzēta vairāku gariņu attēlošanai vienā piegājienā. Sākumā zīmēšana ir jāuzsāk ar Begin() metodi, tad jāveic visas vajadzīgās darbības un beigās viss jāizpilda ar End() metodi. Manuprāt, vienkāršāk to ir saprast no koda:

        /// <summary>
///
This is called when the game should draw itself.
/// </summary>
/// <param name=
"gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);

spriteBatch.Begin();
spriteBatch.Draw(
shipSprite,
new Vector2(100, 100),
Color.White);
spriteBatch.End();

base.Draw(gameTime);
}

Visa šī darba rezultāts redzams nākošajā attēlā.

Lidinators uz zilo debesu fona

Nākošajā turpinājumā mēģināšu "Lidinatoru" padarīt dinamiskāku.

 

 


 

1 Interesanti, ka angliski rudzupuķes ir "kukurūzas puķes". Acīmredzot tās mīl augt kopā ar graudaugiem.

2 Man ļoti patīk šis termins.

Piektdienas krikumi

Lai piektdienas dienā pārāk nesaspringtu ar visādām gudrām lietām, pastāstīšu par dažādām ar .NET platformu saistītām lietām, par kurām diez vai izdosies uzrakstīt garākus aprakstus.

Vakar no PDC videomateriāliem, noskatījos Džefa Kinga "TL48 Microsoft Visual Studio: Web Development Futures" un sapratu, ka jau ar nepacietību gaidu, kad varēšu ikdienā izstrādāt izmantojot Visual Studio 2010. Iemesls? Jau kopš 2005 studijas laikiem gaidu, kad HTML redaktorā tiks atbalstīti"snippets". 2010 versijā tie ne tikai ir atbalstīti, bet jau "out-of-the-box" nāks vairāki simti šo "snippets", kas ļaus daudz ātrāk izstrādāt web lappušu dizainu (šim bija vienkārši graujoša demonstrācija). Ja godīgi, tad priekš šis jaunums aizēnoja visus pārējos (uzlabots Javascript Intellisense mehānisms, labāks CSS atbalsts dizainerī, atvieglots "deployment" process).

Vēl pamanīju, ka klusi, klusi ir iznākusi jauna versija XNA Game Studio. Tiem, kas nezin, varu pastāstīt, ka XNA ir platforma, kas ļauj izstrādāt spēles, kas darbojās uz Windows, XBOX 360  un Zune platformām. Savukārt Game Studio ir  Visual studio papildinājums, kuru var lietot arī ar Visual C# 2008 Express Edition. Vienmēr esmu gribējis uzprogrammēt kādu spēli, kā arī sīkāk pastāstīt par XNA platformas iespējam, bet izskatās, ka tuvākajā laikā nesanāks :(

Atskatoties uz C# 4.0 jaunajām iespējām, kā arī uz to, kā C# ir attīstījies 2.0 un 3.0 versijās, man ir radusies teorija, par to, kur evolūcijas gaitā nonāks C#. Manuprāt, tas evolucionēs uz valodu, kas būs līdzīga vienai no esošajām valodām, t.i Javascript. Kā piemēru varu minēt, paplašinājuma metodes (Extension Methods), ko varētu uzskatīt par prototipa mantošanas simulāciju klašu mantošanas valodā. Ok, mans viedoklis ir ļoti subjektīvs, jo, par spīti, ka es to ne pārāk labi protu pielietot, man ļoti patīk Javascript valoda.

Savukārt, tiem, kuriem vēl nākas strādāt ar DataSetiem un saprast, kas ir par iemeslu baismajai ConstraintException, varu ieteikt izlasīt šo nelielo padomu.

Un neaizmirstiet labi atpūsties garajās brīvdienās!

PDC videomateriāli

Lielākā daļa no izstrādātājiem, kas strādā ar Microsoft produktiem vismaz ir dzirdējuši par Professional Developers Conference, kas notika pirms pāris nedēļām. Vakar, skatoties videomateriālus no šīs konferences es sapratu, ka neviens no dotnet.lv rakstniekiem nav informējis par to, kur šie video ir pieejami.

Viena vieta ir Channel 9 PDC2008 RSS plūsma, kuru ir ērti izmatot, ja lieto kādu podcastu klientu. Arī PDC lapā ir atrodams videomateriālu katalogs, tiesa tas ved uz to pašu Channel 9.

Ja ir vēlme novilkt visus video izmantojot kādu no lejupielādes pārvaldniekiem, tad šeit var atrast teksta failu ar video failu sarakstu. Jābrīdina, ka visi video esot ap 40 GB.

Kaut kur manīju ieteikumu skatīties HQ materiālus, jo tajos esot "attēls attēlā", t.i. gan uzstāšanās, gan slaidi tiek rādīti vienlaicīgi. Par to, ka tas tā ir paspēju pārliecināties, bet nevaru apgalvot ka tā nav zemākas kvalitātes materiālos. Lejupielādes ātrums bija pietiekams, lai nesaspringtu par faila izmēriem, tāpēc vilku HQ materiālus.

Strādāšana attālināti

Sveiki!

Pēdējās dienās esmu nedaudz pieklusis. Kā attaisnojumu varu minēt to, ka rudens ir spējis mani saslimdināt, tāpēc būšu slinks un ievietošu tikai atstāstītu padomu no Sāras Fordas Visual Studio padomiem. Konkrētais padoms mani ieinteresēja ar to, ka slimošanas laikā es reizēm mēdzu pieslēgties darbam. Tā kā mājās man ir viens monitors, bet darba datoram divi, tad ir apnicis katru reizi pārkārtot Visual Studio logus atkarībā no pieejamās ekrāna platības.

Izrādās, ka Visual Studio komandrindas slēdzis /ResetSettings ne tikai ļauj atjaunot noklusētos uzstādījumus, bet arī ielādēt norādīto uzstādījumu failu, līdz ar to, viss kas ir jādara ir:

  1. Jāizveido vēlamais izkārtojums vienam vai diviem monitoriem;
  2. Ar Tools -> Import / Export Settings palīdzību jāizeksportē General Settings / Window Layouts sadaļa;
  3. Jāizveido saīsne (tā laikam latviskojas "shortcut"), kas atver "<drive:>\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe" /ResetSettings <konfigurācija>.vssettings

Nu un tālāk tikai jālaiž Visual Studio, izmantojot pareizo saīsni vienam vai diviem monitoriem. Sīkums, bet ērti.

Neaizmirstiet parakstīties uz Sāras RSS plūsmu!

Oriģinālais raksts

LINQ to SQL pret LINQ to Entities

Vakar ADO.NET komandas blogā atradu interesantu rakstu par LINQ to SQL un LINQ to Entities nākotnes plāniem. Lai gan tiešā tekstā nav teikts, izskatās, ka vienkāršais SQL variants tiek nostumts malā un vairs būtiski attīstīts netiks.

Lai gan es tikai sāku apgūt LINQ piedāvātās iespējas un neesmu jomas eksperts, šis paziņojums izraisa dalītas emocijas. No vienas puses LINQ izmantošana lai "automaģiski" veidot SQL vaicājumus nebūt nav tā svarīgākā lieta, kas būtu vajadzīga. Man vairāk liekas noderīga LINQ to Objects funkcionalitāte, kas ļauj veikt datu atlasi no objektiem, līdzīgi kā tiek veikta datu atlase no datubāzes tabulām.

No otras puses, LINQ to SQL varētu būt ērtāks nelieliem projektiem, kur nav nepieciešamības pēc visām Entity Framework piedāvātajām iespējām. Un tādos gadījumos tas, manuprāt, ir ērtāks par ADO.NET datu kopām (DataSet). Lai gan, ja arī šis projekts vairs netiks īpaši attīstīts, visticamākais, tas nekur nepazudīs un vienkāršajiem lietošanas scenārijiem būs pieejams.

Vienkāršs atkļūdošanas palīgs

Bieži vien, atkļūdojot kādu koda fragmentu mēs vēlamies ātri identificēt objekta instanci un redzēt tās nozīmīgākos datus. Lai to redzētu uzraudzīto objektu ("Watch") logā, bieži nākas "uzraudzīt" vairākas viena objekta īpašības. Ja apskatām personas klasi, kas sastāv no vārda, uzvārda un personas koda,

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Code { get; set; }
    }

tad tas varētu izskatīties apmēram šādi:

debuging_1

Neērti, un pie sarežģītākas objektu struktūras paliek vēl neērtāk. Dzīvi (vismaz atkļūdošanu) var padarīt ērtāku, ja objektam pārraksta ToString() metodi, lai tā atgrieztu svarīgāko objekta informācija teksta formā. T.i. šajā gadījumā papildinot Person klasi ar ToString() metodi

    class Person
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Code { get; set; }

        public string ToString()
        {
            return FirstName + " " + LastName + ", " + Code;
        }
    }

Atkļūdošanā var redzēt svarīgo informāciju jau tajā rindā, kurā ir izvēlētais objekts:

debuging_2

Ja šeit šī iespēja varētu arī nelikties tik iespaidīga, tad īpaši dzīvi tā atvieglo Visual Studio atkļūdošanas režīma konteksta izvēlnē. Salīdziniet paši:

debuging_4

debuging_3

Veiksmīgu atkļūdošanu!

Pastaiga pa .NET bibliotēku tumšajiem kambariem

Sveiki! Izdomāju, ka šis vēsais rudens rīts ir lieliski piemērots nelielai ekskursijai pa .NET bibliotēkas zināmājām un ne tik zināmajām lietām. Vienkārši, braucot uz darbu, ienāca prātā, ka vajadzētu pastāstīt par System.IO vārdu telpas (kā gan lai tulko "namespace"?) klasi Path un tās metodi Combine().

Tātad, Path.Combine(). Path.Combine() ir paredzēts, lai savienotu divus failu sistēmas ceļus. Piemēram, ir dots kāds pamatceļš, teiksim, kur atrodas visi resursi un zināms, ka attēli atrodas apakškatalogā images. Kā dabūt ceļu uz attēlu ar nosaukumu image_1.png?

Pirmais variants, kas varētu ienākt prātā ir simbolu virkņu konkatenācija:

var basePath = "c:\\Resources\\";
var imagePath = "Images\\";
var fileName = "image_1.png";

var fullPath = String.Concat(basePath, imagePath, fileName);

Tomēr šādai pieejai ir acīmredzami trūkumi. Kas notiek, ja kādam no ceļiem beigās nav slīpsvītras? Vai gluži otrādi - ja slīpsvītra ir sākumā? Kods ātri vien izaug:

var basePath = "c:\\Resources\\";
var imagePath = "Images\\";
var fileName = "image_1.png";

if (!basePath.EndsWith("\\"))
{
    basePath = basePath + "\\";
}
if (imagePath.StartsWith("\\"))
{
    imagePath = imagePath.Substring(1, imagePath.Length - 1);
}
if (!imagePath.EndsWith("\\"))
{
    imagePath = imagePath + "\\";
}
if (fileName.StartsWith("\\"))
{
    fileName = fileName.Substring(1, imagePath.Length - 1);
}

var fullPath = String.Concat(basePath, imagePath, fileName);

Evolūcijais gaitā no šāda koda rodās palīgmetodes, kuras nākas uzturēt, labot un papildināt. Lai vienkāršotu dzīvi, .NET platformas izstrādātāji piedāvā sākumā minēto Path.Combine() metodi.

 

var basePath = "c:\\Resources\\";
var imagePath = "Images\\";
var fileName = "image_1.png";

var fullPath = Path.Combine(
        Path.Combine(basePath, imagePath),
        fileName);

Kā zināms, vislabākais kods ir tas kods, kurš nav jāraksta. Domāju, ka Path.Combine() ir paredzēti un tiek apstrādāti daudz vairāk gadījumi, kā mums var ienākt prātā. Kā mazu trūkumu pieminēt tikai to, ka Path.Combine() vienlaicīgi spēj savienot tikai divus ceļus, kas mūsu piemērā noveda pie iekļauta izsaukuma.

Veiksmīgu kodēšanu, un gaidiet citas rudenīgās pastaigas pa tumšajiem un putekļainajiem .NET nostūriem.

Mazais vienkāršais

Ar ko Jūs sākāt programmēt? Es nezinu, kāda valoda šobrīd kalpo, lai "saslimdinātu" ar programmēšanu, bet savulaik tas bija beisiks. Sākumā uz papīra, pēc grāmatas "Kā Pēcis Beisikāns Maiju Saprātiņu programmēt mācīja", vēlāk kādā nezināmā dialektā pie termināļiem, vēl vēlāk QBasic un TurboBasic...

Diemžēl, QBasic vairs nenāk komplektā ar Windows (pēc  Wikipedia datiem, kopš ME versijas), tāpēc es arī nezinu ar ko sāk apgūt programmēšanu. Zinu tikai, ka Microsoft DevLabs ir pieejams mazais vienkāršais SmallBasic, kurš ir balstīts uz tradicionālo BASIC un izmanto .NET platformu.

Pēc ātrās instalācijas mūsu rīcībā ir SmallBasic IDE, kurā jau tūlīt var sākt izstrādi un elektroniskā rokasgrāmata.

paint.net_1 

Pirmais, ko ievēroju - diemžēl nav pierasto PRINT un INPUT komandu :( Otrais - ir rupučgrafikas iespējas. Vairāk paspēlējoties sapratu, ka masīvi ir norealizēti izcili jocīgi.

Kopumā diezgan interesanti, lai gan man labāk patiktu, ja būtu tuvāk "klasiskajai" BASIC sintaksei. Sākt programmēt ir salīdzinoši vienkārši, piemēram, "Sveika, pasaule!" var izvadīt ar vienu rindiņu:

TextWindow.WriteLine("Sveika, pasaule!");

Skatīsimies, kas no mazā beisika izaugs nākotnē, bet jau šobrīd to var izmantot, lai mācītu programmēšanas pamatus.