Meteor shower C language implementation version

Meteor shower C language implementation version

meteor shower

Listen to my nonsense first. It's useless and useful

I think it was because the code was fun, and then I embarked on the road of learning programming. It's easy to get started with C language, but it's difficult to go deep. When you don't have a small project to play when learning C language, you will feel that learning is very boring. Here, we use C language to develop a meteor shower, which is simple to implement. It's mainly used to arouse your enthusiasm for learning C language. The process is easy to play. Especially if you can write it, you will have a sense of achievement. At the beginning, I copied all the code from my teacher, and then understood it bit by bit. At that time, the basis of C language was almost zero, so I just knew the loop and selection structure, and then I didn't understand any pointers. At that time, I didn't know the location of the sub function, and then it was misplaced. As a result, a pile of bugs kept me awake for several days. Now I know that the sub function should be declared before use. Of course, you can also put all the sub functions in front of the main function. That's it. Let's get to the point...

development environment

Visual Studio 2019 VS series is OK. Other environments may need to be configured by themselves

preparation

1, Prepare two pictures. You can draw them yourself. My paintings are ugly, but don't care about these details. Just use them.


The picture was very beautiful when it was small. It's true when it's enlarged... I'm speechless. These two pictures should be placed under the directory where the source file is located.

2, To download a plug-in, easyX, this is a graphics library. Our drawing operation uses this. Then this thing only supports c + +. Although we are developing in c language, the suffix of the source file is. cpp, not. c. Enter the official website https://easyx.cn/ , and then download an appropriate version. Download it quickly and install it directly.

After downloading, this is the icon

Double click Install directly

Locate Visual C++2019 and click Install.

If this happens, the installation is successful.

Desired effect

There are meteors and stars moving to simulate meteor shower.

Header file required

#include<stdio.h> 	// C language standard header file
#include<easyx.h> 	// Header file of graphics library
#include<time.h> 	// Time header file

Pretreatment part

#define LENGTH 800 		// Window length
#define WIDTH 600 		// Window width
#define MAXSTAR 1314 	// Maximum number of stars
#define MAXMETEOR 520 	// Maximum number of meteors

Structure of stars

typedef struct Star
{
	int x;
	int y;
	COLORREF color;
	int xSpeed;
	int ySpeed;
}Star;	//Star is the alias of struct Star, which has the same effect when used

Here is an alias for writing code. Of course, it can also be written in the following way

struct Star
{
	int x;				//x coordinate of the star
	int y;				//y coordinates of stars
	COLORREF color;		//The color of stars
	int xSpeed;			//The velocity of the star in the x direction
	int ySpeed;			//The velocity of the star in the y direction
};

COLORREF is a class. Its essence is int. it can also be replaced by int, but this macro is used for readability.

Create an array of stars

Star star[MAXSTAR];		//How to write alias
struct Star star[MAXSTAR];	
//Can't afford to write alias 	 struct Star cannot be separated. They are a whole

MAXSTAR inside is a macro, which has pre-defined the "preprocessing part" above.

Meteor structure

typedef struct Meteor
{
	int x;		//x coordinate of meteor
	int y;		//y coordinate of meteor
	int style;	//The style of meteor is to choose which picture
	int speed;	//Meteor velocity
}Meteor;

It can also be written without this alias

struct Meteor
{
	int x;
	int y;
	int style;
	int speed;
};

Create an array of meteors

Meteor meteor[MAXMETEOR];	//How to write alias
struct Meteor meteor[MAXMETEOR];	//Can't afford to write alias

MAXMETEOR is also a macro, which has been predefined.

Define picture variables for meteors

IMAGE img1,img2;	//Defines the variables of two pictures,

IMAGE is a class. The concept of class is a concept in C + +. Here, you only need to know that IMAGE is used to create picture variables. Variables in C language are declared first and then used.

In other words, if we want to use pictures, we should first define picture variables before using them.

Implementation and detailed explanation of each sub function

Functions in C language:

Function return value type function name(parameter list)
{
    Function body
}

Generally speaking, when we need the function implemented by the function to return a result, we use the corresponding return value. If we just want to see the effect, we don't need the return value. At this time, we can write void. In our current code, we mainly want to see the picture of meteor shower. What we need is the effect. All we use is void as the return value of the function.

Initialize stars

void initStar(int i)
{
	star[i].x = rand() % LENGTH - LENGTH;	//Initialize the position of the stars
	star[i].y = rand() % WIDTH - WIDTH;
	star[i].color = RGB(rand() % 255, rand() % 255, rand() % 255);	//Initialize Star color
	star[i].xSpeed = rand() % 10;			//Initializes the speed of the star in the x direction
	star[i].ySpeed = rand() % 8;			//Initializes the velocity of the star in the y direction
}
  • rand function means random. The operator% represents modular operation, which is the remainder of the result obtained by dividing one number by another.
  • RGB is a macro. In fact, it is the abbreviation of Red Green Blue, three primary colors.

Draw stars

void drawStar()
{
    //Loop through the points of each star
	for (int i = 0; i < MAXSTAR; i++)
	{
        //Use the method of drawing pixels to draw stars
		putpixel(star[i].x, star[i].y, star[i].color);
		star[i].x += star[i].xSpeed;	//After painting, change the position of the stars and make them move
		star[i].y += star[i].ySpeed;
        //If the star exceeds the window we set, reinitialize the star
		if (star[i].x > LENGTH || star[i].y > WIDTH)
		{
			initStar(i);
			putpixel(star[i].x, star[i].y, star[i].color);
		}
	}
}

Initialize meteor

void initMeteor(int i)
{
	meteor[i].x = rand() % LENGTH - LENGTH;		//Initialize the location of the meteor
	meteor[i].y = rand() % WIDTH - WIDTH-100;	
	meteor[i].style = rand() % 2;				//Initialize meteor style
	meteor[i].speed = rand() % 20 + 2;			//Initialize the speed of meteor, which cannot be zero
}
  • When initializing a meteor, it's best to let the meteor initialize from the place invisible in the window. In this way, it's more romantic to let the meteor enter slowly. At first, it's not good to display the meteor directly on the window.
  • The style of meteor is to make the meteor appearing on the window be any one of the two pictures
  • The used here are random, which is closer to nature
  • The speed cannot be zero because meteors are moving

Draw meteors

The operation of painting meteors uses mapping technology, that is, paste the pictures.

void drawMeteor(int i)
{
    //Using the switch statement, draw different pictures according to the different styles of meteors
	switch (meteor[i].style)
	{
	case 0:
		putimage(meteor[i].x, meteor[i].y, &img1, SRCPAINT);
		break;
	case 1:
		putimage(meteor[i].x, meteor[i].y, &img2, SRCPAINT);
		break;
	}
}
  • &Img1 means to take the address of img1, because the parameter required by this function is an address.
  • SRCPAINT is a macro that can make pictures more harmonious with each other.

Moving meteor

void moveMeteor(int i)
{
	meteor[i].x += meteor[i].speed;		//The x coordinate of the meteor accumulates the speed of the meteor to make the meteor move
	meteor[i].y += meteor[i].speed;		//The y coordinate of the meteor accumulates the velocity of the meteor
    //If the meteor moves outside the window, reinitialize the meteor
	if (meteor[i].x >= LENGTH || meteor[i].y >= WIDTH)
	{
		initMeteor(i);
	}
}

Main function test

int main()
{
	srand((unsigned int)time(NULL));		//Random seed sowing, if not sowing, the random number is a pseudo-random
	loadimage(&img1, L"1.jpg", 10, 10);		//Load picture
	loadimage(&img2, L"2.jpg", 10, 10);		
	initgraph(LENGTH, WIDTH);				//create a window
	for (int i=0; i < MAXSTAR; i++)			//Initialize stars
	{
		initStar(i);
	}
	for (int i = 0; i < MAXMETEOR; i++)		//Initialize meteor
	{
		initMeteor(i);
	}
	BeginBatchDraw();						//Double buffer
	while (1)								//Dead cycle
	{
		cleardevice();						//Wipe map
		drawStar();							//Draw stars
		for (int i = 0; i < MAXMETEOR; i++)	//Single cycle meteor
		{
			drawMeteor(i);					//Draw meteors
			moveMeteor(i);					//Moving meteor
		}
		Sleep(100);							//Dormancy. For paintings that do not dormant, the program runs too fast and the effect is not romantic enough
		FlushBatchDraw();					//Supplementary drawing
	}
	EndBatchDraw();							//End double buffering
	closegraph();							//Close the graphics window
	return 0;
}

The main logic is

1, Load picture

2, Then create a window

3, Then initialize the stars and meteors

4, Enter the dead cycle, draw, wipe and then draw

5, Close this window when you close the program

Overall source code

#include<stdio.h>
#include<easyx.h>
#include<time.h>
#define LENGTH 800
#define WIDTH 600
#define MAXSTAR 1314
#define MAXMETEOR 520

IMAGE img1,img2;

typedef struct Star
{
	int x;
	int y;
	COLORREF color;
	int xSpeed;
	int ySpeed;
}Star;

Star star[MAXSTAR];

typedef struct Meteor
{
	int x;
	int y;
	int style;
	int speed;
}Meteor;

Meteor meteor[MAXMETEOR];

void initStar(int i)
{
	star[i].x = rand() % LENGTH - LENGTH;
	star[i].y = rand() % WIDTH - WIDTH;
	star[i].color = RGB(rand() % 255, rand() % 255, rand() % 255);
	star[i].xSpeed = rand() % 10;
	star[i].ySpeed = rand() % 8;
}

void drawStar()
{
	for (int i = 0; i < MAXSTAR; i++)
	{
		putpixel(star[i].x, star[i].y, star[i].color);
		star[i].x += star[i].xSpeed;
		star[i].y += star[i].ySpeed;
		if (star[i].x > LENGTH || star[i].y > WIDTH)
		{
			initStar(i);
			putpixel(star[i].x, star[i].y, star[i].color);
		}
	}
}

void initMeteor(int i)
{
	meteor[i].x = rand() % LENGTH - LENGTH;
	meteor[i].y = rand() % WIDTH - WIDTH-100;
	meteor[i].style = rand() % 2;
	meteor[i].speed = rand() % 20 + 2;
}

void drawMeteor(int i)
{
	switch (meteor[i].style)
	{
	case 0:
		putimage(meteor[i].x, meteor[i].y, &img1, SRCPAINT);
		break;
	case 1:
		putimage(meteor[i].x, meteor[i].y, &img2, SRCPAINT);
		break;
	}
}

void moveMeteor(int i)
{
	meteor[i].x += meteor[i].speed;
	meteor[i].y += meteor[i].speed;
	if (meteor[i].x >= LENGTH || meteor[i].y >= WIDTH)
	{
		initMeteor(i);
	}
}

int main()
{
	srand((unsigned int)time(NULL));
	loadimage(&img1, L"1.jpg", 10, 10);
	loadimage(&img2, L"2.jpg", 10, 10);
	initgraph(LENGTH, WIDTH);
	for (int i=0; i < MAXSTAR; i++)
	{
		initStar(i);
	}
	for (int i = 0; i < MAXMETEOR; i++)
	{
		initMeteor(i);
	}
	BeginBatchDraw();
	while (1)
	{
		cleardevice();
		drawStar();
		for (int i = 0; i < MAXMETEOR; i++)
		{
			drawMeteor(i);
			moveMeteor(i);
		}
		Sleep(100);
		FlushBatchDraw();
	}
	EndBatchDraw();
	closegraph();
	return 0;
}

Tags: Python C R Language Visual Studio

Posted on Sat, 11 Sep 2021 23:42:29 -0400 by alanzhao