Game console for Arduino. Arduino UNO R3 (Gra u ping pong robimo sami). Creation of master fonts



Let’s begin to create a mental grease called “Arithmetic Calculator.” Gravets is controlled by a joystick with the ability to move around a field measuring 128×90. With zero joystick movements, the gravity moves at the center. Maximum control of the joystick corresponds to maximum movement of the gravel. At regular intervals, objects-digits are generated, which collapse like hell to the bottom. After reaching the bottom position of the screen, the object-digit is known, changing the number of gravel balls by the value of this digit. As the Gravecs scrolls through the object-number on the screen, this will result in a clearer object-number and an increase in the healing value of the Gravets. With regular intervals, the Gravity icon changes its value from the numbers 0 to 9. When you move an object-digit, the healer's score increases by the amount that is equal to the previous amount of the object-digit and the number of the Gravity, which is the number Gravity ancient digits object-digits , then the healer of the graves will increase by gaining numbers. After reaching the previous thresholds of points, a transition to a higher level of values ​​is required, which will lead to greater speed of movement and speed of generation of object-digits. In addition, from the 4th level of a closed gravel with an object-digit, it is necessary not only to increase the healing value of the gravel, but also to change it (as the figure of the gravel is less than the figure of the object-digit). As the number of points in the game becomes less than 0, the game starts from the beginning.

Video axis of what came out

You can access the archives with sketches and files from the TVOut library upon request

I the process of creation itself

Creation of great games

For heating, we create objects to preserve the flow position of the heating. The symbol that represents the gravel, and the symbols that display numeric objects, are displayed as text information, so the entire field of play in rows and all movements of objects will work as if the symbol is displayed in a certain place. field. The values ​​MAX_X=31 and MAX_Y=14 determine the size of the playing field based on the number of horizontal and vertical dimensions. The value MAX_OBJ=30 indicates the maximum number of digit objects that can be on the playing field at one time. The int FIGURA array stores information about the digit objects that are currently on the field:

  • FIGURA[i] – numerical value of the digit object (0 – empty object);
  • FIGURA[i] - exact coordinate x of the object-digit;
  • FIGURA[i] – the exact y coordinate of the digit object.

To save other variables that describe the production line, we create the GAME structure. List of structure fields:

  • xk – coordinate x(/4) of the gravel;
  • yk – coordinate y(/6) of gravity;
  • tekCursor – more precise values ​​for the cursor;
  • blinkCursor – cutting mill for blinking the cursor;
  • vblink - blink speed in vk;
  • vk – smoothness of the gravel handle – check of inputs A0, A1;
  • vo_10 – speed of changing the gravel number;
  • vo_11 - speed of appearance of objects-digits;
  • vo_12 - fluidity of digit-objectives;
  • count_objects - number of objects-digits in the field;
  • level – rhubarb gris;
  • balls - number of balls.

int MAX_X=31; int MAX_Y=14; // structure of the game data struct GAME // structure of the game data ( int xk; // x(/4) coordinate of the gravel int yk; // y(/6) coordinate of the gravel int tekCursor; // more precise cursor values ​​int blinkCursor; / / threading mill of the cursor int vblink;// speed of blink in vk long vk; // speed of the movement of the gravel - re-verification of inputs A0, A1 long vo_10; // speed of changing the digits of the gravel long vo_11; // speed of the appearance of the numbers long vo_12; // speed number of numbers int count_objects;// Number of objects on the field int level; // Number of balls; // Number of balls); int MAX_OBJ=30; int FIGURA=((0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0), (0,0,0 ) ),(0,0,0),(0,0,0),(0,0,0),(0,0,0), (0,0,0),(0,0,0) , (0,0,0),(0,0,0),(0,0,0), (0,0,0),(0,0,0),(0,0,0),( 0 ,0,0),(0,0,0), (0,0,0),(0,0,0),(0,0,0),(0,0,0),(0, 0) ,0), (0,0,0),(0,0,0),(0,0,0),(0,0,0),(0,0,0) );

The driver is positioned behind the joystick.

The position of the gravel on the screen is indicated by the joystick controls. The joystick connectors are connected to analog ports A0, A1 of the Arduino board. The ports are activated after an hour, the values ​​are determined by the GAME.vk parameter, and this data is processed by the map() function, which proportionally transfers the values ​​of the flow range 0-124 to a new range (values ​​of the width and height of the screen). Then this value is converted into contact coordinates. At this location, it is necessary to move the image to the gravel symbol, placing the skip symbol at the front position of the gravel. To display the gravel, a flashing symbol is displayed - a number and a space.

//****************** setting a new gravity position void set_iam() (TV.set_cursor(min(123,GAME1.xk*4),min(84,GAME1) . yk*6));TV.print(" "); , 96);GAME1.xk=GAME1.xk/4;GAME1.yk=GAME1.yk/6;GAME1.vblink–;if(GAME1.vblink<0) { GAME1.blinkCursor=1-GAME1.blinkCursor; GAME1.vblink=5+GAME1.blinkCursor*5; } TV.set_cursor(min(123,GAME1.xk*4),min(84,GAME1.yk*6)); if(GAME1.blinkCursor==1) TV.print(GAME1.tekCursor); else TV.print(” “); }

The symbol that the gravel represents changes after an hour, using the GAME.vo_10 parameter using the set_new_cursor() function, the change is carried out step by step using the additional random() function.

//****************** setting a new type of gravel symbol void set_new_cursor() ( GAME1.tekCursor=random(0,10); )

Generation and movement of digital objects.

Objects-numbers are generated after an hour, using the GAME.vo11 parameter. The set_new_object() function is called. Information about all digital objects is saved in the FIGURA array. The program looks for the first empty index in the array (FIGURA=0), and places a new object-digit. The digital value and horizontal coordinate of the new object are generated by the random function, and the vertical coordinate is set to zero. The symbol that represents the new number object appears on the screen.

//***************** Appearance of a new number object void set_new_object() ( int null_index=0; if(GAME1.count_objects)<>( for(int i=0;i;i++)<>( if(FIGURA[i]==0) (null_index=i;break;) ) FIGURA=random(1,9); FIGURA=random(0,MAX_X); FIGURE = 0; // Visnovok on the board TV.set_cursor (FIGURA * 4.0); TV.print(FIGURA); GAME1.count_objects++; )

The function of moving objects-digits (go_object()) is called after an hour, as determined by the GAME.vo12 parameter. Vizuelizatsya Rukhu Ophtyk-Tsifre Vidbuvas, the fate of the symbol of the fraudster (note of the symbol of the probіl), with the recording of the symbol of the O'Skta (vertical coordination Know the tzifri zbilshah to lonely). When you reach the bottom of the screen, you will see a new object-digit (record 0 element of the FIGURA[i] array), as well as a change in the number of gravel points.

//******************* object-digit void go_object() ( for(int i=0;i;i++)<>( if(FIGURA[i]>0) ( TV.set_cursor(FIGURA[i]*4,FIGURA[i]*6); TV.print(" “); if(FIGURA[i]))<>( FIGURA[i]++; TV.set_cursor(FIGURA[i]*4,FIGURA[i]*6); TV.print(FIGURA[i]); ) else ( TV.tone(294,200); change_balls(FIGURA ) [i]*(-1));FIGURA[i]=0;GAME1.count_objects–; )))))

Inspection of printed gravel and objective-digits.

When moving the engraving symbol on the screen, you must check the engraving with the number objects. For which we use the collision() function. After inserting a symbol that represents gravel, we check the elements of the FIGURA array to see if the object-digit coordinates correspond to the coordinates of the gravel symbol. When the coordinates are lost, the following actions can be completed:

  • the object-digit is found in the FIGURA array (entry 0 in FIGURA[[i]);
  • changes to 1 healer for the number of object-numbers (GAME.count_objects)
  • The doctor can change the number of gravel balls (click the function change_balls()).

//****************** check the connection void collision() ( for(int i=0;i;i++)<>( if(FIGURA[i]>0) ( if(FIGURA[i]==GAME1.xk && FIGURA[i]==GAME1.yk) ( TV.tone(740,200); if(FIGURA[i]==GAME1 ) .tekCursor) change_balls(GAME1.tekCursor*GAME1.tekCursor), else if(FIGURA[i]>GAME1.tekCursor && GAME1.level>3) change_balls(FIGURA[i]*(-1));else change_balls(FIGURA [ i]+GAME1.tekCursor);FIGURA[i]=0;GAME1.count_objects–; ) ) ) )

The function of changing the number of balls in the grave (change_balls()) passes the number as an argument to increase (change) the number of balls in the grave. This number is similar to the sum of the object-digits and the gravel numbers. If a digit is an older digit of a digit object, then the value that is older than the addition of the digits is transmitted. To increase the foldability of the 4th level of the closed gravel with the object-number, do not only increase the treatment of the gravel, but then change it (as the figure of the gravel is less than the figure of the object-number).

Physician of gravel.

The change_balls() function changes the healer of the grave's balls by the value of the input argument. As soon as the number of points healer becomes less than 0, the game ends, the screen is cleared and the game begins. In addition, when the healer reaches the level of the song, the game will switch to a new, higher level. The set value of the new level is determined by the new_level() function.

//****************** change the accumulated points void change_balls(int ball) ( GAME1.balls=GAME1.balls+ball; if(GAME1.balls<0) start_game(); if(GAME1.balls>(GAME1.level+1)*100) new_level(GAME1.level); set_data_tablo(); )

Crossing a new level.

When switching to a new level, new values ​​for the generation speed and the speed of movement of digital objects are installed. From the very beginning, it was necessary to change the values ​​of the speed of changing the numbers of the gravel, the speed of the hand of the gravel, and in the course of testing the game, depending on which one is convinced. The set values ​​of the changes for the new level are determined by the function new_level()

//****************** change level gree void new_level(int tek_level) (GAME1.level++; GAME1.vo_10=5000; GAME1.vo_11=2000-(GAME1.level -1)*100;GAME1.vo_12=1000-(GAME1.level-1)*100;

Images of these data are displayed on the scoreboard.

The data board is located at the bottom of the screen. Here you can see the number of points accumulated and the amount of games played. When changing the score healer, the function set_data_tablo() is called, which changes the value of the number of points collected and the game level in the changeable GAME structures and on the scoreboard.

//****************** displaying data on the scoreboard void set_data_tablo() (TV.print(20,91," balls="); TV.print(70,91 "," level = "); TV.print(48.91,GAME1.balls); TV.print(98.91,GAME1.level);

Sound support gri.

For sound design, use the tone(frequency, duration) function of the TVOut library. When the object-number reaches the bottom of the playing field – TV.tone(294,200) (function go_object()), when the gravel of the object-number is closed – TV.tone(740,200) (function collision()). If you want to insert into the project a fragment from the sequential creation of several notes, after displaying the skin note with the tone(frequency, duration) command, you must insert the delay() command with a delay of at least three levels, the lower duration parameter, 6 – the final output Yenya e two ale z pause.

TV.tone(294,200); TV.delay(400); TV.tone(740,200);

The main cycle of gris.

The main cycle of the program is formed by the call of the functions we looked at set_iam(), collision(), go_object(), set_new_object(), set_new_cursor() after an interval of an hour of installation in the following GAME.vk, GAME.vo_10, GAME.vo_11, GAME.vo_12.

int game1() ( while(GAME1.balls>0 && GAME1.level<6) { long time2=millis(); if(time2-time11>GAME1.vk) (set_iam(); collision(); time11=time2; ) if(time2-time12>GAME1.vo_12) (go_object();time12=time2;) if(time2-time13>GAME1.vo_11) (set_new_object ();time13=time2;) if(time2-time14>GAME1.vo_10) (set_new_cursor();time14=time2;) TV.delay_frame(10); ) if(GAME1.balls<0) return 0; else if(GAME1.level>5) return 0; else return 1; )

Adding a menu for selecting igors.

A menu has been added to the sketch for displaying three games that you can add yourself.

void loop() ( switch(menu(pmenu)) ( case 1:start_game(); while(game1()>0); break; default: break; ) ) //***** menu for selecting game int menu (int poz) (TV.clear_screen(); pmenu=max(poz,1); int pmenu1=pmenu; TV.println(60,30,"Game 1"); TV.println(60,50,"Game 2 ″); TV.println(60,70,”Game 3″); TV.draw_rect(50,5+20*pmenu,40,10,WHITE,INVERT); )==LOW) ( if(analogRead(A1) )<100) pmenu=max(pmenu-1,1); else if(analogRead(A1)>900) pmenu = min (pmenu + 1.3); else; if(pmenu1!=pmenu) (TV.delay(500); TV.draw_rect(50.5+20*pmenu1,40,10,BLACK,INVERT); TV.draw_rect(50.5+20*pmenu,40, 10, WHITE, INVERT);pmenu1 = pmenu;))) return pmenu; )

Hello, Geek Times!
Today I will tell you one not so good story about how I created a simple game console based on Arduino and created a complex game for it in my favorite game engine Unity.

Play

Just recently I’m starting to develop games on the popular game engine Unity (formerly Unity3D). In just one hour, I managed to make a number of small projects for mobile devices, as well as a large amount of insurance for a large-scale project.
This area is less useful and brings great satisfaction to working in it.

Device

However, I feel compelled to try something new, and one day I decided to try arduino.
I became really interested in how to create my power devices and how to program them. Why arduino? There are a lot of posts on the Internet about those who want to use Arduino. Let me just say that for me the most important factor in choosing an arduino is the simplicity of the choice.

How can I eat this?

Once on the Internet, I found a post about how one of the developers collected his simple Arduino-based game console, provided it with a small 84x48 pixel display, and wrote a couple of simple games on it: Pong and Arkanoid. .
This technology didn’t really appeal to me, and I decided to create my own version of a game console based on the atmega328 microcontroller.

The console itself

First of all, I designed and LUT-manufactured a board for a portable console. This was a pity - from the very beginning it was necessary to protest the program on the device board, for example, arduino uno, because I did not transfer the ability of the slider and manually upload the program to the controller. And I also had mercy on the circuit itself, it was possible to correct the wires, but it would still be closed.
After I realized that I had mercy, I connected the buttons through the arduino uno board, and I connected the screen directly.
Axis:



And now to igor

To create the game, I used the Unity game engine. I didn’t write a compiler from Mono C# into a program for Arduino, but instead decided to write a set of scripts, which can be used to easily select games.
I divided all the scripts into 3 groups – dii, umovi and combiners.
I think there is no need to explain the significance of the actions and minds, but I will explain the axis for which the combine operator is needed. The combine operator checks the final idea, and then finalizes the idea.
From these scripts, or more precisely from their presence and combination, the algorithm creates a program for arduino.

What is this game?

I started thinking about something simple. What is the simplest game, do you know? That's right - pong. But I decided to play not just Pong, but Pong for one - one racket, a ball and a wall, instead of another racket.
I took it from the written constructor and compiled it from the controller. Pratsyuє!

And now let's put everything in order

Once the game started, and I played it, I decided that it was time to rework the board, give it a bad look, remove the SMD components, and get all the files. I rebuilt the circuit and made the board.
Axis



Weekends

The output code is very simple.
What to use Unity - from the editor, the developer collects a group of ui objects, attaches action scripts, minds and combiners to them.
What you need to do is run the compiler (parser.cs script) - it goes through all the objects, looks at their scripts and adds code snippets to the text of the build.ino file, which indicate that the analogs of these scripts are generated by the microcontroller.

Weekend message - drive.google.com/open?id=0B5INc3_98cSJMEMxZmlWUTh1Ukk
The compilation fails when starting the game. It is saved in the folder Assets/build/text/built.ino
This sketch needs to be uploaded to the controller.

In a wilted state

I want to say that this is even cooler.
I have lost the opportunity to take up two of my own activities - the development of games and the creation of devices.
I hope you got hooked, and now you can get your own cool device =)

Arduino game console? True true. Behind the screen, buttons and games. And this is not a fantasy. There are a number of projects that we have tried to develop and implement one of them (Gamebuino) ourselves.

Since the project is open, the entire schematic is available on Wiki, as well as sent to the PP, games and other useful information.

To create our own game console, we need inexpensive components - a Nokia 5110 screen, six buttons and a speaker. Everything is easy to find on Aliexpress or other sites of Chinese stores (the most important problem is to find the screen) and in Russia. The screen can be called “massive” and is well described, so connecting it is also not problematic, as it is not enough.

Since Gamebuino is wired manually to place elements on the board, when we try to connect elements through standard Arduino pins, we get the following picture:

In fact, some of the elements have already been “wasted”, because the Gamebuino uses microprocessor contacts that are not wired on the Arduino or are simply not needed. The battery charge sensor, button C and SD card (there is no interaction) and the ambient light sensor went to the "scrap". It is also possible to use resistors - we are not going to vikorize the display in 24/7 mode and you can do without any protection.

It would be possible to create it “beautifully”, but then I would have to correct the code of existing libraries and “change” contacts for a new scheme. I would like to stick to cosmetics - to use “standard” contacts or to make minor edits to the code if necessary.

Also, after creating the circuits, you need to install the Arduino IDE and install the archive axis. You need to unzip it into the Documents/Arduino directory and then launch the Arduino IDE. To this archive, changes have already been made to the library code and out of the box that work with this scheme.

You may have a Gamebuino tool that will allow you to check the display, buttons, etc. And then launch Pong. To pay, try the standard Arduino UNO or Leonardo (haven’t tested the others yet).

If you have everything in order, it collapses and beeps. Regular nutrition is to blame - where are the games? Gamebuino uses its own tool for working with SD cards, so it is impossible to import HEX through its loader without flashing the Arduino itself. If you do this, then due to the lack of signal from the battery, you will not be able to start anything, as the firmware will be barked and corrupted. Precompiled HEX with games will also not run due to problems with the battery charge sensor.

But not everything is lost - you can download the output codes, open them in the Arduino IDE and “upload” them to our console.

I checked part of the smell and the smell... PRACTICE! You can download the archives with the output codes and download them, open them in the Arduino IDE and compile and download them yourself. You can try other games yourself by downloading the output codes from the Gamebuino Wiki.

Ozhe - misia vikonan! We got a miniature game console. Now our task is to earn money on mobile :) And let’s try to earn money from the upcoming articles.

And so, my friends, since you already have an Arduino UNO R3 designer kit (starter kit) or you have become bored, from a technical point of view - be kind. We have a whole series of “lessons” for Arduino. I would like to tell you what can be done in this set, not everything, but perhaps everything that will be used or not. Game console, well, use the joystick to play ping-pong and the like. Whoever lost an old computer with an old joystick, now it doesn’t work, the whole logic that goes through Arduino Kit(http://arduinokit.ru/).

Why bother the project?

I created a simple game console that can play ping-pong and other games, like on an old Atari 2600 computer that can easily use an Arduino R3. Arduino, having become an old computer, reads the inputs and outputs of data from the joystick connected to the TV through the standard TVout library (For Arduino). I created this project solely to demonstrate that anyone (without special skills) can create their own miniature consoles and games. I also want that everyone who reads this article will be able to profit from this joy absolutely without harm.

What is required for an Arduino game console?

5. Now, to play ping pong, we only need a 4-pin connector: Forward (1), Back (2), Button (6) and Ground (8). And for the 2nd joystick, we only need contacts 1, 2 and 8 (The “head” button is used only to “start a game” under the name of the Administrator, so only 1 button is used for the mother button).

6. If you notice the contacts on the side, I connected 4 connections with simple wires that go to Arduino (“Forward” to pin 2, “Back” to pin 3, and “Control” to pin 4). I tried the same for the other 3 contacts for Gravity 2 (on the other Joystick): “Forward” to contact 7 and “Back” to contact 10). Don't forget to connect the Contact 8 joysticks to ground (screen is dripping)!

7. Now, turn on the Ping-pong group and check the joystick inputs. Insert the Arduino UNO R3 and all the parts into the required sockets (I hacked the outer casing of the old hard drive).

Since I first tried to work on this project myself, I was even more worried about starting to work on this project. Fuf it was not easy, wanting to complete this project as soon as possible. My main problem right now is that I am trying to implement old joysticks from Atari to Arduino. Through this action, Internet bloggers wrote incorrectly on their forums, saying that it was impossible to read the input or solder it in the middle of the joystick, while they were having fun vikorizing their standard controllers, having come to their call, I smelled a turnip and a bug then heard a message at your address , saying, “My hands can’t grow,” because I can’t handle a soldering iron in my hands. Prote my project is working! Are you weak?

PS: I think the only thing is that I would look differently now - hmm. Well, for example, having acquired a cartridge from Sega or Dendi and having created any kind of card reader. The axis for you and the TV game console is powered by hand. Golovnya, that my project of scaling, you can work not only with flying robots, but also with game consoles with your own hands. Before speaking, our friends have various components for Arduino UNO R3 (Arduino Design Kits). Whatever you want, you can earn everything with your own hands. I’m doing it!

In the daylight, and then in my sleep, the idea of ​​​​creating a power-controlled set-top box came to me. Vlasna, here the rich and intense world of radio technology appears before me. Since I had previously been unable to cope with the serious breakdown of electronics, my choice was based on a simpler option - Arduino This is the most extensive model - Uno.

Robot plan

1. Contact the library
2. Solder the video output board
3. Write the code
4. Virizati body

The final external warehouse is not particularly important in connection with such projects.

Lesson 1. Let's figure out what's up

After several dozens of elaborate experiments, I couldn’t figure out how to create a prefix like Dandy. Well, what’s there to be bothered with, if you take it, bring it to the end.

On the site dedicated to projects on Arduino, radioelectronics in general (not advertising) contains an article about a similar development. It was decided to select the library TVout, fragments of the TV set-top box. To install this robot, I had to do a little shamanism.

Essential library functions

Mode setting functions

Function begin() Ends the output of the video signal (separate screen size 128x96).
Syntax:
TVOut.begin(mode);
TVOut.begin(mode, x, y);

Parameters:
mode – video signal standard:
_PAL – PAL mode;
_NTSC – NTSC mode.
Meaning that rotates:
0 – for a remote connection, 4 – for a failure (insufficient memory for the output buffer).

Shutter functions

Function delay() This will freeze the displayed image.
Syntax:

TVOut.delay(ms);
Parameters:

ms – ms trim with accuracy: 20 ms for PAL and 16 ms for NTSC.

The delay_frame() function freezes the displayed image.
Syntax:

TVOut.delay_frame(frames);
Parameters:

frames – number of frames for blurring.
The function is useful for minimizing or shrinking the screen, clicking on the latest screen.

Options for selecting parameters

Function hres() rotates the horizontal section of the screen.
Syntax:

TVOut.hrs();
Parameters:

no.
Meaning that rotates:

unsigned char – horizontally separated screen size.

The vres() function rotates the vertical aspect of the screen.
Syntax:

TVOut.vres();
Parameters:

no.
Meaning that rotates:

unsigned char – vertical separation of the screen.

Function char_line() rotates the maximum possible number of characters in one row during the display of text information.
Syntax:

TVOut. char_line();
Parameters:

no.
Meaning that rotates:

unsigned char – number of characters.

Basic graphical functions

Function set_pixel() sets the pixel color of the screen at the point at the specified coordinates.
Syntax:

TVOut.set_pixel(x,y,color);
Parameters:

x, y – pixel coordinates;
color – pixel color:
0 – black;
1 – white;
2 – invert color.
Function get_pixel() takes the screen pixel color from a point at the specified coordinates.
Syntax:

TVOut.get_pixel(x,y);
Parameters:

x, y – pixel coordinates.
Meaning that rotates:

color – pixel color:
0 – black;
1 – white;
2 – invert color.
The fill() function fills the screen with the specified color.
Syntax:

TVOut.fill(color);
Parameters:

color – color of filling:
0 – black;
1 – white;
2 – invert color.
Function clear_screen() clears the screen, restoring it with the specified color.
Syntax:

TVOut.clear_screen(color);
Parameters:

color – color of filling:
0 – black;
1 – white;
2 – invert color.

Function invert() Inverts the screen.
Syntax:

TVOut.invert();
Parameters:

no.
The shift_direction() function destroys the screen.
Syntax:

TVOut.shift_direction(distance, direction);
Parameters:

distance – stand up to take the screen instead of the screen.
direction – directly to zsuwu:
UP = 0 - uphill;
DOWN = 1 - down;
LEFT = 2 - left;
RIGHT = 3 - right-handed.

Function draw_line() connects two dots on the screen.
Syntax:

TVOut.draw_line(x0,y0,x1,y1,color);
Parameters:

x0, y0 – coordinates of the first point;
x1, y1 – coordinates of another point;
color – color of filling:
0 – black;
1 – white;
2 – invert color.
Function draw_row() fills the row with the specified color between two points of the row.
Syntax:

TVOut.draw_row(row,x0,x1,color);
Parameters:

row – vertical coordinate of the row;
x1,x2 – horizontal coordinates of row points;
color – color of filling:
0 – black;
1 – white;
2 – invert color.
The draw_column() function fills the row with the specified color between two column points.
Syntax:

TVOut.draw_column(column,y0,y1,color);
Parameters:

column – horizontal coordinate of the column;
y1, y2 – vertical coordinates of the starting points;
color – color of filling:
0 – black;
1 – white;
2 – invert color.
Function draw_rect() paints an orthocutaneous plant on the screen.
Syntax:

TVOut.draw_rect(x,y,w,h,color);
TVOut.draw_rect(x,y,w,h,color,fillcolor);

Parameters:

x,y - coordinates of the upper left point;
w,h - width and height of the orthocutaneous plant that is being painted;
color – color between upright cuttlefish:
0 – black;
1 – white;
2 – invert color.
fillcolor – color of the grass cover:
0 – black;
1 – white;
2 – invert color.
Function draw_circle() paints on the screen.
Syntax:

TVOut.draw_circle(x,y,r,color);
TVOut.draw_circle(x,y,r,color,fillcolor);

Parameters:

x,y - coordinates to the center of the stake;
r – radius of the stake;
color – color between columns:
0 – black;
1 – white;
2 – invert color.
fillcolor – color of filling:
0 – black;
1 – white;
2 – invert color.
Function bitmap() Display a raster image on the screen.
Syntax:

TVOut.bitmap(x,y,bmp,w,h);
Parameters:

x,y – coordinates of the upper left corner of the viewpoint;
bmp – indicator of the memory array where the picture is saved;
w,h - width, height of the image to be displayed;
Below we will look at the process of creating the code for creating raster images.

Functions for displaying text information

To enable the function of displaying text information, you need to connect files with included files or fonts to the library. To connect to the set of fonts of the client, you need to include the header file in the sketches:
#include
The following font sets are included in the library's warehouse:

font4x6;
font6x8;
font8x8;
font8x8ext.
Function select_font() selects a font for displaying text information.
Syntax:

TVOut.select_font(font);
Parameters:

font – font, connected to the sketch.

The print_char() function displays a character on the screen.
Syntax:

TVOut.print_char(x,y,char);
Parameters:

x,y – position on the screen of the symbol;
char – character from the current font.

Function set_cursor() sets the cursor position for displaying text information on the screen.
Syntax:

TVOut.set_cursor(x,y);
Parameters:

x, y – coordinates of the cursor.
Function print() Display a row on the screen, a chi number symbol.
Syntax:

TVOut.print(x,y,string);
TVOut.print(x,y,char,base);
TVOut.print(x,y,int,base).

Parameters:

x, y – coordinates of the cursor.
base – display format:
BYTE = 0;
DEC = 10 (default);
HEX = 16.

Function println() display on the screen a row, a symbol or a number and at the end a symbol for the transfer of a row:
Syntax:

TVOut.println(x,y,string);
TVOut.println(x,y,char,base);
TVOut.println(x,y,int,base).

Parameters:

x, y – coordinates of the cursor.
base – display format:
BYTE = 0;
DEC = 10 (default);
HEX = 16.

Audio output functions

Sound output functions allow a song frequency signal to be sent to the TV via the audio output.
Function tone() sees an audio signal of song frequency.
Syntax:

TVOut.tone(frequency,duration);
TVOut.tone(frequency).

Parameters:

frequency – audio signal frequency;
duration – duration of the signal.
Function noTone() assigns the output of an audio signal.
Syntax:

TVOut.noTone().

Croc 2. Soldering video bases

First of all, we need to solder this board to output the video signal through the composite AV output (RCA). Let's follow the step diagram:


We connect two resistors with a nominal value of 470 ohms and 1 kohm in parallel, one to the other, and solder the “plus” to them via a tulip cable. Next, we will connect the resistor to the 470th wire of the Arduino pin, because This indicates that the video was displayed ( video), and from the resistor in one we have a wire in the ninth pin, since this indicates synchronization ( sync). And minus the tulip cable to the ground on the Arduino. More details ( English)

Krok 3. Write code (gru)

I will not explain what to include, or the necessary information, which can always be found on the Internet. I will describe those that are difficult to know what is missing.

Let's start with Vitannaya screen kudi without nyogo. But here the food is more important, what can you call this miracle? I scattered the smears and came up with - Shimo. It sounds bad, it sounds technological, it sounds Chinese, it sounds bad, but it doesn’t matter.

Let's start. Draw a line through the middle of the screen for help TV.draw_line(60,0,60,96,1);. The bag appears exactly in the center of the screen. Let's write the function yogo rukh void ballmove(int vel, int angle). Install for help TV.set_pixel(x,y,1);, I called them that.

Further, before manipulating the bag, it is necessary to update the screen, or more precisely, so that the bag does not “stay” on the screen, then when moving to the offensive position, it is necessary to fill the front with black. For which we need to write before the decision TV.set_pixel(x,y,0);. After all changes to the coordinates, it is necessary to register the already established positions and a small note - TV.delay(50);. This is approximately how you can enter:

Void ballmove(int vel, int angle) (TV.set_pixel(x,y,0); //Manipulation of coordinates TV.set_pixel(x,y,1); )

Now about changing coordinates. Usyogo in all directions (1-8), change int angle. And there it’s already simple, carefully before turning, we take away or add to the change any part of the int velocity. I did it like this:

If(angle == 1) ( y -= vel; ) if(angle == 3) ( x += vel; ) if(angle == 5) ( y += vel; ) if(angle == 7) ( x -= vel; ) if(angle == 2) ( x += round(vel/2); y -= round(vel/2); 2);y += round(vel/2); ) if(angle == 6) ( x -= round(vel/2); y += round(vel/2); ( x -= round(vel/2); y -= round(vel/2); )

Now the rackets are crashing. It’s important to clarify here - I’m a vikorist without the coordinates y, so how are the positions of the rackets? x don't change. Let's prescribe the next function void racketsmove(). Next we paint the rackets, change them int yb1, int yb2, TV.draw_line(10, yb1+8, 10, yb1-8, 1);і TV.draw_line(110, yb2+8, 110, yb2-8, 1);. Updating the screen, so that “without a trace”, is similar to dropping out of a bag.

To control the rackets, follow the buttons. Connect buttons, pins 2 і 3 - first racket, 4 і 5 - Another racket. We check the pressure of the buttons and change the coordinates.

The axis is the following function:

Void racketsmove() ( TV.draw_line(10, yb1+8, 10, yb1-8, 0); TV.draw_line(110, yb2+8, 110, yb2-8, 0); if((yb1 - 8) > 1) ( if(digitalRead(2) == HIGH) ( yb1 -= 2;) ) if((yb1 + 8)< 95) { if(digitalRead(3) == HIGH) {yb1 += 2;} } if((yb2 - 8) >1) ( if(digitalRead(4) == HIGH) (yb2 -= 2; ) ) if((yb2 + 8)< 95) { if(digitalRead(5) == HIGH) {yb2 += 2;} } TV.draw_line(10, yb1+8, 10, yb1-8, 1); TV.draw_line(110, yb2+8, 110, yb2-8, 1); }

I'll turn around now ball. Now let's write down the size of the wheel and the placement of rackets and walls. Function - void ballcol(). For which we simply check the location of the objects, and then the location. Then this cut is changed to another one. It's easy to figure out who it is.

Here is the image of the ancient city, where the fall

You can create several physical tricks for the singing areas of rackets.

Void ballcol() ( if(x == 1 || x == 119 || (x == 10 && y< (yb1 + 3) && y > < (yb2 + 3) && y > < (yb1 - 3) && y >(yb1 - 8)) ( a = 2; ) if(x == 10 && y > (yb1 + 3) && y< (yb1 + 8)) { a = 4; } if(x == 110 && y < (yb2 - 3) && y >(yb2 - 8)) ( a = 8; ) if(x == 110 && y > (yb2 + 3) && y< (yb2 + 8)) { a = 6; } if(y == 95 || y == 1) { if(a==1){a=5;}else if(a==2){a=4;}else if(a==3){a=7;}else if(a==4){a=2;}else if(a==5){a=1;}else if(a==6){a=8;}else if(a==7){a=3;}else if(a==8){a=6;} } }

As soon as possible, you can die successfully.

At the moment, we can’t only create the system for keeping score, timer and restart.

Let's finish with the timer. Change seconds float ts(it saves absolutely the entire hour), minna int tm(the number of grains that we remove from ts). Set value tm operation tm = ts/60;. І values ​​are displayed on the screen, TV.print(81,1,tm); TV.print(97,1,"."); TV.print(100,1,int(ts-(tm*60)));.

Prodovzhimo. The restart function is called void restart(). Here we turn around the coarse meanings of the changes.

Void restart() ( TV.clear_screen(); x = 60; y = 48; yb1 = 48; yb2 = 48; a = 8; ts = 900.0; c1 = 0; c2 = 0; )

The finale, the system of reward points, is so simple. We open Google and type in “Rules of table tennis”. I wonder what points are given for. We know a bit about penalties, and then we successfully know: “A point is scored if the opponent is unable to hit the ball correctly after the first jump.” The food is maturing, how can we revive the blows?.. And the blows don’t need to be revived, even our ping-pong with dual-dimensional graphics.

We know the exit from the situation and, as always, we simply check the coordinates of the side walls. As soon as there is a gap, then we aim to mark the end of the field. Function - void ballscount(). When the timer comes out, we will equal the balance of the first graver (change int c1) that of another gravel (zminna int c2), there is a loud delay, a timid shutdown and a restart.

Void ballscount() ( if(x == 1) ( c2++; ) if(x == 119) ( c1++; ) if(c1 >< c2 && ts == 0) { TV.println(10, 45, "Player 2 won!"); delay(10000); restart(); } else if(c1 == c2 && ts == 0) { TV.println(10, 45, "You are equal"); delay(10000); restart(); }

Axis and that's it, friends, we wrote the code gri. It turned out to be enough and you can lose it.


For the lazy ones, I'll just write all the code.

New script

Usyogo 218 rows. #include #include TVout TV; int x, y, a, c1, c2, yb1, yb2, tm, tsh, s; float ts; boolean paused=false; void setup() (TV.begin(NTSC, 120, 96); TV.clear_screen(); TV.select_font(font6x8); TV.println(0, 50, "Welcome to Shimo"); TV.clear_screen(); x = 60; y = 48; yb1 = 48; yb2 = 48; a = 8; ts = 900.0; s = 2; ) void loop () ( if(! (60,0,60,96,1); TV .select_font(font8x8); racketsmove(); ballscount(); TV.print(1,1,c1); ;TV.print(26,1,c2);tm = ts / 60; ts -= 0.04; if( ts< 0) { ts = 0; } TV.draw_rect(81,1,38,10,0,0); TV.print(81,1,tm); TV.print(97,1,"."); TV.print(100,1,int(ts-(tm*60))); ballcol(); /*if(ts < 600) { s = 4; } if(ts < 300) { s = 6; }*/ ballmove(s, a); TV.delay(50); if(digitalRead(6) == HIGH) { paused = true; delay(1000); } } else { TV.println(40,4,"pause"); if(digitalRead(6) == HIGH) { paused = false; delay(1000); TV.clear_screen(); } } } void ballscount() { if(x == 1) { c2++; } if(x == 119) { c1++; } if(c1 >c2 && ts == 0) ( TV.println(10, 45, "Player 1 won!"); delay(10000); restart(); ) else if(c1< c2 && ts == 0) { TV.println(10, 45, "Player 2 won!"); delay(10000); restart(); } else if(c1 == c2 && ts == 0) { TV.println(10, 45, "You are equal"); delay(10000); restart(); } } void ballcol() { if(x == 1 || x == 119 || (x == 10 && y < (yb1 + 3) && y >(yb1 - 3)) | (x == 110 && y< (yb2 + 3) && y >(yb2 - 3))) ( if(a==1)(a=5;)else if(a==2)(a=8;)else if(a==3)(a=7;)else if(a==4)(a=6;)else if(a==5)(a=1;)else if(a==6)(a=4;)else if(a==7)( a=3;)else if(a==8)(a=2;) ) if(x == 10 && y< (yb1 - 3) && y >(yb1 - 8)) ( a = 2; ) if(x == 10 && y > (yb1 + 3) && y< (yb1 + 8)) { a = 4; } if(x == 110 && y < (yb2 - 3) && y >(yb2 - 8)) ( a = 8; ) if(x == 110 && y > (yb2 + 3) && y< (yb2 + 8)) { a = 6; } if(y == 95 || y == 1) { if(a==1){a=5;}else if(a==2){a=4;}else if(a==3){a=7;}else if(a==4){a=2;}else if(a==5){a=1;}else if(a==6){a=8;}else if(a==7){a=3;}else if(a==8){a=6;} } } void racketsmove() { TV.draw_line(10, yb1+8, 10, yb1-8, 0); TV.draw_line(110, yb2+8, 110, yb2-8, 0); if((yb1 - 8) >1) ( if(digitalRead(2) == HIGH) ( yb1 -= 2; ) ) if((yb1 + 8)< 95) { if(digitalRead(3) == HIGH) { yb1 += 2; } } if((yb2 - 8) >1) ( if(digitalRead(4) == HIGH) ( yb2 -= 2; ) ) if((yb2 + 8)< 95) { if(digitalRead(5) == HIGH) { yb2 += 2; } } TV.draw_line(10, yb1+8, 10, yb1-8, 1); TV.draw_line(110, yb2+8, 110, yb2-8, 1); } void ballmove(int vel, int angle) { TV.set_pixel(x,y,0); if(angle == 1) { y -= vel; } if(angle == 3) { x += vel; } if(angle == 5) { y += vel; } if(angle == 7) { x -= vel; } if(angle == 2) { x += round(vel/2); y -= round(vel/2); } if(angle == 4) { x += round(vel/2); y += round(vel/2); } if(angle == 6) { x -= round(vel/2); y += round(vel/2); } if(angle == 8) { x -= round(vel/2); y -= round(vel/2); } TV.set_pixel(x,y,1); } void restart() { TV.clear_screen(); x = 60; y = 48; yb1 = 48; yb2 = 48; a = 8; ts = 900.0; c1 = 0; c2 = 0; }

Krok 4. Virizable body

After cutting the body on a laser cutter (or a milling cutter, I don’t know for sure) from 4mm plywood. Having painted in InkScape, I played a little and changed the format of the milling cutter.


For gamepads, I made small boards and drilled holes for the buttons. It turned out bad, but, unfortunately, I wasted the photograph.

Visnovok

In the process, a simple game was created on a TV game console on Arduino with a standard Ping Pong game with two gamepads, in which we can play and get stuck.