Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.net  
   

Die mobilen Seiten von c++.net:
https://m.c-plusplus.net

  
C++ Forum :: Spiele-/Grafikprogrammierung ::  SDL2 Jump'n Run Demo  
Gehen Sie zu Seite 1, 2  Weiter
  Zeige alle Beiträge auf einer Seite
Auf Beitrag antworten
Autor Nachricht
guitarlo
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.04.2017
Beiträge: 9
Beitrag guitarlo Mitglied 14:25:00 06.04.2017   Titel:   SDL2 Jump'n Run Demo            Zitieren

Hallo zusammen,
ich hoffe, dass mir hier jemand weiterhelfen kann.
Ich habe mal probiert eine kleine Jump and Run Demo zu schreiben.
Das ganze ist nur ein kleines Projekt. Vielleicht hilft es ja auch jemanden den es interessiert. :)
Zum Problem:
Wenn ich springe habe ich manchmal einen Pixel abstand zwischen dem Spieler und dem Boden. Ich weiß es wird höchst wahrscheinlich an der Kollisions abfrage liegen, aber ich habe irgendwie gerade ein Brett vorm Kopf.
Vielleicht ist jemand so nett und überfliegt mal den Code. Für Anregungen wäre ich sehr dankbar.
Ich bin reiner Hobbycoder daher hoffe ich das der Code einigermaßen ordendlich geschrieben ist ;)
Vielen Dank schonmal vorab!
Guitarlo

C++:
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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
#include <iostream>
#include<SDL2/SDL.h>
struct _map
{
    int tile=0;
    SDL_Rect xypos;
    bool pass=false;
 
 
}level[25][25];
 
struct _hero
{
    int hy,hx;
    int xVel=0,yVel=0;
    SDL_Rect xypos,_xcolpos,_ycolpos;
 
}Hero;
struct _Collision
{
    int xtile,ytile;
    bool xcollide=false,ycollide=false,up=false,down=false,left=false,right=false;
 
}Collision;
 
SDL_Renderer *rnd;
SDL_Window *wnd;
SDL_Event e;
SDL_Texture *t_Hero,*t_wall,*t_Exit,*t_bg,*t_bg2;
SDL_Rect r_hero, r_wall,tmp;
float grav,speed;
 
const int t_size=32;
int movex;
bool quit=false;
bool jump=false;
using namespace std;
 
 
int Init();
void Control();
void CreateMap();
void CreateTextures();
bool XYCollision(SDL_Rect r1,SDL_Rect r2);
void Scene();
 
 
 
int main()
{
    Init();
    CreateMap();
    CreateTextures();
    while (!quit)
    {
 
        Scene();
        Control();
        SDL_RenderPresent(rnd);
 
    }
 
    SDL_Quit();
    return 0;
}
 
//--------------------------------------------------------------------------------------------------------------------------
 
int Init()
{
    if (!SDL_Init(SDL_INIT_EVERYTHING))
        cerr << SDL_GetError()<<endl;
 
    wnd=SDL_CreateWindow("Jump and Run Test",NULL,NULL,800,600,0);
    if (wnd<0)
            cerr << SDL_GetError() << endl;
 
    rnd=SDL_CreateRenderer(wnd,NULL,SDL_RENDERER_ACCELERATED);
    if(rnd<0)
        cerr << SDL_GetError()<<endl;
 
    SDL_RenderPresent(rnd);
 
}
 
void Control()
{
    while (SDL_PollEvent(&e))
    {
 
        speed=0;
        if(e.type==SDL_QUIT)
            quit=true;
 
 
        const Uint8 *key=SDL_GetKeyboardState(NULL);
        if(key[SDL_SCANCODE_ESCAPE])
            quit=true;
        if(key[SDL_SCANCODE_LEFT])
        {
            speed=-1;
 
        }
 
        if(key[SDL_SCANCODE_RIGHT])
        {
            speed=1;
 
        }
 
        if (!jump)
        {
            if(key[SDL_SCANCODE_LCTRL])
            {
                grav=-4.5;
                jump=true;
            }
        }
    }
 
 
}
void CreateMap()
{
    for(int i=0;i<25;i++)
    {
        level[i][0].tile=1;
        level[i][18].tile=1;
        level[0][i].tile=1;
        level[24][i].tile=1;
    }
    level[4][2].tile=2;
    level[3][1].tile=1;
    level[3][2].tile=1;
    level[3][3].tile=1;
    level[4][3].tile=1;
 
    level[14][16].tile=1;
    level[7][11].tile=1;
    level[2][8].tile=1;
    level[8][7].tile=1;
    level[23][10].tile=1;
    level[19][14].tile=1;
    level[17][15].tile=1;
    level[16][6].tile=1;
    level[11][3].tile=1;
 
    Hero.hx=2;
    Hero.hy=2;
    Hero.xypos.x=Hero.hx*t_size;
    Hero.xypos.y=Hero.hy*t_size;
    Hero.xypos.w=t_size;
    Hero.xypos.h=t_size;
 
    for(int mx=0;mx<25;mx++)
    {
        for(int my=0;my<19;my++)
        {
            if (level[mx][my].tile>0)
            {
                level[mx][my].xypos.x=mx*t_size;
                level[mx][my].xypos.y=my*t_size;
                level[mx][my].xypos.w=t_size;
                level[mx][my].xypos.h=t_size;
            }
 
        }
    }
 
}
 
void CreateTextures()
{
    t_Hero=SDL_CreateTexture(rnd,SDL_PIXELFORMAT_BGRA8888,SDL_TEXTUREACCESS_TARGET,256,256);
    t_wall=SDL_CreateTexture(rnd,SDL_PIXELFORMAT_BGRA8888,SDL_TEXTUREACCESS_TARGET,256,256);
    t_Exit=SDL_CreateTexture(rnd,SDL_PIXELFORMAT_BGRA8888,SDL_TEXTUREACCESS_TARGET,256,256);
    t_bg=SDL_CreateTexture(rnd,SDL_PIXELFORMAT_BGRA8888,SDL_TEXTUREACCESS_TARGET,256,256);
 
    for(int y=0;y<256;y++)
    {
        for(int x=0; x<256;x++)
        {
            SDL_SetRenderTarget(rnd,t_Hero);
            SDL_SetRenderDrawColor(rnd,255-y,0+x,0+y,255);
            SDL_RenderDrawPoint(rnd,x,y);
        }
    }
 
    for(int y=0;y<256;y++)
    {
        for(int x=0; x<256;x++)
        {
            SDL_SetRenderTarget(rnd,t_wall);
            SDL_SetRenderDrawColor(rnd,x^y,x^y,x^y,255);
            SDL_RenderDrawPoint(rnd,x,y);
        }
    }
    for(int y=0;y<256;y++)
    {
        for(int x=0; x<256;x++)
        {
            SDL_SetRenderTarget(rnd,t_Exit);
            SDL_SetRenderDrawColor(rnd,x^y,0,0,255);
            SDL_RenderDrawPoint(rnd,x,y);
        }
    }
 
    for(int y=0;y<256;y++)
    {
        for(int x=0; x<256;x++)
        {
            SDL_SetRenderTarget(rnd,t_bg);
 
            SDL_SetRenderDrawColor(rnd,10,10,y,0);
            SDL_RenderDrawPoint(rnd,x,y);
 
        }
    }
    t_bg2=t_bg;
 
        SDL_SetRenderTarget(rnd,NULL);
 
}
bool XYCollision(SDL_Rect r1,SDL_Rect r2)
{
 
    if( r1.x+r1.w <= r2.x )
    {
        return false;
    }
 
    if( r1.x >= r2.x+r2.w )
    {
        return false;
    }
    if( r1.y+r1.h <= r2.y )
    {
        return false;
    }
 
    if( r1.y >= r2.y+r2.h)
    {
        return false;
    }
 
    return true;
}
 
void Scene()
{
    jump=true;
    SDL_SetRenderDrawColor(rnd,0,0,0,255);
    SDL_RenderClear(rnd);
    SDL_RenderCopy(rnd,t_bg,NULL,NULL);
 
    grav+=0.04;
    if (grav>2)
        grav=2;
 
    Hero.hx=int(Hero.xypos.x/t_size);
    Hero.hy=int(Hero.xypos.y/t_size);
    Hero.yVel=(int)grav;
    Hero.xVel=(int)speed;
 
 
    Hero._xcolpos.x=int(Hero.xypos.x+Hero.xVel);
    Hero._ycolpos.y=int(Hero.xypos.y+Hero.yVel);
 
    for(int mx=0;mx<25;mx++)
    {
        for(int my=0;my<25;my++)
        {
            if(int(mx*32)<800 && int(my*32)<600)
            {
                if (level[mx][my].tile==1)
                {
                    tmp=level[mx][my].xypos;
                    SDL_RenderCopy(rnd,t_wall,NULL,&tmp);
                }
                if (level[mx][my].tile==2)
                {
                    tmp=level[mx][my].xypos;
                    SDL_RenderCopy(rnd,t_Exit,NULL,&tmp);
                }
 
                if (!Collision.ycollide)
                {
 
                    Collision.ycollide=XYCollision(Hero._ycolpos,level[mx][my].xypos);
                    if(Hero.yVel>0)Collision.down=true;
                    Collision.ytile=level[mx][my].tile;
                }
 
                if (!Collision.xcollide)
                {
 
                    Collision.xcollide=XYCollision(Hero._xcolpos,level[mx][my].xypos);
                    Collision.xtile=level[mx][my].tile;
                }
 
            }
        }
    }
 
    if (Collision.ycollide)
    {
        if(grav<0) grav=0;
        Hero._ycolpos.y=Hero.xypos.y;
        if (Collision.down)jump=false;
 
    }
 
    if (Collision.xcollide)
    {
        Hero._xcolpos.x=Hero.xypos.x;
        if(Collision.xtile==2)
        {
            cout << "Level Ziel erreicht!" <<endl<<"Danke fürs Spielen!";
            quit=true;
        }
 
    }
 
    Hero.xypos.x=Hero._xcolpos.x;
    Hero.xypos.y=Hero._ycolpos.y;
    SDL_RenderCopy(rnd,t_Hero,NULL,&Hero.xypos);
 
    Collision.ycollide=false;
    Collision.xcollide=false;
    Collision.down=false;
    Collision.up=false;
    Collision.left=false;
    Collision.right=false;
 
    Hero._xcolpos=Hero.xypos;
    Hero._ycolpos=Hero.xypos;
 
}
rapso
Moderator

Benutzerprofil
Anmeldungsdatum: 17.06.2002
Beiträge: 8752
Beitrag rapso Moderator 09:53:38 07.04.2017   Titel:   Re: SDL2 Jump'n Run Demo            Zitieren

guitarlo schrieb:

Zum Problem:
Wenn ich springe habe ich manchmal einen Pixel abstand zwischen dem Spieler und dem Boden.

Ist nicht der ganze Sinn vom Springen, Abstand vom Boden zu erreichen?

_________________
follow me|
-Mod im Spiele-/Grafikprogrammierung
guitarlo
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.04.2017
Beiträge: 9
Beitrag guitarlo Mitglied 16:01:01 07.04.2017   Titel:              Zitieren

Das ist richtig. Aber komischerweise bleibt der Spieler bei der Landung 1 Pixel über dem Boden stehen. So eckt schonmal eine obere Ecke an darüberliegende block an wenn man zur Seite läuft. Ich glaube ich sehe gerade den Wald vor lauter Bäumen nicht :)
rapso
Moderator

Benutzerprofil
Anmeldungsdatum: 17.06.2002
Beiträge: 8752
Beitrag rapso Moderator 16:49:21 07.04.2017   Titel:              Zitieren

Wohin setzt du den Spieler denn, wenn es eine kolision gab?

_________________
follow me|
-Mod im Spiele-/Grafikprogrammierung
Protipp
Unregistrierter




Beitrag Protipp Unregistrierter 18:06:45 08.04.2017   Titel:              Zitieren

guitarlo schrieb:
Ich bin reiner Hobbycoder daher hoffe ich das der Code einigermaßen ordendlich geschrieben ist ;)
Schalt noch die Warnungen im Compiler ein.
guitarlo
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.04.2017
Beiträge: 9
Beitrag guitarlo Mitglied 11:27:36 21.04.2017   Titel:              Zitieren

rapso schrieb:
Wohin setzt du den Spieler denn, wenn es eine kolision gab?


Ich addiere in der Mainschleife jedesmal die y Position mit der y Velocity. Also in dem Falle der Schwerkraft. Also ich hatte mir das so vorgestellt:

mainschleife
{
y position + velocity= neue position
ycollisions abfrage der neuen Position
Wenn die neue Posiotion mit dem Boden kollidiert, wird die alte Position beibehalten.
Findet keine Kollision statt, wird die neue Position übernommen.
}

Und aus irgendeinem Grund bleibt bei jedem 2. Sprung der Player 1 Pixel über'n boden und kollidiert somit mit freischwebenden Blöcken.
Schlangenmensch
Mitglied

Benutzerprofil
Anmeldungsdatum: 28.11.2008
Beiträge: 395
Beitrag Schlangenmensch Mitglied 13:25:50 21.04.2017   Titel:   Re: SDL2 Jump'n Run Demo            Zitieren

guitarlo schrieb:
coder daher hoffe ich das der Code einigermaßen ordendlich geschrieben ist ;)


Keine Klassenstruktur, globale Variablen, wilder Mischmasch ziwschen float und int => Da ist noch viel Luft nach oben.

Warum setzt du in Scene() jump = true? Willst du immer springen? Warum erhöst du in Scene() grav immer um 0,4?

guitarlo schrieb:

mainschleife
{
y position + velocity= neue position
ycollisions abfrage der neuen Position
Wenn die neue Posiotion mit dem Boden kollidiert, wird die alte Position beibehalten.
Findet keine Kollision statt, wird die neue Position übernommen.
}


Also heißt Kollision mit dem Boden => letzte Position wo noch keine Kollision stattgefunden hat? Und du überprüfst das immer Pixelweise? Kann es nicht sein, dass die letzte geprüfte Position eben 1 Pixel über dem Boden ist, wenn die aktuelle geprüfte Position schon im Boden ist?
guitarlo
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.04.2017
Beiträge: 9
Beitrag guitarlo Mitglied 16:05:26 21.04.2017   Titel:              Zitieren

Ja stimmt, auf Klassen habe ich in diesem Beispiel komplett verzichtet.
Wäre übersichtlicher, hast du recht. Sorry.

Ja die Sache mit der Gravity ist mir auch aufgefallen. Die Gravity ist jetzt konstant. Hab sie im obrigen Quelltext fälschlicherweise anstatt yVelocity benutzt.

Wenn der Player springt wurde die grav auf -4.5 gesetzt und dann beim auf +2 hochgezählt damit er wieder fällt. Somit bekommt jetzt die yVelocity einen wert von -4.5 (fand ich als Sprunggeschwindigkeit okay ;)) und die Gravity wir addiert so dass der Player wieder fällt.


Vor der Kollisionsabfrage ist jump auf true. Findet keine Bodenkollision statt wird jump auf false gesetzt. Sollte ich das anders machen?


Um die Bewegung des Spielers zu verlangsamendie habe ich float benutzt. So konnte ich die Nachkommastellen addieren. Somit wird auf SDL_Rect die xVelocity gerundet und der Spieler ist langsamer. Höchstwahrscheinlich gibt es da eine bessere möglichkeit.

Schlangenmensch schrieb:


Also heißt Kollision mit dem Boden => letzte Position wo noch keine Kollision stattgefunden hat? Und du überprüfst das immer Pixelweise? Kann es nicht sein, dass die letzte geprüfte Position eben 1 Pixel über dem Boden ist, wenn die aktuelle geprüfte Position schon im Boden ist?


Guter Ansatz aber komischer weise ist der Pixel versatz nur nach jedem 2. Sprung drin.

Aber schonmal danke für die Hilfe! :)
rapso
Moderator

Benutzerprofil
Anmeldungsdatum: 17.06.2002
Beiträge: 8752
Beitrag rapso Moderator 16:21:43 21.04.2017   Titel:              Zitieren

guitarlo schrieb:
rapso schrieb:
Wohin setzt du den Spieler denn, wenn es eine kolision gab?


Ich addiere in der Mainschleife jedesmal die y Position mit der y Velocity....

Wenn die neue Posiotion mit dem Boden kollidiert, wird die alte Position beibehalten.
..

wie weit ist die alte position entfernt vom boden?

_________________
follow me|
-Mod im Spiele-/Grafikprogrammierung
guitarlo
Mitglied

Benutzerprofil
Anmeldungsdatum: 06.04.2017
Beiträge: 9
Beitrag guitarlo Mitglied 16:29:00 21.04.2017   Titel:              Zitieren

Ein Pixel da es pixelweise abgefragt wird.
Das wunderliche ist, dass es nur bei jedem 2. Sprung so ist.
C++ Forum :: Spiele-/Grafikprogrammierung ::  SDL2 Jump'n Run Demo  
Gehen Sie zu Seite 1, 2  Weiter
Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.net ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.