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

28.06.2017, 15:45

[C++ / SFML] Sprung

Guten Tag,
ich habe folgendes Problem:
Ich möchte ein Objekt springen lassen, also das es wirklich aussieht als würde es springen.
Im Moment kenne ich nur die Möglichkeit den Spieler einfach um eine bestimmte Anzahl nach oben zu setzten, aber das ist mehr eine Teleportation als alles andere.

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
#ifndef PLAYER_HPP
#define PLAYER_HPP

#include <iostream>
#include <SFML\Graphics.hpp>

class player 
{
public:
    player(int x, int y, sf::String tex);
    void Update();
    void Render(sf::RenderWindow &window);
    sf::Sprite sprite;
    bool dropping;
    bool inAir;
    float speed;

private:
    sf::Texture textur;
};

#endif


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
#include "player.h"

player::player(int x, int y, sf::String tex)
{
    textur.loadFromFile(tex);
    textur.setSmooth(false);
    sprite.setTexture(textur);
    sprite.setPosition(x, y);

    dropping = true;
    inAir = true;
    speed = 1;
}

void player::Update()
{
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
    {
        if(inAir == false) sprite.move(0,-speed*100);
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        sprite.move(-speed,0);
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        sprite.move(speed,0);
    }

    if(dropping) sprite.move(0,speed*2.5);
    else sprite.move(0,0);

    dropping = true;
    inAir = true;
}

void player::Render(sf::RenderWindow &window)
{
    window.draw(sprite);
}

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

28.06.2017, 15:56

Du kannst ja erst mal simpel anfangen. Zusätzlich zur Position merkst du dir die Geschwindigkeit in vertikaler Richtung. Jeden Zeitschritt ziehst du von dieser Geschwindigkeit einen konstanten Gravitationswert ab. Dieser steht in Abhängigkeit von der Zeit. Dadurch fällt dein Charakter nach unten. Kollidiert der Charakter mit dem Boden so setzt du die vertikale Geschwindigkeit auf 0. Bei einem Sprung setzt du die vertikale Geschwindigkeit auf einen relativ hohen Wert.

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// variablen:
var verticalSpeed; // vertikale Geschwindigkeit
var yCoordinate; // Position auf der Y Achse
var gravity; // Die Gravitationskonstante
var grounded; // befindet sich der Spieler am Boden

// update-loop wobei deltaTime die vergangene Zeit seit dem letzten Frame in Sekunden ist
if(grounded) {
  verticalSpeed -= gravity * deltaTime;
} else {
  verticalSpeed = 0;
}
yCoordinate += verticalSpeed;

// Kollisionsbehandlung etc


Dieses System ist erst mal recht simpel, funktioniert aber. Das ganze kannst du natürlich mit richtigen Kräften erweitern.

edit: Was noch fehlt:

Quellcode

1
2
3
4
5
6
7
8
9
// variablen:
var jumpStrength; // Die Sprungkraft
var jumpKeyDown; // Ist die Sprungtaste gedrückt? Alternativ sagt die Variable allgemein aus ob gesprungen werden soll.

// einmal pro Frame:
if(grounded && jumpKeyDown) {
  grounded = false;
  verticalSpeed = jumpStrength;
}


Bei einem Sprung wird die Geschwindigkeit einfach auf einen großen Wert gesetzt. Da die Gravitation jeden Frame von deiner Geschwindigkeit abgezogen wird bewegst du dich jeden Frame etwas langsamer nach oben. Ab einem gewissen Punkt koppt das ganze und du bekommst eine Geschwindigkeit nach unten welche dann mit jedem Frame etwas größer wird. Das ist physikalisch nicht korrekt, reicht aber normalerweise aus.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »Schorsch« (28.06.2017, 16:03)


TGGC

1x Rätselkönig

Beiträge: 1 799

Beruf: Software Entwickler

  • Private Nachricht senden

3

28.06.2017, 16:38

Naja, Springen ist doch nix Anderes als den Spieler nach oben zu teleportieren. Ist halt die Frage wann und wohin genau man den Spieler teleportiert, "wirklich aussieht als würde es springen" ist da jetzt keine so genaue Beschreibung. Jede Bewegung ist doch sowieso eine Teleportation.

4

28.06.2017, 18:36

Vielen Dank für die schnellen Antworten!
Ich hab es nun wie folgt:

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
#include "player.h"

player::player(int x, int y, sf::String tex)
{
    gravity = 0.1f;
    grounded = false;
    verticalSpeed = 1;
    horizontalSpeed = 2;
    posX = x;
    posY = y;

    textur.loadFromFile(tex);
    textur.setSmooth(false);
    sprite.setTexture(textur);
    sprite.setPosition(posX, posY);
}

void player::Update()
{
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::A))
    {
        posX -= horizontalSpeed;
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::D))
    {
        posX += horizontalSpeed;
    }
    if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
    {
        if(grounded)
        {
            verticalSpeed = -2.5f;
            grounded = false;
        }
    }
    else if(grounded) verticalSpeed = 0; 
    else verticalSpeed += gravity; 

    posY += verticalSpeed;
    sprite.setPosition(posX, posY);

    grounded = false;
}

void player::Render(sf::RenderWindow &window)
{
    window.draw(sprite);
}


Das Problem was ich jetzt noch habe ist, wenn man Space gedrückt hält steigt es unendlich weiter nach oben.

BlueCobold

Community-Fossil

Beiträge: 10 738

Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer

  • Private Nachricht senden

5

28.06.2017, 18:40

Genau das steht ja auch in deinem Code.
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]

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

6

28.06.2017, 18:42

if(sf::Keyboard::isKeyPressed(sf::Keyboard::Space))
{
/* .... */
}
else if(grounded) verticalSpeed = 0;

Guck mal hier.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

Werbeanzeige