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

Developer_X

Treue Seele

  • »Developer_X« ist der Autor dieses Themas

Beiträge: 247

Wohnort: Hessen

Beruf: Schüler

  • Private Nachricht senden

21

10.07.2011, 15:34

Ich habe das ganze jetzt mal so umgeschrieben, dass alles bewegt wird, so, dass gespeichert wird, wie weit sich der Spieler in X und Y Achsenrichtung bewegen soll.

Dann aber, checke ich, ob der Spieler, an jener Position, mit irgendwas kollidieren würde, wenn ja, dann wird berechnet, wie weit er zurück gesetzt werden muss.

Ganz am ende, wird seine Position dann mit checkUpdate, geupdated.

Funktioniert aber leider immer noch nicht, da flimmert nur alles rum :

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
void AdventurePlayer::checkCollisions()
{
/// Collision mit Objekten
    for(unsigned int x = 0;x<actual_Level.objects.size();x++)
    {
        for(unsigned int y = 0;y<actual_Level.objects[x].size();y++)
        {
        /// Falls eine Kollision stattgefunden hat
            Rect r(joe.r.x+joe.fx,joe.r.y+joe.fy,joe.r.w,joe.r.h);
            if(collision(r,actual_Level.objects[x][y].r,2))
            {
                determineCase(x,y); // Dort wird entschieden, je nach Typ des Objekts, was passieren soll
            }
        }
    }

/// Update Position
    joe.updatePosition();
}

void AdventurePlayer::CC_Case_01(int x, int y)
{
/// Potenzielles Rechteck
    Rect r(joe.r.x+joe.fx,joe.r.y+joe.fy,joe.r.w,joe.r.h);

    GameObject go = actual_Level.objects[x][y];

/// X
    if(r.x+r.w/2<go.r.x+go.r.w/2)
    {
        int distance = (r.x+r.w)-(go.r.x);
        joe.Move(-distance,0);
    }
    else
    {
        int distance = (go.r.x+go.r.w)-(r.x);
        joe.Move(+distance,0);
    }

/// Y
    if(r.y+r.h/2<go.r.y+go.r.h/2)
    {
        int distance = (r.y+r.h)-(go.r.y);
        joe.Move(0,-distance);
    }
    else
    {
        int distance = (go.r.y+go.r.h)-(r.y);
        joe.Move(0,+distance);
    }

    joe.updatePosition();
}


Hätte jemand ne Idee, was ich da machen könnte?

Er bewegt sich kein Stück :(
- Die Zeit ist wie ein Fluss, und die Gegenwart wie ein Fels, der von dem Fluss der Zeit geschliffen wird. -
Kevin Riehl

Noodle

unregistriert

22

10.07.2011, 17:28

Ich find das Spiel und die Idee putzig :D gefällt mir ;)

Lares

1x Contest-Sieger

  • Private Nachricht senden

23

11.07.2011, 11:14

Was genau ist bei dir fx und fy?
Bei dem geposteten Code sehe ich keinen Fehler (kann aber auch etwas übersehen haben). DetermineCase sucht sich das CC_Case_01 aus nehm ich an? Sehen die anderen Collisionen grundsätzlich anders aus und wenn ja, bist du sicher, dass er ne Kollision mit Blocktyp 1 hat?

Developer_X

Treue Seele

  • »Developer_X« ist der Autor dieses Themas

Beiträge: 247

Wohnort: Hessen

Beruf: Schüler

  • Private Nachricht senden

24

11.07.2011, 17:12

Ja, bei Kollisionen mit Typ 1 wird auch die funktion aufgerufen.

Die anderen Cases sehen anders aus, da diese viel einfacher zu behandeln sind, angenommen du hast ein Objekt berührt, das du einsammeln und somit Punkte bekommen kannst, dann kannst du die Punktzahl erhöhen, etc., alles ganz einfach. Nur die Kollisionsbehandlung stellt für mich ein unüberwindbares hindernis dar :(.

FX und FY stehen für Force_X und Force_Y. Mit der Funktion Move, verändert man die FX und FY Variablen, sie werden nämlich mit den Parametern der Funktion Move addiert (bei negativen Werten natürlich subtrahiert).

Deshalb benutze ich auch nicht das Rechteck vom Spieler (joe) namens joe.r, sondern erstelle ein Rect, was die Größen des Original-Rechtecks hat, nur die Position durch ForceX und Force Y manipuliert hat. Am ende aller kollisionen wird joe.updatePosition() aufgerufen, was dafür sorgt, das FX und FY auf 0 gesetzt werden, und die Koordinaten des Spielers dementsprechend mit FX und FY addiert werden.

So, das sind schon mal die Sachen, die es zu sagen gibt.

Hättest du vllt Zeit, in Skype on zu kommen, mich zu adden und dir das anzuschauen?

Danke,
m.f.G. Developer_X
- Die Zeit ist wie ein Fluss, und die Gegenwart wie ein Fels, der von dem Fluss der Zeit geschliffen wird. -
Kevin Riehl

Lares

1x Contest-Sieger

  • Private Nachricht senden

25

11.07.2011, 21:50

Vllt. kannst du folgendes machen: CC_Case_01 berechnet ja wie weit der Spieler in welche Richtung zurückgesetzt werden muss, stimmts?
Anstatt diese Berechnung durchzuführen, könntest du doch die Position vom Spieler einfach nicht updaten lassen, wenn eine Kollision aufgetreten ist.
Wenn fx und fy klein genug sind sollte das trotzdem eine ziemlich genaue Kollision ergeben wenn ich mich jetzt grad nicht irre.

Sollte es dann noch fehlerhaft sein muss der Fehler in collision() stecken, wobei mir grad auffällt:
Wenn determineCase CC_Case_01 aufruft und determineCase nur aufgerufen wird, wenn eine Kollision vorliegt, wie wird dann joe.updatePosition(); aufgerufen falls keine Kollision auftritt?


Wenn keins von beiden hilft, bin ich mit meinen Latein (was ich nie hatte xD) auch am Ende.

Developer_X

Treue Seele

  • »Developer_X« ist der Autor dieses Themas

Beiträge: 247

Wohnort: Hessen

Beruf: Schüler

  • Private Nachricht senden

26

12.07.2011, 07:57

CheckCollision wird immer aufgerufen, jedes mal, beim Durchgang der Schleife.

Und joe.updatePosition, wird damit (weil es ja unten steht) auch immer aufgerufen.
- Die Zeit ist wie ein Fluss, und die Gegenwart wie ein Fels, der von dem Fluss der Zeit geschliffen wird. -
Kevin Riehl

Developer_X

Treue Seele

  • »Developer_X« ist der Autor dieses Themas

Beiträge: 247

Wohnort: Hessen

Beruf: Schüler

  • Private Nachricht senden

27

12.07.2011, 08:16

Also, ein guter Freund von mir, auch in diesem Forum, hat mir gesagt, ich sollte das mit einem ganz anderen Ansatz versuchen :
Ich sollte es mit Linien kollision versuchen, d.h.:

Der Spieler hat 4 Linien um sich, die seinen Rahmen bilden würden. Diese Linien sind orthogonal.

Wenn ich jetzt Checke, welche Linien mit dem Objekt kollidiert, könne ich besser reagieren.

Das habe ich jetzt mal umgesetzt :

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
void AdventurePlayer::CC_Case_01(int x, int y)
{
    int t = 2;

    Rect r(joe.r.x+joe.fx,joe.r.y+joe.fy,joe.r.w,joe.r.h);
    GameObject go = actual_Level.objects[x][y];

    Line l1(go.r.x,go.r.y,go.r.x+go.r.w,go.r.y);                /// Oben
    Line l2(go.r.x+go.r.w,go.r.y,go.r.x+go.r.w,go.r.y+go.r.h);  /// Rechts
    Line l3(go.r.x,go.r.y+go.r.h,go.r.x+go.r.w,go.r.y+go.r.h);  /// Unten
    Line l4(go.r.x,go.r.y,go.r.x,go.r.y+go.r.h);                /// Links

    /// Oben
    if(l1.y>r.y&&l1.y<r.y+r.h)
    {
        joe.Move(0,-joe.fy);
    }

    /// Unten
    else if(l3.y>r.y&&l3.y<r.y+r.h)
    {
        joe.Move(0,-joe.fy);

        /// Erlauben zu springen
        joe.fUp = 0;
        joe.jumping = false;
    }


    /// Rechts
    if(l2.x>r.x&&l2.x<r.x+r.w)
    {
        joe.Move(-joe.fx,0);
    }

    /// Links
    else if(l4.y>r.y&&l4.y<r.y+r.h)
    {
        joe.Move(-joe.fx,0);
    }
}


Probleme die aber immer noch auftreten :
Er bewegt sich kein Stück. Er kann auch nicht springen. Ich steh nur rum.
Weil am Anfang die Sprung variable false ist, kann ich halt einmal springen,
wenn ich dann seitlich ne mauer runterfalle, kann ich mal durch sie gehen,
oder an einer mini-kante stehen bleiben, das ist auch nicht wirklich gut.

Hättest du ne Idee woran es liegen könnte?
- Die Zeit ist wie ein Fluss, und die Gegenwart wie ein Fels, der von dem Fluss der Zeit geschliffen wird. -
Kevin Riehl

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Developer_X« (12.07.2011, 08:23)


Developer_X

Treue Seele

  • »Developer_X« ist der Autor dieses Themas

Beiträge: 247

Wohnort: Hessen

Beruf: Schüler

  • Private Nachricht senden

28

12.07.2011, 09:51

Sry, dass ich so oft poste.

Ich habe jetzt nochmal was verändert :
1. Nämlich die Linien. Die sollen vom Spieler sein, und dann auf Kollision mit dem Objekt getestet werden, nicht umgekehrt.
2. Problem ist jetzt, nach einigen kleinen Änderungen noch folgendes : Wenn ich, wie im Code zu sehen, die If anweisung >>if(joe.jumping==true)<< wegnehme, bewegt er sich nicht nach links und rechts, solange er auf einem Block sitzt. Weil sie dasteht, kann man sich immer nach links und rechts bewegen, und durch sogut wie alles hindurch :(.

Was könnte ich da denn noch machen?

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
void AdventurePlayer::CC_Case_01(int x, int y)
{
    Rect r(joe.r.x+joe.fx,joe.r.y+joe.fy,joe.r.w,joe.r.h);
    GameObject go = actual_Level.objects[x][y];

    Line l1(r.x,r.y,r.x+r.w,r.y);           /// Oben
    Line l2(r.x+r.w,r.y,r.x+r.w,r.y+r.h);   /// Rechts
    Line l3(r.x,r.y+r.h,r.x+r.w,r.y+r.h);   /// Unten
    Line l4(r.x,r.y,r.x,r.y+r.h);           /// Links

    /// Oben
    if(l1.y>go.r.y&&l1.y<go.r.y+go.r.h)
    {
        joe.Move(0,-joe.fy);
    }

    /// Unten
    else if(l3.y>go.r.y&&l3.y<go.r.y+go.r.h)
    {
        joe.Move(0,-joe.fy);

        joe.fUp = 0;
        joe.jumping = false;
    }


    if(joe.jumping==true)
    {
        /// Rechts
        if(l2.x>go.r.x&&l2.x<go.r.x+go.r.w)
        {
            joe.Move(-joe.fx,0);
        }

        /// Links
        else if(l4.y>go.r.y&&l4.y<go.r.y+go.r.h)
        {
            joe.Move(-joe.fx,0);
        }
    }
}


M.f.G. Developer_X
- Die Zeit ist wie ein Fluss, und die Gegenwart wie ein Fels, der von dem Fluss der Zeit geschliffen wird. -
Kevin Riehl

TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

29

12.07.2011, 10:40

Ehrliche Meinung? Ich hab gedacht: Oh nein, wie schlecht ist das denn.

Nexxtron

Alter Hase

Beiträge: 424

Wohnort: Heilbronn

Beruf: Student - Software Engineering

  • Private Nachricht senden

30

12.07.2011, 15:28

TGGC, du könntest doch uns mal ne elegante Lösung erklären oder zeigen. Du arbeitest ja in dem Bereich Spieleentwicklung? Ich würde echt gerne mal wissen wie es professionelle Spieleentwickler lösen.

Ich machs auf jeden Fall so, wie ich es auf Seite 1 gepostet habe. Ich weis aber nicht, ob es so am performantesten und elegantesten ist.
New Project: Operation CityRacer

Werbeanzeige