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

Korowai

unregistriert

11

06.01.2017, 22:08

Du sprichst, glaube ich, von der D3DXMATRIX?

Wäre natürlich eine Idee, die Sprites in eine eigene Projektion / Koordinatenlage zu betten.

Dann müsste ich die jeweiligen Funktionen für Bewegung, Hintergrund und wiederum zoom und Hintergrund bewegen getrennt steuern.

Das erscheint mir sehr kompliziert. Ich glaube, ich lese mal weiter im Luna, es gibt bestimmt eine leichte Lösung, die ich noch nicht kenne.

Bin ja gerade erst dabei, das zu lernen. Mir sind so einige Zusammenhänge noch nicht ganz klar.

Hat jemand vielleicht sowas schon mal gemacht? Ein 2D Spiel mit einem zoom- und scrollfähigen Hintergrundbild und einigen davor sitzenden Sprites?

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

12

06.01.2017, 22:27

Solange du nicht erklärst, *was* diese Sprites sind und inwiefern sie sich falsch verhalten, kann man hier über eine Lösung nur spekulieren. Wenn ich den Anwendungsfall nicht richtig erraten habe, macht mein Lösungsvorschlag eventuell natürlich keinen Sinn. Is klar.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Korowai

unregistriert

13

11.01.2017, 17:42

Hi,

ich liste mal die relevanten Teile des codes auf. Inzwischen habe ich das Problem teilweise gelöst. Die Sprites werde beim zoomen und scrollen zusammen mit dem Hintergrund per Funktion rect mitverschoben. Ein Problem ist aber noch. Die Sprites verschwinden nach etwa 30-50 Pixel Verschiebung. Sie schieben sich anscheinend aus einem rect, dass ich aber nicht willentlich geschaffen habe. Ich poste mal den code. Ich vermute mal ins Blaue, dass es die Grenzen des ursprünglichen .png Texturbildes ist, aus dem sie heraus geschoben werden. Warum sich das nicht komplett mitverschiebt, ist mir ein Rätsel...

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
void initD3D(HWND hDlg1, HWND hwndRaumkarte, float &Bildschirmbreite, float &Bildschirmhoehe)
{

    RECT screenRect;
    GetClientRect(GetDlgItem(hDlg1, ID_RAUMKARTE),&screenRect);

    Bildschirmbreite=screenRect.right;
    Bildschirmhoehe=screenRect.bottom;

    d3d=Direct3DCreate9(D3D_SDK_VERSION);
    D3DDISPLAYMODE d3ddm;
    d3d->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm );
    D3DPRESENT_PARAMETERS d3dpp;
    ZeroMemory(&d3dpp, sizeof(d3dpp));
    d3dpp.Windowed=TRUE;
    d3dpp.SwapEffect=D3DSWAPEFFECT_DISCARD;
    d3dpp.hDeviceWindow=hwndRaumkarte;
    d3dpp.BackBufferFormat       = d3ddm.Format;
    d3dpp.EnableAutoDepthStencil = TRUE;
    d3dpp.AutoDepthStencilFormat = D3DFMT_D16;
    d3dpp.PresentationInterval   = D3DPRESENT_INTERVAL_IMMEDIATE;

    d3d->CreateDevice(D3DADAPTER_DEFAULT,
                      D3DDEVTYPE_HAL,
                      hwndRaumkarte,
                      D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                      &d3dpp,
                      &d3ddev);
    RECT rect;
    /*screenRect.left=0;
    screenRect.right=1600;//Bildschirmbreite*2;
    screenRect.top=0;
    screenRect.bottom=1200;//Bildschirmhoehe*2;
*/
    d3ddev->StretchRect(pScr, &screenRect, pDst, NULL, D3DTEXF_LINEAR);
    d3ddev->CreateVertexBuffer( 4*sizeof(Vertex), D3DUSAGE_WRITEONLY,
                                      D3DFVF_CUSTOMVERTEX, D3DPOOL_DEFAULT,
                                      &g_pVertexBuffer, NULL );
    void *pVertices = NULL;
    g_pVertexBuffer->Lock( 0, sizeof(g_quadVertices), (void**)&pVertices, 0 );
    memcpy( pVertices, g_quadVertices, sizeof(g_quadVertices) );
    g_pVertexBuffer->Unlock();

    D3DXMatrixPerspectiveFovLH( &Hintergrundmatrix, D3DXToRadian( Kamerawinkel ),
                                800 / 600, 0.00f, 100.0f );
    D3DXMatrixPerspectiveFovLH( &Spritematrix, D3DXToRadian( Kamerawinkel ),
                                800 / 600, 0.00f, 100.0f );
    d3ddev->SetTransform( D3DTS_PROJECTION, &Hintergrundmatrix );
    d3ddev->SetTransform( D3DTS_PROJECTION, &Spritematrix );
    d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
    d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
    d3ddev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_LINEAR);
    d3ddev->SetRenderState(D3DRS_LIGHTING, FALSE);

    d3ddev->SetTransform(D3DTS_WORLD, &Spritematrix);
    d3ddev->SetTransform(D3DTS_WORLD, &Hintergrundmatrix);

    d3ddev->SetTransform( D3DTS_PROJECTION, &Spritematrix );

    d3ddev->SetTextureStageState( 0, D3DTSS_TEXTURETRANSFORMFLAGS,
                                 D3DTTFF_DISABLE );

}


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
void render_frame(float &Worldposx, float &Worldposy, float &Zoomfaktor, bool &Vorzeichen, float &Skalx, float &Skaly, float &Bildschirmbreite, float &Bildschirmhoehe)
{
    Bildgesamtx=Texturbreite*Skalx;
    Bildgesamty=Texturhoehe*Skaly;
    Skalx=Skalx+Zoomfaktor;
    Skaly=Skaly+Zoomfaktor;
    if (Skalx>=3.00||Skaly>=3.00)
               {
                   Skalx=3.00;
                   Skaly=3.00;
               }
    if (Skalx<=1.00||Skaly<=1.00)
                {
                    Skalx=1.00;
                    Skaly=1.00;
                }
    if (Zoomfaktor>0.2)
    {
        Zoomfaktor=0.2;
    }
    RECT rect;

    rect.left=(0+Worldposx)*Skalx;
    rect.right=((Bildschirmbreite)+Worldposx)*Skalx;
    rect.top=(0+Worldposy)*Skaly;
    rect.bottom=(Bildschirmhoehe+Worldposy)*Skaly;

    if (rect.right>Bildschirmbreite*Skalx)
    {
        rect.right=Bildschirmbreite*Skalx;
    }
    if (rect.left>((Bildschirmbreite*Skalx)-(rect.right-rect.left)));
    {
        rect.left=(Bildschirmbreite*Skalx)-(rect.right-rect.left);
    }
    if (rect.right<=Texturbreite*Skalx)
    {
        rect.right=Texturbreite*Skalx;
    }
    if (rect.left<=0)
    {
        rect.left=0;
    }
    if (rect.bottom>Bildschirmhoehe*Skaly)
    {
        rect.bottom=Bildschirmhoehe*Skaly;
    }
    if (rect.top<=0)
    {
        rect.top=0;
    }

    D3DXVECTOR3 position(1.0f,1.0f,1.0f);
    D3DXVECTOR3 targetPoint(1.0f,1.0f,1.0f);
    D3DXVECTOR3 worldup(0.0f,1.0f,0.0f);

    D3DXMatrixLookAtLH(&Spritematrix, &position, &targetPoint, &worldup);

    d3ddev->Clear(0,NULL,D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, D3DCOLOR_COLORVALUE(0.0f,0.0f,0.0f,1.0f), 1.0f, 0);

    D3DXVECTOR2 Scaling(Skalx,Skaly);

    D3DXMatrixTransformation2D(&Hintergrundmatrix,NULL,NULL,&Scaling,NULL,NULL,NULL);
    mSprite->SetTransform(&Hintergrundmatrix);

    D3DXMatrixTransformation2D(&Spritematrix,NULL,NULL,&Scaling,NULL,NULL,NULL);
    mSprite->SetTransform(&Spritematrix);
    d3ddev->SetTransform(D3DTS_WORLD, &Spritematrix);
    d3ddev->SetTransform(D3DTS_WORLD, &Hintergrundmatrix);

    d3ddev->BeginScene();
    mSprite->Begin(D3DXSPRITE_ALPHABLEND);
    mSprite->Draw(Hintergrundtextur, &rect,NULL,&Hintergrundposition, 0xFFFFFFFF);
    mSprite->Draw(Spielertextur,&rect,NULL,&Mobilposition,0xFFFFFFFF);
    mSprite->Draw(Gegnertextur[0],&rect,NULL,&Gegnerposition[0],0xFFFFFFFF);
    mSprite->Draw(Gegnertextur[1],&rect,NULL,&Gegnerposition[1],0xFFFFFFFF);

    mSprite->End();
    d3ddev->SetStreamSource( 0, g_pVertexBuffer, 0, sizeof(Vertex) );
    d3ddev->SetFVF( D3DFVF_CUSTOMVERTEX );
    d3ddev->DrawPrimitive( D3DPT_TRIANGLESTRIP, 0, 2 );

    d3ddev->EndScene();
    d3ddev->Present(NULL,NULL,NULL,NULL);
}


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
HRESULT InitSprite(float &Bildschirmbreite, float &Bildschirmhoehe)
{
    HRESULT hr;



    hr= D3DXCreateTextureFromFileEx(d3ddev, "Frachter_400_300 Kopie.png", 40,30, 0, D3DPOOL_DEFAULT,
                                    D3DFMT_UNKNOWN,D3DPOOL_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT, D3DCOLOR_XRGB(255,0,255),
                                    NULL,NULL,&Spielertextur);
    hr= D3DXCreateTextureFromFileEx(d3ddev, "Frachter_400_300 Kopie.png", 40,30, 0, D3DPOOL_DEFAULT,
                                    D3DFMT_UNKNOWN,D3DPOOL_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT, D3DCOLOR_XRGB(255,0,255),
                                    NULL,NULL,&Gegnertextur[0]);
    hr= D3DXCreateTextureFromFileEx(d3ddev, "Frachter_400_300 Kopie.png", 40,30, 0, D3DPOOL_DEFAULT,
                                    D3DFMT_UNKNOWN,D3DPOOL_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT, D3DCOLOR_XRGB(255,0,255),
                                    NULL,NULL,&Gegnertextur[1]);
    hr= D3DXCreateTextureFromFileEx(d3ddev, "Raumkarte.bmp", Bildgesamtx,Bildgesamty, 0, D3DPOOL_DEFAULT,
                                    D3DFMT_UNKNOWN,D3DPOOL_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT, D3DCOLOR_XRGB(255,0,255),
                                    NULL,NULL,&Hintergrundtextur);

                                    //hr= D3DXCreateTextureFromFile(d3ddev, "Raumkarte.bmp", &Hintergrundtextur);
        hr= D3DXCreateSprite(d3ddev, &mSprite);
        hr= D3DXCreateSprite(d3ddev, &mMobilsprite);
     Gegnerposition[0]= D3DXVECTOR3(Gegner[0].Bildschirmx,Gegner[0].Bildschirmy,0.0f);
     Gegnerposition[1]= D3DXVECTOR3(Gegner[1].Bildschirmx,Gegner[1].Bildschirmy,0.0f);
     Mobilposition= D3DXVECTOR3(Spieler.Bildschirmx,Spieler.Bildschirmy,0.0f);
     Hintergrundposition= D3DXVECTOR3(0.0f,0.0f,0.0f);



}


Und der code zum verschieben und scrollen. Ist Teil eines Dialogwindows:

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
case WM_COMMAND:
        {
        switch (LOWORD (wParam))
       {
           case ID_OK:
        {
                        MessageBox(hDlg1, TEXT ("Runde im All beendet"), "EXO 1.2", MB_ICONEXCLAMATION|MB_OK);
                        cleanD3D();
                        EndDialog(hDlg1,0);
                        return TRUE;
        }
       break;

           case ID_RECHTS:
            {
                Worldposx=Worldposx+0.50;
                render_frame(Worldposx, Worldposy, Zoomfaktor, Vorzeichen, Skalx, Skaly, Bildschirmbreite, Bildschirmhoehe);
                UpdateWindow(hDlg1);

            }
            break;
           case ID_LINKS:
            {
                Worldposx=Worldposx-0.50;
                render_frame(Worldposx, Worldposy, Zoomfaktor, Vorzeichen, Skalx, Skaly, Bildschirmbreite, Bildschirmhoehe);
                UpdateWindow(hDlg1);
            }
            break;
           case ID_OBEN:
            {
                            Worldposy=Worldposy-0.50;
                            render_frame(Worldposx, Worldposy, Zoomfaktor, Vorzeichen, Skalx, Skaly, Bildschirmbreite, Bildschirmhoehe);
                            UpdateWindow(hDlg1);
            }
            break;
           case ID_UNTEN:
            {
                            Worldposy=Worldposy+0.50;
                            render_frame(Worldposx, Worldposy, Zoomfaktor, Vorzeichen, Skalx, Skaly, Bildschirmbreite, Bildschirmhoehe);
                            UpdateWindow(hDlg1);
            }
            break;
           case ID_ZOOMIN:
            {
                Zoomfaktor=+0.2;
                render_frame(Worldposx, Worldposy, Zoomfaktor, Vorzeichen, Skalx, Skaly, Bildschirmbreite, Bildschirmhoehe);
                Zoomfaktor=0;
            }
            break;
           case ID_ZOOMOUT:
            {
                Zoomfaktor=-0.2;
                render_frame(Worldposx, Worldposy, Zoomfaktor, Vorzeichen, Skalx, Skaly, Bildschirmbreite, Bildschirmhoehe);
                Zoomfaktor=0;
            }
            break;
        }
        break;
        }
        break;

    }
    return FALSE;
    }


Und die Resource:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"


LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG1 DIALOGEX 0, 0, 1000, 520
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
CAPTION "Raumkarte"
FONT 8, "Ms Shell Dlg"
{
    CONTROL        "Raumkarte", 5002, WC_STATIC, SS_BLACKFRAME, 200, 0, 733, 400, 0, WS_EX_LEFT
// ...
//...
}

Korowai

unregistriert

14

12.01.2017, 23:08

Anbei noch der Ausschnitt der Bildschirmausgabe.


Man sieht deutlich, wie die drei Sprites durch eine horizontale und vertikale Bildbegrenzung abgeschnitten werden.
»Korowai« hat folgendes Bild angehängt:
  • Ausschnitt.jpg

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

15

13.01.2017, 06:32

Bist du dir sicher, dass das Sprite nicht einfach nur zu nahe an der Ecke der Texur liegt? Dann schlägt nämlich der Textur-Filter zu und interpoliert überall, aber nicht dort, wo die Textur endet (und so etwas kann man durch Code oder Beschreibung allein kaum erraten, sondern wird es nur in Screenshots sehen). Hast du um deine Sprites einen 1-Pixel Rand freigelassen, damit Textur-Filter sauber arbeiten können? Im Falle eines Atlas auch zwischen den jeweiligen Sprites, sonst werden Nachbar-Pixel von anderen Sprites durch den Filter mit einberechnet, was merkwürdige Farben an den Kanten eines Sprites ergeben kann, die da nicht hingehören.

Wo wir schon bei Textur-Filtern sind, ich würde dir empfehlen mit Premultiplied Alpha zu arbeiten, wenn du Sprites hoch skalierst (oder generell immer, wenn sie nicht Pixel-perfekt gerendert werden sollen). Sonst bekommen helle Sprites auf einem hellen Untergrund plötzlich eventuell dunkle Ränder... je nachdem, was dein Tool der Wahl mit dem Farbkanal beim Exportieren macht, sobald der Layer nicht mehr 100% opak ist.
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »BlueCobold« (13.01.2017, 06:46)


Korowai

unregistriert

16

13.01.2017, 07:04

Guten morgen,

habe gerade noch mal in gimp nachgesehen. Die Texturen der im Ausschnitt dargestellten "Raumschiffe" haben gute 70 Pixel Platz zu jedem Rand. Der Hintergrund ist transparent (Mit Gimp nach dem Zeichnen per Entf. gelöscht).

Es wäre noch eine Idee, die Sprites in der render Funktion mit einem Wert für Center zu versehen, was ich allerdings zu einem früheren Zeitpunkt auch probiert habe. Leider ohne Ergebnis.

Ich habe nochmal die MSDN gecheckt, weil ich vermute, dass ich in der Init von Directx was einstellen müsste, was noch nicht geschehen ist. Immerhin laufen 4 Sprites über einen VertexBuffer und ein Device. Vielleicht liegt es daran, dass ich irgendwo was anderes einstellen muss.

Alle Tutorials im Netz und in meinen Büchern laufen mit einem Sprite. Das ist schön und gut aber nirgendwo wird einem mal erklärt, was man den devicecaps und devices mitgeben muss, wenn man mehrere Texturen einbindet.

Wo könnte ich noch ansetzen? Kannst Du Deine Aussage mit Premultiplied Alpha noch etwas präzisieren? Ich glaube, da gibt es ein Tutorial im www...

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

17

13.01.2017, 07:17

Das heißt deine Raumschiff-Sprites sind eigentlich viel größer als das, was man da im Bild sieht? Bist du dir da sicher? Kannst du testweise die Sprites in Gimp mal mit z.B. einem roten Hintergrund füllen?

Zu premultiplied Alpha muss man eigentlich nicht viel mehr als das sagen. Da sollte sich genug finden lassen. Kurz gesagt sind bei solchen Texturen die Farb-Kanäle mit dem Alpha-Kanal multipliziert worden und statt "alpha / one_minus_alpha" blendet man mit "alpha / one".
Teamleiter von Rickety Racquet (ehemals das "Foren-Projekt") und von Marble Theory

Willkommen auf SPPRO, auch dir wird man zu Unity oder zur Unreal-Engine raten, ganz bestimmt.[/Sarkasmus]

Korowai

unregistriert

18

13.01.2017, 07:31

Erstellt habe ich die Texturen mit einer Breite von 400 und Höhe von 300 px.

ich lese sie dann mit

hr= D3DXCreateTextureFromFileEx(d3ddev, "Frachter_400_300 Kopie.png", 40,30, 0, D3DPOOL_DEFAULT,
D3DFMT_UNKNOWN,D3DPOOL_DEFAULT,D3DX_DEFAULT,D3DX_DEFAULT, D3DCOLOR_XRGB(255,0,255),
NULL,NULL,&Spielertextur);

ein.

Ich habe die Werte für Breite und Höhe aber mehrfach geändert, weil ich auch vermutete habe, dass es damit zusammenhängt. Das leider nicht.

ich werde mal den transparenten Hintergrund rot machen und schauen, was mir die Ausgabe zeigt.

Korowai

unregistriert

19

13.01.2017, 18:19

Hi,

also, ich glaube, es hängt mit den Parametern der Texturen zusammen. Die x=40, y=30 Texturgröße erschafft eine Art Rahmen, aus dem die Textur / das Sprite beim scrollen / zoomen herausgeschoben wird.

Wie ich das ändern kann, entzieht sich leider meiner Kenntnis. Habe jetzt mit allen möglichen Variablen gespielt, aber ich müsste glaube ich grundsätzlich bei der Initialisierung etwas anders einstellen.

Hat da jemand einen Tipp? Ich hänge jetzt wirklich fest.

Korowai

unregistriert

20

14.01.2017, 07:04

O.K.

Lösung:

Das Scrollen und Zoomen steuere ich nun nicht mehr über die rect- Funktion, sondern über die Bildschirmplatzierung.
Ist ein höherer Aufwand, da ich umrechnen muss, wann das Schiff die jeweiligen Ränder des controls erreicht, und sie dann nicht mehr gezeichnet werden sollen, weil sie sich in diesem Fall wieder am Rand mitverschieben (???). Und ich muss die jeweiligen posx und posy der Schiffskoordinaten auf die Skalierungswerte und den Verschiebungswert anpassen, und da auch wieder eine Korrektur vornehmen.

Ist umständlich, aber funktioniert wenigstens.

Es würde mich sehr interessieren, warum ein Sprite im Falle des Verschiebens der Koordinaten des windowrects einfach verschwindet, wenn der Rand seines rects der Texturimplementierung erreicht wurde, und warum sich dieses nicht mitverschiebt. Und warum wandert ein Sprite am Bildrand mit, obwohl es doch auf dem Hintergrundrect ausserhalb des Darstellungsbereiches gerendert wird. Wenn ich das screenrect verschiebe, bzw. ein abgeleitetes rect, hat dass doch nix mit den Bildkoordinaten der Sprites zu schaffen.

Das ist ja kafkaesk :pillepalle:

Werbeanzeige