Frage

Wie kann ich diese Funktionalität in meinem Spiel, durch die die Spieler ihre Frisur ändern können, schauen, Stil der Kleidung, usw., und so, wenn sie ein anderes Kleidungsstück tragen ihren Avatar mit ihm aktualisiert wird.

Soll ich:

  • Habe meine Designer alle möglichen Kombinationen von Rüstung, Frisuren erstellen, und Gesichter als Sprites (dies viel Arbeit sein könnte).

  • Wenn der Spieler wählt, was sie während ihrer Einführung in dem Spiel aussehen sollten, würde mein Code automatisch diesen Sprit erstellen, und alle möglichen Kombinationen von Kopfbedeckungen / Rüstung mit diesem Sprit. Dann wird jedes Mal, wenn sie eine andere Rüstung auswählen, das Sprit für die Rüstung / Aussehen Kombination geladen wird.

  • Ist es möglich, ein Zeichen der Sprite in Komponenten aufgeteilt zu haben, wie Gesicht, Hemd, Jeans, Schuhe und haben die Pixelmaße von jedem von diesen. Dann, wenn der Spieler seinen Helm ändert, zum Beispiel verwenden wir die Pixelabmessungen den Helm Bild zu setzen anstelle von wo sein Gesichtsbild normalerweise sein. (Ich bin Java mit diesem Spiel zu bauen)

  • Ist das in 2D nicht möglich und ich soll 3D verwenden dafür?

  • Jede andere Methode?

Bitte beraten.

War es hilfreich?

Lösung

3D wird dies nicht notwendig sein, aber der Maler-Algorithmus, der in der 3D-Welt üblich ist, könnte IMHO Ihnen etwas Arbeit sparen:

Der Maler-Algorithmus arbeitet, indem sie die am weitesten entfernten Objekte zuerst zeichnen, dann mit Objekten näher an der Kamera Überziehungen. In Ihrem Fall würde boild es zu erzeugen, den Puffer für Ihre Sprite nach unten, es auf die Puffer zeichnen, den nächsten abhängigen Sprite-Teil zu finden (zB Rüstung oder Dingsbums), zeichnet, dass die Suche nach dem nächsten abhängigen Spriten-Teils (dh eines besonderen schreiben, das ist auf der Rüstung), und so weiter. Wenn es keine weiteren abhängigen Teile sind, können Sie die vollen erzeugte Sprite malen auf die Anzeige der Benutzer sieht.

Die combinated Teile sollten einen Alphakanal (RGBA statt RGB), so dass Sie nur Teile kombiniert werden, die einen Alpha-Wert auf einen Wert Ihrer Wahl einstellen. Wenn Sie nicht, dass aus irgendeinem Grunde tun, nur Stick mit einer RGB-Kombination, die Sie als transparent behandelt werden.

3D verwenden, kann die Teile leichter machen kombiniert, und Sie würden nicht einmal einen Offscreen-Puffer verwenden oder die Pixel Combinating Code zu schreiben. Die Kehrseite ist, dass man ein wenig 3D lernen müssen, wenn Sie es noch nicht wissen. :-)

Bearbeiten antworten Kommentar:

Das Kombinationsteil wie dieses etwas funktionieren würde (in C ++, Java wird ziemlich ähnlich sein - bitte beachten Sie, dass ich nicht den Code unten durch einen Compiler ausgeführt haben):

// 
// @param dependant_textures is a vector of textures where 
// texture n+1 depends on texture n. 
// @param combimed_tex is the output of all textures combined
void Sprite::combineTextures (vector<Texture> const& dependant_textures, 
                              Texture& combined_tex) {
   vector< Texture >::iterator iter = dependant_textures.begin();
   combined_tex = *iter;

   if (dependant_textures.size() > 1)
     for (iter++; iter != dependant_textures.end(); iter++) {
        Texture& current_tex = *iter;

        // Go through each pixel, painting:
        for (unsigned char pixel_index = 0; 
             pixel_index < current_tex.numPixels(); pixel_index++) {
           // Assuming that Texture had a method to export the raw pixel data
           // as an array of chars - to illustrate, check Alpha value:
           int const BYTESPERPIXEL = 4; // RGBA
           if (!current_tex.getRawData()[pixel_index * BYTESPERPIXEL + 3]) 
              for (int copied_bytes = 0; copied_bytes < 3; copied_bytes++)
              {
                int index = pixel_index * BYTESPERPIXEL + copied_bytes;
                combined_tex.getRawData()[index] = 
                   current_tex.getRawData()[index];
              }               
        }
     }
}

Ihre Frage für eine 3D-Lösung zu beantworten, würde man einfach Rechtecke mit ihren jeweiligen Texturen zeichnen (das wäre einen Alpha-Kanal) übereinander. Sie würden das System eingerichtet in einem orthogonalen Modus angezeigt werden (für OpenGL: gluOrtho2D()).

Andere Tipps

Ein wichtiger Faktor zu berücksichtigen ist, Animation. Wenn ein Charakter Rüstung mit Schulterpolstern hat, müssen diese shoulderpads können mit seinem Oberkörper bewegen. Ebenso, wenn er Stiefel trägt, haben diejenigen, die gleichen Zyklen wie versteckte nackten Füßen folgen würde.

Im Grunde brauchen Sie für Ihre Designer, was ist ein Sprite Blatt , die können Sie Ihre Künstler alle möglichen Rahmen der Animation für Ihre Basiszeichen zu sehen. Sie haben dann sie individuelle Frisuren, Stiefel, Rüstungen erstellen usw. auf der Grundlage dieser Blätter. Ja, es ist eine Menge Arbeit, aber in den meisten Fällen werden die Elemente eine minimale Menge an neu gezeichnet erfordern; Stiefel sind das einzige, was ich da sie über mehrere Frames der Animation zu ändern, neu zu erstellen eine Menge Arbeit wirklich sehen konnte, nehmen. Seien Sie rutheless mit Sprites, versuchen, die erforderliche Anzahl so weit wie möglich zu reduzieren.

Nachdem Sie eine Bibliothek von Elementen angehäuft haben, können Sie betrügen starten. Bereiten Sie die gleiche Frisur und passen ihre Farbe entweder in Photoshop oder direkt im Spiel mit Schiebern in Ihrem Charakter Schöpfer.

Der letzte Schritt, gute Leistung im Spiel zu gewährleisten, wäre all die verschiedenen Elemente Blätter Sprite in ein einzelnes Blatt Sprite zu glätten, die dann aufgespalten und in Sprite-Puffern gespeichert.

ich mit dem Verfahren Generation Lösung (# 2). Solange es keine limitierenden Menge von Sprites ist erzeugt werden, so dass die Erzeugung zu lange dauert. Vielleicht die Erzeugung tun, wenn jedes Element erfaßt wird, um die Last zu senken.

Da ich in den Kommentaren gefragt wurde, Art und Weise als gut ein 3D zu liefern, hier einige, dass ein Auszug einiger Codes, den ich vor längerer Zeit geschrieben. Es ist OpenGL und C ++.

Jeder Sprit würde fragt mich zu ziehen. die Adapter-Muster verwendet, würde ich Sprites verbinden - dh, es wäre Sprites, die zwei oder mehr Sprites halten würden, das eine (0,0) relative Position und einen Sprit mit einer realen Position all dieses „Unter“ Sprites mit hatte.

void Sprite::display (void) const
{
  glBindTexture(GL_TEXTURE_2D, tex_id_);
  Display::drawTranspRect(model_->getPosition().x + draw_dimensions_[0] / 2.0f,
      model_->getPosition().y + draw_dimensions_[1] / 2.0f,
      draw_dimensions_[0] / 2.0f, draw_dimensions_[1] / 2.0f);
}

void Display::drawTranspRect (float x, float y, float x_len, float y_len)
{   
  glPushMatrix();

  glEnable(GL_BLEND);   
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glColor4f(1.0, 1.0, 1.0, 1.0);

  glBegin(GL_QUADS);        
    glTexCoord2f(0.0f, 0.0f); glVertex3f(x - x_len, y - y_len, Z);
    glTexCoord2f(1.0f, 0.0f); glVertex3f(x + x_len, y - y_len, Z);
    glTexCoord2f(1.0f, 1.0f); glVertex3f(x + x_len, y + y_len, Z);
    glTexCoord2f(0.0f, 1.0f); glVertex3f(x - x_len, y + y_len, Z);
  glEnd();

  glDisable(GL_BLEND);  
  glPopMatrix();
}

Der tex_id_ ist ein integraler Wert, der die Textur identifiziert zu OpenGL verwendet wird. Die relevanten Teile der Textur-Manager sind diese. Der Textur-Manager emuliert tatsächlich einen Alpha-Kanal durch Prüfen, ob die gelesene Farbe ist reines Weiß (RGB von (ff, ff, ff)) - der Code arbeitet auf loadfile 24 Bit pro Pixel BMP-Dateien:

TextureManager::texture_id 
TextureManager::createNewTexture (Texture const& tex) {
    texture_id id;
    glGenTextures(1, &id);
    glBindTexture(GL_TEXTURE_2D, id);

    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);   
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);       
    glTexImage2D(GL_TEXTURE_2D, 0, 4, tex.width_, tex.height_, 0, 
        GL_BGRA_EXT, GL_UNSIGNED_BYTE, tex.texture_);

    return id;
}

void TextureManager::loadImage (FILE* f, Texture& dest) const {
  fseek(f, 18, SEEK_SET);
  signed int compression_method;
  unsigned int const HEADER_SIZE = 54;

  fread(&dest.width_, sizeof(unsigned int), 1, f);
  fread(&dest.height_, sizeof(unsigned int), 1, f);
  fseek(f, 28, SEEK_SET);
  fread(&dest.bpp_, sizeof (unsigned short), 1, f);
  fseek(f, 30, SEEK_SET);
  fread(&compression_method, sizeof(unsigned int), 1, f);

  // We add 4 channels, because we will manually set an alpha channel
  // for the color white.
  dest.size_ = dest.width_ * dest.height_ * dest.bpp_/8 * 4;
  dest.texture_ = new unsigned char[dest.size_];
  unsigned char* buffer = new unsigned char[3 * dest.size_ / 4];    

  // Slurp in whole file and replace all white colors with green
  // values and an alpha value of 0:
  fseek(f, HEADER_SIZE, SEEK_SET);      
  fread (buffer, sizeof(unsigned char), 3 * dest.size_ / 4, f); 
  for (unsigned int count = 0; count < dest.width_ * dest.height_; count++) {       
    dest.texture_[0+count*4] = buffer[0+count*3];
    dest.texture_[1+count*4] = buffer[1+count*3];
    dest.texture_[2+count*4] = buffer[2+count*3];
    dest.texture_[3+count*4] = 0xff;

    if (dest.texture_[0+count*4] == 0xff &&
        dest.texture_[1+count*4] == 0xff &&
        dest.texture_[2+count*4] == 0xff) {
      dest.texture_[0+count*4] = 0x00;
      dest.texture_[1+count*4] = 0xff;
      dest.texture_[2+count*4] = 0x00;
      dest.texture_[3+count*4] = 0x00;
      dest.uses_alpha_ = true;
    }                   
  }
  delete[] buffer;          
}

Das war eigentlich eine kleine Jump'nRun, die ich gelegentlich in meiner Freizeit entwickelt. Es verwendet gluOrtho2D Modus () als gut, btw. Wenn Sie Mittel verlassen, Sie zu kontaktieren, werde ich Ihnen die Quelle senden, wenn Sie wollen.

Ältere 2d Spiele wie Diablo und Ultima Online verwenden, um eine Sprite-Compositing-Technik, um dies zu tun. Sie könnten für die Kunst aus dieser Art von älteren 2d isometrischer Spielen suchen, um zu sehen, wie sie es getan haben.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top