Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

15.06.2007, 14:30

Frage::Spielkarte mit Funktionen versehen

Tach,

für ein Strategiespiel möchte ich gerne eine Spielkarte (bmp) mit einer gewissen Funktionalität versehen:

1. Provinzen in der Farbe des Spielers, der sie momentan besitzt,
2. Provinzen sollen anklickbar sein - das Programm muß also merken,
über welcher Provinz der Mauszeiger sich befindet

:?: Wie geht man da am besten vor? Alle Vorschläge sind willkommen!

Danke schon mal,

Gruß Passwort

ChrisJ

Alter Hase

Beiträge: 487

Wohnort: Schweich

Beruf: Schüler

  • Private Nachricht senden

2

15.06.2007, 15:15

wie man genau vorgeht?

zu 1. du könntest eine farbe in der bilddatei für die provinzen durch die spielerfarbe ersetzen, oder komplett in einer farbe einfärben.

zu 2. ich gehe davon aus, dass du ein 2d spiel programmieren möchtest...
entweder du prüfst pixel für pixel ob sich der mauszeiger über dem bild einer provinz befindet, oder prüft lediglich ob er sich in dem umliegenden rechteck befindet, was meistens ausreicht. wie man sich die angeklickte provinz merken soll? id zuweisen, in eine liste auf nehmen, wie es dir gefällt...

ich weiss ehrlich gesagt nicht, was dein problem ist, sry

3

15.06.2007, 15:21

1: Nimm x+1 Tilesets. Ein neutrales und 1 für jeden Spieler.

2: Speicher ein short array das so groß ist wie du Tiles hast. Dann einfach an der Pos x,y speichern ob es 0(neutral) oder 1-255(Spielernummer) ist

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

4

16.06.2007, 15:18

Ich mache sowas per Colormap.

Man nehme eine normale Textur + eine Textur in denen die verschiedenen Bereiche verschiedene Farben haben.
Aus der Colormap + der Information welchem Spieler welche Bereiche gehören(dem Spieler werden ein oder mehrere Farbwerte zugeordnet ->Colorkey).

Für das Testen über welchen Bereich man ist, holt man sich die Vertices der Objektes mit der normalen Textur, transformiere sie manuell und mache dann einen Linie-Dreieck-Kollisionstest. Über das Dreieck kommt man wiederum an die Texturkoordinate und damit an den Farbwert.

Habe das auch schon gemacht. Suche eben die Datei auf dem SVN.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

5

16.06.2007, 17:32

So.....

das ganz ist mit Irrlicht gemacht, aber das ändert nichts am Grundprinzip.

Das erstellen der Texturen aus der Colormap:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
{
        List<unsigned long> KnownColors;

        size = ParzellenKey->getSize();
        s32 Pcount(size.Height * size.Width);

        unsigned long CToAdd;
        CArray = new unsigned long[Pcount];

        //die Anzahl der Farben feststellen

        {
            char* lockedrect = (char*)ParzellenKey->lock(); 
            switch(ParzellenKey->getColorFormat())
            {
            case ECF_A8R8G8B8:
                {
                    memcpy(CArray, lockedrect, 4 * Pcount);

                    CToAdd = 0xFF000000;
                    KnownColors.push_back(CToAdd);
                    for(s32 counter = 0; counter < Pcount; counter++)
                    {
                        if(!KnownColors.GetElementByContent(CArray[counter]))
                            KnownColors.push_back(CArray[counter]);
                    }
                }break;

            default:
                return;
            }
            ParzellenKey->unlock();
        }
        NumSelectMaps = KnownColors.getSize();

        //Stimmt die Anzahl der Parzellen mit der Anzahl der Farben überein?

        if(NumSelectMaps - 1 != planet->getParzellenCount())
        {
            std::cout<<"Die Anzahl der Parzellen auf der Colormap entspricht nicht der angegeben Anzahl des Planeten. Betroffene Textur: "<< ParzellenKey->getName().c_str() << std::endl;
            return;//error

        }

        //Die dazu gehörige Parzelle und den Besitzer feststellen

        PFrames = new SelectMap[NumSelectMaps];

        List<unsigned long>::Iterator iter  = KnownColors.begin();
        List<Parzelle*>::Iterator temp      = planet->GetParzelle();


        PFrames[0].SelectTexture = smgr->getVideoDriver()->addTexture(size, "", ECF_A8R8G8B8);
        PFrames[0].ColorKey = *iter;
        PFrames[0].parzelle = NULL;
        PFrames[0].OldOwner = NULL;
        PFrames[0].ReplaceColor[0] = 0xFF555555;
        PFrames[0].ReplaceColor[1] = 0xFF000000;

        iter++;
        for(short counter = 1; counter < NumSelectMaps; iter++, counter++, temp++)
        {   
            if(temp == planet->GetParzelleEnd())
                return; //EDIT: Fehler es müssen gleichviele vorhanden sein



            PFrames[counter].SelectTexture = smgr->getVideoDriver()->addTexture(size, "", ECF_A8R8G8B8);
            PFrames[counter].ColorKey = *iter;
            PFrames[counter].parzelle = (*temp);
            PFrames[counter].OldOwner = (*temp)->GetOwner();

            if(!PFrames[counter].OldOwner)  //Kein Besitzer

            {
                PFrames[counter].ReplaceColor[0] = 0xFFFFFFFF;
                PFrames[counter].ReplaceColor[1] = 0xFF999999;
            }
            else if(FVerwaltung::GetFiregalaxy()->Player == PFrames[counter].OldOwner)  //Der Spieler ist der Besitzer

            {
                PFrames[counter].ReplaceColor[0] = 0xFF00FF00;
                PFrames[counter].ReplaceColor[1] = 0xFF009900;
            }
            else if(FVerwaltung::GetFiregalaxy()->Player->GetFraction() == PFrames[counter].OldOwner->GetFraction()) // Der Besitzer ist in der selben Fraktion wie der Spieler

            {
                PFrames[counter].ReplaceColor[0] = 0xFF0000FF;
                PFrames[counter].ReplaceColor[1] = 0xFF000099;
            }
            else    //Der Spieler ist mit dem anderen Verfeindet

            {
                PFrames[counter].ReplaceColor[0] = 0xFFFF0000;
                PFrames[counter].ReplaceColor[1] = 0xFF990000;
            }
        }

        //Auf Basis der oben gesammelten Informationen, werden nun die einzelnen Parzellen auf der Textur eingefärbt

        for(short counter = 0; counter < NumSelectMaps; counter++)
        {   
            //Die einzelnen Textur einfärben

            char* lockedtext = (char*)PFrames[counter].SelectTexture->lock();

            for(s32 counter2 = 0; counter2 < Pcount; counter2++)
            {
                if(CArray[counter2] == 0xFF000000)
                    CToAdd = 0xFF000000;
                else if(CArray[counter2] == PFrames[counter].ColorKey)
                    CToAdd = PFrames[counter].ReplaceColor[0];
                else
                    for(short counter1 = 1; counter1 < NumSelectMaps; counter1++)
                    {
                        if(CArray[counter2] == PFrames[counter1].ColorKey)
                        {
                            CToAdd = PFrames[counter1].ReplaceColor[1];
                            break;
                        }
                    }

                    memcpy(lockedtext + counter2 * 4, &CToAdd, 4);
            }
            PFrames[counter].SelectTexture->unlock();
            PFrames[counter].SelectTexture->regenerateMipMapLevels(); 
        }
    }

Und so findet man raus welcher Bereich gerade selektiert wurde:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
    //Farbe des selektierten Sektor rausfinden

    DWORD SelectedColor;
    {
        vector3df outpoint;
        triangle3df outtri, tri;

        ISceneCollisionManager* Collm = smgr->getSceneCollisionManager();
        line3d<f32> line = Collm->getRayFromScreenCoordinates(Main->GetCursorPos(), Kamera);

        if(!Collm->getCollisionPoint(line, PlanetModell->getTriangleSelector(), outpoint, outtri))
            return;

        vector2df TextPos(0,0);
        PlanetModell->updateAbsolutePosition();

        //Die 3 zu dem Dreieck gehörenden Vertices sammeln bzw. deren Texturkoords

        for(s32 counter = 0; counter < numVertices; counter++)
        {
            vector3df tempvec = Vertices[counter];
            PlanetModell->getAbsoluteTransformation().transformVect(tempvec);

            if(tempvec / 100.0f  == outtri.pointA / 100.0f || tempvec / 100.0f  == outtri.pointB / 100.0f || tempvec / 100.0f  == outtri.pointC / 100.0f)
                TextPos += Textcoord[counter];
        }
        TextPos = TextPos / 3.0f;
    
        s32 texel = (s32)(((s32)(TextPos.Y * size.Height)) * size.Width + TextPos.X * size.Width);
        SelectedColor = CArray[texel];
    }
    //Nun die aktuell ausgewählte Parzelle feststellen und die entsprechende Textur reinhauen

    {
        SelectedSector = 0;
        for(short counter = 1; counter < NumSelectMaps; counter++)
        {
            if(PFrames[counter].ColorKey == SelectedColor)
            {
                SelectedSector = counter;
                break;
            }
        }
        PlanetModell->setMaterialTexture(1, PFrames[SelectedSector].SelectTexture);
    }


Ich hoffe es ist das was du gesucht hast.
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

6

20.06.2007, 14:18

Vielen Dank für die Vorschläge - mir scheint jetzt das Prinzip am praktikabelsten:

:arrow: Die Provinzen der Karte mit Namenskürzeln versehen (je 2 Buchstaben)
:arrow: Anhand der Abkürzungen die Provinzen einfärben (R=200, G=200+(int)1.Buchstabe, B=200+(int)2.Buchstabe) ...wobei

Quellcode

1
enum enmAlphabet { a to z }

:arrow:

Quellcode

1
2
3
4
5
Bitmap karte = ...;
Color farbe = karte.GetPixel(maus.x, maus.y);
enmAlphabet[] name = new enmAlphabet[2];
name[0] = farbe.G - 200;
name[1] = farbe.b - 200;

ergibt dann die Namensabkürzung der Provinz,über der der Mauszeiger ist.
:arrow: Diese Karte wird natürlich nicht angezeigt, sondern eine zweite Version
der Bitmap, in der die Provinzen dann in den Spielerfarben eingefärbt sind.

@Nox: Danke - die Idee ist so ähnlich wie bei Dir - allerdings habe ich lediglich eine
Bitmap und keine Dreiecke.

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

7

20.06.2007, 15:55

Wozu diese Namenskürzel Sache? Kannst doch direkt den Farbwert als Colorkey nehmen. Das spart einiges an Rumrechnerei und mit Paint o.ä. ist eine Karte dann schnell erstellt.
Bzw. ist der Algo ja in der Lage aus jeder beliebigen Textur heraus je nach Anzahl der verschiedenen Farben die entsprechende Anzahl an Parzellen zu erstellen. Damit entfällt komplett das Laden von zusätzlichen Informationen aus einer anderen Datei (z.b. Name, Anzahl der Parzellen, Colorkey).
PRO Lernkurs "Wie benutze ich eine Doku richtig"!
CONTRA lasst mal die anderen machen!
networklibbenc - Netzwerklibs im Vergleich | syncsys - Netzwerk lib (MMO-ready) | Schleichfahrt Remake | Firegalaxy | Sammelsurium rund um FPGA&Co.

Werbeanzeige