2017-04-12 3 views
-1

Ich erstelle ein Spiel, wo Sie einen Punkt entlang der x-Achse in der Mitte des Bildschirms bewegen können und es werden Elemente von oben fallen, die Sie versuchen müssen auszuweichen, klar dafür brauche ich eine Form von Kollisionserkennung, die ich implementiert habe und es scheint richtig zu funktionieren.Nachdem ich eine Kollision zwischen meinem Charakter und einem Objekt entdeckt habe, kann sich der Charakter nicht mehr bewegen?

Mein Problem ist, dass, wenn das Zeichen (Punkt) in Richtung des Objekts bewegt wurde und die Kollision aufgetreten ist, Sie das Zeichen nicht mehr bewegen können, es bleibt einfach in einer festen Position. Dies passiert nicht, wenn das Zeichen mit den Kanten des Fensters kollidiert. Wie Sie jedoch sehen werden, haben sowohl die Fenster-Kollision als auch die Objekt-Kollision denselben Code zum Ausführen.

Hauptspielschleife:

while(running) { 

    // Queue of the events happening 
    while(SDL_PollEvent(&event)) { 
     if(event.type == SDL_QUIT) { 
     running = false; 
     } 
     else if(event.type == SDL_KEYDOWN && event.key.repeat == 0) { 
     switch(event.key.keysym.sym) { 
      case SDLK_UP: 
      //sprite->yVel -= VELOCITY; 
      break; 
      case SDLK_DOWN: 
      //sprite->yVel += VELOCITY; 
      break; 
      case SDLK_LEFT: 
      sprite->xVel -= VELOCITY; 
      break; 
      case SDLK_RIGHT: 
      sprite->xVel += VELOCITY; 
      break; 
     } 
    } 
    else if(event.type == SDL_KEYUP && event.key.repeat == 0) { 
     switch(event.key.keysym.sym) { 
     case SDLK_UP: 
      //sprite->yVel += VELOCITY; 
      break; 
     case SDLK_DOWN: 
      //sprite->yVel -= VELOCITY; 
      break; 
     case SDLK_LEFT: 
      sprite->xVel += VELOCITY; 
      break; 
     case SDLK_RIGHT: 
      sprite->xVel -= VELOCITY; 
      break; 
     } 
    } 
    } // Poll event loop 

    float timeStep = getTicks(ticks)/(float) 1000; 
    move(sprite, timeStep, WINDOW_WIDTH, WINDOW_HEIGHT, head); 

    startTimer(ticks); 

    // Clear window then draw image 
    SDL_RenderClear(rend); 
    SDL_RenderCopy(rend, background->element, NULL, NULL); 
    SDL_RenderCopy(rend, sofa->element, NULL, &sofa->dest); 

    setPosition(sprite, sprite->xPos, sprite->yPos); 
    SDL_RenderCopy(rend, sprite->element, NULL, &sprite->dest); 

    SDL_RenderPresent(rend); 
    capFrameRate(timeStep); 
} // Main game loop 

Verschieben und Kollisionsfunktionen:

void move(Character *c, float timeStep, const int WIDTH, const int HEIGHT, Scene *scene) { 
    c->xPos += c->xVel * timeStep; 

    // Collision check for the walls 
    if(((c->xPos < 0) || (c->xPos + c->dest.w > WIDTH)) || (collision(c, scene))) { 
    c->xPos -= c->xVel * timeStep; 
    } 
} 

bool collision(Character *character, Scene *scene) { 
    if(SDL_HasIntersection(&character->dest, &scene->element->dest)) { 
    return true; 
    } 
    else { 
    if(scene->nextElement == NULL) { 
     return false; 
    } 
    else { 
     collision(character, scene->nextElement); 
    } 
    } 
    return false; 
} 

Da gibt es ein paar Elemente aus dem oberen Rand des Bildschirms fallen sein habe ich eine verlinkte Liste für diejenigen, umgesetzt , warum also die Rekursion auf der Kollisionsfunktion. Wenn jemand eine Ahnung hat, warum sich der Charakter nach einer Kollision nicht bewegt, bin ich sehr dankbar.

Antwort

0

Meine Schätzung: Ihre collision(c, scene) Methode betrachtet Kollisionen für die aktuelle Zeit Schritt. In diesem Fall Ihre if-Anweisung in der move Funktion

             // \/ This here is the problem -- if you're currently colliding with an object you don't allow any movement, even if you're moving out of the object 
if(((c->xPos < 0) || (c->xPos + c->dest.w > WIDTH)) || (collision(c, scene))) { 
    c->xPos -= c->xVel * timeStep; 
} 

die Spieler nicht bewegen kann, nachdem sie mit einem Objekt kollidiert sind. Die Lösung ist für eine Kollision zu überprüfen vor Sie den Schritt nehmen:

float newX = c->xPos + c->xVel*timeStep; 
float newY = ...; 
if (!collision(newX, newY, scene)) { 
    c->xPos = newX; 
    ... 
} 
+0

Also meinst du, ich sollte die Move-Funktion vor der Ereigniswarteschlange initiieren? – JLW

+0

@JLW Ich bin mir nicht sicher, was das bedeutet. Mein Vorschlag ist, _check und sehen, ob Ihre nächste Position ist eine zulässige Position_, nicht zu überprüfen, ob Ihre aktuelle Position erlaubt ist oder nicht. Wenn Sie Kollisionskörper bewegen, müssen Sie jedoch einige zusätzliche Änderungen vornehmen. – pingul

+0

Ah ok ja ich verstehe was du jetzt meinst. Ich werde es in ein oder zwei Tagen versuchen, danke für die Hilfe, werde Sie wissen lassen, ob es die Dinge gelöst hat! Vielen Dank! – JLW

Verwandte Themen