Сделал змейку на C в OpenGL.

This commit is contained in:
Arseniy Romenskiy 2025-07-03 20:02:17 +03:00
parent c544ad3400
commit d561cf318b
6 changed files with 492 additions and 3 deletions

2
.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
build/
*~

41
.kdev4/test.kdev4 Normal file
View file

@ -0,0 +1,41 @@
[Buildset]
BuildItems=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x01\x00\x00\x00\x0b\x00\x00\x00\x00\x01\x00\x00\x00\x08\x00t\x00e\x00s\x00t)
[CMake]
Build Directory Count=1
Current Build Directory Index-Основная система=0
[CMake][CMake Build Directory 0]
Build Directory Path=/home/romenskiy2012/projects/test/build
Build Type=Debug
CMake Binary=/usr/bin/cmake
CMake Executable=/usr/bin/cmake
Environment Profile=
Extra Arguments=
Install Directory=/usr/local
Runtime=Основная система
[Launch]
Launch Configurations=Launch Configuration 0
[Launch][Launch Configuration 0]
Configured Launch Modes=execute
Configured Launchers=nativeAppLauncher
Name=Новая конфигурация «Компилируемая программа»
Type=Native Application
[Launch][Launch Configuration 0][Data]
Arguments=
Dependencies=@Variant(\x00\x00\x00\t\x00\x00\x00\x00\x00)
Dependency Action=Nothing
EnvironmentGroup=
Executable=file:///home/romenskiy2012/projects/test
External Terminal=konsole --noclose --workdir %workdir -e %exe
Kill Before Executing Again=4194304
Project Target=test,test
Use External Terminal=true
Working Directory=
isExecutable=false
[Project]
VersionControlSupport=kdevgit

View file

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.0)
project(test)
set (CMAKE_CXX_FLAGS "-L /lib/libglut.so -lglut -lGLU -lGL")
add_executable(test main.cpp)
install(TARGETS test RUNTIME DESTINATION bin)

BIN
main Executable file

Binary file not shown.

450
main.cpp
View file

@ -1,6 +1,452 @@
#include <iostream>
#include <GL/glut.h>
#include <thread>
#include <iomanip>
//SAS_M d, m[1];
bool play = 1;
int score = 0;
float k;
//struct M = SAS_M;
unsigned char goal_direction = 0;
unsigned char map[16][16];
unsigned char direction = 0; // вверх 0 внис 1 вправо 2 влево 3
void redirection(unsigned char& s,int p){
switch (p){
case 0 :
if (direction != 1) s = 0; break;
case 1 :
if (direction != 0) s = 1; break;
case 2 :
if (direction != 3) s = 2; break;
case 3 :
if (direction != 2) s = 3; break;
}
}
//unsigned char snaik[] = {2,2};
struct snaik_tip{
unsigned char x;
unsigned char y;
struct snaik_tip *next = NULL;
};
snaik_tip snaik;
/*
Построй связанный масив для змеи, в нём будут кардинаты секций змеи
Главный масив используем только как карта, камни, края, яблоко.
Как таргетить поподение в свой хост ???
При новом рендоре, сверяем кординаты хвоста с кординатоми головы.
*/
//int spid = 1000000000;
int spid = 500000000;
float spid_multiplier = 0.01;
//int x = rand() % (0 - 15);
double i = 1.0f;
double *a = &i;
void apol(){
srand(time(NULL));
int num = 0 + rand() % (15 - 0 + 1);
int num_2 = 0 + rand() % (15 - 0 + 1);
std::cout << "num: " << num << "num_2: " << num_2 << std::endl;
map[num][num_2] = 1;
}
void apol(int& spid){
srand(time(NULL));
int num = 0 + rand() % (15 - 0 + 1);
int num_2 = 0 + rand() % (15 - 0 + 1);
std::cout << "num: " << num << "num_2: " << num_2 << std::endl;
map[num][num_2] = 1;
spid = spid / (1.1 - spid_multiplier);
//spid_multiplier = spid_multiplier + 0.05;
score = score + 100;
}
void number_bit(unsigned char x){
// https://r2ino.ru/img/cms/Lessons/Arduino-7-Segment-Display-Tutorial-Segment-Layout-Diagram%5B1%5D.png
if (x & 1){ // A 0000001
glVertex2f(0.5, 1);
glVertex2f(-0.5, 1);
}
if (x & 2){ // B 0000010
glVertex2f(0.5, 1);
glVertex2f(0.5, 0);
}
if (x & 4){ // C 0000100
glVertex2f(0.5, 0);
glVertex2f(0.5, -1);
}
if (x & 8){ // D 0001000
glVertex2f(0.5, -1);
glVertex2f(-0.5, -1);
}
if (x & 16){ // E 0010000
glVertex2f(-0.5, 0);
glVertex2f(-0.5, -1);
}
if (x & 32){ // F 0100000
glVertex2f(-0.5, 1);
glVertex2f(-0.5, 0);
}
if (x & 64){ // G 1000000
glVertex2f(0.5, 0);
glVertex2f(-0.5, 0);
}
}
void displayMe(void){
//glClearColor(0.8f,0.8f,0.0f,0.0f);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
//glClear(GL_COLOR_BUFFER_BIT);
glutPostRedisplay();
glPushMatrix();
/*
glLineWidth(5);
glBegin(GL_LINES);
glColor3f(0.1f,0.8f,0.0f);
// https://r2ino.ru/img/cms/Lessons/Arduino-7-Segment-Display-Tutorial-Segment-Layout-Diagram%5B1%5D.png
// A 0000001
glVertex2f(0.5, 1);
glVertex2f(-0.5, 1);
// B 0000010
glVertex2f(0.5, 1);
glVertex2f(0.5, 0);
// C 0000100
glVertex2f(0.5, 0);
glVertex2f(0.5, -1);
// D 0001000
glVertex2f(0.5, -1);
glVertex2f(-0.5, -1);
// E 0010000
glVertex2f(-0.5, 0);
glVertex2f(-0.5, -1);
// F 0100000
glVertex2f(-0.5, 1);
glVertex2f(-0.5, 0);
// G 1000000
glVertex2f(0.5, 0);
glVertex2f(-0.5, 0);
number(24);
*/
//glTranslatef(-1,-1,0);
//glRotatef(i,0.0f,0.0f,1.0f);
glBegin(GL_POLYGON);
//glTranslatef(-1,-1);
for (int y = 0; y != 16; y+=1){
for (int x = 0; x != 16; x+=1){
//map[y][x];
//std::cout << "y: " << float(y)/8-1 << " x :" << float(x)/8-1 << '\n';
if (map[y][x] == 1){
glLoadIdentity();
glOrtho(-k,k, -1,1, -1,1);
glTranslatef(float(x)/8-1,float(y)/8-1,0);
glBegin(GL_POLYGON);
glColor3f(0.1f,0.8f,0.0f);
glVertex2f(0, 0);
glVertex2f(0.1, 0);
glVertex2f(0.1, 0.1);
glVertex2f(0, 0.1);
}
glEnd();
}
}
//glLoadIdentity();
//glLoadIdentity();
snaik_tip* segment = &snaik;
//do {
float x = 1.0f;
while (segment != NULL){
glLoadIdentity();
glOrtho(-k,k, -1,1, -1,1);
glTranslatef(float(segment->y)/8-1,float(segment->x)/8-1,0);
glBegin(GL_POLYGON);
glColor3f(x,x,x);
glVertex2f(0, 0);
glVertex2f(0.1, 0);
glVertex2f(0.1, 0.1);
glVertex2f(0, 0.1);
if (x < 0.5) x = x - 0.01;
else x = x - 0.05;
/*
glColor3f(0.1f,0.8f,0.0f); glVertex2f(0, 0);
glColor3f(0.7f,0.0f,0.2f); glVertex2f(0.1, 0);
glColor3f(0.0f,0.1f,0.8f); glVertex2f(0.1, 0.1);
glColor3f(0.7f,0.0f,0.2f); glVertex2f(0, 0.1);
*/
glEnd();
segment = segment->next;
//printf("TEST: \n");
} //while (segment->next != NULL);
//glPushMatrix();
//glutSwapBuffers();
//double& i = &i;
//double& i += 0.1f;
//Sleep (1);
float P = 0.04f;
//int i = 82301;
// 823/10%10 = 2
int i = score;
do {
glLoadIdentity();
glOrtho(-k,k, -1,1, -1,1);
glTranslatef(1.0f-P,1.0f-0.04f,0);
glScalef(0.04,0.04,1);
P = P + 0.06f;
glLineWidth(2);
glBegin(GL_LINES);
glColor3f(0.1f,0.8f,0.0f);
switch (i%10){
case 1 : number_bit(6); break;
case 2 : number_bit(91); break;
case 3 : number_bit(79); break;
case 4 : number_bit(102); break;
case 5 : number_bit(109); break;
case 6 : number_bit(125); break;
case 7 : number_bit(7); break;
case 8 : number_bit(127); break;
case 9 : number_bit(111); break;
case 0 : number_bit(63); break;
}
i = i / 10;
glEnd();
}while (i >= 1);
glLoadIdentity();
glOrtho(-k,k, -1,1, -1,1);
glLineWidth(2);
glBegin(GL_LINES);
glVertex2f(1, -1);
glVertex2f(-1, -1);
glVertex2f(1, 1);
glVertex2f(-1, 1);
glVertex2f(1, -1);
glVertex2f(1, 1);
glVertex2f(-1, -1);
glVertex2f(-1, 1);
glEnd();
glutSwapBuffers();
//glPushMatrix();
glFlush();
//std::this_thread::sleep_for(std::chrono::nanoseconds(spid));
}
void TEST(int key, int x, int y){
printf("goal_direction: %i\n", goal_direction);
switch (key){
case 100 : printf("GLUT_KEY_LEFT %d\n",key) ; redirection(goal_direction, 3); break;
case 102 : printf("GLUT_KEY_RIGHT %d\n",key); redirection(goal_direction, 2); break;
case 101 : printf("GLUT_KEY_UP %d\n",key) ; redirection(goal_direction, 0); break;
case 103 : printf("GLUT_KEY_DOWN %d\n",key) ; redirection(goal_direction, 1); break;
}
}
void callback(const std::string& data){
std::cout << "Callback called because: " << data << '\n';
}
/*
1 2 3 4 5
A = 1
x = A_1->x # 1
x_2 = A->next->x # 2
A->next->x = x # 1 1 3 4 5
x = x_2 # 2
A = A->next # 1
x_2 = A->next->x # 3
A_1 = A_1->next
A_2 = A_2->next
A_2->x = x # 1 1 2 4 5
A_1->x = A_1->next->x# 2 2 3 4 5
A_1 = A_1->next # 2
A_1->x = A_1->next->x# 2 3 3 4 5
A_1 = A_3 # 2 2 3 4 5
A_3 = A_3->next
"
A_1 = 2
A_2 = 1
A_3 = 3
"
A_1 = A_3 # 2 2 3 4 5
*/
void tail(bool& play){
snaik_tip* segment = &snaik;
unsigned char cord[2][2];
cord[0][0] = segment->x;
cord[0][1] = segment->y;
int x = 0;
printf("snaik: x=%i, y=%i\n", snaik.y, snaik.x);
unsigned char head_x = segment->x, head_y = segment->y;
while (segment->next != NULL){
cord[1][0] = segment->next->x;
cord[1][1] = segment->next->y;
printf("tail x: %i y: %i\n", segment->x, segment->y);
std::cout << "ID: " << segment << '\n';
segment->next->x = cord[0][0];
segment->next->y = cord[0][1];
if (cord[1][0] == head_x and cord[1][1] == head_y){
printf("GAME OWER!!!\nGAME OWER!!!\nGAME OWER!!!\nGAME OWER!!!\nGAME OWER!!!\nGAME OWER!!!\nGAME OWER!!!\n");
printf("segment x: %i y: %i ID: %i\n", cord[1][0], cord[1][1], x);
printf("head x: %i y: %i\n", head_x, head_y);
play = 0;
}
cord[0][0] = cord[1][0];
cord[0][1] = cord[1][1];
segment = segment->next;
x++;
}
printf("\n-------------------------------\n");
}
/*
void tail(){
snaik_tip* segment_l1 = &snaik;
snaik_tip* segment_l2 = segment_l1->next;
snaik_tip* segment_l3 = segment_l1->next;
while (segment_l3 != NULL){
printf("LLLLL x: %i y: %i\n", segment_l1->x, segment_l1->y);
std::cout << "NNNN: " << segment_l1 << '\n';
segment_l3->x = segment_l1->x;
segment_l3->y = segment_l1->y;
segment_l1 = segment_l3;
segment_l2 = segment_l1->next;
}
}
*/
void task(void){
while (play){
std::this_thread::sleep_for(std::chrono::nanoseconds(spid));
//displayMe();
//SAS_s(i);
tail(play);
direction = goal_direction;
switch (goal_direction){
case 0 :
snaik.x = snaik.x + 1;
if (snaik.x == 16) snaik.x = 0;
break;
case 1 :
if (snaik.x == 0) snaik.x = 16;
snaik.x = snaik.x - 1;
break;
case 2 :
snaik.y = snaik.y + 1;
if (snaik.y == 16) snaik.y = 0;
break;
case 3 :
if (snaik.y == 0) snaik.y = 16;
snaik.y = snaik.y - 1;
break;
}
//if (snaik[1] == -1) snaik[1] = 16;
//else if (snaik[0] == -1) snaik[0] = 16;
//else else if (snaik[1] == 15) snaik[1] = 0;
//else if (snaik[0] == 15) snaik[0] = 0;
printf("snaik: x=%i, y=%i\n", snaik.y, snaik.x);
std::cout << "TEST: " << snaik.next << '\n';
if (map[snaik.x][snaik.y] == 1){
map[snaik.x][snaik.y] = 0;
apol(spid);
//snaik_tip *q;
//q = (snaik_tip *) malloc(sizeof(snaik_tip));
//q->x = 4;
//q->y = 4;
//snaik.next = q;
snaik_tip* segment = &snaik;
while (segment != NULL){
if (segment->next == NULL){
snaik_tip *q;
q = (snaik_tip *) malloc(sizeof(snaik_tip));
/*
q->x = segment->x;
q->y = segment->y;
*/
// Костыль для первого элемента.
q->x = 16;
q->y = 16;
segment->next = q;
segment = q;
}
segment = segment->next;
}
}
//waitEvent();
printf("SAS %i\n", goal_direction);
//std::cout << "goal_direction: " << goal_direction << '\n';
}
//callback("async task done");
}
void ChangeWindow(int width, int height){
printf("width: %i width: %i\n", width, height);
glViewport(0,0, width, height);
glLoadIdentity();
k = width / (float)height;
glOrtho(-k,k, -1,1, -1,1);
}
int main(int argc, char** argv)
{
snaik.x = 2;
snaik.y = 2;
for (int x = 0; x != 15; x+=1){
for (int i = 0; i != 15; i+=1){
map[x][i] = 0;
}
}
apol();
//GetKeyState(VK_UP);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_SINGLE);
glutInitWindowSize(800, 800);
glutInitWindowPosition(100, 100);
glutCreateWindow("Hello world!");
glutDisplayFunc(displayMe);
glutReshapeFunc(ChangeWindow);
std::thread bt(task);
glutSpecialFunc(TEST);
glutMainLoop();
int main(int argc, char **argv) {
std::cout << "Hello, world!" << std::endl;
return 0;
}

BIN
main222 Executable file

Binary file not shown.