• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Uruchomienie programu w sfml

Aruba Cloud - Virtual Private Server VPS
0 głosów
103 wizyt
pytanie zadane 15 stycznia w C i C++ przez konrad_ Nowicjusz (120 p.)
zamknięte 22 stycznia przez konrad_

Napisałem grę xonix w c++ z użyciem biblioteki sfml, ale nie potrafię jej uruchomić. Nie wyskakują żądne błędy i nie wiem co jest nie tak, ponieważ mechanika nie działa tak jak powinna. W programie są 3 klasy kolejno po sobie dziedziczące Enemy Player i Game. Klasa Game posiada metodę run, która z założenia miała po wywołaniu jej w funkcji main, uruchomić cały program. 

 

Game.cpp

#include<SFML/System/Clock.hpp>
#include<SFML/System/Time.hpp>
#include"Game.h"
#include "Player.h"

Game::Game() {
    game_window.create(sf::VideoMode(K * tile_size, W * tile_size), "XONIX"); // tworzenie okna
	game_window.setFramerateLimit(60);
	resetGame();
    set_frame();
    Render();
	Run();
}



void Game::resetGame() {
  
    gPlayer.user_x = 0;
    gPlayer.user_y = 0;
    gPlayer.user_dx = 0;
    gPlayer.user_dy = 0;
    gameplay = true;

    // Reset grid
    set_frame();
    
    occupiedCount = -90;
    calculateOccupiedPercentage();

    // Reset enemies
    for (int i = 0; i < numEnemies; i++) {
        new enemy(); // Reinitialize enemies
    }
}



float Game::calculateOccupiedPercentage() {
    occupiedCount = -90.0;
    int totalCount = ((W - 2) * (K - 2)) - 27; // Pomijamy obramowanie i miejsce na procenty

    for (int i = 0; i < W - 1; i++) {
        for (int j = 0; j < K - 1; j++) {
            if (grid[i][j] == 1) occupiedCount++;
        }
    }

    float occupiedPercentage = (occupiedCount / static_cast<float>(totalCount)) * 100.0f;

    if (static_cast<int>(occupiedPercentage) > 80) {
       // game_window.draw(sLevel_up);
        resetGame();
        
    }
    return occupiedPercentage;
}


void Game::set_frame() {
    for (int i = 0; i < W; i++) {
        for (int j = 0; j < K; j++) {
            if (i == 0 || j == 0 || i == W - 1 || j == K - 1) {
                grid[i][j] = 1; // ustawianie wartości 1 w tablicy dla obramowania
			}
            else {
                grid[i][j] = 0; // ustawianie wartości 0 w tablicy dla pustych pól
            }
        }
    }

    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 10; j++) {
            grid[i][j] = 1; // ustawianie wartości 1 w tablicy dla percentage bar
        }
    }
}



void Game::Render() {
    Texture texture1, texture2, texture3, texture4,texture5; // loading textures
    texture1.loadFromFile("images/tiles.png");
    texture2.loadFromFile("images/gameover.png");
    texture3.loadFromFile("images/enemy.png");
    texture4.loadFromFile("images/level_up.png");

    Sprite sTile(texture1), sGameover(texture2), sEnemy(texture3), sLevel_up(texture4), sPlayer(texture5);
    sLevel_up.setOrigin(100, 100);
    sGameover.setPosition(100, 100);
    sEnemy.setOrigin(20, 20);

    Font font;
    if (!font.loadFromFile("font/agency_fb.ttf")) {
        std::cerr << "Nie udało się załadować czcionki!" << std::endl;
    }

    Text percentageText;
    percentageText.setFont(font);
    percentageText.setCharacterSize(30);
    percentageText.setFillColor(Color::White);
    percentageText.setStyle(sf::Text::Bold);
    percentageText.setPosition(10, 10);

    float occupiedPercentage = calculateOccupiedPercentage();
    percentageText.setString("Occupied: " + std::to_string(static_cast<int>(occupiedPercentage)) + "%");
    game_window.draw(percentageText);

    
    ////////////////////////////////////////////////////////////////////////
    
    set_frame();

    for (int i = 0; i < W; i++) { // rysuje siatke, przeciwnikow i postac gracza
        for (int j = 0; j < K; j++) {
            if (grid[i][j] == 0) continue; // puste pole
            if (grid[i][j] == 1) sTile.setTextureRect(IntRect(0, 0, tile_size, tile_size)); // sciana
            if (grid[i][j] == 2) sTile.setTextureRect(IntRect(54, 0, tile_size, tile_size)); // slad gracza
            sTile.setPosition(static_cast<float>(j * tile_size), static_cast<float>(i * tile_size));
            game_window.draw(sTile);
        }
    }

    sTile.setTextureRect(IntRect(36, 0, tile_size, tile_size));
    sTile.setPosition(user_x * tile_size, user_y * tile_size);
    game_window.draw(sTile);

    RectangleShape black_bar(sf::Vector2f(162, 54));
    black_bar.setFillColor(sf::Color::Black);
    black_bar.setPosition(0, 0);
    game_window.draw(black_bar);

    sEnemy.rotate(10);
    for (int i = 0; i < numEnemies; i++) {
        sEnemy.setPosition(static_cast<float>(tab[i].x), static_cast<float>(tab[i].y));
        game_window.draw(sEnemy);
    }

	game_window.draw(percentageText);


}




void Game::Run() {
    //game_window.create(sf::VideoMode(K * tile_size, W * tile_size), "XONIX"); // tworzenie okna
    //game_window.setFramerateLimit(60);

    while (game_window.isOpen()) {
        while (game_window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                game_window.close();
            }

            if (event.type == sf::Event::KeyPressed) {
                if (event.key.code == sf::Keyboard::Space) {
                    resetGame();
                }
            }
        }
        
        
        // Aktualizujemy stan gry
        gPlayer.clock.restart();
        gPlayer.Move();
        gPlayer.collisions();
        for (int i = 0; i < numEnemies; i++) {
                tab[i].move();
            }
    
        // Sprawdzanie kolizji gracza z przeciwnikami
        for (int i = 0; i < numEnemies; i++) {
            if (grid[tab[i].y / tile_size][tab[i].x / tile_size] == 2) {
                gameplay = false;
            }
        }

        if (!gameplay) {
            game_window.clear();
           // game_window.draw(sGameover);
            game_window.display();
            //sf::sleep(sf::seconds(2)); // Krótka pauza po zakończeniu gry
            resetGame();
            continue;
        }

        // Renderowanie gry
        game_window.clear();
        Render();
        game_window.display();
    }
}

ale po jej wywołaniu, obiekt player nawet się nie pokazuje a obiekty enemy wylatują poza okno. Poniżej załączam resztę kodu

 

Game.h

#pragma once
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include<SFML/System/Time.hpp>
#include <time.h>
#include <iostream>
#include"Player.h"


extern enemy tab[5];
using namespace sf;


class Game: public Player
{
public:
	
	//Sprite sTile, sGameover, sEnemy, sLevel_up;
	float occupiedCount=0;
	sf::RenderWindow game_window;
	sf::Event event;
	Game();
	void resetGame();
	float calculateOccupiedPercentage();
	void set_frame();
	//void Draw();
	void Render();
	void Run();	
	Player gPlayer;
	enemy gEnemy;

};




 

Player.h

#pragma once
#include <time.h>
#include<Windows.h>
#include<sfml/Window.hpp>
#include"enemy.h"

extern int grid[25][40];
extern int tile_size;
class Game;
extern enemy tab[5];


class Player: public enemy
{
public:
	int user_dx, user_dy, user_x, user_y;
	sf::Clock clock;
	float timer = 0;
	double delay = 0.07;
	Player();
	void Move();
	void collisions();
	int send_components();
	static const int W = 25;
	static const int K = 40;

};

 

Player.cpp

#include "Player.h"
#include<SFML/Window.hpp>
#include<windows.h>

using namespace sf;


Player::Player()
{
    user_x = 0, user_y = 0, user_dx = 0, user_dy = 0;
    srand(static_cast<int>(time(NULL)));
    float time = clock.getElapsedTime().asSeconds();
    clock.restart();
    timer += time;

}


void Player::Move()
{
    if (Keyboard::isKeyPressed(Keyboard::Left)) { user_dx = -1; user_dy = 0; } // ruchy gracza
    if (Keyboard::isKeyPressed(Keyboard::Right)) { user_dx = 1; user_dy = 0; }
    if (Keyboard::isKeyPressed(Keyboard::Up)) { user_dx = 0; user_dy = -1; }
    if (Keyboard::isKeyPressed(Keyboard::Down)) { user_dx = 0; user_dy = 1; }


    if (timer > delay) // przesuwanie gracza o jedno pole co jakis czas
    {
        user_x += user_dx;
        user_y += user_dy;

        if (user_x < 0) user_x = 0;
        if (user_y < 0) user_y = 0;
        if (user_x > K - 1) user_x = K - 1;
        if (user_y > W - 1) user_y = W - 1;

        if (grid[user_y][user_x] == 2) gameplay = false; // kolizja w wlasnym sladem
        if (grid[user_y][user_x] == 0) grid[user_y][user_x] = 2; // tworzenie sladu
        timer = 0;
    }
}

void Player::collisions() {

    if (grid[user_y][user_x] == 1) // sprawdza czy gracz zamknął obszar i aktualizuje siatke
    {
        user_dx = user_dy = 0;

        for (int i = 0; i < numEnemies; i++)
            tab[i].occupy(tab[i].y / tile_size, tab[i].x / tile_size);

        for (int i = 0; i < W; i++)
            for (int j = 0; j < K; j++)
                if (grid[i][j] == -1) grid[i][j] = 0; // obszar zamnkniety
                else grid[i][j] = 1; // sciany
    }

}


int Player::send_components()
{
    return user_x, user_y, user_dx, user_dy;
}

 

enemy.h

#pragma once
#include<time.h>
#include <stdlib.h>



static int grid[25][40] = { 0 };
static int tile_size=18;


class enemy{
public:
	static bool gameplay;
	int x, y, dx, dy;
	int numEnemies = 5; // number of enemies
	enemy();
	void move();
	void occupy(int y, int x);
	~enemy() = default;
};

static enemy tab[5];

 

enemy.cpp

#include "enemy.h"


bool enemy::gameplay=1;


enemy::enemy()
{
	x = 300;
	y = 300;
	dx = 3- rand() % 6;
	dy = 3-rand() % 6;
	void move();
}

void enemy::move()
{
	x += dx;
	if (grid[y / tile_size][x / tile_size] == 1) { dx = -dx; x += dx; }
	y += dy;
	if (grid[y / tile_size][x / tile_size] == 1) { dy = -dy; y += dy; }
}

//zajmowanie planszy
void enemy::occupy(int y, int x)
{
	if (grid[y][x] == 0) grid[y][x] = -1;
	if (grid[y - 1][x] == 0) occupy(y - 1, x);
	if (grid[y + 1][x] == 0) occupy(y + 1, x);
	if (grid[y][x - 1] == 0) occupy(y, x - 1);
	if (grid[y][x + 1] == 0) occupy(y, x + 1);
}

Funkcja main to tylko zdefiniowanie obiektu game klasy Game i wywołanie dla niego metody Run().

Byłbym bardzo wdzięczny, gdyby ktoś chociaż podpowiedział gdzie szukać błędów, bo siedzę nad tym już naprawdę długo a na nic nie wpadłem.
 

komentarz zamknięcia: Problem rozwiązany
komentarz 15 stycznia przez Ehlert Ekspert (214,940 p.)

Jak chcesz sam pisać to obowiązkowo: https://gameprogrammingpatterns.com/contents.html

1 odpowiedź

+1 głos
odpowiedź 15 stycznia przez adrian17 Mentor (352,580 p.)

obiekt player nawet się nie pokazuje

Ale... nigdzie nie napisałeś kodu który by rysował gracza?

Nigdzie przy rysowaniu nie używasz gPlayer, masz też sprite sPlayer z którym nic nie robisz ani nawet nie ładujesz dla niego żadnej tekstury.

komentarz 15 stycznia przez adrian17 Mentor (352,580 p.)
Jeszcze na boku zaznaczę że ładowanie wszystkich tekstur z pliku co klatkę nie jest najlepszym pomysłem ;)

No i ogólnie polecam uporządkowanie trochę tego kodu. Też nie rozumiem w jaki sposób napisałeś tyle do przodu bez upewnienia się, że podstawy działają. Czemu pisałeś kod ruszający gracza zanim w ogóle go wyświetliłeś...?

No i na przyszłość wrzuć cały projekt do jakiegoś repo, bo tak bez dodatkowych plików to i tak nikt nie będzie w stanie go uruchomić :c

Podobne pytania

0 głosów
0 odpowiedzi 416 wizyt
pytanie zadane 19 czerwca 2022 w C i C++ przez hicodyn Początkujący (420 p.)
0 głosów
1 odpowiedź 418 wizyt
pytanie zadane 30 lipca 2021 w C i C++ przez tonn204 Mądrala (7,470 p.)
0 głosów
1 odpowiedź 546 wizyt
pytanie zadane 28 lipca 2021 w C i C++ przez tonn204 Mądrala (7,470 p.)

93,335 zapytań

142,331 odpowiedzi

322,415 komentarzy

62,670 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...