allegro - kilka problemów podczas tworzenia gry 2D

0

Są to moje początki z allegro i tworzę grę typu: space defender, lecz napotkałem kilka problemów. Gra się kompiluje, mogę niszczyć obiekty, lecz podczas gdy statek powinien stracić życie oraz dostać punkty za zniszczenie, to niestety nic się nie dzieje. Program oparty jest na klasach, mam takiego maina(jeżeli zajdzie potrzeba, to udostępnię pozostałe pliki klas.):

#include<allegro5\allegro.h>
#include<allegro5\allegro_primitives.h>
#include<allegro5\allegro_ttf.h>
#include<allegro5\allegro_primitives.h>
#include "kometa.h"
#include "statek.h"
#include "pocisk.h"

const int NUM_BULLETS = 5;
const int NUM_COMETS = 10;
enum KEYS{UP, DOWN, LEFT, RIGHT, SPACE};
bool keys[5] = {false, false, false, false, false};

int main()
{
	//primitive variable
	bool done = false;
	bool redraw = true;
	const int FPS = 60;
	bool isGameOver = false;

	//zmienne obiektowe
	statek ship;
	pocisk bullets[NUM_BULLETS];
	kometa comets[NUM_COMETS];

	//zmienne allegro
	ALLEGRO_DISPLAY *display = NULL;
	ALLEGRO_EVENT_QUEUE *event_queue = NULL;
	ALLEGRO_TIMER *timer = NULL;
	ALLEGRO_FONT *font18 = NULL;

	if(!al_init()) //inicjalizacja allegro
	{
		return -1;
	}

	display = al_create_display(WIDTH, HEIGHT); //stworzenie objektu wyswiettlającego

	if(!display) //testowanie obiektu wyświetlającego
	{
		return -1;
	}

	al_init_primitives_addon();
	al_install_keyboard();
	al_init_font_addon();
	al_init_ttf_addon();

	event_queue = al_create_event_queue();
	timer = al_create_timer(1.0 / FPS);

	font18 = al_load_font("arial.ttf", 18, 0);

	srand(time(NULL));
	al_register_event_source(event_queue, al_get_keyboard_event_source());
	al_register_event_source(event_queue, al_get_timer_event_source(timer));
	al_register_event_source(event_queue, al_get_display_event_source(display));
	
	al_start_timer(timer);

	int j = 0;//zmienna dla odpalania pocisku
	int akt_zycie = ship.zwroc_lives();
	int zycia;
	while (!done)
	{
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);
		
		if (ev.type == ALLEGRO_EVENT_TIMER)
		{
			redraw = true;
			if (keys[UP])
			{
				ship.moveShipUP();
			}
			if (keys[DOWN])
			{
				ship.moveShipDOWN();
			}
			if (keys[LEFT])
			{
				ship.moveShipLEFT();
			}
			if (keys[RIGHT])
			{
				ship.moveShipRIGHT();
			}
			if (!isGameOver)
			{
				bullets->updatePocisk(bullets, NUM_BULLETS);
				comets->startKomety(comets, NUM_COMETS);
				comets->updateKomety(comets, NUM_COMETS);
				bullets->kolizjaPocisku(bullets, NUM_BULLETS, comets, NUM_COMETS, ship);
				comets->kolizjaKomety(comets, NUM_COMETS, ship);
				zycia = ship.zwroc_lives();
				if (zycia <=0)
				{
					isGameOver = true;
				}
			}
		}
		else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{
			done = true;
		}
		else if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			switch (ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = true;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = true;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = true;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = true;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = true;
				bullets[j].odpalPocisk(bullets, NUM_BULLETS, ship);
				j++;
				if (j == 5)
				{
					j = 0;
				}
				break;
			}
		}
		else if (ev.type == ALLEGRO_EVENT_KEY_UP)
		{
			switch (ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = false;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = false;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = false;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = false;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = false;
				break;
			}
		}
		
		if (redraw && al_is_event_queue_empty(event_queue))
		{
			redraw = false;

			if (!isGameOver)
			{
				ship.drawShip();
				bullets->rysujPocisk(bullets, NUM_BULLETS);
				comets->rysujKomete(comets, NUM_COMETS);
				al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Player has %i lives. Player destroyed %i objects", ship.zwroc_lives(), ship.zwroc_wynik());
			}
			else
			{
			}

			al_flip_display();
			al_clear_to_color(al_map_rgb(0, 0, 0));
		}
	}

	al_destroy_event_queue(event_queue); // znieszczenie kolejki
	al_destroy_timer(timer); // znieszczenie timera
	al_destroy_display(display); //znieszczenie obiektu wyświetlającegoa
	
	return 0;
}

Może ktoś wie dlaczego nie nalicza mi tych punktów, oraz nie odejmuje żyć.

0

Jak możemy cokolwiek powiedzieć, skoro mamy jedynie fragment kodu? ...
Wrzuć to całe, a najlepiej jeszcze sam debuggerem przeleć ten kod i posprawdzaj wartości zmiennych.

0

ok. Wrzucam cały kod:
Klasa pocisku:

#pragma once
#include "statek.h"
#include "kometa.h"

class pocisk
{
public:
	pocisk(void);
	~pocisk(void);
private:
	int ID;
	int x;
	int y;
	bool live;
	int speed;
public:
	void initPocisk(void);
	void rysujPocisk(pocisk pocisk[], int size);
	void odpalPocisk(pocisk pociski[], int size, statek ship);
	void updatePocisk(pocisk pocisk[], int size);
	void kolizjaPocisku(pocisk pocisk[], int pSize, kometa kometa[], int kSize, statek statek);
};

metody klasy:

#include "pocisk.h"
#include<allegro5\allegro_primitives.h>


pocisk::pocisk(void)
{
	ID = BULLET;
	speed = 10;
	live = false;
}


pocisk::~pocisk(void)
{
}


void pocisk::initPocisk(void)
{
}

void pocisk::rysujPocisk(pocisk pocisk[], int size)
{
	for (int i = 0; i < size; i++)
	{
		if (pocisk[i].live)
		{
			al_draw_filled_circle(pocisk[i].x, pocisk[i].y, 2, al_map_rgb(255, 255, 255));
		}
	}
}

void pocisk::odpalPocisk(pocisk pociski[], int size, statek ship)
{
	for (int i = 0; i < size; i++)
	{
		if (!pociski[i].live)
		{
			pociski[i].x = ship.zwroc_x() + 17;
			pociski[i].y = ship.zwroc_y();
			pociski[i].live = true;
			break;
		}
	}
}

void pocisk::updatePocisk(pocisk pocisk[], int size)
{
	for (int i = 0; i < size; i++)
	{
		if (pocisk[i].live)
		{
			pocisk[i].x += pocisk[i].speed;
			if (pocisk[i].x > WIDTH)
			{
				pocisk[i].live = false;
			}
		}
	}
}

void pocisk::kolizjaPocisku(pocisk pocisk[], int pSize, kometa kometa[], int kSize, statek statek)
{
	for (int i = 0; i < pSize; i++)
	{
		if (pocisk[i].live)
		{
			for (int j = 0; j < kSize; j++)
			{
				if (kometa[j].zwroc_live())
				{
					if (pocisk[i].x > (kometa[j].zwroc_x() - kometa[j].zwroc_boundx()) &&
						pocisk[i].x < (kometa[j].zwroc_x() + kometa[j].zwroc_boundx()) &&
						pocisk[i].y > (kometa[j].zwroc_y() - kometa[j].zwroc_boundy()) &&
						pocisk[i].y < (kometa[j].zwroc_y() + kometa[j].zwroc_boundy()))
					{
						pocisk[i].live = false;
						kometa[j].zmienBool();
						statek.zwiekszWynik();
					}
				}
			}
		}
	}
}

Klasa komety:

#pragma once
#include "statek.h"
class kometa
{
public:
	kometa(void);
	~kometa(void);
private:
	int ID;
	int x;
	int y;
	bool live;
	int speed;
	int boundy;
	int boundx;
public:
	void startKomety(kometa kometa[], int size);
	void rysujKomete(kometa kometa[], int size);
	void updateKomety(kometa kometa[], int size);
	void kolizjaKomety(kometa kometa[], int kSize, statek ship);
	int zwroc_x(void);
	int zwroc_y(void);
	int zwroc_boundx(void);
	int zwroc_boundy(void);
	bool zwroc_live(void);
	void zmienBool(void);
};

Metody klasy:

 #include "kometa.h"
#include "statek.h"
#include<allegro5\allegro_primitives.h>


kometa::kometa(void)
{
	ID = ENEMY;
	live = false;
	speed = 5;
	boundx = 20;
	boundy = 20;
}


kometa::~kometa(void)
{
}

void kometa::startKomety(kometa kometa[], int size)
{
	for (int i = 0; i < size; i++)
	{
		if (!kometa[i].live)
		{
			if (rand() % 500 == 0)
			{
				kometa[i].live = true;
				kometa[i].x = WIDTH;
				kometa[i].y = 30 + rand() % (HEIGHT - 60);
				break;
			}
		}
	}
}

void kometa::rysujKomete(kometa kometa[], int size)
{
	for (int i = 0; i < size; i++)
	{
		if (kometa[i].live)
		{
			al_draw_filled_circle(kometa[i].x, kometa[i].y, 20, al_map_rgb(255, 0, 0));
		}
	}
}

void kometa::updateKomety(kometa kometa[], int size)
{
	for (int i = 0; i < size; i++)
	{
		if (kometa[i].live)
		{
			kometa[i].x -= kometa[i].speed;
		}
	}
}

void kometa::kolizjaKomety(kometa kometa[], int kSize, statek ship)
{
	for (int i = 0; i < kSize; i++)
	{
		if (kometa[i].live)
		{
			if (kometa[i].x - kometa[i].boundx < ship.zwroc_x() + ship.zwroc_boundx() &&
				kometa[i].x + kometa[i].boundx > ship.zwroc_x() - ship.zwroc_boundx() &&
				kometa[i].y - kometa[i].boundy < ship.zwroc_y() + ship.zwroc_boundy() &&
				kometa[i].y + kometa[i].boundy > ship.zwroc_y() - ship.zwroc_boundy())
			{
				ship.zmniejsz_zycie();
				kometa[i].live = false;
			}
			else if (kometa[i].x < 0)
			{
				kometa[i].live = false;
				ship.zmniejsz_zycie();
			}
		}
	}
}

int kometa::zwroc_x(void)
{
	return x;
}

int kometa::zwroc_y(void)
{
	return y;
}

int kometa::zwroc_boundx(void)
{
	return boundx;
}

int kometa::zwroc_boundy(void)
{
	return boundy;
}

bool kometa::zwroc_live(void)
{
	return live;
}

void kometa::zmienBool(void)
{
	if (live = true)
	{
		live = false;
	}
	else
	{
		live = true;
	}
}

klasa statku:

#pragma once
const int WIDTH = 1250;
const int HEIGHT = 650;
enum IDS{PLAYER, BULLET, ENEMY};

class statek
{
public:
	statek(void);
	~statek(void);
private:
	int ID;
	int x;
	int y;
	int lives;
	int speed;
	int boundx;
	int boundy;
	int score;
public:
	void moveShipUP(void);
	void moveShipDOWN(void);
	void moveShipLEFT(void);
	void moveShipRIGHT(void);
	void drawShip(void);
	int zwroc_x(void);
	int zwroc_y(void);
	int zwroc_boundx(void);
	int zwroc_boundy(void);
	int zwroc_lives(void);
	int zwroc_wynik(void);
	void zwiekszWynik(void);
	void zmniejsz_zycie(void);
};

 

Metody klasy:

#include "statek.h"
#include<allegro5\allegro_primitives.h>

statek::statek(void)
{
	x = 20;
	y = HEIGHT / 2;
	ID = PLAYER;
	lives = 3;
	speed = 7;
	boundx = 6;
	boundy = 7;
	score = 0;
}


statek::~statek(void)
{
}


void statek::moveShipUP(void)
{
	y -= speed;
	if (y < 0)
	{
		y = 0;
	}
}

void statek::moveShipDOWN(void)
{
	y += speed;
	if (y > 650)
	{
		y = 650;
	}
}

void statek::moveShipLEFT(void)
{
	x -= speed;
	if (x < 12)
	{
		x = 12;
	}
}

void statek::moveShipRIGHT(void)
{
	x += speed;
	if (x > 450)
	{
		x = 450;
	}
}

void statek::drawShip(void)
{
	al_draw_filled_rectangle(x, y - 9, x + 10, y - 7, al_map_rgb(255, 0, 0));
	al_draw_filled_rectangle(x, y + 9, x + 10, y + 7, al_map_rgb(255, 0, 0));
	al_draw_filled_triangle(x - 12, y - 17, x + 12, y, x - 12, y + 17, al_map_rgb(0, 255, 0));
	al_draw_filled_rectangle(x - 12, y - 2, x +15, y + 2, al_map_rgb(0, 0, 255));
}

int statek::zwroc_x(void)
{
	return x;
}

int statek::zwroc_y(void)
{
	return y;
}

int statek::zwroc_boundx(void)
{
	return boundx;
}

int statek::zwroc_boundy(void)
{
	return boundy;
}

int statek::zwroc_lives(void)
{
	return lives;
}

int statek::zwroc_wynik(void)
{
	return score;
}

void statek::zwiekszWynik()
{
	score++;
}

void statek::zmniejsz_zycie(void)
{
	lives--;
}
0

ten fragment nie powinien by cczasem w jakiejs petli?

                                bullets->updatePocisk(bullets, NUM_BULLETS);
                                comets->startKomety(comets, NUM_COMETS);
                                comets->updateKomety(comets, NUM_COMETS);
                                bullets->kolizjaPocisku(bullets, NUM_BULLETS, comets, NUM_COMETS, ship);
                                comets->kolizjaKomety(comets, NUM_COMETS, ship);

mam wrażenie, że coś tu jest przekombinowane

0

Być może, ale te funkcje działają dobrze, bo spełniają swoje zadanie, oprócz funkcji, które powinny zmieniać zmienne obiektu statek. Co takiego może być przekombinowane?

3

spróbuj przekazać statek przez referencje a nie przez wartość do tych funkcji

0

krwq, dzięki teraz działa prawidłowo. Wiem już dlaczego wcześniej nie działało, ale dziwne, że sam na to nie wpadłem :) Dobrze mi się wydaje, że przez referencję, to zmieniam od razu ten obiekt, a przez wartość, to go w ogóle nie ruszałem?

0

Zacząłem dodawać bitmapy do mojej gry, żeby lepiej wyglądała i już w pierwszym momencie mam pewnie problem z dodaniem grafiki do mojego statku, bo wszystko się kompiluje, ale jak już pokarze się okno gry, wtedy wyświetla błąd: debug error.
Oto kod wszystkiego:
main.cpp

 #include<allegro5\allegro.h>
#include<allegro5\allegro_ttf.h>
#include "kometa.h"
#include "statek.h"
#include "pocisk.h"
#include "eksplozja.h"

const int NUM_BULLETS = 5;
const int NUM_COMETS = 10;
const int NUM_EKSPLOSIONS = 5;
enum KEYS{UP, DOWN, LEFT, RIGHT, SPACE};
bool keys[5] = {false, false, false, false, false};

int main()
{
	//zmienne allegro
	ALLEGRO_DISPLAY *display = NULL;
	ALLEGRO_EVENT_QUEUE *event_queue = NULL;
	ALLEGRO_TIMER *timer = NULL;
	ALLEGRO_FONT *font18 = NULL;
	ALLEGRO_BITMAP *shipImage;

	//zmienne
	bool done = false;
	bool redraw = true;
	const int FPS = 60;
	bool isGameOver = false;

	if(!al_init()) //inicjalizacja allegro
	{
		return -1;
	}

	display = al_create_display(WIDTH, HEIGHT); //stworzenie objektu wyswiettlającego

	if(!display) //testowanie obiektu wyświetlającego
	{
		return -1;
	}

	al_init_primitives_addon();
	al_install_keyboard();
	al_init_font_addon();
	al_init_ttf_addon();

	event_queue = al_create_event_queue();
	timer = al_create_timer(1.0 / FPS);

	font18 = al_load_font("arial.ttf", 18, 0);

	shipImage = al_load_bitmap("statek.png");
	//al_convert_mask_to_alpha(shipImage, al_map_rgb(255, 0, 255));

	//zmienne obiektowe
	statek ship(shipImage);	
	pocisk bullets[NUM_BULLETS];
	kometa comets[NUM_COMETS];
	eksplozja eksplozje[NUM_EKSPLOSIONS];


	srand(time(NULL));
	al_register_event_source(event_queue, al_get_keyboard_event_source());
	al_register_event_source(event_queue, al_get_timer_event_source(timer));
	al_register_event_source(event_queue, al_get_display_event_source(display));
	
	al_start_timer(timer);

	int j = 0;//zmienna dla odpalania pocisku
	int zycia;
	while (!done)
	{
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);
		
		if (ev.type == ALLEGRO_EVENT_TIMER)
		{
			redraw = true;
			if (keys[UP])
			{
				ship.moveShipUP();
			}
			if (keys[DOWN])
			{
				ship.moveShipDOWN();
			}
			if (keys[LEFT])
			{
				ship.moveShipLEFT();
			}
			if (keys[RIGHT])
			{
				ship.moveShipRIGHT();
			}
			if (!isGameOver)
			{
				bullets->updatePocisk(bullets, NUM_BULLETS);
				comets->startKomety(comets, NUM_COMETS);
				//comets->updateKomety(comets, NUM_COMETS);
				bullets->kolizjaPocisku(bullets, NUM_BULLETS, comets, NUM_COMETS, ship);
				comets->kolizjaKomety(comets, NUM_COMETS, ship);
				zycia = ship.zwroc_lives();
				if (zycia <=0)
				{
					isGameOver = true;
				}
			}
		}
		else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{
			done = true;
		}
		else if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			switch (ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = true;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = true;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = true;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = true;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = true;
				bullets[j].odpalPocisk(bullets, NUM_BULLETS, ship);
				j++;
				if (j == 5)
				{
					j = 0;
				}
				break;
			}
		}
		else if (ev.type == ALLEGRO_EVENT_KEY_UP)
		{
			switch (ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = false;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = false;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = false;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = false;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = false;
				break;
			}
		}
		
		if (redraw && al_is_event_queue_empty(event_queue))
		{
			redraw = false;

			if (!isGameOver)
			{
				ship.drawShip();
				bullets->rysujPocisk(bullets, NUM_BULLETS);
				comets->rysujKomete(comets, NUM_COMETS);
				if (ship.zwroc_wynik() == 1)
				{
					al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Gracz posiada %i zycia. Zniszczyles %i objekt", ship.zwroc_lives(), ship.zwroc_wynik());
				}
				else if (ship.zwroc_wynik() > 1 && ship.zwroc_wynik() < 5)
				{
					al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Gracz posiada %i zycia. Zniszczyles %i objety", ship.zwroc_lives(), ship.zwroc_wynik());
				}
				else
				{
					al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Gracz posiada %i zycia. Zniszczyles %i objektow", ship.zwroc_lives(), ship.zwroc_wynik());
				}
			}
			else
			{
				al_draw_textf(font18, al_map_rgb(0, 255, 255), WIDTH / 2, HEIGHT / 2, ALLEGRO_ALIGN_CENTRE, "KONIEC GRY! WYNIK KONCZOWY: %i", ship.zwroc_wynik());
			}

			al_flip_display();
			al_clear_to_color(al_map_rgb(0, 0, 0));
		}
	}

	al_destroy_bitmap(shipImage); // znieszczenie obrazu statku
	al_destroy_event_queue(event_queue); // znieszczenie kolejki
	al_destroy_timer(timer); // znieszczenie timera
	al_destroy_display(display); //znieszczenie obiektu wyświetlającegoa
	
	return 0;
}

klasa statek.h

 #pragma once
#include<allegro5\allegro_primitives.h>
const int WIDTH = 1250;
const int HEIGHT = 650;
enum IDS{PLAYER, BULLET, ENEMY};

class statek
{
public:
	statek(ALLEGRO_BITMAP *simage);
	~statek(void);
private:
	int ID;
	int x;
	int y;
	int lives;
	int speed;
	int boundx;
	int boundy;
	int score;

	int max_frame;
	int cur_frame;
	int frame_count;
	int frame_delay;
	int frame_width;
	int frame_height;
	int animation_columns;
	int animation_direction;
	int animation_row;

	ALLEGRO_BITMAP *image;
public:
	void resetShipAnimation(statek &statek, int pozycja);
	void moveShipUP(void);
	void moveShipDOWN(void);
	void moveShipLEFT(void);
	void moveShipRIGHT(void);
	void drawShip(void);
	int zwroc_x(void);
	int zwroc_y(void);
	int zwroc_boundx(void);
	int zwroc_boundy(void);
	int zwroc_lives(void);
	int zwroc_wynik(void);
	void zwiekszWynik(void);
	void zmniejsz_zycie(void);
};

funkcje klasy statek.h, statek.cpp

 #include "statek.h"

statek::statek(ALLEGRO_BITMAP *simage)
{
	x = 20;
	y = HEIGHT / 2;
	ID = PLAYER;
	lives = 3;
	speed = 7;
	boundx = 6;
	boundy = 7;
	score = 0;

	max_frame = 3;
	cur_frame = 0;
	frame_count = 0;
	frame_delay = 50;
	frame_width = 46;
	frame_height = 41;
	animation_columns = 3;
	animation_direction = 1;
	animation_row = 1;

	image = simage;
}


statek::~statek(void)
{
}


void statek::resetShipAnimation(statek &statek, int pozycja)
{
}


void statek::moveShipUP(void)
{
	animation_row = 0;
	y -= speed;
	if (y < 0)
	{
		y = 0;
	}
}

void statek::moveShipDOWN(void)
{
	animation_row = 2;
	y += speed;
	if (y > 650)
	{
		y = 650;
	}
}

void statek::moveShipLEFT(void)
{
	cur_frame = 2;
	x -= speed;
	if (x < 12)
	{
		x = 12;
	}
}

void statek::moveShipRIGHT(void)
{
	cur_frame = 1;
	x += speed;
	if (x > 450)
	{
		x = 450;
	}
}

void statek::drawShip(void)
{
	int fx = (cur_frame % animation_columns) * frame_width;
	int fy = animation_row * frame_height;

	al_draw_bitmap_region(image, fx, fy, frame_width, frame_height, x - frame_width / 2, y - frame_height / 2, 0);

	/*al_draw_filled_rectangle(x, y - 9, x + 10, y - 7, al_map_rgb(255, 0, 0));
	al_draw_filled_rectangle(x, y + 9, x + 10, y + 7, al_map_rgb(255, 0, 0));
	al_draw_filled_triangle(x - 12, y - 17, x + 12, y, x - 12, y + 17, al_map_rgb(0, 255, 0));
	al_draw_filled_rectangle(x - 12, y - 2, x +15, y + 2, al_map_rgb(0, 0, 255));*/
}

int statek::zwroc_x(void)
{
	return x;
}

int statek::zwroc_y(void)
{
	return y;
}

int statek::zwroc_boundx(void)
{
	return boundx;
}

int statek::zwroc_boundy(void)
{
	return boundy;
}

int statek::zwroc_lives(void)
{
	return lives;
}

int statek::zwroc_wynik(void)
{
	return score;
}

void statek::zwiekszWynik()
{
	score++;
}

void statek::zmniejsz_zycie(void)
{
	lives--;
}

Kod w pozostałych plikach jest taki sam, jak powyżej. Proszę o nakierowanie, co mozę być nie tak.
Oto screen błędu:
user image

0

zapuść tak debuggera, żeby można było stwierdzić która linia wywołała błąd. Wskaż tą linię razem ze stosem wywołań, to dostaniesz szybko odpowiedź, bo to co teraz wysłałeś jest zbyt czasochłonne żeby komuś się chciało oglądać

0

Ten błąd pojawił się w momencie użycia funkcji:

if (!isGameOver)
                        {
                                ship.drawShip(); // w momencie użycia tej funkcji został wyrzucony ten błąd
                                bullets->rysujPocisk(bullets, NUM_BULLETS);
                                comets->rysujKomete(comets, NUM_COMETS);
                                if (ship.zwroc_wynik() == 1) 

Co może być złego w funkcji drawShip() ?

void statek::drawShip(void)
{
        int fx = (cur_frame % animation_columns) * frame_width;
        int fy = animation_row * frame_height;
 
        al_draw_bitmap_region(image, fx, fy, frame_width, frame_height, x - frame_width / 2, y - frame_height / 2, 0); <- tutaj wyrzuciło ten błąd
0

Znalazłem problem. Nie zainicjowałem w moim kodzie używania biblioteki do bitmap

zadeklarowanie takiej instrukcji rozwiązało problem:
al_init_image_addon();

0

możliwe, że image jest NULL-em.
możliwe, że (fx, fy) lub ta obliczona pozycja są gdzieś poza image'em.

proste do sprawdzenia:
#include <cassert>

przed linijką:
al_draw_bitmap_region(image, fx, fy, frame_width, frame_height, x - frame_width / 2, y - frame_height / 2, 0);
dodaj:
assert(image != NULL); // jeśli ten warunek nie będzie spełniony to program zawiesi się na tej linijsce (dostaniesz w konsoli numer linii na której się zawiesił)

upewnij się przede wszystkim, że ta bitmapka ma zaalokowaną pamięć

0

Z tamtym już jest w porządku, ale teraz z kometa mam podobny problem
Klasa kometa.h

 #pragma once
#include "statek.h"
class kometa
{
public:
	kometa();
	~kometa(void);
private:
	int ID;
	int x;
	int y;
	bool live;
	int speed;
	int boundy;
	int boundx;

	int max_frame;
	int cur_frame;
	int frame_count;
	int frame_delay;
	int frame_width;
	int frame_height;
	int animation_columns;
	int animation_direction;

	ALLEGRO_BITMAP *image;
public:
	void ustawObraz(ALLEGRO_BITMAP *kimage);
	void startKomety(kometa kometa[], int size);
	void rysujKomete(kometa kometa[], int size);
	void updateKomety(kometa kometa[], int size);
	void kolizjaKomety(kometa kometa[], int kSize, statek &ship);
	int zwroc_x(void);
	int zwroc_y(void);
	int zwroc_boundx(void);
	int zwroc_boundy(void);
	bool zwroc_live(void);
	void zmienBool(void);
};

metody klasy kometa, kometa.cpp

#include "kometa.h"

kometa::kometa()
{
	ID = ENEMY;
	live = false;
	speed = 5;
	boundx = 20;
	boundy = 20;

	max_frame = 143;
	cur_frame = 0;
	frame_count = 0;
	frame_delay = 2;
	frame_width = 96;
	frame_height = 96;
	animation_columns = 21;
	if (rand() % 2)
	{
		animation_direction = 1;
	}
	else
	{
		animation_direction = -1;
	}
}


kometa::~kometa(void)
{
}


void kometa::ustawObraz(ALLEGRO_BITMAP *kimage)
{
	image = kimage;
}


void kometa::startKomety(kometa kometa[], int size)
{
	for (int i = 0; i < size; i++)
	{
		if (!kometa[i].live)
		{
			if (rand() % 500 == 0)
			{
				kometa[i].live = true;
				kometa[i].x = WIDTH;
				kometa[i].y = 30 + rand() % (HEIGHT - 60);
				break;
			}
		}
	}
}

void kometa::rysujKomete(kometa kometa[], int size)
{
	ALLEGRO_BITMAP *kometaImage;
	kometaImage = al_load_bitmap("kometa.png");
	for (int i = 0; i < size; i++)
	{
		if (kometa[i].live)
		{
			kometa[i].ustawObraz(kometaImage);
			int fx = (kometa[i].cur_frame % kometa[i].animation_columns) * kometa[i].frame_width;
			int fy = (kometa[i].cur_frame / kometa[i].animation_columns) * kometa[i].frame_height;

			al_draw_bitmap_region(kometa[i].image, fx, fy, kometa[i].frame_width,
				kometa[i].frame_height, kometa[i].x - kometa[i].frame_width / 2, kometa[i].y - kometa[i].frame_height / 2, 0);

			al_draw_filled_rectangle(kometa[i].x - kometa[i].boundx, kometa[i].y - kometa[i].boundy, 
				kometa[i].x + kometa[i].boundx, kometa[i].y + kometa[i].boundy, al_map_rgba(255, 0, 255, 100));
		}
	}
	/*for (int i = 0; i < size; i++)
	{
		if (kometa[i].live)
		{
			al_draw_filled_circle(kometa[i].x, kometa[i].y, 20, al_map_rgb(255, 0, 0));
		}
	}*/
}

void kometa::updateKomety(kometa kometa[], int size)
{
	for (int i = 0; i < size; i++)
	{
		if (kometa[i].live)
		{
			if (++kometa[i].frame_count >= kometa[i].frame_delay)
			{
				kometa[i].cur_frame += kometa[i].animation_direction;
				if (kometa[i].cur_frame >= kometa[i].max_frame)
				{
					kometa[i].cur_frame = 0;
				}
				else if (kometa[i].cur_frame <=0)
				{
					kometa[i].cur_frame = kometa[i].max_frame - 1;
				}

				kometa[i].frame_count = 0;
			}

			kometa[i].x -= kometa[i].speed;
		}
	}
}

void kometa::kolizjaKomety(kometa kometa[], int kSize, statek &ship)
{
	for (int i = 0; i < kSize; i++)
	{
		if (kometa[i].live)
		{
			if (kometa[i].x - kometa[i].boundx < ship.zwroc_x() + ship.zwroc_boundx() &&
				kometa[i].x + kometa[i].boundx > ship.zwroc_x() - ship.zwroc_boundx() &&
				kometa[i].y - kometa[i].boundy < ship.zwroc_y() + ship.zwroc_boundy() &&
				kometa[i].y + kometa[i].boundy > ship.zwroc_y() - ship.zwroc_boundy())
			{
				ship.zmniejsz_zycie();
				kometa[i].live = false;
			}
			else if (kometa[i].x < 0)
			{
				kometa[i].live = false;
				ship.zmniejsz_zycie();
			}
		}
	}
}

int kometa::zwroc_x(void)
{
	return x;
}

int kometa::zwroc_y(void)
{
	return y;
}

int kometa::zwroc_boundx(void)
{
	return boundx;
}

int kometa::zwroc_boundy(void)
{
	return boundy;
}

bool kometa::zwroc_live(void)
{
	return live;
}

void kometa::zmienBool(void)
{
	if (live = true)
	{
		live = false;
	}
	else
	{
		live = true;
	}
} 

main.cpp

 #include<allegro5\allegro.h>
#include<allegro5\allegro_font.h>
#include<allegro5\allegro_ttf.h>
#include<allegro5\allegro_image.h>
#include "kometa.h"
#include "statek.h"
#include "pocisk.h"
#include "eksplozja.h"
 
const int NUM_BULLETS = 5;
const int NUM_COMETS = 10;
const int NUM_EKSPLOSIONS = 5;
enum KEYS{UP, DOWN, LEFT, RIGHT, SPACE};
bool keys[5] = {false, false, false, false, false};
 
int main()
{
	//zmienne allegro
	ALLEGRO_DISPLAY *display = NULL;
	ALLEGRO_EVENT_QUEUE *event_queue = NULL;
	ALLEGRO_TIMER *timer = NULL;
	ALLEGRO_FONT *font18 = NULL;
	ALLEGRO_BITMAP *shipImage;
	//ALLEGRO_BITMAP *kometaImage;
 
	//zmienne
	bool done = false;
	bool redraw = true;
	const int FPS = 60;
	bool isGameOver = false;
 
	if(!al_init()) //inicjalizacja allegro
	{
		return -1;
	}
 
	display = al_create_display(WIDTH, HEIGHT); //stworzenie objektu wyswiettlającego
 
	if(!display) //testowanie obiektu wyświetlającego
	{
		return -1;
	}
 
	al_init_primitives_addon();
	al_install_keyboard();
	al_init_font_addon();
	al_init_ttf_addon();
	al_init_image_addon();

	event_queue = al_create_event_queue();
	timer = al_create_timer(1.0 / FPS);
 
	font18 = al_load_font("arial.ttf", 18, 0);
 
	shipImage = al_load_bitmap("statek.png");
	al_convert_mask_to_alpha(shipImage, al_map_rgb(255, 0, 255));

	//kometaImage = al_load_bitmap("kometa.png");
 
	//zmienne obiektowe
	statek ship(shipImage);        
	pocisk bullets[NUM_BULLETS];
	kometa comets[NUM_COMETS];
	eksplozja eksplozje[NUM_EKSPLOSIONS];
 
 
	srand(time(NULL));
	al_register_event_source(event_queue, al_get_keyboard_event_source());
	al_register_event_source(event_queue, al_get_timer_event_source(timer));
	al_register_event_source(event_queue, al_get_display_event_source(display));
 
	al_start_timer(timer);
 
	int j = 0;//zmienna dla odpalania pocisku
	int zycia;
	while (!done)
	{
		ALLEGRO_EVENT ev;
		al_wait_for_event(event_queue, &ev);
 
		if (ev.type == ALLEGRO_EVENT_TIMER)
		{
			redraw = true;
			if (keys[UP])
			{
				ship.moveShipUP();
			}
			else if (keys[DOWN])
			{
				ship.moveShipDOWN();
			}
			else
			{
				ship.resetShipAnimation(ship, 1);
			}
			if (keys[LEFT])
			{
				ship.moveShipLEFT();
			}
			else if (keys[RIGHT])
			{
				ship.moveShipRIGHT();
			}
			else
			{
				ship.resetShipAnimation(ship, 2);
			}
			if (!isGameOver)
			{
				bullets->updatePocisk(bullets, NUM_BULLETS);
				comets->startKomety(comets, NUM_COMETS);
				//comets->updateKomety(comets, NUM_COMETS);
				bullets->kolizjaPocisku(bullets, NUM_BULLETS, comets, NUM_COMETS, ship);
				comets->kolizjaKomety(comets, NUM_COMETS, ship);
				zycia = ship.zwroc_lives();
				if (zycia <=0)
				{
					isGameOver = true;
				}
			}
		}
		else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
		{
			done = true;
		}
		else if (ev.type == ALLEGRO_EVENT_KEY_DOWN)
		{
			switch (ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = true;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = true;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = true;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = true;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = true;
				bullets[j].odpalPocisk(bullets, NUM_BULLETS, ship);
				j++;
				if (j == 5)
				{
					j = 0;
				}
				break;
			}
		}
		else if (ev.type == ALLEGRO_EVENT_KEY_UP)
		{
			switch (ev.keyboard.keycode)
			{
			case ALLEGRO_KEY_ESCAPE:
				done = true;
				break;
			case ALLEGRO_KEY_UP:
				keys[UP] = false;
				break;
			case ALLEGRO_KEY_DOWN:
				keys[DOWN] = false;
				break;
			case ALLEGRO_KEY_LEFT:
				keys[LEFT] = false;
				break;
			case ALLEGRO_KEY_RIGHT:
				keys[RIGHT] = false;
				break;
			case ALLEGRO_KEY_SPACE:
				keys[SPACE] = false;
				break;
			}
		}
		if (redraw)
		{
			redraw = false;
 
			if (!isGameOver)
			{
				ship.drawShip();
				bullets->rysujPocisk(bullets, NUM_BULLETS);
				comets->rysujKomete(comets, NUM_COMETS);
				if (ship.zwroc_wynik() == 1)
				{
					al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Gracz posiada %i zycia. Zniszczyles %i objekt", ship.zwroc_lives(), ship.zwroc_wynik());
				}
				else if (ship.zwroc_wynik() > 1 && ship.zwroc_wynik() < 5)
				{
					al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Gracz posiada %i zycia. Zniszczyles %i objety", ship.zwroc_lives(), ship.zwroc_wynik());
				}
				else
				{
					al_draw_textf(font18, al_map_rgb(255, 0, 255), 5, 5, 0, "Gracz posiada %i zycia. Zniszczyles %i objektow", ship.zwroc_lives(), ship.zwroc_wynik());
				}
			}
			else
			{
				al_draw_textf(font18, al_map_rgb(0, 255, 255), WIDTH / 2, HEIGHT / 2, ALLEGRO_ALIGN_CENTRE, "KONIEC GRY! WYNIK KONCZOWY: %i", ship.zwroc_wynik());
			}
 
			al_flip_display();
			al_clear_to_color(al_map_rgb(0, 0, 0));
		}
	}
 
	al_destroy_bitmap(shipImage); // znieszczenie obrazu statku
	al_destroy_event_queue(event_queue); // znieszczenie kolejki
	al_destroy_timer(timer); // znieszczenie timera
	al_destroy_display(display); //znieszczenie obiektu wyświetlającegoa
 
	return 0;
}

Wyrzuca ten sam bład. W konsoli pojawia się takie coś: Assertion failed: bitmap, file allegro-5.0.x\src\bitmap.c, line 248
Gra się uruchomi, tylko w momencie, gdy powinna pojawić się kometa, to wyrzuca ten sam bład co na poprzedniej stronie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1