Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Kolizja gracza i mapy za pomocą dziedziczenia

Ostatnio zmodyfikowano 2012-10-16 21:13
Autor Wiadomość
pjpeg_objected
Temat założony przez niniejszego użytkownika
Kolizja gracza i mapy za pomocą dziedziczenia
» 2012-10-15 18:34:29
Witam. Otóż mam pewien problem ze sprawdzaniem kolizji gracza i mapy kafelkowej. Nie chodzi mi o samo sprawdzanie, tylko w jaki sposób uzyskać dostęp do wszystkich składników. Mam oczywiście klasę gracza:

C/C++
#include <SDL/SDL.h>
#include <iostream>
#ifndef PLAYER_H
#define PLAYER_H
class CPlayer {
private:
    int x, y, ix, iy;
    enum DIRECTION { NONE, LEFT, RIGHT, UP, DOWN };
    DIRECTION Direction;
public:
    CPlayer();
    SDL_Surface * Player;
    bool TurnRight();
    bool TurnLeft();
    bool TurnUp();
    bool TurnDown();
    bool Move();
    void Draw( SDL_Surface * Screen );
};

#endif

oraz klasę mapy:

C/C++
#include <SDL/SDL.h>
#include <fstream>
#ifndef MAP_H
#define MAP_H

using namespace std;

class CMap {
public:
    int Map[ 20 ][ 15 ];
    CMap();
    SDL_Surface * Tile;
    bool Read();
    void Draw( SDL_Surface * Screen );
};

#endif

I jeszcze główna funkcja gry:

C/C++
#include <SDL/SDL.h>
#include "player.h"
#include "map.h"
#ifndef GAME_H
#define GAME_H

class CGame {
private:
    CPlayer Player;
    CMap Map;
    bool GameRun;
    SDL_Event Event;
    SDL_Surface * LoadFile( const char * );
    SDL_Surface * Screen;
    SDL_Surface * Bg;
   
public:
    CGame();
    bool Start();
    bool HandleInput();
    void GamePlay();
    void CheckAndStuff();
    void Render();
};
#endif



I teraz mam pytanie. W jaki sposób mogę otrzymać dostęp do tablicy dwuwymiarowej znajdującej się w klasie CMap z poziomu np. klasy CPlayer? Próbowałem odziedziczyć klasę CMap jako pochodną ale tablica dwuwymiarowa była wypełniona ogromnymi liczbami zamiast "0" i "1". Dodam, że dziedziczenie jest dla mnie dość nowym pojęciem więc nie jestem w pełni z tym obeznany. Kolizja ma sprawdzać czy gracz może zmienić kierunek czy może napotkał ścianę. Jeśli napotkał ścianę jedzie nadal w tą samą stronę. Z góry dzięki za wszelką pomoc/podpowiedź.

Funkcja ruchu:

C/C++
bool CPlayer::Move() {
    if( Direction == RIGHT && /*TU WARUNEK KOLIZJI*/ ) x += 32;
   
    if( Direction == LEFT && /*TU WARUNEK KOLIZJI*/ ) x -= 32;
   
    if( Direction == UP && /*TU WARUNEK KOLIZJI*/ ) y -= 32;
   
    if( Direction == DOWN && /*TU WARUNEK KOLIZJI*/ ) y += 32;
   
    return true;
}




P-66875
DejaVu
» 2012-10-15 22:21:52
Hm... w zasadzie to problemem nie jest tu "kolizja gracza", tylko problemy z właściwym zaprojektowaniem kodu. Klasa CGame (która ma dostęp do mapy i wszystkich graczy) powinna zajmować się wykrywaniem kolizji. Klasa CGame powinna co najwyżej kierować pytanie do klasy CPlayer, tj.
C/C++
gracz[ x ].czyKoliduje( gracz[ y ] ); //metoda zwykła
//lub:
CPlayer::czyKoliduja( gracz[ x ], gracz[ y ] ); //metoda statyczna
P-66912
pjpeg_objected
Temat założony przez niniejszego użytkownika
» 2012-10-16 15:07:18
Wielkie dzięki. Problem prosty aczkolwiek przysporzył mi trochę kłopotów. Dzisiaj jednak doszedł kolejny. Wcześniej używałem dosyć kiepskiej funkcji SDL_Delay() zamiast użycia timerów i dzisiaj chciałem to zmienić. Dodałem obsługę FPSów, zmieniłem ruch gracza z zamiast x+=32 na x+=0.3 i mam problem z funkcją rysującą mapę, ponieważ zużywa 20 procent procesora. Byłbym wdzięczny za wskazanie błędu w funkcji rysującej mapę lub naprowadzenie mnie na inny sposób. Moim zdaniem  chodzi o Blita wywoływanego 30 razy na sekundę ale nie jestem do końca pewien jak to zmienić.

Funkcja rysująca mapę:
C/C++
void CMap::Draw( SDL_Surface * Screen ) {
    SDL_Rect MapRect;
    for( int i = 0; i < 15; i++ )
    {
        for( int j = 0; j < 20; j++ )
        {
            MapRect.x = j * 32;
            MapRect.y = i * 32;
            if( Map[ j ][ i ] == 1 ) SDL_BlitSurface( Tile, NULL, Screen, & MapRect ); //rysowanie kafelka
           
            if( Map[ j ][ i ] == 2 ) SDL_BlitSurface( Dot, NULL, Screen, & MapRect ); //rysowanie kropek(ta gra to Pacman)
           
        }
    }
}

Funkcja wczytująca mapę:
C/C++
fstream plik;
plik.open( "MAPS/Map0.txt", ios::in );
for( int i = 0; i < 15; i++ )
{
    for( int j = 0; j < 20; j++ )
    {
        plik >> Map[ j ][ i ];
    }
}
plik.close();
return true;
P-66927
waxx
» 2012-10-16 17:28:28
jest k nie przejmuj sie tym lol
P-66935
hincu
» 2012-10-16 17:44:24
            if( Map[ j ][ i ] == 1 ) SDL_BlitSurface( Tile, NULL, Screen, & MapRect ); //rysowanie kafelka
           
            if( Map[ j ][ i ] == 2 ) SDL_BlitSurface( Dot, NULL, Screen, & MapRect ); //rysowanie kropek(ta gra to Pacman)
           


zamien na

            if( Map[ j ][ i ] == 1 ) SDL_BlitSurface( Tile, NULL, Screen, & MapRect ); //rysowanie kafelka
           
            else if( Map[ j ][ i ] == 2 ) SDL_BlitSurface( Dot, NULL, Screen, & MapRect ); //rysowanie kropek(ta gra to Pacman)
           

wtedy kazda taka petla bedzie sprawdzala tylko raz warunek a nie wszystkie po koleji szczegolnie jak juz znajdzie odpowiedni id tilesetu
P-66937
pjpeg_objected
Temat założony przez niniejszego użytkownika
» 2012-10-16 18:10:17
Zrobiłem jak mi poradziłeś lecz nie podziałało. Zużycie procesora waha się od 20-25% przy czym mam 4 rdzeniowy procesor. Kod od renderowania:

C/C++
void CGame::Render() {
    SDL_BlitSurface( Bg, NULL, Screen, NULL );
    Map.Draw( Screen );
    Player.Draw( Screen );
    if( Timer < SDL_GetTicks() ) {
        Player.Animation();
        Timer = SDL_GetTicks() + 170;
    }
    SDL_Flip( Screen );
    if( 1000 / 30 >( SDL_GetTicks() - Timer ) )
    {
        SDL_Delay( 1000 / 30 -( SDL_GetTicks() - Timer ) );
    }
}

Jeśli wykomentuję Player.Draw(Screen) to 1-2% zużycie. Nie wiem jaki może być problem.
P-66940
Mrovqa
» 2012-10-16 19:24:06
Nie widzę nigdzie czegoś na wzór Sleepa = nic dziwnego, że gra zajeżdża cały rdzeń procesora.
P-66944
pjpeg_objected
Temat założony przez niniejszego użytkownika
» 2012-10-16 19:30:46
Jest kontrola FPSów

C/C++
if( 1000 / 30 >( SDL_GetTicks() - Timer ) )
{
    SDL_Delay( 1000 / 30 -( SDL_GetTicks() - Timer ) );
}

Wcześniej jak robiłem sam SDL_Delay(200) gra nie chodziła płynnie bo dodawałem do player'a +32 zamiast np. +0.3.

P-66947
« 1 » 2
  Strona 1 z 2 Następna strona