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

Dziwne działanie biblioteki C++ SFML 2.4.2

Object Storage Arubacloud
0 głosów
542 wizyt
pytanie zadane 10 czerwca 2017 w C i C++ przez TomaszA2 Obywatel (1,720 p.)
#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <cmath>
#include <windows.h>
#include <stdio.h>
#include <cstdarg>
#include <stdlib.h>
#include <cstdlib>
#include <math.h>
#include <time.h>
#include <iostream>
#include <fstream>
#include <conio.h>
#include <string>
#include <sstream>
#include <iostream>

int main()
{
	sf::Vector2i mysz;
	int myszX;
	int myszY;
	int rend[25][80];
	std::string bufor2;
	std::string bufor;
	std::fstream plik;
	plik.open( "plik.txt", std::ios::in );
	for(int e=0; e!=25; e++)
	{
		getline(plik, bufor);
		for(int f=0; f!=80; f++)
		{
			bufor2=bufor[f];
			rend[e][f]=atoi(bufor2.c_str());
		}
	}
	
	int obrazY=0;
	int obrazX=0;
    sf::RenderWindow Okno(sf::VideoMode( 790, 250, 32 ) ,"Test");
    sf::Texture test;
    test.loadFromFile("tekstury/test.BMP");
    sf::Sprite obraz;
    obraz.setTexture(test);
    Okno.setFramerateLimit(60);
    //Okno.create(sf::VideoMode( 400, 400, 32 ) ,"", sf::Style::None);
    while(Okno.isOpen())
    {
     	sf::Event zdarzenie;
     	while( Okno.pollEvent( zdarzenie ) )
     	{
		    if( zdarzenie.type == sf::Event::Closed )
    		{
           		
   				Okno.close();
   			}
		}
        if(sf::Keyboard::isKeyPressed( sf::Keyboard::Left )) obrazX-=3;
   		if(sf::Keyboard::isKeyPressed( sf::Keyboard::Right )) obrazX+=3;
   		if(sf::Keyboard::isKeyPressed( sf::Keyboard::Up )) obrazY-=3;
   		if(sf::Keyboard::isKeyPressed( sf::Keyboard::Down )) obrazY+=3;
   		//=
   		obraz.setPosition(obrazX, obrazY);
   		plik.clear();
		plik.seekg(0);
   		
   		for(int e=0; e!=25; e++)
		{
			getline(plik, bufor);
			for(int f=0; f!=80; f++)
			{
				bufor2=bufor[f];
				rend[e][f]=atoi(bufor2.c_str());
			}
		}
		if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
   		{
   			mysz=sf::Mouse::getPosition(Okno);
   			myszX=mysz.x/10;
   			myszY=mysz.y/10;
   			//if(rend[myszY][myszX]==1) rend[myszY][myszX+1]=0;
   			if(rend[myszX][myszX]!=1) rend[myszY][myszX+1]=1;
		}
   		for(int a=0; a!=25; a++)
   		{
   			for(int b=0; b!=80; b++)
   			{
   				//Sleep(100);
   				if(rend[a][b]==1) Okno.draw(obraz);
   				
   				
   				obraz.setPosition(b*10, a*10);
			}
			
		}
	
     	Okno.display();
     	Okno.clear(sf::Color(0,0,0));	
	}
	plik.close();
    return 0;
}

 

Problem leży w tym że aplikacja przestaje odpowiadać po kliknięciu myszką lub używaniu jej w nim przez jakiś czas. Zauważyłem że problem sprawiają linijki:

if(rend[myszY][myszX]==1) rend[myszY][myszX+1]=0;
if(rend[myszX][myszX]!=1) rend[myszY][myszX+1]=1;

 

Teoretycznie zmiana wartości zmiennej nie powinna w ogóle sprawiać problemu. Nie wiem co tutaj może być nie tak, ale jeśli tych dwóch linijek nie ma to wszystko działa dobrze cały czas.

 

1 odpowiedź

0 głosów
odpowiedź 10 czerwca 2017 przez draghan VIP (106,230 p.)
wybrane 11 czerwca 2017 przez TomaszA2
 
Najlepsza
Stawiam na przekroczenie zakresu tablicy i tym samym próbę zapisu w niedozwolonym obszarze pamięci. Powinieneś ograniczyć wartości zmiennych myszX i myszY do rozmiaru odpowiednich tablic.
komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)

Mógłbyś spróbować nieco dokładniej mi to wytłumaczyć? Z tego co zrozumiałem wynika że mam wszystko dobrze ponieważ:

myszX=mysz.x/10;
myszY=mysz.y/10;

 

Zmienne mają wartość mieszczącą się w zakresie tablicy. (niezależnie od tego czy chodzi o ilość miejsc w tablicy czy jej typ [int])

komentarz 11 czerwca 2017 przez draghan VIP (106,230 p.)

Czy aby na pewno?

Zmienna mysz zawiera pozycję kursora w oknie o rozmiarach 790x250. Zatem maksymalna wartość wyrażenia mysz.x / 10 = 78, zaś mysz.y / 10 = 24 (załóżmy, że sf::Mouse::getPosition() zwraca wartości [0; rozmiar-1] - w dokumentacji nie sprecyzowano)

Tablica rend ma wymiary 25x80, więc maksymalne dozwolone indeksy to [24][79].

Pisząc:

if(rend[myszX][myszX]!=1)

powinieneś upewnić się, że zmienna myszX użyta jako pierwszy indeks tablicy ma wartość mniejszą niż 25.

komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)

,, powinieneś upewnić się, że zmienna myszX użyta jako pierwszy indeks tablicy ma wartość mniejszą niż 25. "

Dodałem:

if(myszX==25)myszX-=1;

Przed:

if(rend[myszY][myszX]==1) rend[myszY][myszX+1]=0;
if(rend[myszX][myszX]!=1) rend[myszY][myszX+1]=1;

 

Problem wciąż występuje.

,, Tablica rend ma wymiary 25x80, więc maksymalne dozwolone indeksy to [24][79]. "

Czy aby na pewno? Jakoś to:

for(int a=0; a!=25; a++)
        {
            for(int b=0; b!=80; b++)
            {
                //Sleep(100);
                if(rend[a][b]==1) Okno.draw(obraz);
                 
                 
                obraz.setPosition(b*10, a*10);
            }
             
        }

 

Działa dobrze tylko jeśli odwołuję się do 25x80. (z 24x79 nie pokazuje 25 rzędu i 80 kolumny)

komentarz 11 czerwca 2017 przez draghan VIP (106,230 p.)

,, Tablica rend ma wymiary 25x80, więc maksymalne dozwolone indeksy to [24][79]. "

Czy aby na pewno?

Na pewno.

Dodałem: if(myszX==25)myszX-=1;

A ja napisałem, że powinieneś zadbać o to, żeby wartość była mniejsza od 25. Przy Twoim warunku każda wartość > 25 zostanie przepuszczona.

 

komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)
Właśnie zobaczyłem że w jednym z warunków miałem coś takiego: [myszX][myszX]

Zaraz to sprawdzę. [czy to nie to powoduje błąd]
komentarz 11 czerwca 2017 przez draghan VIP (106,230 p.)

Przecież tutaj Ci o tym napisałem...

komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)
Sprawdziłem, to nie była przyczyna.
komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)
Nie crashuje już. Przyczyną jednak był X oraz Y wychodzące poza okno programu.

Dodałem warunki ograniczające to do wymiarów okna. Ale nie wiem czemu warunek z X działa jakby było 78 kolumn. Oprócz tego mam jeszcze jeden problem nierozwiązany ale później go opiszę.
komentarz 11 czerwca 2017 przez draghan VIP (106,230 p.)

Jeśli nie wierzyłeś w to że zasady języka jednak działają, wystarczyło uruchomić debugger - rzucał segfaultem w linii:

if(rend[myszX][myszX]!=1) rend[myszY][myszX+1]=1;

Życzę powodzenia w dalszej nauce. :)

komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)

Wiesz może dlaczego blok nr. 25x80 (lub 24x79, zależy od której strony patrzeć, to taki najbardziej na dół i prawo za razem) jest ignorowany przez program? Zmieniłem go trochę na wzór konsoli windowsowej. (dokładnie 800x250)

#include <SFML/Graphics.hpp>
#include <SFML/Window.hpp>
#include <SFML/System.hpp>
#include <cmath>
#include <windows.h>
#include <stdio.h>
#include <cstdarg>
#include <stdlib.h>
#include <cstdlib>
#include <math.h>
#include <time.h>
#include <iostream>
#include <fstream>
#include <conio.h>
#include <string>
#include <sstream>
#include <iostream>

int main()
{
	sf::Vector2i mysz;
	int myszX;
	int myszY;
	int rend[25][80];
	std::string bufor2;
	std::string bufor;
	std::fstream plik;
	plik.open( "plik.txt", std::ios::in );
	for(int e=0; e!=25; e++)
	{
		getline(plik, bufor);
		for(int f=0; f!=80; f++)
		{
			bufor2=bufor[f];
			rend[e][f]=atoi(bufor2.c_str());
		}
	}
	
	int obrazY=0;
	int obrazX=0;
    sf::RenderWindow Okno(sf::VideoMode( 800, 250, 32 ) ,"Test");
    sf::Texture test;
    test.loadFromFile("tekstury/test.BMP");
    sf::Sprite obraz;
    obraz.setTexture(test);
    Okno.setFramerateLimit(60);
    //Okno.create(sf::VideoMode( 400, 400, 32 ) ,"", sf::Style::None);
    while(Okno.isOpen())
    {
     	sf::Event zdarzenie;
     	while( Okno.pollEvent( zdarzenie ) )
     	{
		    if( zdarzenie.type == sf::Event::Closed )
    		{
           		
   				Okno.close();
   			}
		}
        if(sf::Keyboard::isKeyPressed( sf::Keyboard::Left )) obrazX-=3;
   		if(sf::Keyboard::isKeyPressed( sf::Keyboard::Right )) obrazX+=3;
   		if(sf::Keyboard::isKeyPressed( sf::Keyboard::Up )) obrazY-=3;
   		if(sf::Keyboard::isKeyPressed( sf::Keyboard::Down )) obrazY+=3;
   		//=
   		obraz.setPosition(obrazX, obrazY);
   		plik.clear();
		plik.seekg(0);
   		
   		for(int e=0; e!=25; e++)
		{
			getline(plik, bufor);
			for(int f=0; f!=80; f++)
			{
				bufor2=bufor[f];
				rend[e][f]=atoi(bufor2.c_str());
			}
		}
		if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
   		{
   			mysz=sf::Mouse::getPosition(Okno);
   			myszX=mysz.x/10;
   			myszY=mysz.y/10;
   			if(myszY>24)myszY=24;
   			if(myszY<0)myszY=0;
   			if(myszX>79)myszX=79;
   			if(myszX<0)myszX=0;
   			
   			if(rend[myszY][myszX]!=1) rend[myszY][myszX+1]=1;
   			if(rend[myszY][myszX]==1) rend[myszY][myszX+1]=0;
		}
   		for(int a=0; a!=25; a++)
   		{
   			for(int b=0; b!=80; b++)
   			{
   				//Sleep(100);
   				if(rend[a][b]==1) Okno.draw(obraz);
   				
   				
   				obraz.setPosition(b*10, a*10);
			}
			
		}
	
     	Okno.display();
     	Okno.clear(sf::Color(0,0,0));	
	}
	plik.close();
    return 0;
}

Oprócz tego program w przypadku zmiany z 1 na 0 nie reaguje na ściśle określone przez sam nie wiem co bloki.

Masz może discorda? Moglibyśmy na czacie pisać zamiast tutaj. Wszystko poszłoby o wiele sprawniej. Oprócz tego wyślę ci tam paczkę ze wszystkim żebyś mógł zobaczyć co mam na myśli.

https://discord.gg/XnTyBgs

komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)
https://drive.google.com/open?id=0B0G4a8MmpuxoMXpweXRjRXRKQ0E

Tutaj paczka do wglądu jak błędy wyglądają.
komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)
Okazało się że to po prostu pierwsza z rzędu 1 lub 0 w danej linijce jest blokowana, ale nie wiem jeszcze jak to naprawić.
komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)

Wystarczyło zrobić else if zamiast drugiego ifa w:

if(rend[myszY][myszX+1]!=1) rend[myszY][myszX+1]=1;
if(rend[myszY][myszX+1]==1) rend[myszY][myszX+1]=0;

 

Oprócz tego wróciłem do 80 bloków w rozmiarze 790 px. Czyli na razie wszystko działa.

komentarz 11 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)
Kolejne 2 błędy których nie umiem naprawić...

 Mógłbyś wejść na tego discorda żeby mi pomóc? (tak pójdzie znacznie szybciej niż jakbym miał tutaj pytać o wszystko co pójdzie z tym kodem nie tak) Chcę tylko doprowadzić to do stanu stabilnego a później sam sobie poradzę.
komentarz 14 czerwca 2017 przez draghan VIP (106,230 p.)
Wybacz, nie miałem czasu wejść na Forum. Nadal masz jakiś problem z tym?
komentarz 14 czerwca 2017 przez TomaszA2 Obywatel (1,720 p.)
Na razie jest stabilnie. Problem obecnie mam głównie z źle[w ogóle tego nie robią] wyświetlającymi się pierwszymi znakami każdej linii. Ludzie z forum już mi z tym pomagają. Założyłem drugi wątek bo tutaj nikt by nie zauważył, ten jest już za stary i nikt poza nami chyba o nim już nie myśli.

Szczerze pisząc to przez chwilę nawet zapomniałem o jaki problem w tym temacie chodziło. To crashowanie aplikacji powodowane było przez wychodzenie myszki poza okno. Zablokowałem więc wszystkie zmienne zależne od myszki na ramy okna. I działa.
komentarz 14 czerwca 2017 przez draghan VIP (106,230 p.)
Problem nie polegał na wychodzeniu kursora poza obręb okna, tylko na niepoprawnym operowaniu tablicami (które było zależne od pozycji kursora, ale to szczegół). :)

Skoro stabilnie, to fajnie. Owocnej nauki życzę.

Podobne pytania

0 głosów
2 odpowiedzi 148 wizyt
pytanie zadane 2 kwietnia 2018 w C i C++ przez grubix Nowicjusz (210 p.)
0 głosów
2 odpowiedzi 198 wizyt
pytanie zadane 20 stycznia 2018 w C i C++ przez Kurczak Użytkownik (940 p.)

92,617 zapytań

141,466 odpowiedzi

319,783 komentarzy

61,999 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...