Thread overview
D ile yazılmış bir oyun: ICE
Dec 21, 2012
Salih Dinçer
Dec 21, 2012
Salih Dinçer
December 20, 2012

http://icegame.nfshost.com/pages/screenshots.html

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 21, 2012

Derelict alt yapısı üzerine çoğunlukla override yapılarak baştan kurulmuş ilginç bir motor olmuş...

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 21, 2012

Alıntı:

>

states_[ButtonState.Normal].borderColor = rgba!"C0C0FF60";

Renk (rgba) şablonunu çok beğendim, akıllıca özellikler içeriyor...


//          Copyright Ferdinand Majerech 2010 - 2012.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE_1_0.txt or copy at
//          http://www.boost.org/LICENSE_1_0.txt)


///RGBA Color struct and utility functions.
module color;


import std.algorithm;
import std.random;
import std.string;
import std.traits;

import math.math;
import util.unittests;


///Represents color formats used by images and screen.
enum ColorFormat
{
   ///16-bit RGB without alpha.
   RGB_565,
   ///24-bit RGB.
   RGB_8,
   ///32-bit RGBA.
   RGBA_8,
   ///8-bit grayscale.
   GRAY_8
}

/**
* Return number of bytes specified color format uses per pixel.
*
* Params:  format = Color format to check.
*
* Returns: Bytes per pixel needed by specified color format.
*/
uint bytesPerPixel(const ColorFormat format) pure
{
   final switch(format)
   {
       case ColorFormat.RGB_565: return 2;
       case ColorFormat.RGB_8:   return 3;
       case ColorFormat.RGBA_8:  return 4;
       case ColorFormat.GRAY_8:  return 1;
   }
}

///32-bit RGBA8 color.
struct Color
{
   ///Red channel.
   ubyte r;
   ///Green channel.
   ubyte g;
   ///Blue channel.
   ubyte b;
   ///Alpha channel.
   ubyte a = 255;

   ///Common color constants, identical to HTML.
   static immutable white        = rgb!"FFFFFF";
   static immutable grey         = rgb!"888";
   static immutable black        = rgb!"000";

   static immutable red          = rgb!"FF0000";
   static immutable green        = rgb!"00FF00";
   static immutable blue         = rgb!"0000FF";
   static immutable burgundy     = rgb!"800";

   static immutable yellow       = rgb!"FFFF00";
   static immutable cyan         = rgb!"00FFFF";
   static immutable magenta      = rgb!"FF00FF";
   static immutable forestGreen = rgb!"880";
   static immutable darkPurple  = rgb!"808";

   /**
    * Construct a color.
    *
    * Params:  r = Red channel value.
    *          g = Green channel value.
    *          b = Blue channel value.
    *          a = Alpha channel value.
    */
   this(const ubyte r, const ubyte g, const ubyte b, const ubyte a) pure
   {
       this.r = r;
       this.g = g;
       this.b = b;
       this.a = a;
   }

   ///Comparison for sorting.
   int opCmp(ref const Color c) const pure nothrow
   {
       return r != c.r ? r - c.r :
              g != c.g ? g - c.g :
              b != c.b ? b - c.b :
              a != c.a ? a - c.a :
                         0;
   }

   ///Return the average RGB intensity of the color.
   @property ubyte average() const
   {
       const real average = (r + g + b) / 3.0L;
       return round!ubyte(average);
   }
   ///Unittest for average().
   private static void unittestAverage()
   {
       Color color = Color(253, 254, 255, 255);
       assert(color.average == 254);
       color = Color(253, 253, 254, 255);
       assert(color.average == 253);
       color = Color(253, 254, 254, 255);
       assert(color.average == 254);
       color = Color(0, 0, 1, 255);
       assert(color.average == 0);
       color = Color(255, 255, 255, 255);
       assert(color.average == 255);
   }

   ///Return lightness of the color.
   @property ubyte lightness() const
   {
       uint d = max(r, g, b) + min(r, g, b);
       return round!ubyte(0.5f * d);
   }

   ///Return luminance of the color.
   @property ubyte luminance() const
   {
       return round!ubyte(0.3 * r + 0.59 * g + 0.11 * b);
   }
   ///Unittest for luminance().
   private static void unittestLuminance()
   {
       Color color = Color(253, 254, 255, 255);
       assert(color.luminance == 254);
   }

   ///Add two colors (values are clamped to range 0 .. 255).
   Color opBinary(string op)(const Color c) const pure if(op == "+")
   {
       return Color(cast(ubyte)min(255, r + c.r),
                    cast(ubyte)min(255, g + c.g),
                    cast(ubyte)min(255, b + c.b),
                    cast(ubyte)min(255, a + c.a));
   }
   ///Unittest for opBinary!"+"
   private static void unittestPlus()
   {
       Color color1 = Color(253, 254, 255, 255);
       Color color2 = Color(128, 0, 87, 42);
       Color color3 = Color(3, 145, 192, 17);
       assert(color1 + color2 == Color(255, 254, 255, 255));
       assert(color2 + color3 == Color(131, 145, 255, 59));
       assert(color3 + color1 == Color(255, 255, 255, 255));
   }

   ///Multiply a color by a float (values are clamped to range 0 .. 255).
   Color opBinary(string op)(const float m) const if(op == "*")
   {
       return Color(round!ubyte(clamp(r * m, 0.0f, 255.0f)),
                    round!ubyte(clamp(g * m, 0.0f, 255.0f)),
                    round!ubyte(clamp(b * m, 0.0f, 255.0f)),
                    round!ubyte(clamp(a * m, 0.0f, 255.0f)));
   }
   ///Unittest for opBinary!"*"
   private static void unittestMultiply()
   {
       Color color1 = Color(128, 128, 128, 128);
       Color color2 = Color(255, 255, 255, 255);
       assert(color1 * 0.5 == color2 * 0.25);
       assert(color1 * 0.5 == Color(64, 64, 64, 64));
   }

   ///Add a color to this color (values are clamped to range 0 .. 255).
   void opOpAssign(string op)(const Color c) pure if(op == "+")
   {
       this = this + c;
   }
   ///Unittest for opOpAssign!"+"
   private static void unittestPlusAssign()
   {
       Color color1 = Color(253, 254, 255, 255);
       Color color2 = Color(128, 0, 87, 42);
       Color color3 = Color(3, 145, 192, 17);
       color1 += color2;
       color2 += color3;
       color3 += color1;
       assert(color1 == Color(255, 254, 255, 255));
       assert(color2 == Color(131, 145, 255, 59));
       assert(color3 == Color(255, 255, 255, 255));
   }

   ///Multiply this color by a float (values are clamped to range 0 .. 255).
   void opOpAssign(string op)(const float m) if(op == "*")
   {
       this = this * m;
   }
   ///Unittest for opOpAssign!"*"
   private static void unittestMultiplyAssign()
   {
       Color color1 = Color(128, 128, 128, 128);
       Color color2 = Color(255, 255, 255, 255);
       color1 *= 0.5;
       color2 *= 0.25;
       assert(color1 == color2);
       assert(color1 == Color(64, 64, 64, 64));
   }

   /**
    * Interpolate this color to another color.
    *
    * Params:  c = Color to interpolate with.
    *          d = Interpolation ratio. 1 is this color, 0 other color, 0.5 half in between.
    *              Must be in 0.0 .. 1.0 range.
    */
   Color interpolated(const Color c, const float d) const
   in{assert(d >= 0.0 && d <= 1.0, "Color interpolation value must be between 0.0 and 1.0");}
   body
   {
       const dByte   = floor!ubyte(d * 255.0);
       const invByte = cast(ubyte)(255 - dByte);

       //ugly, but fast
       //colors are multiplied as ubytes from 0 to 255 and then divided by 256
       return Color(cast(ubyte)((r * dByte + c.r * invByte) >> 8),
                    cast(ubyte)((g * dByte + c.g * invByte) >> 8),
                    cast(ubyte)((b * dByte + c.b * invByte) >> 8),
                    cast(ubyte)((a * dByte + c.a * invByte) >> 8));
   }

   ///Set grayscale color.
   @property void gray8(const ubyte gray) pure {r = g = b = a = gray;}

   ///Gamma correct the color with specified factor.
   void gammaCorrect(const real factor) pure
   in{assert(factor >= 0.0, "Can't gamma correct with a negative factor");}
   body
   {
       real scale = 1.0;
       real temp = 0.0;
       real R = cast(real)r;
       real G = cast(real)g;
       real B = cast(real)b;
       const real factorInv = factor / 255.0;
       R *= factorInv;
       G *= factorInv;
       B *= factorInv;
       if (R > 1.0 && (temp = (1.0 / R)) < scale) scale = temp;
       if (G > 1.0 && (temp = (1.0 / G)) < scale) scale = temp;
       if (B > 1.0 && (temp = (1.0 / B)) < scale) scale = temp;
       scale *= 255.0;
       R *= scale;
       G *= scale;
       B *= scale;
       r = cast(ubyte)R;
       g = cast(ubyte)G;
       b = cast(ubyte)B;
   }

   ///Return a random color with full opacity.
   static Color randomRGB()
   {
       Color result;
       result.r = cast(ubyte)uniform(0, 256);
       result.g = cast(ubyte)uniform(0, 256);
       result.b = cast(ubyte)uniform(0, 256);
       result.a = 255;
       return result;
   }

   /**
    * Gamma correct a GRAY_8 color.
    *
    * Params:  color  = Color (grayscale) to gamma correct.
    *          factor = Gamma correction factor.
    *
    * Returns: Gamma corrected color.
    */
   static ubyte gammaCorrect(const ubyte color, const real factor) pure
   in
   {
       assert(factor >= 0.0, "Can't gamma correct with a negative factor");
   }
   body
   {
       return cast(ubyte)min(cast(real)color * factor, 255.0L);
   }
}
mixin registerTest!(Color.unittestAverage, "Color.average");
mixin registerTest!(Color.unittestLuminance, "Color.luminance");
mixin registerTest!(Color.unittestPlus, "Color.+");
mixin registerTest!(Color.unittestMultiply, "Color.multiply");
mixin registerTest!(Color.unittestPlusAssign, "Color.+=");
mixin registerTest!(Color.unittestMultiplyAssign, "Color.*=");

///RGB color from a hexadecimal string (CSS style), e.g. FFFFFF for white.
template rgb(string c) if(c.length == 6)
{
   enum auto rgb = rgba!(c ~ "FF");
}

///RGBA color from a hexadecimal string (CSS style), e.g. FFFFFF80 for half-transparent white.
template rgba(string c) if(c.length == 8)
{
   enum auto rgba = Color(hexColor(c[0 .. 2]), hexColor(c[2 .. 4]),
                          hexColor(c[4 .. 6]), hexColor(c[6 .. 8]));
}

///RGB color from a short hexadecimal string (CSS style), e.g. FFF for white.
template rgb(string c) if(c.length == 3)
{
   enum auto rgb = rgb!(c[0] ~ "0" ~ c[1] ~ "0" ~ c[2] ~ "0");
}

///RGBA color from a short hexadecimal string (CSS style), e.g. FFF8 for half-transparent white.
template rgba(string c) if(c.length == 4)
{
   enum auto rgba = rgba!(c[0] ~ "0" ~ c[1] ~ "0" ~ c[2] ~ "0" ~ c[3] ~ "0");
}
void unittestRgba()
{
   assert(rgba!"f0F0F0F0" == rgba!"FFFF"  &&
          rgb!"FFF"       == rgb!"F0F0F0" &&
          rgb!"FFF"       == rgba!"F0F0F0FF" &&
          rgb!"FFF"       == Color(240, 240, 240, 255));
}
mixin registerTest!(unittestRgba, "color.rgba");
///Get value of a 2-character hexadecimal sequence corresponding to single color channel.
ubyte hexColor(string hex) pure
{
   assert(hex.length == 2, "Hex string to get color from must have 2 chars");
   hex = toUpper(hex);
   return cast(ubyte)(16 * hexDigit(hex[0]) + hexDigit(hex[1]));
}

private:
///Convert a hexadecimal digit to integer.
auto hexDigit(const char hex) pure
{
   if(hex >= '0' && hex <= '9')     {return hex - '0';}
   else if(hex >= 'A' && hex <= 'F'){return 10 + hex - 'A';}
   assert(false, "'" ~ hex ~ "' is not a hexadecimal digit");
}

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]

December 21, 2012

Haklısın. Çok güzel kod ve benim alıştığım biçimde yazıldığı için de okuması çok kolay geldi. Düşündürdükleri:

  • İşlevleri olabildiğince const, pure, ve nothrow olarak işaretlemek.

  • Ben sabit yerel değişkenlerin immutable olarak işaretlenmelerinin daha doğru olduğunu savunuyorum. Şimdi bu kararı sorgulayacağım: Bunun nedeni, o değişkenin immutable'da ısrar eden işlevlere de gönderilebilmesidir. Ancak, bu konu yalnızca referens türleri için geçerli olmalı. Ayrıca ileride belki immutable isteyen işleve de gönderirim diye kodlamak da ne kadar doğru? Değişkeni şimdiden const yapsak, sonra ileride gerektiğinde immutable olarak tanımlayabiliriz. O yüzden bu kararım yavaş yavaş değişmeye başladı. Değişken tanımlarken immutable yerine const belki daha iyi:

   immutable a = foo();     // gereksizce uzun
   const b = foo();         // hem kısa hem başka dillerden alışıldığı gibi

Ali

--
[ Bu gönderi, http://ddili.org/forum'dan dönüştürülmüştür. ]