⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 classes.h

📁 打飞机的过关游戏(linux)
💻 H
字号:
extern void showErrorAndExit(int errorId, char *name);

class Collision {

	private:
	
		Collision(){}

	public:

	static signed char collision(float x0, float y0, int w0, int h0, float x2, float y2, int w1, int h1)
	{
		float x1 = x0 + w0;
		float y1 = y0 + h0;

		float x3 = x2 + w1;
		float y3 = y2 + h1;

		return !(x1<x2 || x3<x0 || y1<y2 || y3<y0);
	}

	static signed char collision(object *object1, object *object2)
	{
		float x0 = object1->x;
		float y0 = object1->y;
		float w0 = object1->image[0]->w;
		float h0 = object1->image[0]->h;

		float x2 = object2->x;
		float y2 = object2->y;
		float w1 = object2->image[0]->w;
		float h1 = object2->image[0]->h;

		float x1 = x0 + w0;
		float y1 = y0 + h0;

		float x3 = x2 + w1;
		float y3 = y2 + h1;

		return !(x1<x2 || x3<x0 || y1<y2 || y3<y0);
	}

	static signed char collision(collectables *object1, object *object2)
	{
		float x0 = object1->x;
		float y0 = object1->y;
		float w0 = object1->image->w;
		float h0 = object1->image->h;

		float x2 = object2->x;
		float y2 = object2->y;
		float w1 = object2->image[0]->w;
		float h1 = object2->image[0]->h;

		float x1 = x0 + w0;
		float y1 = y0 + h0;

		float x3 = x2 + w1;
		float y3 = y2 + h1;

		return !(x1<x2 || x3<x0 || y1<y2 || y3<y0);
	}

};

class Math {

	private:
	
		Math(){}

	public:

	static void limitChar(signed char *in, int low, int high)
	{
		if (*in < low)
			*in = low;
		if (*in > high)
			*in = high;
	}

	static void limitChar(unsigned char *in, int low, int high)
	{
		if (*in < low)
			*in = low;
		if (*in > high)
			*in = high;
	}

	static void limitInt(int *in, int low, int high)
	{
		if (*in < low)
			*in = low;
		if (*in > high)
			*in = high;
	}

	static void limitFloat(float *in, float low, float high)
	{
		if (*in < low)
			*in = low;
		if (*in > high)
			*in = high;
	}

	static void wrapChar(signed char *in, signed char low, signed char high)
	{
		if (*in < low)
			*in = high;
		if (*in > high)
			*in = low;
	}

	static void wrapInt(int *in, int low, int high)
	{
		if (*in < low)
			*in = high;
		if (*in > high)
			*in = low;
	}

	static void wrapFloat(float *in, float low, float high)
	{
		if (*in < low)
			*in = high;
		if (*in > high)
			*in = low;
	}

	static int rrand(int min, int max)
	{
		int r = min;

		max++;

		if ((max - min) == 0)
			return min;

		r += rand() % (max - min);

		return r;
	}

};


class Graphics {

	public:

		Uint32 red;
		Uint32 darkRed;
		Uint32 yellow;
		Uint32 darkYellow;
		Uint32 green;
		Uint32 darkGreen;
		Uint32 blue;
		Uint32 darkBlue;
		Uint32 darkerBlue;
		Uint32 black;
		Uint32 white;
		Uint32 lightGrey;
		Uint32 darkGrey;
		SDL_Surface *screen, *background;
		SDL_Surface *shape[MAX_SHAPES];
		SDL_Surface *shipShape[MAX_SHIPSHAPES];
		SDL_Surface *fontShape[MAX_FONTSHAPES];
		SDL_Surface *shopSurface[MAX_SHOPSHAPES];
		bRect *bufferHead;
		bRect *bufferTail;
		textObject textShape[MAX_TEXTSHAPES];
		SDL_Rect blitRect;
		SDL_Surface *messageBox;

	Graphics()
	{
		bufferHead = new bRect;
		bufferHead->next = NULL;
		bufferTail = bufferHead;

		for (int i = 0 ; i < MAX_SHAPES ; i++)
			shape[i] = NULL;

		for (int i = 0 ; i < MAX_SHIPSHAPES ; i++)
			shipShape[i] = NULL;

		for (int i = 0 ; i < MAX_TEXTSHAPES ; i++)
			textShape[i].image = NULL;

		for (int i = 0 ; i < MAX_SHOPSHAPES ; i++)
			shopSurface[i] = NULL;

		background = NULL;
		messageBox = NULL;
	}

	SDL_Surface *setTransparent(SDL_Surface *sprite)
	{
		SDL_SetColorKey(sprite, (SDL_SRCCOLORKEY|SDL_RLEACCEL), SDL_MapRGB(sprite->format, 0, 0, 0));
		return sprite;
	}

	void addBuffer(int x, int y, int w, int h)
	{
		bRect *rect = new bRect;

		rect->next = NULL;
		rect->x = x;
		rect->y = y;
		rect->w = w;
		rect->h = h;

		bufferTail->next = rect;
		bufferTail = rect;
	}

	void blit(SDL_Surface *image, int x, int y, SDL_Surface *dest)
	{
		// Set up a rectangle to draw to
		blitRect.x = x;
		blitRect.y = y;
		blitRect.w = image->w;
		blitRect.h = image->h;

		/* Blit onto the screen surface */
		if(SDL_BlitSurface(image, NULL, dest, &blitRect) < 0)
		{
			printf("BlitSurface error: %s\n", SDL_GetError());
			showErrorAndExit(2, "");
		}

		addBuffer(blitRect.x, blitRect.y, blitRect.w, blitRect.h);
	}

	void blit(SDL_Surface *image, int x, int y)
	{
		blit(image, x, y, screen);
	}

	void blitText(int i)
	{
		blit(textShape[i].image, (int)textShape[i].x, (int)textShape[i].y, screen);
	}

	void flushBuffer()
	{
		bRect *prevRect = bufferHead;
		bRect *rect = bufferHead;
		bufferTail = bufferHead;

		while (rect->next != NULL)
		{
			rect = rect->next;

			prevRect->next = rect->next;
			delete rect;
			rect = prevRect;
		}

		bufferHead->next = NULL;
	}

	void unBuffer()
	{
		bRect *prevRect = bufferHead;
		bRect *rect = bufferHead;
		bufferTail = bufferHead;

		while (rect->next != NULL)
		{
			rect = rect->next;

			blitRect.x = rect->x;
			blitRect.y = rect->y;
			blitRect.w = rect->w;
			blitRect.h = rect->h;

			if (SDL_BlitSurface(background, &blitRect, screen, &blitRect) < 0)
			{
				printf("BlitSurface error: %s\n", SDL_GetError());
				showErrorAndExit(2, "");
			}

			prevRect->next = rect->next;
			delete rect;
			rect = prevRect;
		}

		bufferHead->next = NULL;
	}

	/*
	In 16 bit mode this is slow. VERY slow. Don't write directly to a surface
	that constantly needs updating (eg - the main game screen)
	*/
	int renderString(char *in, int x, int y, int fontColor, signed char wrap, SDL_Surface *dest)
	{
		SDL_Rect area;
		area.x = x;
		area.y = y;
		area.w = 8;
		area.h = 14;

		SDL_Rect letter;
		letter.y = 0;
		letter.w = 8;
		letter.h = 14;

		while (*in != '\0')
		{
			if (*in != 32)
			{
				letter.x = (*in - 33);
				letter.x *= 8;
				letter.x--; // Temp fix

				/* Blit onto the screen surface */
				 if(SDL_BlitSurface(fontShape[fontColor], &letter, dest, &area) < 0)
				 {
				 	printf("BlitSurface error: %s\n", SDL_GetError());
				 	showErrorAndExit(2, "");
				 }
			}

			area.x += 9;

			if (wrap)
			{
				if ((area.x > (dest->w - 70)) && (*in == 32))
				{
					area.y += 16;
					area.x = x;
				}
			}

			*in++;
		}

		return area.y;
	}

	int drawString(char *in, int x, int y, int fontColor, signed char wrap, SDL_Surface *dest)
	{
		renderString(in, x, y - 1, FONT_OUTLINE, wrap, dest);
		renderString(in, x, y + 1, FONT_OUTLINE, wrap, dest);
		renderString(in, x, y + 2, FONT_OUTLINE, wrap, dest);
		renderString(in, x - 1, y, FONT_OUTLINE, wrap, dest);
		renderString(in, x - 2, y, FONT_OUTLINE, wrap, dest);
		renderString(in, x + 1, y, FONT_OUTLINE, wrap, dest);
		return renderString(in, x, y, fontColor, wrap, dest);
	}

	int drawString(char *in, int x, int y, int fontColor, SDL_Surface *dest)
	{
		if (x == -1)
			x = (dest->w - (strlen(in) * 9)) / 2;
		return drawString(in, x, y, fontColor, 0, dest);
	}

	int drawString(char *in, int x, int y, int fontColor)
	{
		if (x == -1)
			x = (800 - (strlen(in) * 9)) / 2;
		return drawString(in, x, y, fontColor, 0, screen);
	}

	/*
	Finds the location of the requested color within the palette and returns
	it's number. This colors are used for drawing rectangles, circle, etc in
	the correct colors.
	*/
	void setColorIndexes()
	{
		red = SDL_MapRGB(screen->format, 0xff, 0x00, 0x00);
		darkRed = SDL_MapRGB(screen->format, 0x66, 0x00, 0x00);

		yellow = SDL_MapRGB(screen->format, 0xff, 0xff, 0x00);
		darkYellow = SDL_MapRGB(screen->format, 0x66, 0x66, 0x00);

		green = SDL_MapRGB(screen->format, 0x00, 0xff, 0x00);
		darkGreen = SDL_MapRGB(screen->format, 0x00, 0x66, 0x00);

		blue = SDL_MapRGB(screen->format, 0x00, 0x00, 0xff);
		darkBlue = SDL_MapRGB(screen->format, 0x00, 0x00, 0x99);
		darkerBlue = SDL_MapRGB(screen->format, 0x00, 0x00, 0x44);

		black = SDL_MapRGB(screen->format, 0x00, 0x00, 0x00);
		white = SDL_MapRGB(screen->format, 0xff, 0xff, 0xff);
		lightGrey = SDL_MapRGB(screen->format, 0xcc, 0xcc, 0xcc);
		darkGrey = SDL_MapRGB(screen->format, 0x99, 0x99, 0x99);
	}

	/*
	Draws the background surface that has been loaded
	*/
	void drawBackGround()
	{
		blit(background, 0, 0, screen);
	}

	void clearScreen(Uint32 color)
	{
		SDL_FillRect(screen, NULL, color);
	}

	void updateScreen()
	{
		SDL_Flip(screen);
		// Give the audio (and possibly the X server) time to work...
		SDL_Delay(1);
	}

	/*
	 * Set the pixel at (x, y) to the given value
	 * NOTE: The surface must be locked before calling this!
	 */
	void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
	{
		 int bpp = surface->format->BytesPerPixel;
		 /* Here p is the address to the pixel we want to set */
		 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

		 switch(bpp) {
		 case 1:
			  *p = pixel;
			  break;

		 case 2:
			  *(Uint16 *)p = pixel;
			  break;

		 case 3:
			  if(SDL_BYTEORDER == SDL_BIG_ENDIAN) {
					p[0] = (pixel >> 16) & 0xff;
					p[1] = (pixel >> 8) & 0xff;
					p[2] = pixel & 0xff;
			  } else {
					p[0] = pixel & 0xff;
					p[1] = (pixel >> 8) & 0xff;
					p[2] = (pixel >> 16) & 0xff;
			  }
			  break;

		 case 4:
			  *(Uint32 *)p = pixel;
			  break;
		 }
	}

	void drawLine(SDL_Surface *dest, int x1, int y1, int x2, int y2, int col)
	{
		int counter = 0;

		if ( SDL_MUSTLOCK(dest) ) {
			if ( SDL_LockSurface(dest) < 0 ) {
				printf("Can't lock screen: %s\n", SDL_GetError());
				showErrorAndExit(2, "");
			}
		}

		while(1)
		{
			putpixel(dest, x1, y1, col);

			if (x1 > x2) x1--;
			if (x1 < x2) x1++;
			if (y1 > y2) y1--;
			if (y1 < y2) y1++;

			if ((x1 == x2) && (y1 == y2))
				{break;}
			if (counter == 1000)
				{printf("Loop Error!\n"); break;}
			counter++;
		}

		if ( SDL_MUSTLOCK(dest) ) {
			SDL_UnlockSurface(dest);
		}
	}

	void drawLine(int x1, int y1, int x2, int y2, int col)
	{
		drawLine(screen, x1, y1, x2, y2, col);
	}

	/*
	A quick(?) circle draw function. This code was posted to the SDL
	mailing list... I didn't write it myself.
	*/
	void circle(int xc, int yc, int R, SDL_Surface *PIX, int col)
	{
		int x = 0, xx = 0;
		int y = R, yy = R+R;
		int p = 1-R;

		putpixel(PIX, xc, yc - y, col);
		putpixel(PIX, xc, yc + y, col);
		putpixel(PIX, xc - y, yc, col);
		putpixel(PIX, xc + y, yc, col);

		while(x < y)
		{
			xx += 2;
			++x;
			if (p >= 0)
			{
				yy -= 2;
				--y;
				p -= yy;
			}
			p += xx + 1;

			putpixel(PIX, xc - x, yc - y, col);
			putpixel(PIX, xc + x, yc - y, col);
			putpixel(PIX, xc - x, yc + y, col);
			putpixel(PIX, xc + x, yc + y, col);
			putpixel(PIX, xc - y, yc - x, col);
			putpixel(PIX, xc + y, yc - x, col);
			putpixel(PIX, xc - y, yc + x, col);
			putpixel(PIX, xc + y, yc + x, col);
		}

		if ((x = y))
		{
			putpixel(PIX, xc - x, yc - y, col);
			putpixel(PIX, xc + x, yc - y, col);
			putpixel(PIX, xc - x, yc + y, col);
			putpixel(PIX, xc + x, yc + y, col);
		}
	}

	void blevelRect(SDL_Surface *dest, int x, int y, int w, int h, Uint8 red, Uint8 green, Uint8 blue)
	{
		SDL_Rect r = {x, y, w, h};
		SDL_FillRect(dest, &r, SDL_MapRGB(screen->format, red, green, blue));

		drawLine(dest, x, y, x + w, y, SDL_MapRGB(screen->format, 255, 255, 255));
		drawLine(dest, x, y, x, y + h, SDL_MapRGB(screen->format, 255, 255, 255));
		drawLine(dest, x, y + h, x + w, y + h, SDL_MapRGB(screen->format, 128, 128, 128));
		drawLine(dest, x + w, y + 1, x + w, y + h, SDL_MapRGB(screen->format, 128, 128, 128));
	}

	void blevelRect(int x, int y, int w, int h, Uint8 red, Uint8 green, Uint8 blue)
	{
		blevelRect(screen, x, y, w, h, red, green, blue);
	}

	SDL_Surface *createSurface(int width, int height)
	{
		SDL_Surface *surface, *newImage;
		Uint32 rmask, gmask, bmask, amask;

		/* SDL interprets each pixel as a 32-bit number, so our masks must depend
		on the endianness (byte order) of the machine */
		#if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
			rmask = 0xff000000;
			gmask = 0x00ff0000;
			bmask = 0x0000ff00;
			amask = 0x000000ff;
		#else
			rmask = 0x000000ff;
			gmask = 0x0000ff00;
			bmask = 0x00ff0000;
			amask = 0xff000000;
		#endif

		surface = SDL_CreateRGBSurface(SDL_SWSURFACE, width, height, 32, rmask, gmask, bmask, amask);

		if (surface == NULL) {
			printf("CreateRGBSurface failed: %s\n", SDL_GetError());
			showErrorAndExit(2, "");
		}

		newImage = SDL_DisplayFormat(surface);

		SDL_FreeSurface(surface);

		return newImage;
	}

	SDL_Surface *textSurface(char *inString, int color)
	{
		SDL_Surface *surface = createSurface(strlen(inString) * 10, 16);

		drawString(inString, 1, 1, color, surface);

		return setTransparent(surface);
	}

	void textSurface(int index, char *inString, int x, int y, int fontColor)
	{
		strcpy(textShape[index].text, inString);
		textShape[index].x = x;
		textShape[index].y = y;
		textShape[index].fontColor = fontColor;
		if (textShape[index].image != NULL)
		{
			SDL_FreeSurface(textShape[index].image);
		}
		textShape[index].image = textSurface(inString, fontColor);
		if (x == -1)
			textShape[index].x = (800 - textShape[index].image->w) / 2;
	}

	SDL_Surface *alphaRect(int width, int height, Uint8 red, Uint8 green, Uint8 blue)
	{
		SDL_Surface *surface = createSurface(width, height);

		SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, red, green, blue));

		SDL_SetAlpha(surface, SDL_SRCALPHA|SDL_RLEACCEL, 128);

		return surface;
	}

	void createMessageBox(SDL_Surface *face, char *message, signed char transparent)
	{
		if (messageBox != NULL)
		{
			SDL_FreeSurface(messageBox);
			messageBox = NULL;
		}

		if (transparent)
			messageBox = alphaRect(550, 60, 0x00, 0x00, 0x00);
		else
			messageBox = createSurface(550, 60);

		signed char x = 60;

		if (face != NULL)
		{
			blevelRect(messageBox, 0, 0, messageBox->w - 1, messageBox->h - 1, 0x00, 0x00, 0xaa);
			blit(face, 5, 5, messageBox);
		}
		else
		{
			blevelRect(messageBox, 0, 0, messageBox->w - 1, messageBox->h - 1, 0x00, 0x00, 0x00);
			x = 10;
		}

		drawString(message, x, 5, FONT_WHITE, 1, messageBox);
	}

	void freeGraphics()
	{
		for (int i = 0 ; i < MAX_SHAPES ; i++)
		{
			if (shape[i] != NULL)
			{
				SDL_FreeSurface(shape[i]);
				shape[i] = NULL;
			}
		}

		for (int i = 0 ; i < MAX_SHIPSHAPES ; i++)
		{
			if (shipShape[i] != NULL)
			{
				SDL_FreeSurface(shipShape[i]);
				shipShape[i] = NULL;
			}
		}

		for (int i = 0 ; i < MAX_TEXTSHAPES ; i++)
		{
			if (textShape[i].image != NULL)
			{
				SDL_FreeSurface(textShape[i].image);
				textShape[i].image = NULL;
			}
		}

		for (int i = 0 ; i < MAX_SHOPSHAPES ; i++)
		{
			if (shopSurface[i] != NULL)
			{
				SDL_FreeSurface(shopSurface[i]);
				shopSurface[i] = NULL;
			}
		}

		if (messageBox != NULL)
		{
			SDL_FreeSurface(messageBox);
			messageBox = NULL;
		}
	}
};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -