[Hardcore] Dreaming back to Xiaobawang

[Hardcore] Dreaming back to Xiaobawang

Growing up is a process of constant loss.

The author is a post-90s generation.

When I was young, everyone's home conditions were poor, and entertainment was very poor. Unlike today s children who can play with mobile phones, tablets and computers, at that time, a stack of Little Raccoon Water Margin cards could play for a whole day. If there is a rare card, such as Song Jiang, Lu Junyi, Hu Yanzhuo, that ass Later, I will definitely follow a long list of fans.

And to say that there is something more enviable than this in this world, it is definitely that there is a small bully learning machine at home.Although they are coaxing parents to buy it under the banner of learning Wubi, no one really buys this for learning, right? Dog head.

A learning machine, a cassette, a handle, and a cassette ("Contra", "Sharo Slow Snake", "Tank Battle", "Teenage Mutant Ninja Turtles", "Double Dragon", "Super Mario" Wait, etc.), how to quickly cool down that hot black power adapter constitutes countless happy childhood memories. On the other hand, now, the game screen is more gorgeous, the mechanism is more complicated, it is difficult to experience the pure happiness brought by those simple pixel games when playing.

Growing up is really a process of constant loss.

It seems to be a bit far, back to the topic. Then, I will take everyone to build a You Xi (Xi) machine, play games on it, and reminisce about the happy time when I was a child, Didi.


If a worker wants to do well, he must first sharpen his tools. -"The Analects of Confucius Wei Linggong"

Single chip microcomputer 1.

Here, it looks like this.

What is a microcontroller?

Simply put, a single-chip computer is a computer, but a lot of peripherals are missing.

How to choose a microcontroller?

For novices, I recommend an Arduino development board that is easy to use and has an active community, although it is nicknamed a toy by industry insiders. The model I bought is UNO R3, which is sold by both cats and dogs. There are more than 100 Italian version and dozens of Chinese version.

What is a development board?

The development board is suitable for learning and experimentation, and provides more pins: convenient to realize functions, and supporting parts: such as communication serial port, program burning port, reset button and so on. The development board is fully functional, but the size is also larger. In actual production, all these things may not be needed.

How does the microcontroller work?

You want to chat with me about this, I'm not sleepy anymore. Here is only a brief introduction, because the author is just an amateur.

Let me introduce the pins first . Pins are like human senses and are used to receive feedback information. The pin can be an input or an output. The pin status is divided into high level and low level (do you think of anything?). The pin level status will affect the external devices connected to it. The following Hello World will demonstrate.

Essentially, the program burned into the development board is to control the level of each pin, plus various logic gates to form a more complex state, from the light on and off, to the control of the aircraft, it can be controlled by 01 To represent.

People can't help but sigh the wisdom of the ancestors, there is quite a feeling: Tao begets one, one life two, two begets three, three begets everything .

Once the development board is powered on, it will continue to repeat [input -> operation] according to the program. This process is familiar to those who have studied computers: read instructions, fetch data from registers, CPU calculates the results, and finally store the results back to the registers.

FBI Warning, I have my humble opinion on the above, if there are any errors, please correct me.

Four-pin key switch 3.

Put on you a cute little green hat.

The one that makes a "tick" sound when pressed, the same style as the Cassidy handle.

There are several male-to-male DuPont lines.

The thoughtful friend will ask, since there is a male, there must be a female? The author will put a picture for you to experience by yourself.

220 resistance 3.

How do you see if the resistance is 220 ?

For those who have never learned electrical engineering knowledge, only need to understand that the order of the color circle on the resistor is: red, red, brown, and yellow.

Breadboard 1.

It is equivalent to the base of Lego bricks. The details will be discussed later.


Hello World! Brian Kernighan

If the hardware leaves the software, it is nothing. So let's briefly understand the syntax of Arduino.

Go to the official website ( www.arduino.cc/en/software... IDE (there is a web version, in order to facilitate uploading programs, or download the client). This IDE is already very simple and supports Chinese, so the details will not be introduced.

A simple LED light experiment.

Hardware connection: development board pin N -> the yellow end of the 220 resistor -> LED positive (the end with the long leg); LED negative -> development board GND (can be understood as the negative pole of the power supply). The purpose of adding resistors is to weaken the current flowing into the LED and prevent burnout of the device. Considering that some friends may not be able to come to the schematic, so directly upload the photo.

Start writing the program (Arduino is a C-like language):

//This function will only be executed once void setup () { //Set pin 6 as output, which is the above N pinMode( 6 , OUTPUT); } //This guy will execute void loop () { digitalWrite( 6 , HIGH); //High level light delay( 1000 ); digitalWrite( 6 , LOW); //low level off delay( 1000 ); } Copy code

Click the button in the red frame below to upload the program to the development board.

IF upload failed, click Tools -> Port, check whether the correct COM (Windows) or device (Linux) is selected. If the IF is correct, you need to install the driver ( www.arduino.cn/thread-1008...

If everything is normal, you can see that the small yellow light of the development board is blinking, which means that there is data transmission. After the upload is complete, your light bulb will repeat the process of turning on for one second and turning off for one second.


Let the game begin. -Medivh

Let's assemble this first. It's not that the author is hypocritical, the characters are not of the author P, the original picture is there!

Since the author did not have enough four-corner buttons, only three were connected, and the connections were the same except for the different pins connected to the board. Turn the button over and you can see that there will be a 1234 label next to the pin. It should be noted that 12 can be energized, 34 can be energized (the direction is not important), but 13, 24, 14, 23 cannot be connected together.

Connection: pin N -> button pin 1, button pin 2 -> 220 resistor yellow end, 220 resistor red end -> development board 5V; button pin 3 -> development board GND.

After connecting, you can find that one of the buttons is not used, which is normal. The rest follows the same pattern.

Careful friends will find that there are only 2 GNDs on the development board, so one button connected to one GND is definitely not enough.

At this time, you need to plug the DuPont cable into a special area of the breadboard. As shown in the figure, on both sides of the breadboard, the part between the red line and the blue line is connected horizontally, and all the pins in this row are considered to be connected to 5V or GND. And the area in the middle of the bread is connected vertically, this should be noted.

Next, write a program to read the key signal, not much to say, everything is in the code:

//Here is the pin number const byte left = 7 ; const byte right = 8 ; const byte act = 9 ; //Here is the pin status byte leftHit; byte rightHit; byte actHit; void setup () { pinMode( 7 , INPUT); pinMode( 8 , INPUT); pinMode( 9 , INPUT); //New guy, here is the serial initialization, used to receive and send data Serial.begin( 9600 ); } void loop () { //read the level of the four-pin button leftHit = digitalRead(left); rightHit = digitalRead(right); actHit = digitalRead(act); //When pressed, the level is LOW if (leftHit == LOW) { sendSerial( 0 ); } if (rightHit == LOW) { sendSerial( 1 ); } if (actHit == LOW) { sendSerial( 2 ); } //Because of pressing and releasing this period of time, it is still very long for the program. //This delay is a while to reduce the frequency of sending data. //For the game, you can t keep pressing to connect Hit " delay( 100 ); } void sendSerial (byte data) { //When sending data, interrupt once to ensure the timing delayMicroseconds( 2 ); Serial.print(data); delayMicroseconds( 2 ); } Copy code

So far, so good, come and test it quickly. Take this to introduce a trick: After uploading the program, open the IDE tool -> serial monitor (when uploading the program, the serial port will be occupied, so you have to wait for the program to upload), adjust the baud rate to 9600 in the program, IF in the lower right corner The hardware is connected correctly, and every time a button is pressed, the corresponding value will be displayed on the monitor.

Okay, the controller is there, now it's time to write the game.


Hello World! Again! Brian Kernighan

Since the author is a layman for game development, I chose a relatively simple Processing language for development. Processing was originally used for image design, but here is also used to do a rather side-effect. Considering that most of the friends have never heard of this guy, let's take an example to see how Processing is played.

As usual, go to the official website ( processing.org/download/) to free... IDE. Its interface is very similar to Arduino, so I won't introduce it too much.

Demo:

//Haha, like Arduino, a setup function and a loop function void setup () { //set the canvas size size( 200 , 200 ); } //Like Arduino, it keeps looping and can match the frame number of the game. void draw () { //Set the background to black. For specific parameters, please refer to the official website background( 0 ); //Fill the next elements with white fill( 255 ); //Using the mouse coordinates as the center, draw a circle with a radius of 80 pixels ellipse(mouseX, mouseY, 80 , 80 ); } Copy code

Click Run in the upper left corner. If the IF code is correct, a black box will pop up. After the mouse enters, there will be a white circle that keeps moving with the mouse.

Make a slight modification, define an int x = 0 before setup, then increment it by x++ in the tail of draw, change the ellipse parameter to ellipse(x, 40, 80, 80), the circle will move from left to right , So that you can control the movement of the element by the variable value.

Then the same reason can be proved, as long as it is a function provided by Processing, you can use variables to control the attributes or behavior of the element.

If the background is commented out in IF, a circle will be left wherever the circle has moved.

Why should this point be emphasized separately? Of course, this feature will be used later to keep or remove some elements.

At this point, you already have the basic knowledge of writing games with Processing (error).


All is ready except for the opportunity. Zhuge Liang

The many foreshadowings in front finally usher in the final moment. Let's start writing the game of flying airplanes now. Generally speaking, for normal programming, the actual coding time ratio is 8 to 2. So don't worry, just take care of it first.

The author refers to the classic game Little Bee.

Game type: flying shooting

Victory conditions: destroy all enemy aircraft

Failure condition: the player is shot

Human-computer interaction interface (User Interface, to put it another way, is it going to be tall in an instant, dog head):

  • At the top of the screen are 3 rows with 6 enemy aircraft in each row. The enemy's behaviors are: moving left and right, shooting.

  • Below the screen is the player, 1 airplane. The instructions are: move left and right, shoot.

  • Game flow: Press any key to start the game; the player is shot or the enemy aircraft is completely destroyed, the corresponding text is displayed in the middle of the screen, and the game is interrupted; when interrupted, press any key to start a new game.

The above is the part that the player sees, and the following is the inside of the program:

Move: Very simple, that is, change the x-axis and y-axis positions of the player and the enemy aircraft.

Shooting: A bullet is produced, the enemy's bullet moves downwards, the x-axis is fixed, and the y-axis is changed. The direction of the player's bullet is opposite.

Collision determination: The most difficult part is to determine whether the bullet has hit an object. Since each bullet has to be calculated for each frame, when there are a large number of bullets on the screen, the amount of calculation will increase geometrically. If it is not properly optimized, or if it is violent, it will likely be stuck and cause poor player experience.

It's almost done, get to work. Processing provides multiple language modes, the author chose the Java mode (upper right corner of the IDE).

//First complete the protagonist class Ship { //current position int sx; int sy; //moving speed int speed = 6 ; Ship( int initX, int initY) { sx = initX; sy = initY; } void display () { //The player s plane is a 40x26 picture, you can change it to your favorite image(shipShape, sx, sy, 40 , 26 ); } void drive ( int direct) { //move to the left if ( 0 == direct) { sx = sx-speed; //Can't fly out of the screen if (sx <= 0 ) { sx = 0 ; } return ; } sx += speed; int right = width- 40 ; if (sx >= right) { sx = right; } } } PImage shipShape; Ship ship; void setup () { size( 600 , 360 ); //The file path is at the same level as the Process file shipShape = loadImage( "resource/ship.png" ); ship = new Ship( 280 , 324 ); } void draw () { //To fly //ship.drive(1); ship.display(); } Copy code

So far, by calling the drive method of ship, you can control the aircraft. The classes of the enemy aircraft are similar, so I won t repeat the code here.

Wait, how do you respond to Arduino buttons? In fact, this question has been answered before, serial communication!

import processing.serial.*; Serial port; void setup () { ... //The breaking rate must be the same as that of Arduino port = new Serial( this , "{Your serial port/device}" , 9600 ); } void draw () { if (port.available() <= 0 ) { return ; } //The data output by Arduino needs to be changed to its own definition int coming = port.read(); switch (coming) { case 48 : ship.drive( 0 ); break ; case 49 : ship.drive( 1 ); break ; case 50 : //The attack method of the aircraft has not been defined yet ship.attack(); break ; } } Copy code

According to common sense, the attack logic should be written now, but it can only be hit if there is a bullet, so first write the code related to the bullet object.

class Bullet { int bx = 0 ; int by = 0 ; int speed = 5 ; //Public bullet class, call different methods to fly up or down boolean up () { by -= speed; image(bulletUp, bx, by, 2 , 14 ); } boolean down () { by += speed; image(bulletDown, bx, by, 2 , 14 ); } } //Use different pictures to distinguish between enemy and friend bullets PImage bulletUp; PImage bulletDown; //For demonstration, here is a new bullet Bullet bullet = new Bullet(); void setup () { ... bulletUp = loadImage( "resource/bullet_up.png" ); bulletDown = loadImage( "resource/bullet_down.png" ); } void draw () { ... bullet.up(); } Copy code

Next, it's an attack.

//Add attributes to the bullet class, the method //Whether to display boolean alive = false ; //fire void trigger ( int initX, int initY, int initSpeed) { alive = true ; bx = initX; by = initY; speed = initSpeed; } //After flying out of the screen, the bullet does not need to be displayed void clean () { alive = false ; bx = 0 ; by = 0 ; } //Modify the up down method boolean up () { by -= speed; //The reason for the negative number here is because you have to wait for the bullet to completely fly out of the screen before removing it if (by <=- 14 ) { return false ; } image(bulletUp, bx, by, 2 , 14 ); return true ; } boolean down () { by += speed; if (by >= height + 14 ) { return false ; } image(bulletDown, bx, by, 2 , 14 ); return true ; } //Add an attack method to the aircraft void attack () { //Sorry, we only recruit dormant bullets if (!bullet.alive) { //The initial position of the bullet on the x axis, 5 is the bullet flight speed bullet.trigger(sx + 20 , sy, 5 ); break ; } } void draw () { ... //Show only the living bullets if (bullet.alive) { if (!bullet.up()) { //Goodbye, bullets flying out of the screen bullet.clean(); } } } Copy code

In order to control the number of bullets on the screen, I did not press the attack button to create a new bullet. Instead, a container was created and put some in advance. When the container runs out of bullets, it no longer responds to the attack. When the bullets fly out of the screen, the bullets are awakened for standby.

Finally, the hardest part is the crash test.

The author's idea is the simplest and violent way, the fake code is as follows:

int len = number of remaining enemies for ( int i = 0 ; i <len; i++) { //Calculate the upper, lower, left, and right boundaries of the enemy, the enemy is a 28 x 38 square //int top = enemy.pool[i].ey; int bottom = enemy.pool[i].ey + 28 ; //int left = enemy.pool[i].ex; int right = enemy.pool[i].ex + 38 ; int len2 = number of surviving bullets for ( int j = 0 ; j <len2; j++) { Bullet tmp = bullet[j]; //Although the bullet has a width, the author is lazy to regard it as a point if (tmp.bx> enemy.pool[i].ex && tmp.bx <right && tmp.by <bottom && tmp.by> enemy.pool [i].ey) { //If this point coincides with the enemy's block, then it is determined that the enemy was hit enemy[i].alive = false ; //The bullet hits the object and disappears tmp.clean(); } } } } Copy code

This can be functional, but it is still too rough. So the author made a small optimization and showed my ugliness.

Because the y-axis of the player and the enemy are fixed, I created 2 containers. Each time the bullet is refreshed, load the bullets that enter the enemy's y-axis movement area and the player's y-axis movement area, and then modify the above code to only traverse the bullets in these two containers. This greatly reduces the number of traversals. When the screen is refreshed next time, empty the container again. Of course, a more mature approach is to use algorithms to speed up calculations, but the author's ability is limited and there is no practice.

The rest of the work is very simple.

Instantiate enemies and players in a loop. The enemy is set to a random number every time it moves, and if it is greater than this number, it will attack. In the draw loop, it is judged whether the player is hit or the enemy is completely destroyed to judge whether the game should continue. When I finished, the code was less than 400 lines. The final effect is as follows:

The complete code can be found in the repository ( gitee.com/kyzx/mutali...

With the above skeleton, friends can realize their brains crazy. For example, change the movement of the aircraft to one that can move up and down, add health bars for players and enemies, add bullet trajectories, bullets can offset bullets, score mechanisms, etc.


I have already written so much before I know it.

In retrospect, this process was difficult and there were no experts around me. However, relying on the powerful tool of the Internet, the author still stumbled and completed it. The sense of accomplishment is self-evident.

This game is really easy to play, and it's not even comparable to the games in the yellow cassettes. But from 0 to 1, the process of groping is the same as when I was playing games when I was a child, painful and happy.

May you always be a teenager.