diff --git a/P01_runningletter.c b/P01_runningletter.c new file mode 100644 index 00000000..078a440b --- /dev/null +++ b/P01_runningletter.c @@ -0,0 +1,30 @@ +#include +#include +#define SPACE 50 + +void show(char *pos); + +int main() +{ + char pos[102] = { " " }; + + for(int i=0;i<100;i++) + { + pos[i] = 'R'; + show(pos); + pos[i] = ' '; + if(i==99) //字母碰到边界时变为递减 + for(;i>=0;i--) + { + pos[i] = 'R'; + show(pos); + pos[i] = ' '; + } + } + return 0; +} +void show(char *pos) { + printf("%s", pos); + Sleep(SPACE); + system("cls"); +} diff --git a/P02_isprime.c b/P02_isprime.c new file mode 100644 index 00000000..3a8ef76c --- /dev/null +++ b/P02_isprime.c @@ -0,0 +1,39 @@ +#include +#include +int IS(int); //判断是否为素数 + +int main() { + int x; + + printf("输入一个正整数,程序判断它是否为素数(q to quit):"); + while (scanf_s("%d", &x)) + { + if (x == 1 || x == 2) + { + puts("是素数"); + } + else if (IS(x)) + puts("是素数."); + else puts("不是素数."); + printf("输入一个正整数,程序判断它是否为素数(q to quit):"); + } + system("pause"); + return 0; +} +int IS(int x) +{ + int i; + int mark = 0; //创建标记 + + for (i = 2; i < x; i++) + { + if (x%i == 0) + { + mark = 1; //若被整除,标记mark为1 + break; + } + } + if (mark == 1) + return 0; + else return 1; +} diff --git a/Stack/Stack.cpp b/Stack/Stack.cpp new file mode 100644 index 00000000..ccdf9286 --- /dev/null +++ b/Stack/Stack.cpp @@ -0,0 +1,38 @@ +#include +#include"Stack.h" + +using namespace std; + +void Stack::push(int item) +{ + this->item[pos] = item; + pos++; +} + +void Stack::pop() +{ + cout << "pop " << item[pos-1]< +#include"Stack.h" + +using namespace std; + +void main() +{ + Stack s; + + char ch; + + while (1) + { + cin >> ch; + switch (ch) + { + case'p': + if (!s.IsFull()) + { + cout << "push: "; + int tem; + cin >> tem; + s.push(tem); + } + else cout << "Full"; + break; + case'o': + if (!s.IsEmpty()) + { + s.pop(); + } + else cout << "Empty"; + break; + case's': + if(!s.IsEmpty()) + s.show(); + else cout << "Empty" << endl; + break; + } + + } +} \ No newline at end of file diff --git a/cpp/Clock/Clock.cpp b/cpp/Clock/Clock.cpp new file mode 100644 index 00000000..3009002e --- /dev/null +++ b/cpp/Clock/Clock.cpp @@ -0,0 +1,73 @@ +#include"Clock.h" +#include +#include +#include + +void Clock::SetTime(int h, int m,int s) +{ + this->h = h; + this->m = m; + this->s = s; +} + +void Clock::operate() +{ + + + using namespace std; + + time_t t1, t2; + t1 = clock(); + + int ds, dm, dh; + time_t delta_t; + + while (1) + { + Sleep(500); + t2 = clock(); + + delta_t = (t2 - t1) / CLOCKS_PER_SEC; + + ps = (s + delta_t) % 60; + pm = ((s + delta_t) / 60 + m) % 60; + ph = ((((s + delta_t) / 60) + m) / 60 + h) % 24; + + to_xy(10, 10); + + cout.width(2); + cout << ph << ":"; + cout.width(2); + cout << pm << ":"; + cout.width(2); + cout<< ps; + + + + } +} + +void AlarmClock::SetAlarm(int h, int m, int s, bool alarm) +{ + ah = h; + am = m; + as = s; + this->alarm = alarm; +} +void AlarmClock::Alarm() +{ + if ((ah == h&&am == m&&as == s) && alarm == true) + { + puts("AAAAAAAA"); + } +} + +void to_xy(int x, int y) //ָ +{ + HANDLE hout; + COORD coord; + coord.X = x; + coord.Y = y; + hout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(hout, coord); +} \ No newline at end of file diff --git a/cpp/Clock/Clock.h b/cpp/Clock/Clock.h new file mode 100644 index 00000000..e55976d4 --- /dev/null +++ b/cpp/Clock/Clock.h @@ -0,0 +1,33 @@ +#ifndef CLOCK_H_ +#define CLOCK_H_ + +class Clock +{ +private: + int h, m, s; //ʼʱ + int ps, pm, ph; //ǰʱ +public: + friend class AlarmClock; + Clock(int h, int m, int s) { this->h = h; this->m = m; this->s = s; ps = s; pm = m; ph = h; } + void SetTime(int h, int m,int s); + void operate(); +}; + +class AlarmClock :public Clock +{ +private: + int ah; + int am; + int as; + bool alarm; + +public: + friend class Clock; + AlarmClock(int h, int m, int s) :Clock(h, m, s) { alarm = false; } + void SetAlarm(int h, int m, int s,bool alarm); + void Alarm(); +}; + +void to_xy(int x, int y); + +#endif diff --git a/cpp/Clock/mian.cpp b/cpp/Clock/mian.cpp new file mode 100644 index 00000000..a1855b51 --- /dev/null +++ b/cpp/Clock/mian.cpp @@ -0,0 +1,10 @@ +#include +#include"Clock.h" + + +void main() +{ + AlarmClock aclock(11, 8, 20); + aclock.SetAlarm(12, 0, 0, 0); + aclock.operate(); +} \ No newline at end of file diff --git a/cpp/p01_Queue/Queue.cpp b/cpp/p01_Queue/Queue.cpp new file mode 100644 index 00000000..bb73c43d --- /dev/null +++ b/cpp/p01_Queue/Queue.cpp @@ -0,0 +1,54 @@ +#include +#include"Queue.h" +#define WIDTH 100 + +using namespace std; + +void Queue::append(int item) +{ + + + rear++; + if (rear == WIDTH + 1) rear = 0; + this->item[rear] = item; + + + + +} +void Queue::pop() +{ + cout << item[front + 1] << "pop" << endl; + + front++; + if (front == WIDTH + 1) front = 0; + + + +} + +int Queue::IsFull() +{ + int temp; + rear == WIDTH ? temp = -1 : temp = rear; + return (temp + 1) == front; +} + +int Queue::IsEmpty() +{ + return rear == front; +} + +void Queue::show() +{ + for (int i = front + 1; i != rear + 1; i++) //i为当前访问的item + { + if (i > WIDTH) i = 0; //处理front在数组尾情况,此时i不对应item,将i设为0指向数组首端 + + cout << item[i]; + + if (i == WIDTH && rear != WIDTH) //处理rear在数组尾情况 + i = -1; + + } +} \ No newline at end of file diff --git a/cpp/p01_Queue/Queue.h b/cpp/p01_Queue/Queue.h new file mode 100644 index 00000000..fd390fdb --- /dev/null +++ b/cpp/p01_Queue/Queue.h @@ -0,0 +1,21 @@ +#ifndef Queue_H_ +#define Queue_H_ + +#define WIDTH 100 + +class Queue +{ +private: + int item[WIDTH + 1]; + int front = 0; //front+1是队列首元 + int rear = 0; + +public: + void append(int item); + void pop(); + int IsFull(); + int IsEmpty(); + void show(); +}; + +#endif \ No newline at end of file diff --git a/cpp/p01_Queue/p01_Queue.cpp b/cpp/p01_Queue/p01_Queue.cpp new file mode 100644 index 00000000..34392272 --- /dev/null +++ b/cpp/p01_Queue/p01_Queue.cpp @@ -0,0 +1,46 @@ +#include +#include +#include"Queue.h" + +#define WIDTH 100 + +using namespace std; + + +int main() +{ + Queue queue; + + char ch; + int item; + while (1) + { + + cin >> ch; + switch (ch) + { + case'a': + if (!queue.IsFull()) + { + cout << "add:"; + cin >> item; + queue.append(item); + } + else cout << "full" << endl; + break; + case'p': + if (!queue.IsEmpty()) + { + queue.pop(); + cout << endl; + } + else cout << "empty" << endl; + break; + case's': + queue.show(); + cout << endl; + } + } + return 0; +} + diff --git a/cpp/p02_Stack/Stack.cpp b/cpp/p02_Stack/Stack.cpp new file mode 100644 index 00000000..ccdf9286 --- /dev/null +++ b/cpp/p02_Stack/Stack.cpp @@ -0,0 +1,38 @@ +#include +#include"Stack.h" + +using namespace std; + +void Stack::push(int item) +{ + this->item[pos] = item; + pos++; +} + +void Stack::pop() +{ + cout << "pop " << item[pos-1]< +#include"Stack.h" + +using namespace std; + +void main() +{ + Stack s; + + char ch; + + while (1) + { + cin >> ch; + switch (ch) + { + case'p': + if (!s.IsFull()) + { + cout << "push: "; + int tem; + cin >> tem; + s.push(tem); + } + else cout << "Full"; + break; + case'o': + if (!s.IsEmpty()) + { + s.pop(); + } + else cout << "Empty"; + break; + case's': + if(!s.IsEmpty()) + s.show(); + else cout << "Empty" << endl; + break; + } + + } +} \ No newline at end of file diff --git a/cpp/p03_SafeArray/SafeArray.cpp b/cpp/p03_SafeArray/SafeArray.cpp new file mode 100644 index 00000000..89425ae7 --- /dev/null +++ b/cpp/p03_SafeArray/SafeArray.cpp @@ -0,0 +1,20 @@ +#include +#include"SafeArray.h" + +using namespace std; + +void Array::visit(int pos, int& visitor) +{ + if (pos > len) + cout << "over edge" << endl; + else + visitor = *(pt + pos); +}; + +void Array::change(int pos, int value) +{ + if (pos > len) + cout << "over edge" << endl; + else + *(pt + pos) = value; +} diff --git a/cpp/p03_SafeArray/SafeArray.h b/cpp/p03_SafeArray/SafeArray.h new file mode 100644 index 00000000..ae25ea06 --- /dev/null +++ b/cpp/p03_SafeArray/SafeArray.h @@ -0,0 +1,29 @@ +#ifndef SAFEARRAR_H_ +#define SAFEARRAY_H_ + +class Array +{ + +public: + void visit(int pos, int& visitor); //posλõֵvisitor + void change(int pos, int value); //valueֵposλ + Array(int len) + { + pt = new int(len); + this->len = len; + + for (int i = 0; i < len; i++) //ʼ + { + *(pt + i) = 0; + } + }; + +private: + + int* pt; + int len; + +}; + +#endif + diff --git a/cpp/p03_SafeArray/p03_SafeArry.cpp b/cpp/p03_SafeArray/p03_SafeArry.cpp new file mode 100644 index 00000000..a3ae76ad --- /dev/null +++ b/cpp/p03_SafeArray/p03_SafeArry.cpp @@ -0,0 +1,45 @@ +#include +#include"SafeArray.h" + +using namespace std; + + +void main() +{ + int pos, value; + + cout << "len of array:"; + cin >> pos; + Array array(pos); + + char ch; + + while (1) + { + cout << "v to visit, c to change:" << endl; + + cin >> ch; + switch (ch) + { + case'v': + cout << "pos in array:" << endl; + cin >> pos; + array.visit(pos,value); + cout <<"the value is:"<> pos; + cout << "value to change:" << endl; + cin >> value; + array.change(pos, value); + break; + } + + cout << endl; + } + + + + system("pause"); +} \ No newline at end of file diff --git a/cpp/p04_cppScoreManagement/Stu.cpp b/cpp/p04_cppScoreManagement/Stu.cpp new file mode 100644 index 00000000..a63f3574 --- /dev/null +++ b/cpp/p04_cppScoreManagement/Stu.cpp @@ -0,0 +1,317 @@ +#include +#include"Stu.h" + +using namespace std; + +void Stu::AddName(char* name) +{ + strcpy_s(this->name,11,name); +} + +void Stu::AddCourse(char* course) +{ + strcpy_s(this->course,11, course); +} + +void Stu::AddScore(int score) +{ + this->score = score; +} + + +void Stu::info() +{ + cout <<"student info: "<< endl << "name: " << this->name << " " << "course: " << this->course << " " << "score: " << this->score << endl; +} + +void Queue::AddStu() +{ + Stu* pt = new Stu; + count++; + + if (front == NULL) + front = pt; + else + rear->next = pt; + + rear = pt; + + char temp[11] ; + cout << "name:"; + cin.get(temp,11); + + for (int i = 0; i < 11; i++) + { + if (temp[i] == ' ') + { + temp[i] = '\0'; + break; + } + } + + while (cin.get() != '\n'); + pt->AddName(temp); + cout << "course: "; + cin.get(temp, 11); + for (int i = 0; i < 11; i++) + { + if (temp[i] == ' ') + { + temp[i] = '\0'; + break; + } + } + while (cin.get() != '\n'); + pt->AddCourse(temp); + cout << "score:"; + int score; + cin >> score; + pt->AddScore(score); + + +} + + +Stu* Queue::find(char* name) +{ + Stu* pre=front; + for (Stu* pt = front; pt != NULL; pt = pt->next) + { + if (strcmp(name, pt->name) == 0) + { + pt->info(); + return pre; //preĿѧǰһ,Ŀڶףpre==pt + } + pre = pt; + } + cout << "no such student" << endl; + return NULL; +} + + +void Queue::DelStu(char* name) +{ + if (strcmp(name, front->name) == 0) //ڶ + { + Stu* temp = front; + front->info(); + front = front->next; + delete(temp); + } + else + { + Stu*pt = find(name); //ptĿѧǰһ + if (pt != NULL) + { + if (pt->next->next == NULL) //Ŀڶβ + { + rear = pt; + delete(pt->next); + pt->next = NULL; + } + else + { + Stu* del = pt->next; + pt->next = pt->next->next; + delete(del); + } + + } + } + cout << "is deleted." << endl; +} + +void Queue::list() +{ + if (front == NULL) + + cout << "empty list." << endl; + else + { + for (Stu* temp = front; temp != NULL; temp = temp->next) + cout << "name: " << temp->name << " " << "course: " << temp->course << " " << "score: " << temp->score << endl; + } +} + +void Queue::menu() +{ + cout << endl << "'a' to add stuent, 'c' to change info, 'd' to delete student, 'f' to find student,\n'l' to list all students, 's' to sort by score, 'q' to save and quit." << endl; +} + +void Queue::ChangeInfo() +{ + + + if (front == NULL) + cout << "empty list" << endl; + else + { + cout << "name to change: "; + char temp[11]; + cin.get(temp, 11); + for (int i = 0; i < 11; i++) + { + if (temp[i] == ' ') + { + temp[i] = '\0'; + break; + } + } + + while (cin.get() != '\n'); + if (strcmp(temp, front->name) == 0) //ڶ + { + cout << "name: "; + cin.get(temp, 11); + for (int i = 0; i < 11; i++) + { + if (temp[i] == ' ') + { + temp[i] = '\0'; + break; + } + } + + while (cin.get() != '\n'); + front->AddName(temp); + cout << "course: "; + cin.get(temp, 11); + for (int i = 0; i < 11; i++) + { + if (temp[i] == ' ') + { + temp[i] = '\0'; + break; + } + } + + while (cin.get() != '\n'); + front->AddCourse(temp); + cout << "score: "; + int score; + cin >> score; + front->AddScore(score); + } + else + { + Stu* pt = find(temp); + + cout << "name: "; + cin.get(temp, 11); + for (int i = 0; i < 11; i++) + { + if (temp[i] == ' ') + { + temp[i] = '\0'; + break; + } + } + + while (cin.get() != '\n'); + pt->next->AddName(temp); + cout << "course: "; + cin.get(temp, 11); + for (int i = 0; i < 11; i++) + { + if (temp[i] == ' ') + { + temp[i] = '\0'; + break; + } + } + + while (cin.get() != '\n'); + pt->next->AddCourse(temp); + cout << "score: "; + int score; + cin >> score; + pt->next->AddScore(score); + } + } +} + +void Queue::load(FILE* pt) +{ + char temp[11]; + while (fscanf_s(pt, "%s", temp,10)!=EOF) + { + AddStu(pt,temp); + count++; + } +} + +void Queue::AddStu(FILE* pt,char* name) +{ + Stu* temp = new Stu; + + if (front == NULL) + front = temp; + else + rear->next = temp; + + rear = temp; + + char course[11]; + int score; + fscanf_s(pt, "%s", course,10); + fscanf_s(pt, "%d", &score); + temp->AddName(name); + temp->AddCourse(course); + temp->AddScore(score); +} + +void Queue::save(FILE* pt) +{ + for (Stu* temp = front; temp != NULL; temp = temp->next) + { + fprintf(pt, "%s ", temp->name); + fprintf(pt, "%s ", temp->course); + fprintf(pt, "%d ", temp->score); + fprintf(pt, "%c", '\n'); + } +} + +void Queue::sort() +{ + int n = count; + + struct room + { + char name[11]; + char course[11]; + int score; + }; + struct room* pt = new struct room[n]; + + int i = 0; + for (Stu* temp = front; temp != NULL; temp = temp->next) + { + strcpy_s((pt + i)->name,temp->name); + strcpy_s((pt + i)->course,temp->course); + (pt + i)->score = temp->score; + i++; + } + + for (int i = 0; iscore < (pt+j+1)->score) + { + struct room temp = *(pt+j); + *(pt + j) = *(pt + j + 1); + *(pt + j + 1) = temp; + } + } + } + + i = 0; + for (Stu* temp = front; temp != NULL; temp = temp->next) + { + temp->AddName((pt + i)->name); + temp->AddCourse((pt + i)->course); + temp->score = (pt+i)->score; + i++; + } + +} \ No newline at end of file diff --git a/cpp/p04_cppScoreManagement/Stu.h b/cpp/p04_cppScoreManagement/Stu.h new file mode 100644 index 00000000..f04cd3c5 --- /dev/null +++ b/cpp/p04_cppScoreManagement/Stu.h @@ -0,0 +1,60 @@ +#include +#ifndef STU_H_ +#define STU_H_ + +class Stu; +class Queue +{ +public: + + + friend class Stu; + + + void list(); + void AddStu(); + void AddStu(FILE* pt,char* name); + void DelStu(char* name); + Stu* find(char* name); + void ChangeInfo(); + void load(FILE* pt); + void save(FILE* pt); + void sort(); + + void menu(); + Queue() + { + count = 0; + front = rear = NULL; + } +private: + Stu* front; + Stu* rear; + int count; +}; + +class Stu +{ +private: + char name[11]; + char course[11]; + int score; + Stu* next; + + +public: + friend class Queue; + + void AddName(char* name); + void AddCourse(char* course); + void AddScore(int score); + + void info(); + + Stu() + { + this->next = NULL; + } +}; + +#endif \ No newline at end of file diff --git a/cpp/p04_cppScoreManagement/ToDoList.txt b/cpp/p04_cppScoreManagement/ToDoList.txt new file mode 100644 index 00000000..b861c885 --- /dev/null +++ b/cpp/p04_cppScoreManagement/ToDoList.txt @@ -0,0 +1,11 @@ +1.ʵstudent + γ̣ +2.ʵֶ + +3.ʵֻ + ӣɾѧ¼Ϣ޸Ϣ +4.ļ + +5.ӹ + ѯ +6. \ No newline at end of file diff --git a/cpp/p04_cppScoreManagement/p04_cppScoreManagement.cpp b/cpp/p04_cppScoreManagement/p04_cppScoreManagement.cpp new file mode 100644 index 00000000..fdf29fe1 --- /dev/null +++ b/cpp/p04_cppScoreManagement/p04_cppScoreManagement.cpp @@ -0,0 +1,65 @@ +#include +#include"Stu.h" + + + +using namespace std; + +void main() +{ + FILE* pt; + if (fopen_s(&pt, "info.txt", "r") != 0) + cout << "can not open file." << endl; + + Queue pq; + + pq.load(pt); + fclose(pt); + + pq.menu(); + char ch; + cin >> ch; + while (cin.get() != '\n'); + + + char name[11]; + + while (ch != 'q') + { + + switch (ch) + { + case'a': + pq.AddStu(); + break; + case'd': + cout << "name:"; + cin >> name; + pq.DelStu(name); + break; + case'l': + pq.list(); + break; + case'f': + cout << "name:"; + cin >> name; + pq.find(name); + break; + case'c': + pq.ChangeInfo(); + break; + case's': + pq.sort(); + } + pq.menu(); + cin >> ch; + while (cin.get() != '\n'); + } + + if (fopen_s(&pt, "info.txt", "w") != 0) + cout << "can not save info." << endl; + pq.save(pt); + fclose(pt); + + getchar(); +} diff --git a/cpp/p05_Canvas/Shape.cpp b/cpp/p05_Canvas/Shape.cpp new file mode 100644 index 00000000..c1f93673 --- /dev/null +++ b/cpp/p05_Canvas/Shape.cpp @@ -0,0 +1,35 @@ +#include"Shape.h" + +void Shape::show() +{ + cout << "location:" << x << " " << y << endl; +} + +void Shape::move(int x , int y) +{ + this-> x= x; + this-> y = y; +} +void Circle::show() +{ + Shape::show(); + cout << "type:" << type << " r=" << r << endl; + +} + +void Rect::show() +{ + Shape::show(); + cout << "type: " << type << " a=" << a << " b=" << b << endl; +} + +void Circle::change() +{ + this->r = 8; +} + +void Rect::change() +{ + this->a = 7; + this->b = 8; +} \ No newline at end of file diff --git a/cpp/p05_Canvas/Shape.h b/cpp/p05_Canvas/Shape.h new file mode 100644 index 00000000..24a6e23b --- /dev/null +++ b/cpp/p05_Canvas/Shape.h @@ -0,0 +1,42 @@ +#ifndef SHAPE_H_ +#define SHAPE_H_ +#include + +using namespace std; + +class Shape +{ +public: + Shape(int x = 0,int y = 0) { this->x = x; this->y = y; } + void move(int x, int y); + virtual void show() = 0; + virtual void change() = 0; +private: + int x, y; + +}; + +class Circle : public Shape +{ +public: + void change(); + void show(); + Circle(int x = 0, int y = 0, int r = 0) :Shape(x, y) { this->r = r; } +private: + char* type = "Circle"; + int r; +}; + +class Rect : public Shape +{ +public: + void change(); + void show(); + Rect(int x, int y, int a, int b) :Shape(x, y) { this->a = a; this->b = b; } +private: + char* type = "Rect"; + int a; + int b; +}; + +#endif diff --git a/cpp/p05_Canvas/main.cpp b/cpp/p05_Canvas/main.cpp new file mode 100644 index 00000000..cf38b249 --- /dev/null +++ b/cpp/p05_Canvas/main.cpp @@ -0,0 +1,20 @@ +#include +#include"Shape.h" + +void main() +{ + Shape* pt[2]; + + Circle c(5, 5, 2); + pt[0] = &c; + pt[0]->change(); + pt[0]->move(8, 7); + pt[0]->show(); + + Rect r(5, 5, 6, 10); + pt[1] = &r; + pt[1]->change(); + pt[1]->move(6, 7); + pt[1]->show(); + +} \ No newline at end of file diff --git a/cpp/p06_CircleAndPoint/Point.cpp b/cpp/p06_CircleAndPoint/Point.cpp new file mode 100644 index 00000000..4934106b --- /dev/null +++ b/cpp/p06_CircleAndPoint/Point.cpp @@ -0,0 +1,35 @@ +#include"point.h" + +void Point::MovePoint(int x, int y) +{ + this->x = x; + this->y = y; +} + +void Circle::move(int x, int y) +{ + this->pt.MovePoint(x, y); +} + +void Circle::ChangeR(int r) +{ + this->r = r; +} + +/*void Circle::show() +{ + int x = pt->x; + int y = pt->y; + + for (int i = x - r; i < x + r; i++) + { + for (int j = y - r; j < y + y; j++) + { + if () + { + cout << "*"; + } + } + } +} +*/ \ No newline at end of file diff --git a/cpp/p06_CircleAndPoint/p06_CircleAndPoint.cpp b/cpp/p06_CircleAndPoint/p06_CircleAndPoint.cpp new file mode 100644 index 00000000..ad208744 --- /dev/null +++ b/cpp/p06_CircleAndPoint/p06_CircleAndPoint.cpp @@ -0,0 +1,10 @@ +#include +#include"point.h" + +void main() +{ + Circle circle(10, 10, 5); + circle.move(20, 20); + circle.ChangeR(10); + +} \ No newline at end of file diff --git a/cpp/p06_CircleAndPoint/point.h b/cpp/p06_CircleAndPoint/point.h new file mode 100644 index 00000000..77000e91 --- /dev/null +++ b/cpp/p06_CircleAndPoint/point.h @@ -0,0 +1,30 @@ +#ifndef POINT_H_ +#define POINT_H_ + +class Point +{ +public: + void MovePoint(int x, int y); + Point(int x=0,int y=0) { this->x = 0; this->y = 0; } + + friend class Circle; +private: + int x; + int y; + +}; + +class Circle +{ +public: +// void show(); + void move(int x, int y); + void ChangeR(int r); + Circle(int x=0, int y=0, int r=0) { pt.x = x; pt.y = y; this->r = r; } + +private: + int r; + Point pt; +}; + +#endif diff --git a/cpp/p07_Circuit/Circuit.cpp b/cpp/p07_Circuit/Circuit.cpp new file mode 100644 index 00000000..cf1406ab --- /dev/null +++ b/cpp/p07_Circuit/Circuit.cpp @@ -0,0 +1,85 @@ +#include"Circuit.h" +#include + +using namespace std; + +void Circuit::AddUnit(int unit,int slot) +{ + switch (unit) + { + case 0: + pt[slot] = new Light(unit,slot); + count++; + break; + case 1: + pt[slot] = new Motor(unit,slot); + count++; + break; + } + +} + +void Circuit::show() +{ + for (int i = 0; i < count; i++) + { + + } +} + +void Unit::TurnSwitch(bool isOn) +{ + Switch = isOn; +} + +int Unit::isON() +{ + return Switch == 1; +} + +void Light::ChangeType(int type) +{ + this->type = type; +} + +void Light::show() +{ + cout << "light type: " << type << endl; + switch (type) + { + case 1: + cout << "10W" << endl; + break; + case 2: + cout << "20W" << endl; + } + + + + switch (isON()) + { + case 1: + cout << " is on" << endl; + break; + case 0: + cout << " is off" << endl; + } +} + +void Motor::ChangeType(int n) +{ + type = n; +} + +void Motor::show() +{ + cout << "motor type: " << type << endl; + switch (type) + { + case 1: + cout << "1000r" << endl; + break; + case 2: + cout << "2000r" << endl; + } +} diff --git a/cpp/p07_Circuit/Circuit.h b/cpp/p07_Circuit/Circuit.h new file mode 100644 index 00000000..28b912f6 --- /dev/null +++ b/cpp/p07_Circuit/Circuit.h @@ -0,0 +1,54 @@ +#ifndef CIRCUIT_H_ +#define CIRCUIT_H_ + +class Unit; + +class Circuit +{ +public: + Unit* pt[20]; + void show(); + void AddUnit(int unit,int slot); + Circuit() { count = 0; } +private: + int count; + +}; + +class Unit +{ +private: + bool Switch; + int slot; +public: + virtual void show() = 0; + virtual void ChangeType(int type) = 0; + void TurnSwitch(bool isOn); + int isON(); + Unit(int slot) { this->slot = slot; this->Switch = 0; } +}; + +class Light:public Unit +{ +public: + Light(int type,int slot):Unit(slot) + { + this->type = type; + } + void show(); + void ChangeType(int n); +private: + int type; +}; + +class Motor:public Unit +{ +public: + void show(); + void ChangeType(int n); + Motor(int type,int slot):Unit(slot) { this->type = type; } +private: + int type; +}; + +#endif diff --git a/cpp/p07_Circuit/mian.cpp b/cpp/p07_Circuit/mian.cpp new file mode 100644 index 00000000..c932a733 --- /dev/null +++ b/cpp/p07_Circuit/mian.cpp @@ -0,0 +1,8 @@ +#include"Circuit.h" + +void main() +{ + Circuit cc; + cc.AddUnit(0,1); + cc.pt[1]->show(); +} \ No newline at end of file diff --git a/cpp/p09_Tree/Node.cpp b/cpp/p09_Tree/Node.cpp new file mode 100644 index 00000000..1e19c154 --- /dev/null +++ b/cpp/p09_Tree/Node.cpp @@ -0,0 +1,10 @@ +#include"Node.h" +#include + +Node::Node(Node* parent, int value) +{ + this->value = value; + this->parent = parent; + left = right = NULL; + +} \ No newline at end of file diff --git a/cpp/p09_Tree/Node.h b/cpp/p09_Tree/Node.h new file mode 100644 index 00000000..43e60f51 --- /dev/null +++ b/cpp/p09_Tree/Node.h @@ -0,0 +1,18 @@ +#ifndef NODE_H_ +#define NODE_H_ + + +class Node +{ +public: + Node(Node* parent, int value = 0); + friend class Tree; +private: + Node* left; + Node* right; + Node* parent; + int value; + +}; + +#endif diff --git a/cpp/p09_Tree/Tree.cpp b/cpp/p09_Tree/Tree.cpp new file mode 100644 index 00000000..7fd9ab95 --- /dev/null +++ b/cpp/p09_Tree/Tree.cpp @@ -0,0 +1,104 @@ +#include"Tree.h" + +using namespace std; + +Tree::Tree() +{ + count = 0; + root = NULL; + +} + +void Tree::append(int value) +{ + Node* temp=root; + if (root == NULL) + { + root = new Node(root,value); + count++; + } + else + { + while (1) + { + if (value > temp->value) + { + if (temp->right == NULL) + { + temp->right = new Node(temp, value); + count++; + break; + } + temp = temp->right; + } + else if (value < temp->value) + { + if (temp->left == NULL) + { + temp->left = new Node(temp, value); + count++; + break; + } + temp = temp->left; + } + else break; //valueѾ + } + } +} + +Node* Tree::locate(int value) +{ + + + Node* temp = root; + + while (1) + { + if (value > temp->value) + { + if (temp->right == NULL) + { + cout << "not found" << endl; + return NULL; + } + temp = temp->right; + } + else if (value < temp->value) + { + if (temp->left == NULL) + { + cout << "not found" << endl; + return NULL; + } + temp = temp->left; + } + else //valueѾҵ + { + cout << "found" << endl; + return temp; + } + } + +} + +void Tree::countNode() +{ + cout << count << endl; +} + +Node* Tree::getParent(int value) +{ + Node* temp = locate(value); + if (temp != NULL) + { + if (temp->parent == NULL) + { + cout << "target is root" << endl; + } + else + { + cout << temp->parent->value << endl; + } + return temp->parent; + } +} \ No newline at end of file diff --git a/cpp/p09_Tree/Tree.h b/cpp/p09_Tree/Tree.h new file mode 100644 index 00000000..0b0d2987 --- /dev/null +++ b/cpp/p09_Tree/Tree.h @@ -0,0 +1,21 @@ +#ifndef TREE_H_ +#define TREE_H_ + +#include"Node.h" +#include + +class Tree +{ +public: + void append(int value); + void countNode(); + Node* getParent(int value); + Node* locate(int value); + Tree(); +private: + Node* root; + Node* pNode; + int count; +}; + +#endif diff --git a/cpp/p09_Tree/main.cpp b/cpp/p09_Tree/main.cpp new file mode 100644 index 00000000..2e2aab13 --- /dev/null +++ b/cpp/p09_Tree/main.cpp @@ -0,0 +1,16 @@ +#include"Node.h" +#include"Tree.h" + +void main() +{ + Tree* tr = new Tree; + tr->append(5); + tr->append(7); + tr->append(6); + tr->append(1); + tr->append(9); + + tr->countNode(); + tr->getParent(5); + +} \ No newline at end of file diff --git a/fighters/Include/Aircraft.hpp b/fighters/Include/Aircraft.hpp new file mode 100644 index 00000000..26773389 --- /dev/null +++ b/fighters/Include/Aircraft.hpp @@ -0,0 +1,146 @@ +#ifndef BOOK_AIRCRAFT_HPP +#define BOOK_AIRCRAFT_HPP + +#include "ResourceIdentifiers.hpp" +#include "Entity.hpp" +#include "ResourceIdentifiers.hpp" +#include"Projectile.hpp" +#include"SoundHolder.hpp" +#include "Command.hpp" +#include"CommandQueue.hpp" +#include "PlayerStatusMenu.h" +#include"Player.hpp" +#include"Flash.h" + +#include + +class Player; + +class Aircraft : public Entity +{ +public: + enum Type + { + Eagle, + Raptor, + Avenger, + + RaptorA1, + RaptorA2, + RaptorB1, + RaptorB2, + RaptorC1, + RaptorC2, + RaptorD1, + RaptorD2, + + + AvengerA1, + AvengerA2, + AvengerB1, + AvengerB2, + AvengerC1, + AvengerC2, + AvengerD1, + AvengerD2, + + + + EagleA1, + EagleA2, + EagleB1, + EagleB2, + + TypeCount, + }; + + +public: + Aircraft(sf::RenderWindow& window, Type type, const TextureHolder& textures, const FontHolder& fonts, SoundHolder& mSounds + ,bool isPlayer=false,Player* player=NULL); + virtual unsigned int getCategory() const; + Aircraft::Type getType() const; + virtual sf::FloatRect getBoundingRect() const; + virtual bool isMarkedForRemoval() const; + bool isAllied() const; + float getMaxSpeed() const; + + bool increaseFireRate(); + bool increaseSpread(); + bool increaseMissileSlot(); + void GetMissileORUpgradeFire(); + void GetHpOrFirePile(); + void collectMissiles(unsigned int count); + + void fire(); + void launchMissile(); + + void openEMenu(); + void openQMenu(); + + void closeMenuOrUpgradeMissileSlot(); + void addPoints(int points); + void updateScore(int scores); + bool reborn(); + void restart(); + int getScore(); + +private: + virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const; + virtual void updateCurrent(sf::Time dt, CommandQueue& commands); + void updateMovementPattern(sf::Time dt); + void checkProjectileLaunch(sf::Time dt, CommandQueue& commands); + + void createBullets(SceneNode& node, const TextureHolder& textures) const; + void createProjectile(SceneNode& node, Projectile::Type type, float xOffset, float yOffset, const TextureHolder& textures) const; + void setAllyVelocity(float x, float y); + void addCountDowm(); + + +private: + Type mType; + sf::Sprite mSprite; + sf::Texture mDamaged; + sf::Texture mOrigin; + + Command mFireCommand; + Command mMissileCommand; + SoundHolder& mSounds; + sf::RenderWindow& mWindow; + sf::Clock mPlayerClock; + + sf::Time mFireCountdown; + sf::Time mPurchaseCountDown; + sf::Time mTimeSincePurchase; + bool mIsFiring; + bool mIsLaunchingMissile; + bool mIsMarkedForRemoval; + bool isPlayerAircraft; + bool callingReborn = false; + + float mFireRateLevel; + int mSpreadLevel; + int mMissileAmmo; + int mMissileSlot; + int mPoints; + int mScore; + + int FireRateCost; + int FireSpreadCost; + int MissileSlotCost; + + Command mDropPickupCommand; + float mTravelledDistance; + std::size_t mDirectionIndex; + + + + PlayerStatusMenu mMenu; + Player* mPlayer; + SceneNode* mCountDownNode; + sf::Texture* mCountDownTexture; + Flash* mCountDown; + +}; + +#endif // BOOK_AIRCRAFT_HPP diff --git a/fighters/Include/Animation.hpp b/fighters/Include/Animation.hpp new file mode 100644 index 00000000..fb717c8f --- /dev/null +++ b/fighters/Include/Animation.hpp @@ -0,0 +1,52 @@ +#ifndef BOOK_ANIMATION_HPP +#define BOOK_ANIMATION_HPP + +#include +#include + + +class Animation : public sf::Drawable, public sf::Transformable +{ + public: + Animation(); + explicit Animation(const sf::Texture& texture); + + void setTexture(const sf::Texture& texture); + const sf::Texture* getTexture() const; + + void setFrameSize(sf::Vector2i mFrameSize); + sf::Vector2i getFrameSize() const; + + void setNumFrames(std::size_t numFrames); + std::size_t getNumFrames() const; + + void setDuration(sf::Time duration); + sf::Time getDuration() const; + + void setRepeating(bool flag); + bool isRepeating() const; + + void restart(); + bool isFinished() const; + + sf::FloatRect getLocalBounds() const; + sf::FloatRect getGlobalBounds() const; + + void update(sf::Time dt); + + + private: + void draw(sf::RenderTarget& target, sf::RenderStates states) const; + + + private: + sf::Sprite mSprite; + sf::Vector2i mFrameSize; + std::size_t mNumFrames; + std::size_t mCurrentFrame; + sf::Time mDuration; + sf::Time mElapsedTime; + bool mRepeat; +}; + +#endif // BOOK_ANIMATION_HPP diff --git a/fighters/Include/Category.hpp b/fighters/Include/Category.hpp new file mode 100644 index 00000000..802b6dcb --- /dev/null +++ b/fighters/Include/Category.hpp @@ -0,0 +1,25 @@ +#ifndef BOOK_CATEGORY_HPP +#define BOOK_CATEGORY_HPP + + +// Entity/scene node category, used to dispatch commands +namespace Category +{ + enum Type + { + None = 0, + SceneAirLayer = 1 << 0, + PlayerAircraft = 1 << 1, + AlliedAircraft = 1 << 2, + EnemyAircraft = 1 << 3, + Pickup = 1 << 4, + AlliedProjectile = 1 << 5, + EnemyProjectile = 1 << 6, + SoundEffect = 1 << 7, + + Aircraft = PlayerAircraft | AlliedAircraft | EnemyAircraft, + Projectile = AlliedProjectile | EnemyProjectile, + }; +} + +#endif // BOOK_CATEGORY_HPP diff --git a/fighters/Include/Command.hpp b/fighters/Include/Command.hpp new file mode 100644 index 00000000..c77add01 --- /dev/null +++ b/fighters/Include/Command.hpp @@ -0,0 +1,36 @@ +#ifndef BOOK_COMMAND_HPP +#define BOOK_COMMAND_HPP + +#include + +#include +#include + + +class SceneNode; +class Player; + +struct Command +{ + Command(); + + std::function action; + std::function option; + unsigned int category; +}; + +template +std::function derivedAction(Function fn) +{ + return [=] (SceneNode& node, sf::Time dt) + { + // Check if cast is safe + assert(dynamic_cast(&node) != nullptr); + + // Downcast node and invoke function on it + fn(static_cast(node), dt); + }; +} + + +#endif // BOOK_COMMAND_HPP diff --git a/fighters/Include/CommandQueue.hpp b/fighters/Include/CommandQueue.hpp new file mode 100644 index 00000000..140d6ed8 --- /dev/null +++ b/fighters/Include/CommandQueue.hpp @@ -0,0 +1,21 @@ +#ifndef BOOK_COMMANDQUEUE_HPP +#define BOOK_COMMANDQUEUE_HPP + +#include "Command.hpp" + +#include + + +class CommandQueue +{ + public: + void push(const Command& command); + Command pop(); + bool isEmpty() const; + + + private: + std::queue mQueue; +}; + +#endif // BOOK_COMMANDQUEUE_HPP diff --git a/fighters/Include/Datatables.hpp b/fighters/Include/Datatables.hpp new file mode 100644 index 00000000..0374f0dc --- /dev/null +++ b/fighters/Include/Datatables.hpp @@ -0,0 +1,53 @@ +#ifndef BOOK_DATATABLES_HPP +#define BOOK_DATATABLES_HPP + +#include "ResourceIdentifiers.hpp" + +#include +#include + +#include +#include + + +class Aircraft; + +struct Direction +{ + Direction(float angle, float distance) + : angle(angle) + , distance(distance) + { + } + + float angle; + float distance; +}; + +struct AircraftData +{ + int hitpoints; + float speed; + Textures::ID texture; + sf::Time fireInterval; + std::vector directions; +}; + +struct ProjectileData +{ + int damage; + float speed; + Textures::ID texture; +}; + +struct PickupData +{ + std::function action; + Textures::ID texture; +}; + + +std::vector initializeAircraftData(); +std::vector initializeProjectileData(); + +#endif // BOOK_DATATABLES_HPP diff --git a/fighters/Include/Entity.hpp b/fighters/Include/Entity.hpp new file mode 100644 index 00000000..338c9419 --- /dev/null +++ b/fighters/Include/Entity.hpp @@ -0,0 +1,37 @@ +#ifndef BOOK_ENTITY_HPP +#define BOOK_ENTITY_HPP + +#include "SceneNode.hpp" + + +class Entity : public SceneNode +{ +public: + explicit Entity(int hitpoints); + + void setVelocity(sf::Vector2f velocity); + void setVelocity(float vx, float vy); + void accelerate(sf::Vector2f velocity); + void accelerate(float vx, float vy); + sf::Vector2f getVelocity() const; + void setHP(int HP); + + int getHitpoints() const; + void increaseHP(int increase); + void repair(int points); + void damage(int points); + void destroy(); + virtual bool isDestroyed() const; + + +protected: + virtual void updateCurrent(sf::Time dt, CommandQueue& commands); + + +private: + sf::Vector2f mVelocity; + int mHitpoints; + int mMaxHP; +}; + +#endif // BOOK_ENTITY_HPP diff --git a/fighters/Include/Flash.h b/fighters/Include/Flash.h new file mode 100644 index 00000000..bb30ceab --- /dev/null +++ b/fighters/Include/Flash.h @@ -0,0 +1,38 @@ +#ifndef FLASH_H_ +#define FLASH_H_ + +#include"SceneNode.hpp" +#include"ResourceIdentifiers.hpp" + +#include +#include +#include + +class Flash :public SceneNode +{ +public: + Flash(const sf::Texture & texture, Textures::ID type); + void updateFlash(sf::Time dt); + virtual bool isMarkedForRemoval() const; + void loadTexture(sf::Texture texture); + void remove(); +private: + void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const; //!!!!!!!!!ڵ mWindow.draw(SceneNode) ʱ˺ʵֻͼ!!!!!!!!! + sf::Sprite mSprite; + Textures::ID mType; + sf::Time flashTime; + sf::Time curTime; + sf::Clock clock; + sf::Vector2f frameSize; + sf::Time timePerFrame; + sf::Time frameShifter; + bool mIsMarkedForRemoval; + int curFrame; + int framePerline; + sf::IntRect frameRect; + int xframes, yframes; + +}; + +#endif // !FLASH_H_ + diff --git a/fighters/Include/Foreach.hpp b/fighters/Include/Foreach.hpp new file mode 100644 index 00000000..9e972794 --- /dev/null +++ b/fighters/Include/Foreach.hpp @@ -0,0 +1,26 @@ +#ifndef BOOK_FOREACH_HPP +#define BOOK_FOREACH_HPP + +// Preprocessor trick to allow nested loops +#define BOOK_PP_CAT_IMPL(a, b) a ## b +#define BOOK_PP_CAT(a, b) BOOK_PP_CAT_IMPL(a, b) +#define BOOK_ID(identifier) BOOK_PP_CAT(auroraDetail_, identifier) +#define BOOK_LINE_ID(identifier) BOOK_PP_CAT(BOOK_ID(identifier), __LINE__) + + +// Macro to emulate C++11 range-based for loop +// Instead of for (decl : range) you write FOREACH(decl, range) as in the following example +// +// std::vector v = ...; +// FOREACH(int& i, v) +// { +// i += 2; +// } +#define FOREACH(declaration, container) \ + if (bool BOOK_LINE_ID(broken) = false) {} else \ + for (auto BOOK_LINE_ID(itr) = (container).begin(); BOOK_LINE_ID(itr) != (container).end() && !BOOK_LINE_ID(broken); ++BOOK_LINE_ID(itr)) \ + if (bool BOOK_LINE_ID(passed) = false) {} else \ + if (BOOK_LINE_ID(broken) = true, false) {} else \ + for (declaration = *BOOK_LINE_ID(itr); !BOOK_LINE_ID(passed); BOOK_LINE_ID(passed) = true, BOOK_LINE_ID(broken) = false) + +#endif // BOOK_FOREACH_HPP diff --git a/fighters/Include/Game.h b/fighters/Include/Game.h new file mode 100644 index 00000000..ce432d29 --- /dev/null +++ b/fighters/Include/Game.h @@ -0,0 +1,99 @@ +#ifndef GAME_H_ +#define GAME_H_ + +#include +#include"ResourceHolder.hpp" +#include"Include\Aircraft.hpp" +#include"SceneNode.hpp" +#include"World.hpp" +#include"Player.hpp" +#include"MusicPlayer.h" +#include"Flash.h" + +class Game +{ +public: + Game(); + void run(); + void processInput(); + void updateGameStatus(sf::Time dt); + void loadMedia(); + void initialize(); + void buildWorld(); + void Restart(); + void getReborn(); + + +private: + void introInterface(sf::Keyboard::Key key); + void startInterface(sf::Keyboard::Key key); + void handleGameOutput(); + void processEvents(); + void update(sf::Time deltaTime); + void updateStatistics(sf::Time elapsedTime); + void render(); + + void drawCurScene(); + + void handlePlayerInput(sf::Keyboard::Key key, bool isPressed); + void updateStatus(); +private: + enum gameStatus + { + Intro, + Start, + Pause, + Reborn, + Over, + }; + + + Player* mPlayer; + sf::RenderWindow* mWindow; + World* mWorld; + sf::VideoMode mMode; + sf::String mTitle; + sf::Clock clock; //clockԭ¼ѭ + MusicPlayer IntroTheme; + MusicPlayer BattleTheme; + MusicPlayer DefeatedTheme; + MusicPlayer PauseTheme; + + sf::Texture Intro1; + sf::Texture Intro2; + sf::Texture Intro3; + sf::Texture Intro4; + sf::Texture Intro5; + + sf::Sprite introSprite; + + sf::Font mFont; + sf::Text mStatisticsText; + sf::Texture mGameOver; + sf::Texture mReborn; + sf::Time mStatisticsUpdateTime; + std::size_t mStatisticsNumFrames; + sf::Time TimePerFrame; + + sf::Texture pauseTexture; + + sf::Sprite pauseSprite; + sf::Sprite GameoverSprite; + sf::Sprite RebornSprite; + + int myScore; + sf::Time myTime; + + int curStatus; + int introCount; + bool BattleThemeShifted; + + sf::Texture mRebornTexture; + SceneNode* mRebornNode; + Flash* mRebornCircle; + +}; + + +#endif // !GAME_H_ + diff --git a/fighters/Include/MusicPlayer.h b/fighters/Include/MusicPlayer.h new file mode 100644 index 00000000..54e4b530 --- /dev/null +++ b/fighters/Include/MusicPlayer.h @@ -0,0 +1,30 @@ +#ifndef BOOK_MUSICPLAYER_HPP +#define BOOK_MUSICPLAYER_HPP + +#include "ResourceHolder.hpp" +#include "ResourceIdentifiers.hpp" + +#include +#include +#include + + +class MusicPlayer +{ +public: + MusicPlayer(); + + void play(Music::ID theme); + void stop(); + void setPaused(bool paused); + void setVolume(float volume); + + +private: + sf::Music mMusic; + std::map mFilenames; + float mVolume; +}; + +#endif // BOOK_MUSICPLAYER_HPP +#pragma once diff --git a/fighters/Include/Player.hpp b/fighters/Include/Player.hpp new file mode 100644 index 00000000..440e1676 --- /dev/null +++ b/fighters/Include/Player.hpp @@ -0,0 +1,71 @@ +#ifndef BOOK_PLAYER_HPP +#define BOOK_PLAYER_HPP + +#include "Command.hpp" +#include"Aircraft.hpp" + +#include + +#include + + +class CommandQueue; + +class Player +{ + public: + enum Action + { + MoveLeft, + MoveRight, + MoveUp, + MoveDown, + LaunchMissile, + Fire, + EMenu, + QMenu, + CloseMenuOrUpgradeMissileSlot, + GetMissileORUpgradeFire, + GetHpOrFirePile, + Restart, + Continue, + Exit, + ActionCount, + }; + + + public: + int RaptorPoint; + int AvengerPoint; + int EaglePoint; + int RaptorScore; + int AvengerScore; + int EagleScore; + + Player(); + + void handleEvent(const sf::Event& event, CommandQueue& commands); + void handleRealtimeInput(CommandQueue& commands); + + void assignKey(Action action, sf::Keyboard::Key key); + sf::Keyboard::Key getAssignedKey(Action action) const; + + bool isPlayerAlive(); + void setPlayerDead(); + void setPlayerAlive(); + void gameContinue(); + void Reborn(); + Aircraft* mAircraft; + private: + void initializeActions(); + static bool isRealtimeAction(Action action); + + + private: + bool playerAlive; + std::map mKeyBinding; + std::map mActionBinding; + +}; + +#endif // BOOK_PLAYER_HPP diff --git a/fighters/Include/PlayerStatusMenu.h b/fighters/Include/PlayerStatusMenu.h new file mode 100644 index 00000000..d025da96 --- /dev/null +++ b/fighters/Include/PlayerStatusMenu.h @@ -0,0 +1,73 @@ +#ifndef PLAYERSTATUSMENU_H_ +#define PLAYERSTATUSMENU_H_ + + +#include + +class Aircraft; + +class PlayerStatusMenu +{ +public: + enum Menus + { + QMenu, + EMenu + }; + + PlayerStatusMenu(sf::RenderWindow& window); + void updateMenu(sf::Vector2f position,int HP,int points,int missiles, int fireRateCost, int fireSpreadCost,int mMissileSlotCost); + void showMenu()const; + void openMenu(Menus menu); + void closeMenus(); + bool isEOpened(); + bool isQOpened(); + void initializeTexts(); + void updateTexts(sf::Vector2f position, int HP, int points, int missiles, int fireRateCost, int fireSpreadCost, int mMissileSlotCost); + void updateTextsColor(int HP, int points, int missiles, int fireRateCost, int fireSpreadCost, int mMissileSlotCost); + void updateRings(sf::Vector2f position, int fireRateCost, int fireSpreadCost, int SlotCost); + +private: + sf::Font mFont; + sf::Text mStatusText; + sf::Text mHPText; + sf::Text mMissileCost; + sf::Text mHPCost; + sf::Text mPoints; + sf::Text mFireRateCost; + sf::Text mFireSpreadCost; + sf::Text mMissileSlotCost; + sf::RenderWindow& mWindow; + + sf::Sprite EMenuSprite; + sf::Sprite QMenuSprite; + sf::Sprite RingA; + sf::Sprite RingB; + sf::Sprite RingC; + sf::Sprite Missiles; + sf::Sprite Slot; + sf::Texture EMenuTexture; + sf::Texture QMenuTexture; + sf::Texture RingATexture; + sf::Texture RingBTexture; + sf::Texture RingCTexture; + sf::Texture SlotTexture; + sf::Texture MissileTexture; + sf::Vector2f missileSize; + sf::Vector2f slotSize; + sf::IntRect missileFrame; + sf::IntRect slotFrame; + + bool isQMEnuOpened; + bool isEMenuOpened; + bool isRingAChanged; + bool isRingBChanged; + int Speedcount; + int Pilecount; + int Slotcount; +}; + + +#endif // !PLAYERSTATUSMENU_H_ + +#pragma once diff --git a/fighters/Include/PostEffect.hpp b/fighters/Include/PostEffect.hpp new file mode 100644 index 00000000..b0664789 --- /dev/null +++ b/fighters/Include/PostEffect.hpp @@ -0,0 +1,27 @@ +#ifndef BOOK_POSTEFFECT_HPP +#define BOOK_POSTEFFECT_HPP + +#include + + +namespace sf +{ + class RenderTarget; + class RenderTexture; + class Shader; +} + +class PostEffect : sf::NonCopyable +{ + public: + virtual ~PostEffect(); + virtual void apply(const sf::RenderTexture& input, sf::RenderTarget& output) = 0; + + static bool isSupported(); + + + protected: + static void applyShader(const sf::Shader& shader, sf::RenderTarget& output); +}; + +#endif // BOOK_POSTEFFECT_HPP diff --git a/fighters/Include/Projectile.hpp b/fighters/Include/Projectile.hpp new file mode 100644 index 00000000..a5e7925f --- /dev/null +++ b/fighters/Include/Projectile.hpp @@ -0,0 +1,46 @@ +#ifndef BOOK_PROJECTILE_HPP +#define BOOK_PROJECTILE_HPP + +#include "Entity.hpp" +#include "ResourceIdentifiers.hpp" + +#include + +class CommandQueue; + +class Projectile : public Entity +{ + public: + enum Type + { + AlliedBullet, + EnemyBullet, + Missile, + TypeCount + }; + + + public: + Projectile(Type type, const TextureHolder& textures); + + void guideTowards(sf::Vector2f position); + bool isGuided() const; + + virtual unsigned int getCategory() const; + virtual sf::FloatRect getBoundingRect() const; + float getMaxSpeed() const; + int getDamage() const; + + + private: + virtual void updateCurrent(sf::Time dt, CommandQueue& commands); + virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const; + + + private: + Type mType; + sf::Sprite mSprite; + sf::Vector2f mTargetDirection; +}; + +#endif // BOOK_PROJECTILE_HPP diff --git a/fighters/Include/ResourceHolder.hpp b/fighters/Include/ResourceHolder.hpp new file mode 100644 index 00000000..c6587700 --- /dev/null +++ b/fighters/Include/ResourceHolder.hpp @@ -0,0 +1,31 @@ +#ifndef RESOURCEHOLDER_HPP +#define RESOURCEHOLDER_HPP + +#include +#include +#include +#include +#include + +template +class ResourceHolder +{ + public: + void load(Identifier id, const std::string& filename); + + template + void load(Identifier id, const std::string& filename, const Parameter& secondParam); + + Resource& get(Identifier id); + const Resource& get(Identifier id) const; + + + private: + void insertResource(Identifier id, std::unique_ptr resource); + + + private: + std::map> mResourceMap; +}; +#include "ResourceHolder.inl" +#endif // RESOURCEHOLDER_HPP diff --git a/fighters/Include/ResourceHolder.inl b/fighters/Include/ResourceHolder.inl new file mode 100644 index 00000000..9ef7ccf3 --- /dev/null +++ b/fighters/Include/ResourceHolder.inl @@ -0,0 +1,51 @@ + +template +void ResourceHolder::load(Identifier id, const std::string& filename) +{ + // Create and load resource + std::unique_ptr resource(new Resource()); + if (!resource->loadFromFile(filename)) + throw std::runtime_error("ResourceHolder::load - Failed to load " + filename); + + // If loading successful, insert resource to map + insertResource(id, std::move(resource)); +} + +template +template +void ResourceHolder::load(Identifier id, const std::string& filename, const Parameter& secondParam) +{ + // Create and load resource + std::unique_ptr resource(new Resource()); + if (!resource->loadFromFile(filename, secondParam)) + throw std::runtime_error("ResourceHolder::load - Failed to load " + filename); + + // If loading successful, insert resource to map + insertResource(id, std::move(resource)); +} + +template +Resource& ResourceHolder::get(Identifier id) +{ + auto found = mResourceMap.find(id); + assert(found != mResourceMap.end()); + + return *found->second; +} + +template +const Resource& ResourceHolder::get(Identifier id) const +{ + auto found = mResourceMap.find(id); + assert(found != mResourceMap.end()); + + return *found->second; +} + +template +void ResourceHolder::insertResource(Identifier id, std::unique_ptr resource) +{ + // Insert and check success + auto inserted = mResourceMap.insert(std::make_pair(id, std::move(resource))); + assert(inserted.second); +} diff --git a/fighters/Include/ResourceIdentifiers.hpp b/fighters/Include/ResourceIdentifiers.hpp new file mode 100644 index 00000000..eef91d81 --- /dev/null +++ b/fighters/Include/ResourceIdentifiers.hpp @@ -0,0 +1,99 @@ +#ifndef BOOK_RESOURCEIDENTIFIERS_HPP +#define BOOK_RESOURCEIDENTIFIERS_HPP + + +// Forward declaration of SFML classes +namespace sf +{ + class Texture; + class Font; + class SoundBuffer; + class Shader; +} + +namespace SoundEffect +{ + enum ID + { + AlliedGunfire, + EnemyGunfire, + Explosion1, + Explosion2, + LaunchMissile, + CollectPickup, + Button, + Upgrade, + Purchase, + }; +} + +namespace Music +{ + enum ID + { + IntroTheme, + BattleTheme1, + BattleTheme2, + DefeatedTheme, + PauseTheme, + }; +} + +namespace Textures +{ + enum ID + { + Eagle, + Raptor, + Avenger, + Bullet, + Missile, + Desert, + Jungle, + HealthRefill, + MissileRefill, + FireSpread, + FireRate, + TitleScreen, + ButtonNormal, + ButtonSelected, + ButtonPressed, + Explosion, + Spark, + Loop, + Explosion_missile, + RebornCircle, + UpCloud, + DownCloud, + MidCloud, + }; +} + +namespace Shaders +{ + enum ID + { + BrightnessPass, + DownSamplePass, + GaussianBlurPass, + AddPass, + }; +} + +namespace Fonts +{ + enum ID + { + Main, + }; +} + +// Forward declaration and a few type definitions +template +class ResourceHolder; + +typedef ResourceHolder TextureHolder; +typedef ResourceHolder FontHolder; +typedef ResourceHolder SoundBufferHolder; +typedef ResourceHolder ShaderHolder; +#endif // BOOK_RESOURCEIDENTIFIERS_HPP diff --git a/fighters/Include/SceneNode.hpp b/fighters/Include/SceneNode.hpp new file mode 100644 index 00000000..a364b9ed --- /dev/null +++ b/fighters/Include/SceneNode.hpp @@ -0,0 +1,75 @@ +#ifndef BOOK_SCENENODE_HPP +#define BOOK_SCENENODE_HPP + +#include"Category.hpp" + +#include +#include +#include +#include + +#include +#include +#include +#include + +struct Command; +class CommandQueue; + +class SceneNode : public sf::Transformable, public sf::Drawable, private sf::NonCopyable +{ +public: + friend class Aircraft; + typedef std::unique_ptr Ptr; + typedef std::pair Pair; + + +public: + explicit SceneNode(Category::Type category = Category::None); + + void attachChild(Ptr child); + Ptr detachChild(const SceneNode& node); + + void update(sf::Time dt, CommandQueue& commands); + void update(sf::Time dt); + virtual void updateFlash(sf::Time dt); + virtual bool toRemove(); + + sf::Vector2f getWorldPosition() const; + sf::Transform getWorldTransform() const; + + void onCommand(const Command& command, sf::Time dt); //ִжӦָ + virtual unsigned int getCategory() const; + + void checkSceneCollision(SceneNode& sceneGraph, std::set& collisionPairs); + void checkNodeCollision(SceneNode& node, std::set& collisionPairs); + void removeWrecks(); + void removeBlooms(); + virtual sf::FloatRect getBoundingRect() const; + virtual bool isMarkedForRemoval() const; + virtual bool isDestroyed() const; + virtual bool toRemove()const; + + +private: + virtual void updateCurrent(sf::Time dt, CommandQueue& commands); + void updateChildren(sf::Time dt, CommandQueue& commands); + + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; + virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const; + void drawChildren(sf::RenderTarget& target, sf::RenderStates states) const; + void drawBoundingRect(sf::RenderTarget& target, sf::RenderStates states) const; + + +private: + + SceneNode* mParent; + Category::Type mDefaultCategory; +public: + std::vector mChildren; +}; + +bool collision(const SceneNode& lhs, const SceneNode& rhs); +float distance(const SceneNode& lhs, const SceneNode& rhs); + +#endif // BOOK_SCENENODE_HPP diff --git a/fighters/Include/ShadersEffect.h b/fighters/Include/ShadersEffect.h new file mode 100644 index 00000000..2a8b2e6f --- /dev/null +++ b/fighters/Include/ShadersEffect.h @@ -0,0 +1,45 @@ +#ifndef SHADERS_H_ +#define SHADERS_H_ + +#include "PostEffect.hpp" +#include "ResourceIdentifiers.hpp" +#include "ResourceHolder.hpp" + +#include +#include + +#include + +class ShadersEffect : public PostEffect +{ +public: + ShadersEffect(); + + virtual void apply(const sf::RenderTexture& input, sf::RenderTarget& output); + + +private: + typedef std::array RenderTextureArray; + + +private: + void prepareTextures(sf::Vector2u size); + + void filterBright(const sf::RenderTexture& input, sf::RenderTexture& output); + void blurMultipass(RenderTextureArray& renderTextures); + void blur(const sf::RenderTexture& input, sf::RenderTexture& output, sf::Vector2f offsetFactor); + void downsample(const sf::RenderTexture& input, sf::RenderTexture& output); + void add(const sf::RenderTexture& source, const sf::RenderTexture& bloom, sf::RenderTarget& target); + + +private: + ShaderHolder mShaders; + + sf::RenderTexture mBrightnessTexture; + RenderTextureArray mFirstPassTextures; + RenderTextureArray mSecondPassTextures; +}; + +#endif // !SHADERS_H_ + +#pragma once diff --git a/fighters/Include/SoundHolder.hpp b/fighters/Include/SoundHolder.hpp new file mode 100644 index 00000000..89dfae92 --- /dev/null +++ b/fighters/Include/SoundHolder.hpp @@ -0,0 +1,26 @@ +#ifndef SOUNDHOLDER_H_ +#define SOUNDHOLDER_H_ + +#include"ResourceIdentifiers.hpp" +#include"ResourceHolder.hpp" + +#include +#include +#include + +class SoundHolder +{ +public: + SoundHolder(); + + void play(SoundEffect::ID type);; + void emptyQueue(); + + +private: + SoundBufferHolder mSounds; + std::queue soundQueue; + +}; + +#endif // !SOUNDHOLER_H_ diff --git a/fighters/Include/SoundNode.h b/fighters/Include/SoundNode.h new file mode 100644 index 00000000..6f70f09b --- /dev/null +++ b/fighters/Include/SoundNode.h @@ -0,0 +1 @@ +#pragma once diff --git a/fighters/Include/SoundPlayer.hpp b/fighters/Include/SoundPlayer.hpp new file mode 100644 index 00000000..85dd52c0 --- /dev/null +++ b/fighters/Include/SoundPlayer.hpp @@ -0,0 +1,21 @@ +#ifndef SoundPlayer_H_ +#define SoundPlayer_H_ + +#include"ResourceHolder.hpp" +#include"ResourceIdentifiers.hpp" + +#include +#include + +class SoundPlayer +{ +public: + SoundPlayer(); + + void play(SoundEffect::ID type); +private: + SoundBufferHolder mSounds; +}; + + +#endif // !SoundPlayer_H_ diff --git a/fighters/Include/SpriteNode.hpp b/fighters/Include/SpriteNode.hpp new file mode 100644 index 00000000..1de6ad39 --- /dev/null +++ b/fighters/Include/SpriteNode.hpp @@ -0,0 +1,25 @@ +#ifndef BOOK_SPRITENODE_HPP +#define BOOK_SPRITENODE_HPP + +#include "SceneNode.hpp" + +#include + + +class SpriteNode : public SceneNode +{ + public: + explicit SpriteNode(const sf::Texture& texture); + SpriteNode(const sf::Texture& texture, const sf::IntRect& textureRect); //ʼsprite + + + private: + virtual void drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const; + + + private: + sf::Sprite mSprite; +}; + + +#endif // BOOK_SPRITENODE_HPP diff --git a/fighters/Include/StringHelpers.inl b/fighters/Include/StringHelpers.inl new file mode 100644 index 00000000..8ccd4329 --- /dev/null +++ b/fighters/Include/StringHelpers.inl @@ -0,0 +1,8 @@ + +template +std::string toString(const T& value) +{ + std::stringstream stream; + stream << value; + return stream.str(); +} diff --git a/fighters/Include/Utility.inl b/fighters/Include/Utility.inl new file mode 100644 index 00000000..8ccd4329 --- /dev/null +++ b/fighters/Include/Utility.inl @@ -0,0 +1,8 @@ + +template +std::string toString(const T& value) +{ + std::stringstream stream; + stream << value; + return stream.str(); +} diff --git a/fighters/Include/World.hpp b/fighters/Include/World.hpp new file mode 100644 index 00000000..c87c5399 --- /dev/null +++ b/fighters/Include/World.hpp @@ -0,0 +1,166 @@ +#ifndef BOOK_WORLD_HPP +#define BOOK_WORLD_HPP + +#include "ResourceHolder.hpp" +#include "ResourceIdentifiers.hpp" +#include "SceneNode.hpp" +#include "SpriteNode.hpp" +#include "Aircraft.hpp" +#include "Command.hpp" +#include "CommandQueue.hpp" +#include "SoundHolder.hpp" +#include "Flash.h" + + +#include +#include +#include + +#include + +// Forward declaration +namespace sf +{ + class RenderWindow; +} + +class Player; + +class World : private sf::NonCopyable +{ +public: + + explicit World(sf::RenderWindow& window,int& mScore, Player* player); + void update(sf::Time dt); + void draw(); + + CommandQueue& getCommandQueue(); + + bool hasAlivePlayer() const; + bool hasPlayerReachedEnd() const; + sf::Vector2f getViewCenter(); + float getWorldLength(); + +private: + void loadTextures(); + void adaptPlayerPosition(); + void handleCollisions(); + void randomEvents(sf::Time dt); + void randomEnemys(sf::Time dt); + void randomTroop(sf::Time dt); + + void buildScene(); + void addEnemies(); + + //ڵǰλ + //Ϊ1 2 + void addTroopA1(); + void addTroopA2(); + void addTroopB1(); + void addTroopB2(); + void addTroopC1(); + void addTroopC2(); + void addTroopD1(); + void addTroopE1(); + void addTroopE2(); + void addEagleA1(); + void addEagleA2(); + void addEagleB1(); + void addEagleB2(); + //Ԥ + void addTroopA1(float y); //һraptor + void addTroopA2(float y); + void addTroopB1(float y); //2 raptor + 1 avenger + void addTroopB2(float y); + void addTroopC1(float y); //3 raptor + 3 avenger + void addTroopC2(float y); + void addTroopD1(float y); + void addTroopE1(float y); + void addTroopE2(float y); + void addEagleA1(float y); + void addEagleA2(float y); + void addEagleB1(float y); + void addEagleB2(float y); + + void addEnemy(Aircraft::Type type, float relX, float relY); + void spawnEnemies(); + void destroyEntitiesOutsideView(); + void guideMissiles(); + sf::FloatRect getViewBounds() const; + sf::FloatRect getBattlefieldBounds() const; + void updateScore(Aircraft& mAircraft); + void addAlly(); + void addFlash(Textures::ID type,float x, float y); + + + +private: + enum Layer + { + Background, + DownCloud, + Air, + UpCloud, + LayerCount + }; + + struct SpawnPoint + { + SpawnPoint(Aircraft::Type type, float x, float y) + : type(type) + , x(x) + , y(y) + { + } + + Aircraft::Type type; + float x; + float y; + }; + + struct RandomEvents + { + RandomEvents(sf::Time RandomEnemyInterval, sf::Time RandomPickupInterval, sf::Time RandomEventsCountdown) + : RandomEnemyInterval(RandomEnemyInterval) + , RandomPickupInterval(RandomPickupInterval) + , RandomEventsCountdown(RandomEventsCountdown) + { + } + + sf::Time RandomEnemyInterval; + sf::Time RandomPickupInterval; + + sf::Time RandomEventsCountdown; + }; + + +private: + sf::RenderWindow& mWindow; + sf::View mWorldView; + sf::Vector2f mViewCenter; + TextureHolder mTextures; + FontHolder& mFonts; + SoundHolder mSounds; + + SceneNode mSceneGraph; + std::array mSceneLayers; + CommandQueue mCommandQueue; + + float mWorldLength; + sf::FloatRect mWorldBounds; + sf::Vector2f mSpawnPosition; + float mScrollSpeed; + Aircraft* mPlayerAircraft; + RandomEvents mRandomEvents; + + std::unique_ptr mAllies[2]; + std::vector mEnemySpawnPoints; + std::vector mActiveEnemies; + + int& mScore; + SceneNode mFlashNode; + Player* mPlayer; + + +}; +#endif // BOOK_WORLD_HPP diff --git a/fighters/Include/stringhelpers.hpp b/fighters/Include/stringhelpers.hpp new file mode 100644 index 00000000..6d6916f9 --- /dev/null +++ b/fighters/Include/stringhelpers.hpp @@ -0,0 +1,12 @@ +#ifndef BOOK_STRINGHELPERS_HPP +#define BOOK_STRINGHELPERS_HPP + +#include + +// Since std::to_string doesn't work on MinGW we have to implement +// our own to support all platforms. +template +std::string toString(const T& value); + +#include "StringHelpers.inl" +#endif // BOOK_STRINGHELPERS_HPP diff --git a/fighters/Include/utility.hpp b/fighters/Include/utility.hpp new file mode 100644 index 00000000..ca6f94cb --- /dev/null +++ b/fighters/Include/utility.hpp @@ -0,0 +1,41 @@ +#ifndef BOOK_UTILITY_HPP +#define BOOK_UTILITY_HPP + +#include +#include + +#include + + +namespace sf +{ + class Sprite; + class Text; +} + +// Since std::to_string doesn't work on MinGW we have to implement +// our own to support all platforms. +template +std::string toString(const T& value); + +// Convert enumerators to strings +std::string toString(sf::Keyboard::Key key); + +// Call setOrigin() with the center of the object +void centerOrigin(sf::Sprite& sprite); +void centerOrigin(sf::Text& text); + +// Degree/radian conversion +float toDegree(float radian); +float toRadian(float degree); + +// Random number generation +int randomInt(int exclusiveMax); + +// Vector operations +float length(sf::Vector2f vector); +sf::Vector2f unitVector(sf::Vector2f vector); + + +#include "Utility.inl" +#endif // BOOK_UTILITY_HPP diff --git a/fighters/Source/Aircraft.cpp b/fighters/Source/Aircraft.cpp new file mode 100644 index 00000000..5fa5f461 --- /dev/null +++ b/fighters/Source/Aircraft.cpp @@ -0,0 +1,576 @@ +#include "Include/Aircraft.hpp" +#include "Include/ResourceHolder.hpp" +#include "Include\Datatables.hpp" +#include"Include\utility.hpp" + + +#include +#include + +namespace +{ + const std::vector Table = initializeAircraftData(); +} + +Aircraft::Aircraft(sf::RenderWindow& window, Type type, const TextureHolder& textures, const FontHolder& fonts, SoundHolder& mSounds + , bool isPlayer + , Player* player) + : Entity(Table[type].hitpoints) + , mType(type) + , mSprite(textures.get(Table[type].texture)) + , mSounds(mSounds) + , mFireCommand() + , mMissileCommand() + , mFireCountdown(sf::Time::Zero) + , mIsFiring(false) + , mIsLaunchingMissile(false) + , mIsMarkedForRemoval(false) + , mFireRateLevel(1) + , mSpreadLevel(1) + , mMissileAmmo(2) + , mDropPickupCommand() + , mTravelledDistance(0.f) + , mDirectionIndex(0) + , mPoints(0) + , mMenu(window) + , FireRateCost(10) + , FireSpreadCost(20) + , MissileSlotCost(15) + , mMissileSlot(2) + , mWindow(window) + , isPlayerAircraft(isPlayer) + , mOrigin(textures.get(Table[type].texture)) + , mPurchaseCountDown(sf::seconds(1.5)) +{ + centerOrigin(mSprite); + + mFireCommand.category = Category::SceneAirLayer; + mFireCommand.action = [this, &textures](SceneNode& node, sf::Time) + { + createBullets(node, textures); + }; + + mMissileCommand.category = Category::SceneAirLayer; + mMissileCommand.action = [this, &textures](SceneNode& node, sf::Time) + { + createProjectile(node, Projectile::Missile, 0.f, 0.5f, textures); + }; + + if (isPlayer) + { + mPlayerClock.restart(); + mDamaged.loadFromFile("Media/Textures/EagleDamaged.png"); + mPlayer = player; + + mCountDownNode = new SceneNode; + mCountDownTexture = new sf::Texture; + mCountDownTexture->loadFromFile("Media/Flash/Loop.png"); + + } + +} + +void Aircraft::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const +{ + + + if (isPlayerAircraft) + { + mMenu.showMenu(); + } + target.draw(mSprite, states); +} + +void Aircraft::updateCurrent(sf::Time dt, CommandQueue& commands) +{ + + + if (isPlayerAircraft) + { + mMenu.updateMenu(getPosition(), getHitpoints(), mPoints, mMissileAmmo, FireRateCost, FireSpreadCost,MissileSlotCost); + update(dt); //AircraftFlashڵ + + if (getHitpoints() <= 0) + { + mPlayer->setPlayerDead(); + + mMenu.closeMenus(); + mSprite.setTexture(mDamaged); + } + if(callingReborn) + callingReborn = false; + } + + + // Entity has been destroyed: Possibly drop pickup, mark for removal + if (isDestroyed()) + { +// checkPickupDrop(commands); + if(!isPlayerAircraft) + mIsMarkedForRemoval = true; + return; + } + + // Check if bullets or missiles are fired + checkProjectileLaunch(dt, commands); + + // Update enemy movement pattern; apply velocity + updateMovementPattern(dt); + Entity::updateCurrent(dt, commands); + + // Update texts +// updateTexts(); + + +} + +unsigned int Aircraft::getCategory() const +{ + if (isAllied()) + return Category::PlayerAircraft; + else + return Category::EnemyAircraft; +} + +Aircraft::Type Aircraft::getType() const +{ + switch (mType) + { + case Type::Raptor: + return Type::Raptor; + case Type::RaptorA1: + return Type::RaptorA1; + case Type::RaptorA2: + return Type::RaptorA2; + case Type::RaptorB1: + return Type::RaptorB1; + case Type::RaptorB2: + return Type::RaptorB2; + case Type::RaptorC1: + return Type::RaptorC1; + case Type::RaptorC2: + return Type::RaptorC2; + case Type::RaptorD1: + return Type::RaptorD1; + case Type::RaptorD2: + return Type::RaptorD2; + + case Type::Avenger: + return Type::Avenger; + case Type::AvengerA1: + return Type::AvengerA1; + case Type::AvengerA2: + return Type::AvengerA2; + case Type::AvengerB1: + return Type::AvengerB1; + case Type::AvengerB2: + return Type::AvengerB2; + case Type::AvengerC1: + return Type::AvengerC1; + case Type::AvengerC2: + return Type::AvengerC2; + case Type::AvengerD1: + return Type::AvengerD1; + case Type::AvengerD2: + return Type::AvengerD2; + + case Type::Eagle: + return Type::Eagle; + case Type::EagleA1: + return Type::EagleA1; + case Type::EagleA2: + return Type::EagleA2; + case Type::EagleB1: + return Type::EagleB1; + case Type::EagleB2: + return Type::EagleB2; + } +} + +sf::FloatRect Aircraft::getBoundingRect() const +{ + return getWorldTransform().transformRect(mSprite.getGlobalBounds()); +} + +bool Aircraft::isMarkedForRemoval() const +{ + return mIsMarkedForRemoval; +} + +bool Aircraft::isAllied() const +{ + return mType == Eagle; +} + +float Aircraft::getMaxSpeed() const +{ + return Table[mType].speed; +} + +bool Aircraft::increaseFireRate() +{ + if (mFireRateLevel < 7) + { + mFireRateLevel+=0.5; + return true; + } + return false; + +} + +bool Aircraft::increaseSpread() +{ + if (mSpreadLevel < 4) + { + ++mSpreadLevel;; + return true; + } + return false; + + +} + +bool Aircraft::increaseMissileSlot() +{ + if (mMissileSlot < 4) + { + mMissileSlot++; + return true; + } + return false; +} + + +void Aircraft::collectMissiles(unsigned int count) +{ + mMissileAmmo += count; +} + +void Aircraft::fire() +{ + // Only ships with fire interval != 0 are able to fire + if (Table[mType].fireInterval != sf::Time::Zero) + mIsFiring = true; + + if (isPlayerAircraft) + { + mMenu.closeMenus(); + } +} + +void Aircraft::launchMissile() +{ + if (mMissileAmmo > 0) + { + mIsLaunchingMissile = true; + --mMissileAmmo; + + if (isPlayerAircraft) + { + mMenu.closeMenus(); + } + } +} + +void Aircraft::updateMovementPattern(sf::Time dt) +{ + // Enemy airplane: Movement pattern + const std::vector& directions = Table[mType].directions; + if (!directions.empty()) + { + // Moved long enough in current direction: Change direction + if (mTravelledDistance > directions[mDirectionIndex].distance) + { + mDirectionIndex = (mDirectionIndex + 1) % directions.size(); + mTravelledDistance = 0.f; + } + + // Compute velocity from direction + float radians = toRadian(directions[mDirectionIndex].angle + 90.f); + float vx = getMaxSpeed() * std::cos(radians); + float vy = getMaxSpeed() * std::sin(radians); + + setVelocity(vx, vy); + + //addTroopE()Ķ + if (getType() == Aircraft::RaptorD1 || getType() == Aircraft::RaptorD2|| getType() == Aircraft::AvengerD1 ||getType() == Aircraft::AvengerD2) + { + accelerate(0, -50); + + if (radians == 0) + { + setVelocity(getMaxSpeed(), 0); + } + } + mTravelledDistance += getMaxSpeed() * dt.asSeconds(); + } +} +/* +void Aircraft::checkPickupDrop(CommandQueue& commands) +{ +if (!isAllied() && randomInt(3) == 0) +commands.push(mDropPickupCommand); +} +*/ +void Aircraft::checkProjectileLaunch(sf::Time dt, CommandQueue& commands) +{ + // Enemies try to fire all the time + if (!isAllied()) + { + fire(); + } + + + // Check for automatic gunfire, allow only in intervals + if (mIsFiring && mFireCountdown <= sf::Time::Zero) + { + // Interval expired: We can fire a new bullet + commands.push(mFireCommand); + mFireCountdown += Table[mType].fireInterval / (mFireRateLevel + 0.8f); + mIsFiring = false; + if (!isAllied()) + { + mSounds.play(SoundEffect::EnemyGunfire); + } + else + { + mSounds.play(SoundEffect::AlliedGunfire); + } + + } + else if (mFireCountdown > sf::Time::Zero) + { + // Interval not expired: Decrease it further + mFireCountdown -= dt; + mIsFiring = false; + } + + // Check for missile launch + if (mIsLaunchingMissile) + { + commands.push(mMissileCommand); + mIsLaunchingMissile = false; + mSounds.play(SoundEffect::LaunchMissile); + + } +} + +void Aircraft::createBullets(SceneNode& node, const TextureHolder& textures) const +{ + Projectile::Type type = isAllied() ? Projectile::AlliedBullet : Projectile::EnemyBullet; + + switch (mSpreadLevel) + { + case 1: + createProjectile(node, type, 0.0f, 0.5f, textures); + break; + + case 2: + createProjectile(node, type, -0.33f, 0.33f, textures); + createProjectile(node, type, +0.33f, 0.33f, textures); + break; + + case 3: + createProjectile(node, type, -0.5f, 0.33f, textures); + createProjectile(node, type, 0.0f, 0.5f, textures); + createProjectile(node, type, +0.5f, 0.33f, textures); + break; + case 4: + createProjectile(node, type, -0.55f, 0.33f, textures); + createProjectile(node, type, -0.17f, 0.55f, textures); + createProjectile(node, type, +0.17f, 0.55f, textures); + createProjectile(node, type, +0.55f, 0.33f, textures); + + + } +} + +void Aircraft::createProjectile(SceneNode& node, Projectile::Type type, float xOffset, float yOffset, const TextureHolder& textures) const +{ + std::unique_ptr projectile(new Projectile(type, textures)); + + sf::Vector2f offset(xOffset * mSprite.getGlobalBounds().width, yOffset * mSprite.getGlobalBounds().height); + sf::Vector2f velocity(0, projectile->getMaxSpeed()); + + float sign = isAllied() ? -1.f : +1.f; + projectile->setPosition(getWorldPosition() + offset * sign); + projectile->setVelocity(velocity * sign); + node.attachChild(std::move(projectile)); +} + +void Aircraft::setAllyVelocity(float x,float y) +{ +// this->mch +} + +void Aircraft::addCountDowm() +{ +// mCountDownNode->removeWrecks(); + + std::unique_ptr mflash(new Flash(*mCountDownTexture, Textures::Loop)); //֮ǰcircleµ +// mflash->setPosition(getPosition().x, getPosition().y-500); + mCountDown = mflash.get(); +// mCountDownNode->attachChild(std::move(mflash)); + + this->attachChild(std::move(mflash)); +} + +int Aircraft::getScore() +{ + return mScore; +} + +void Aircraft::GetMissileORUpgradeFire() +{ + mTimeSincePurchase += mPlayerClock.restart(); + + if (mTimeSincePurchase > mPurchaseCountDown) + { + if (mMenu.isEOpened()) + { + if (mPoints - 2 >= 0 && mMissileAmmo < mMissileSlot) + { + mPoints -= 2; + mMissileAmmo++; + mSounds.play(SoundEffect::Purchase); + mTimeSincePurchase = sf::seconds(0); + addCountDowm(); + } + } + else if (mMenu.isQOpened() && mTimeSincePurchase>mPurchaseCountDown) + { + if (mPoints - FireRateCost >= 0) + { + + if (increaseFireRate()) + { + mPoints -= FireRateCost; + mSounds.play(SoundEffect::Upgrade); + FireRateCost = FireRateCost / 3 + 5 + FireRateCost; // + mTimeSincePurchase = sf::seconds(0); + addCountDowm(); + } + + } + } + } + +} + +void Aircraft::GetHpOrFirePile() +{ + mTimeSincePurchase += mPlayerClock.restart(); + if (mMenu.isEOpened()) + { + if (mPoints - 5 >= 0 && getHitpoints()<100&& mTimeSincePurchase>mPurchaseCountDown) + { + repair(20); + mPoints -= 5; + mSounds.play(SoundEffect::Purchase); + mTimeSincePurchase = sf::seconds(0); + addCountDowm(); + } + } + else if (mMenu.isQOpened()) + { + if (mPoints - FireSpreadCost >= 0 && mTimeSincePurchase>mPurchaseCountDown) + { + + if (increaseSpread()) + { + mPoints -= FireSpreadCost; + mSounds.play(SoundEffect::Upgrade); + FireSpreadCost = FireSpreadCost / 2 + 5 + FireSpreadCost; + mTimeSincePurchase = sf::seconds(0); + addCountDowm(); + } + + } + } + + +} + +void Aircraft::openEMenu() +{ + if (!mMenu.isEOpened()) + { + mMenu.closeMenus(); + mMenu.openMenu(PlayerStatusMenu::Menus::EMenu); + } + else + { + mMenu.closeMenus(); + } +} + +void Aircraft::openQMenu() +{ + if (!mMenu.isQOpened()) + { + mMenu.closeMenus(); + mMenu.openMenu(PlayerStatusMenu::Menus::QMenu); + } + else + { + mMenu.closeMenus(); + } + +} + +void Aircraft::closeMenuOrUpgradeMissileSlot() +{ + mTimeSincePurchase += mPlayerClock.restart(); + if (mMenu.isEOpened()) + { + mMenu.closeMenus(); + } + else if (mMenu.isQOpened()) + { + if ( mTimeSincePurchase>mPurchaseCountDown && mPoints - MissileSlotCost >= 0) + { + if (increaseMissileSlot()) + { + mPoints -= MissileSlotCost; + mSounds.play(SoundEffect::Upgrade); + MissileSlotCost = 2*MissileSlotCost ; + mTimeSincePurchase = sf::seconds(0); + addCountDowm(); + } + + } + + } + + +} + +void Aircraft::addPoints(int points) +{ + mPoints += points; +} + +void Aircraft::updateScore(int scores) +{ + mScore = scores; +} + +bool Aircraft::reborn() +{ + if (mScore >=500&& getHitpoints() <= 0) + { + setHP(60); + mPlayer->setPlayerAlive(); + mScore -= 500; + mSprite.setTexture(mOrigin); + return true; + } + return false; +} + +void Aircraft::restart() +{ + + +} + diff --git a/fighters/Source/Animation.cpp b/fighters/Source/Animation.cpp new file mode 100644 index 00000000..a7fdbd3a --- /dev/null +++ b/fighters/Source/Animation.cpp @@ -0,0 +1,146 @@ +#include "Include\Animation.hpp" + +#include +#include + + +Animation::Animation() +: mSprite() +, mFrameSize() +, mNumFrames(0) +, mCurrentFrame(0) +, mDuration(sf::Time::Zero) +, mElapsedTime(sf::Time::Zero) +, mRepeat(false) +{ +} + +Animation::Animation(const sf::Texture& texture) +: mSprite(texture) +, mFrameSize() +, mNumFrames(0) +, mCurrentFrame(0) +, mDuration(sf::Time::Zero) +, mElapsedTime(sf::Time::Zero) +, mRepeat(false) +{ +} + +void Animation::setTexture(const sf::Texture& texture) +{ + mSprite.setTexture(texture); +} + +const sf::Texture* Animation::getTexture() const +{ + return mSprite.getTexture(); +} + +void Animation::setFrameSize(sf::Vector2i frameSize) +{ + mFrameSize = frameSize; +} + +sf::Vector2i Animation::getFrameSize() const +{ + return mFrameSize; +} + +void Animation::setNumFrames(std::size_t numFrames) +{ + mNumFrames = numFrames; +} + +std::size_t Animation::getNumFrames() const +{ + return mNumFrames; +} + +void Animation::setDuration(sf::Time duration) +{ + mDuration = duration; +} + +sf::Time Animation::getDuration() const +{ + return mDuration; +} + +void Animation::setRepeating(bool flag) +{ + mRepeat = flag; +} + +bool Animation::isRepeating() const +{ + return mRepeat; +} + +void Animation::restart() +{ + mCurrentFrame = 0; +} + +bool Animation::isFinished() const +{ + return mCurrentFrame >= mNumFrames; +} + +sf::FloatRect Animation::getLocalBounds() const +{ + return sf::FloatRect(getOrigin(), static_cast(getFrameSize())); +} + +sf::FloatRect Animation::getGlobalBounds() const +{ + return getTransform().transformRect(getLocalBounds()); +} + +void Animation::update(sf::Time dt) +{ + sf::Time timePerFrame = mDuration / static_cast(mNumFrames); + mElapsedTime += dt; + + sf::Vector2i textureBounds(mSprite.getTexture()->getSize()); + sf::IntRect textureRect = mSprite.getTextureRect(); + + if (mCurrentFrame == 0) + textureRect = sf::IntRect(0, 0, mFrameSize.x, mFrameSize.y); + + // While we have a frame to process + while (mElapsedTime >= timePerFrame && (mCurrentFrame <= mNumFrames || mRepeat)) + { + // Move the texture rect left + textureRect.left += textureRect.width; + + // If we reach the end of the texture + if (textureRect.left + textureRect.width > textureBounds.x) + { + // Move it down one line + textureRect.left = 0; + textureRect.top += textureRect.height; + } + + // And progress to next frame + mElapsedTime -= timePerFrame; + if (mRepeat) + { + mCurrentFrame = (mCurrentFrame + 1) % mNumFrames; + + if (mCurrentFrame == 0) + textureRect = sf::IntRect(0, 0, mFrameSize.x, mFrameSize.y); + } + else + { + mCurrentFrame++; + } + } + + mSprite.setTextureRect(textureRect); +} + +void Animation::draw(sf::RenderTarget& target, sf::RenderStates states) const +{ + states.transform *= getTransform(); + target.draw(mSprite, states); +} diff --git a/fighters/Source/Command.cpp b/fighters/Source/Command.cpp new file mode 100644 index 00000000..8e13d37e --- /dev/null +++ b/fighters/Source/Command.cpp @@ -0,0 +1,8 @@ +#include "Include\Command.hpp" +#include"Include\Category.hpp" + +Command::Command() +: action() +, category(Category::None) +{ +} diff --git a/fighters/Source/CommandQueue.cpp b/fighters/Source/CommandQueue.cpp new file mode 100644 index 00000000..7c361b03 --- /dev/null +++ b/fighters/Source/CommandQueue.cpp @@ -0,0 +1,20 @@ +#include "Include\CommandQueue.hpp" +#include "Include\SceneNode.hpp" + + +void CommandQueue::push(const Command& command) +{ + mQueue.push(command); +} + +Command CommandQueue::pop() +{ + Command command = mQueue.front(); + mQueue.pop(); + return command; +} + +bool CommandQueue::isEmpty() const +{ + return mQueue.empty(); +} diff --git a/fighters/Source/DataTables.cpp b/fighters/Source/DataTables.cpp new file mode 100644 index 00000000..7c2c4801 --- /dev/null +++ b/fighters/Source/DataTables.cpp @@ -0,0 +1,303 @@ +#include "Include\datatables.hpp" +#include "Include\Aircraft.hpp" +#include "Include\Projectile.hpp" + + +// For std::bind() placeholders _1, _2, ... +using namespace std::placeholders; + +std::vector initializeAircraftData() +{ + std::vector data(Aircraft::TypeCount); + + data[Aircraft::Eagle].hitpoints = 100; + data[Aircraft::Eagle].speed = 200.f; + data[Aircraft::Eagle].fireInterval = sf::seconds(1.5); + data[Aircraft::Eagle].texture = Textures::Eagle; + + data[Aircraft::Raptor].hitpoints = 30; + data[Aircraft::Raptor].speed = 80.f; + data[Aircraft::Raptor].texture = Textures::Raptor; + data[Aircraft::Raptor].directions.push_back(Direction(+45.f, 80.f)); + data[Aircraft::Raptor].directions.push_back(Direction(-45.f, 160.f)); + data[Aircraft::Raptor].directions.push_back(Direction(+45.f, 80.f)); + data[Aircraft::Raptor].fireInterval = sf::Time::Zero; + + data[Aircraft::Avenger].hitpoints = 70; + data[Aircraft::Avenger].speed = 50.f; + data[Aircraft::Avenger].texture = Textures::Avenger; + data[Aircraft::Avenger].directions.push_back(Direction(+45.f, 50.f)); + data[Aircraft::Avenger].directions.push_back(Direction( 0.f, 50.f)); + data[Aircraft::Avenger].directions.push_back(Direction(-45.f, 100.f)); + data[Aircraft::Avenger].directions.push_back(Direction( 0.f, 50.f)); + data[Aircraft::Avenger].directions.push_back(Direction(+45.f, 50.f)); + data[Aircraft::Avenger].fireInterval = sf::seconds(2); + + + data[Aircraft::RaptorA1].hitpoints = 30; + data[Aircraft::RaptorA1].speed = 110.f; + data[Aircraft::RaptorA1].texture = Textures::Raptor; + data[Aircraft::RaptorA1].directions.push_back(Direction(+45.f, 200.f)); + data[Aircraft::RaptorA1].directions.push_back(Direction(+90.f, 500.f)); + data[Aircraft::RaptorA1].fireInterval = sf::Time::Zero; + + data[Aircraft::RaptorA2].hitpoints = 30; + data[Aircraft::RaptorA2].speed = 110.f; + data[Aircraft::RaptorA2].texture = Textures::Raptor; + data[Aircraft::RaptorA2].directions.push_back(Direction(-45.f, 200.f)); + data[Aircraft::RaptorA2].directions.push_back(Direction(-90.f, 500.f)); + data[Aircraft::RaptorA2].fireInterval = sf::Time::Zero; + + data[Aircraft::AvengerA1].hitpoints = 70; + data[Aircraft::AvengerA1].speed = 110.f; + data[Aircraft::AvengerA1].texture = Textures::Avenger; + data[Aircraft::AvengerA1].directions.push_back(Direction(+45.f, 200.f)); + data[Aircraft::AvengerA1].directions.push_back(Direction(+90.f, 500.f)); + data[Aircraft::AvengerA1].fireInterval = sf::seconds(2); + + data[Aircraft::AvengerA2].hitpoints = 70; + data[Aircraft::AvengerA2].speed = 110.f; + data[Aircraft::AvengerA2].texture = Textures::Avenger; + data[Aircraft::AvengerA2].directions.push_back(Direction(-45.f, 200.f)); + data[Aircraft::AvengerA2].directions.push_back(Direction(-90.f, 500.f)); + data[Aircraft::AvengerA2].fireInterval = sf::seconds(2); + + data[Aircraft::RaptorB1].hitpoints = 30; + data[Aircraft::RaptorB1].speed = 70.f; + data[Aircraft::RaptorB1].texture = Textures::Raptor; + data[Aircraft::RaptorB1].directions.push_back(Direction(+25.f, 80.f)); + data[Aircraft::RaptorB1].directions.push_back(Direction(-25.f, 160.f)); + data[Aircraft::RaptorB1].directions.push_back(Direction(+25.f, 80.f)); + data[Aircraft::RaptorB1].fireInterval = sf::Time::Zero; + + data[Aircraft::RaptorC1].hitpoints = 30; + data[Aircraft::RaptorC1].speed = 70.f; + data[Aircraft::RaptorC1].texture = Textures::Raptor; + data[Aircraft::RaptorC1].directions.push_back(Direction(0.f, 500.f)); + data[Aircraft::RaptorC1].fireInterval = sf::Time::Zero; + + data[Aircraft::RaptorC2].hitpoints = 30; + data[Aircraft::RaptorC2].speed = 70.f; + data[Aircraft::RaptorC2].texture = Textures::Raptor; + data[Aircraft::RaptorC2].directions.push_back(Direction(0.f, 500.f)); + data[Aircraft::RaptorC2].fireInterval = sf::Time::Zero; + + data[Aircraft::RaptorD1].hitpoints = 50; + data[Aircraft::RaptorD1].speed = 110.f; + data[Aircraft::RaptorD1].texture = Textures::Raptor; + data[Aircraft::RaptorD1].directions.push_back(Direction(0.f, 180.f)); + for (int i = 0; i < 3; i++) + { + for (int i = 0; i < 36; i++) + { + data[Aircraft::RaptorD1].directions.push_back(Direction(0.f + i * 10, 20.f)); + } + for (int i = 0; i < 36; i++) + { + data[Aircraft::RaptorD1].directions.push_back(Direction(0.f + i * 10, 20.f)); + } + data[Aircraft::RaptorD1].directions.push_back(Direction(0.f, 50.f)); + } + data[Aircraft::RaptorD1].directions.push_back(Direction(90.f, 500.f)); + + data[Aircraft::RaptorD2].hitpoints = 50; + data[Aircraft::RaptorD2].speed = 110.f; + data[Aircraft::RaptorD2].texture = Textures::Raptor; + data[Aircraft::RaptorD2].directions.push_back(Direction(0.f, 180.f)); + for (int i = 0; i < 3; i++) + { + for (int i = 0; i < 36; i++) + { + data[Aircraft::RaptorD2].directions.push_back(Direction(0.f - i * 10, 20.f)); + } + for (int i = 0; i < 36; i++) + { + data[Aircraft::RaptorD2].directions.push_back(Direction(0.f - i * 10, 20.f)); + } + data[Aircraft::RaptorD2].directions.push_back(Direction(0.f, 50.f)); + } + data[Aircraft::RaptorD2].directions.push_back(Direction(90.f, 500.f)); + data[Aircraft::RaptorD2].fireInterval = sf::Time::Zero; + + data[Aircraft::AvengerB1].hitpoints = 70; + data[Aircraft::AvengerB1].speed = 70.f; + data[Aircraft::AvengerB1].texture = Textures::Avenger; + data[Aircraft::AvengerB1].directions.push_back(Direction(+25.f, 80.f)); + data[Aircraft::AvengerB1].directions.push_back(Direction(-25.f, 160.f)); + data[Aircraft::AvengerB1].directions.push_back(Direction(+25.f, 80.f)); + data[Aircraft::AvengerB1].fireInterval = sf::seconds(1.5); + + data[Aircraft::RaptorB2].hitpoints = 30; + data[Aircraft::RaptorB2].speed = 70.f; + data[Aircraft::RaptorB2].texture = Textures::Raptor; + data[Aircraft::RaptorB2].directions.push_back(Direction(+25.f, 80.f)); + data[Aircraft::RaptorB2].directions.push_back(Direction(-25.f, 160.f)); + data[Aircraft::RaptorB2].directions.push_back(Direction(+25.f, 80.f)); + data[Aircraft::RaptorB2].fireInterval = sf::Time::Zero; + + + + data[Aircraft::AvengerB2].hitpoints = 70; + data[Aircraft::AvengerB2].speed = 70.f; + data[Aircraft::AvengerB2].texture = Textures::Avenger; + data[Aircraft::AvengerB2].directions.push_back(Direction(+25.f, 80.f)); + data[Aircraft::AvengerB2].directions.push_back(Direction(-25.f, 160.f)); + data[Aircraft::AvengerB2].directions.push_back(Direction(+25.f, 80.f)); + data[Aircraft::AvengerB2].fireInterval = sf::seconds(1.5); + + data[Aircraft::AvengerC1].hitpoints = 70; + data[Aircraft::AvengerC1].speed = 70.f; + data[Aircraft::AvengerC1].texture = Textures::Avenger; + data[Aircraft::AvengerC1].directions.push_back(Direction(0.f, 80.f)); + data[Aircraft::AvengerC1].directions.push_back(Direction(-25.f, 100.f)); + data[Aircraft::AvengerC1].directions.push_back(Direction(-50.f, 100.f)); + data[Aircraft::AvengerC1].directions.push_back(Direction(-75.f, 100.f)); + data[Aircraft::AvengerC1].directions.push_back(Direction(-90.f, 200.f)); + data[Aircraft::AvengerC1].fireInterval = sf::seconds(1.5); + + data[Aircraft::AvengerC2].hitpoints = 70; + data[Aircraft::AvengerC2].speed = 70.f; + data[Aircraft::AvengerC2].texture = Textures::Avenger; + data[Aircraft::AvengerC2].directions.push_back(Direction(0.f, 80.f)); + data[Aircraft::AvengerC2].directions.push_back(Direction(+25.f, 100.f)); + data[Aircraft::AvengerC2].directions.push_back(Direction(+50.f, 100.f)); + data[Aircraft::AvengerC2].directions.push_back(Direction(+75.f, 100.f)); + data[Aircraft::AvengerC2].directions.push_back(Direction(+90.f, 200.f)); + data[Aircraft::AvengerC2].fireInterval = sf::seconds(1.5); + + data[Aircraft::AvengerD1].hitpoints = 70; + data[Aircraft::AvengerD1].speed = 110.f; + data[Aircraft::AvengerD1].texture = Textures::Avenger; + data[Aircraft::AvengerD1].directions.push_back(Direction(0.f, 180.f)); + for (int i = 0; i < 3; i++) + { + for (int i = 0; i < 13; i++) + { + for (int i = 0; i < 36; i++) + { + data[Aircraft::AvengerD1].directions.push_back(Direction(0.f + i * 10, 5.f)); + } + } + data[Aircraft::AvengerD1].directions.push_back(Direction(0.f, 50.f)); + } + data[Aircraft::AvengerD1].directions.push_back(Direction(90.f, 500.f)); + data[Aircraft::AvengerD1].fireInterval = sf::seconds(1.5); + + data[Aircraft::AvengerD2].hitpoints = 70; + data[Aircraft::AvengerD2].speed = 110.f; + data[Aircraft::AvengerD2].texture = Textures::Avenger; + data[Aircraft::AvengerD2].directions.push_back(Direction(0.f, 180.f)); + for (int i = 0; i < 3; i++) + { + for (int i = 0; i < 13; i++) + { + for (int i = 0; i < 36; i++) + { + data[Aircraft::AvengerD2].directions.push_back(Direction(0.f - i * 10, 5.f)); + } + } + data[Aircraft::AvengerD2].directions.push_back(Direction(0.f, 50.f)); + } + data[Aircraft::AvengerD2].directions.push_back(Direction(-90.f, 500.f)); + data[Aircraft::AvengerD2].fireInterval = sf::seconds(1.5); + + data[Aircraft::EagleA1].hitpoints = 250; + data[Aircraft::EagleA1].speed = 170.f; + data[Aircraft::EagleA1].texture = Textures::Eagle; + data[Aircraft::EagleA1].directions.push_back(Direction(0.f, 100.f)); + data[Aircraft::EagleA1].directions.push_back(Direction(+110.f, 100.f)); + data[Aircraft::EagleA1].directions.push_back(Direction(+140.f, 200.f)); + data[Aircraft::EagleA1].directions.push_back(Direction(0.f, 30.f)); + data[Aircraft::EagleA1].directions.push_back(Direction(-110.f, 100.f)); + data[Aircraft::EagleA1].directions.push_back(Direction(-140.f, 200.f)); + data[Aircraft::EagleA1].directions.push_back(Direction(0.f, 40.f)); + data[Aircraft::EagleA1].directions.push_back(Direction(-90.f, 200.f)); + data[Aircraft::EagleA1].fireInterval = sf::seconds(2); + + data[Aircraft::EagleA2].hitpoints = 250; + data[Aircraft::EagleA2].speed = 170.f; + data[Aircraft::EagleA2].texture = Textures::Eagle; + data[Aircraft::EagleA2].directions.push_back(Direction(0.f, 100.f)); + data[Aircraft::EagleA2].directions.push_back(Direction(-110.f, 100.f)); + data[Aircraft::EagleA2].directions.push_back(Direction(-140.f, 200.f)); + data[Aircraft::EagleA2].directions.push_back(Direction(0.f, 30.f)); + data[Aircraft::EagleA2].directions.push_back(Direction(+110.f, 100.f)); + data[Aircraft::EagleA2].directions.push_back(Direction(+140.f, 200.f)); + data[Aircraft::EagleA2].directions.push_back(Direction(0.f, 40.f)); + data[Aircraft::EagleA2].directions.push_back(Direction(+90.f, 200.f)); + data[Aircraft::EagleA2].fireInterval = sf::seconds(2); + + data[Aircraft::EagleB1].hitpoints = 250; + data[Aircraft::EagleB1].speed = 170.f; + data[Aircraft::EagleB1].texture = Textures::Eagle; + data[Aircraft::EagleB1].directions.push_back(Direction(0.f, 100.f)); + for (int i = 0; i < 36; i++) + { + data[Aircraft::EagleB1].directions.push_back(Direction(0.f - i * 10, 12.f)); + } + data[Aircraft::EagleB1].directions.push_back(Direction(+110.f, 100.f)); + data[Aircraft::EagleB1].directions.push_back(Direction(+140.f, 200.f)); + data[Aircraft::EagleB1].directions.push_back(Direction(0.f, 30.f)); + for (int i = 0; i < 36; i++) + { + data[Aircraft::EagleB1].directions.push_back(Direction(0.f - i * 10,12.f)); + } + data[Aircraft::EagleB1].directions.push_back(Direction(-110.f, 100.f)); + data[Aircraft::EagleB1].directions.push_back(Direction(-140.f, 200.f)); + data[Aircraft::EagleB1].directions.push_back(Direction(0.f, 40.f)); + for (int i = 0; i < 36; i++) + { + data[Aircraft::EagleB1].directions.push_back(Direction(0.f - i * 10, 8.f)); + } + data[Aircraft::EagleB1].directions.push_back(Direction(-90.f, 200.f)); + data[Aircraft::EagleB1].fireInterval = sf::seconds(2); + + + + data[Aircraft::EagleB2].hitpoints = 250; + data[Aircraft::EagleB2].speed = 170.f; + data[Aircraft::EagleB2].texture = Textures::Eagle; + data[Aircraft::EagleB2].directions.push_back(Direction(0.f, 100.f)); + for (int i = 0; i < 36; i++) + { + data[Aircraft::EagleB1].directions.push_back(Direction(0.f + i * 10, 12.f)); + } + data[Aircraft::EagleB2].directions.push_back(Direction(-110.f, 100.f)); + data[Aircraft::EagleB2].directions.push_back(Direction(-140.f, 200.f)); + data[Aircraft::EagleB2].directions.push_back(Direction(0.f, 30.f)); + for (int i = 0; i < 36; i++) + { + data[Aircraft::EagleB2].directions.push_back(Direction(0.f + i * 10, 12.f)); + } + data[Aircraft::EagleB2].directions.push_back(Direction(+110.f, 100.f)); + data[Aircraft::EagleB2].directions.push_back(Direction(+140.f, 200.f)); + data[Aircraft::EagleB2].directions.push_back(Direction(0.f, 40.f)); + for (int i = 0; i < 36; i++) + { + data[Aircraft::EagleB2].directions.push_back(Direction(0.f + i * 10, 8.f)); + } + data[Aircraft::EagleB2].directions.push_back(Direction(+90.f, 200.f)); + data[Aircraft::EagleB2].fireInterval = sf::seconds(2); + + return data; +} + +std::vector initializeProjectileData() +{ + std::vector data(Projectile::TypeCount); + + data[Projectile::AlliedBullet].damage = 10; + data[Projectile::AlliedBullet].speed = 300.f; + data[Projectile::AlliedBullet].texture = Textures::Bullet; + + data[Projectile::EnemyBullet].damage = 10; + data[Projectile::EnemyBullet].speed = 300.f; + data[Projectile::EnemyBullet].texture = Textures::Bullet; + + data[Projectile::Missile].damage = 200; + data[Projectile::Missile].speed = 400.f; + data[Projectile::Missile].texture = Textures::Missile; + + return data; +} + diff --git a/fighters/Source/Entity.cpp b/fighters/Source/Entity.cpp new file mode 100644 index 00000000..0bf73f91 --- /dev/null +++ b/fighters/Source/Entity.cpp @@ -0,0 +1,84 @@ +#include "Include/Entity.hpp" + +Entity::Entity(int hitpoints) + : mVelocity() + , mHitpoints(hitpoints) + , mMaxHP(hitpoints) +{ +} + +void Entity::setVelocity(sf::Vector2f velocity) +{ + mVelocity = velocity; +} + +void Entity::setVelocity(float vx, float vy) +{ + mVelocity.x = vx; + mVelocity.y = vy; +} + +sf::Vector2f Entity::getVelocity() const +{ + return mVelocity; +} + +void Entity::setHP(int HP) +{ + mHitpoints = HP; +} + +void Entity::accelerate(sf::Vector2f velocity) +{ + mVelocity += velocity; +} + +void Entity::accelerate(float vx, float vy) +{ + + mVelocity.x += vx; + mVelocity.y += vy; + +} + +int Entity::getHitpoints() const +{ + return mHitpoints; +} + +void Entity::increaseHP(int increase) +{ + mHitpoints += increase; +} + + +void Entity::repair(int points) +{ + // assert(points > 0); + mHitpoints += points; + + if (mHitpoints > mMaxHP) mHitpoints = mMaxHP; + +} + +void Entity::damage(int points) +{ + // assert(points > 0); + + mHitpoints -= points; +} + +void Entity::destroy() +{ + mHitpoints = 0; +} + +bool Entity::isDestroyed() const +{ + return mHitpoints <= 0; +} + +void Entity::updateCurrent(sf::Time dt, CommandQueue&) +{ + move(mVelocity * dt.asSeconds()); +} \ No newline at end of file diff --git a/fighters/Source/Flash.cpp b/fighters/Source/Flash.cpp new file mode 100644 index 00000000..761185ae --- /dev/null +++ b/fighters/Source/Flash.cpp @@ -0,0 +1,132 @@ +#include "Include\Flash.h" +#include "Include\ResourceIdentifiers.hpp" + + +Flash::Flash(const sf::Texture & texture, Textures::ID type) + : mSprite(texture) + , mIsMarkedForRemoval(false) + , curTime(sf::seconds(0)) + , clock() + , curFrame(1) + , frameShifter(sf::seconds(0)) + , mType(type) +{ + + switch (type) + { + case Textures::Explosion: + xframes = 4; + yframes = 4; + timePerFrame = sf::seconds(1.f / 20.f); + mSprite.setPosition(-100, -100); //flashλ + break; + case Textures::Spark: + xframes = 4; + yframes = 4; + timePerFrame = sf::seconds(1.f / 40.f); + mSprite.setPosition(-25, -45); + break; + case Textures::Loop: + xframes = 5; + yframes = 5; + timePerFrame = sf::seconds(1.5f / 25.f); + mSprite.setPosition(-20, -10); + break; + case Textures::Explosion_missile: + xframes = 4; + yframes = 4; + timePerFrame = sf::seconds(1.f / 35.f); + mSprite.setPosition(-45, -45); + break; + case Textures::RebornCircle: + xframes = 7; + yframes = 7; + timePerFrame = sf::seconds(1.f / 7.f); + mSprite.setPosition(0, 0); + break; + + } + + + frameSize.x = texture.getSize().x / xframes; + frameSize.y = texture.getSize().y / yframes; + + frameRect.top = 0; + frameRect.left = 0; + frameRect.width = frameSize.x; + frameRect.height = frameSize.y; + + + flashTime = sf::seconds(xframes*yframes*timePerFrame.asSeconds()); + + + mSprite.setTextureRect(frameRect); + +} + +void Flash::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const +{ + if (!mIsMarkedForRemoval) + { + target.draw(mSprite, states); + } +} + +bool Flash::isMarkedForRemoval() const +{ + if (mType == Textures::RebornCircle) + { + if (mIsMarkedForRemoval) + { + int i = mIsMarkedForRemoval; + i = mIsMarkedForRemoval; + } + } + return mIsMarkedForRemoval; +} + +void Flash::loadTexture(sf::Texture texture) +{ + mSprite.setTexture(texture); +} + +void Flash::remove() +{ + mIsMarkedForRemoval = true; +} + + +void Flash::updateFlash(sf::Time dt) +{ + + curTime += dt; + frameShifter += dt; + + + + if (frameShifter > timePerFrame) + { + curFrame++; + frameShifter -= timePerFrame; + + if (curFrame % xframes== 1) //һ + { + float t = xframes; + frameRect.left = 0; + frameRect.top += frameRect.height; + } + else + { + frameRect.left += frameSize.x; + } + } + + mSprite.setTextureRect(frameRect); + + + if (curTime > flashTime) + { + mIsMarkedForRemoval = true; + } + +} \ No newline at end of file diff --git a/fighters/Source/Game.cpp b/fighters/Source/Game.cpp new file mode 100644 index 00000000..84d4c5db --- /dev/null +++ b/fighters/Source/Game.cpp @@ -0,0 +1,374 @@ +#include"Include\Game.h" +#include "Include\StringHelpers.hpp" +#include +#include + + + +Game::Game(): + mStatisticsNumFrames(0) + , myTime(sf::seconds(0)) + , mMode(640, 700) + , mTitle("F I G H T E R S") +{ + loadMedia(); //ȡҪļ + initialize(); //Ϸ + buildWorld(); // + +} +void Game::run() +{ + sf::Time timeSinceLastUpdate = sf::Time::Zero; + + while (mWindow->isOpen()) + { + sf::Time elapsedTime = clock.restart(); + timeSinceLastUpdate += elapsedTime; + + while (timeSinceLastUpdate > TimePerFrame) + { + timeSinceLastUpdate -= TimePerFrame; + //ֻStart Reborn 棬ҲϷҪػ + if (curStatus == gameStatus::Start || curStatus == gameStatus::Reborn) + { + processInput(); + update(TimePerFrame); + updateStatistics(elapsedTime); + + } + //ֻ滥 + updateStatus(); + } + + render(); + } +} + +void Game::updateStatus() +{ + sf::Event event; + while (mWindow->pollEvent(event)) + { + switch (event.type) + { + case sf::Event::KeyPressed: + handlePlayerInput(event.key.code, true); //ҶԽӰ + break; + case sf::Event::Closed: + mWindow->close(); + break; + } + } + handleGameOutput(); //ϷҪضԽӰ + + +} + +void Game::processInput() +{ + + CommandQueue& mCommands = mWorld->getCommandQueue(); + + sf::Event event; + while (mWindow->pollEvent(event)) + { + switch (event.type) + { + case sf::Event::KeyPressed: + handlePlayerInput(event.key.code, true); + break; + case sf::Event::Closed: + mWindow->close(); + break; + } + + mPlayer->handleEvent(event, mCommands); + + if (event.type == sf::Event::Closed) + mWindow->close(); + } + + mPlayer->handleRealtimeInput(mCommands); +} + + + +void Game::update(sf::Time deltaTime) +{ + updateGameStatus(deltaTime); //ϷҪضԽļʱӰ + mWorld->update(deltaTime); +} +void Game::render() +{ + + mWindow->clear(); + mWorld->draw(); + + mWindow->setView(mWindow->getDefaultView()); + mWindow->draw(mStatisticsText); + drawCurScene(); //ʾǰ + + mWindow->display(); + + +} + +void Game::updateStatistics(sf::Time elapsedTime) +{ + myTime += elapsedTime; + + mStatisticsText.setString("Score: " + toString(myScore)); + +} + + +void Game::handleGameOutput() +{ + switch (curStatus) //л + { + case gameStatus::Start: //Start ת Reborn + if (!mPlayer->isPlayerAlive()) + { + curStatus = gameStatus::Reborn; + BattleTheme.setPaused(true); + DefeatedTheme.play(Music::DefeatedTheme); + + mRebornNode->removeWrecks(); + + std::unique_ptr mflash(new Flash(mRebornTexture, Textures::RebornCircle)); //֮ǰcircleµ + mflash->setPosition(100, 70); + mRebornCircle = mflash.get(); + mRebornNode->attachChild(std::move(mflash)); + + } + break; + case gameStatus::Reborn: //Reborn ת Start + if (mPlayer->isPlayerAlive()) + { + getReborn(); + } + break; + } + + if (mWorld->getViewCenter().y < mWorld->getWorldLength()/2 +1500 &&!BattleThemeShifted) + { + BattleTheme.setVolume(-50.f); + + if (mWorld->getViewCenter().y < mWorld->getWorldLength() / 2 + 800 && !BattleThemeShifted) + { + BattleThemeShifted = true; + BattleTheme.setVolume(50); + BattleTheme.play(Music::BattleTheme2); + } + + + + } +} + + +void Game::handlePlayerInput(sf::Keyboard::Key key, bool isPressed) +{ + switch (curStatus) + { + case gameStatus::Intro: + introInterface(key); //intro + break; + case gameStatus::Start: + case gameStatus::Pause: + startInterface(key); //StartPauseл + break; + case gameStatus::Reborn: + if (key == sf::Keyboard::Num1) + { +// mPlayer->Reborn(); +// getReborn(); + } + case gameStatus::Over: + if (key == sf::Keyboard::Space&&mRebornCircle->isMarkedForRemoval()) + { + Restart(); + } + break; + } + +} + +void Game::updateGameStatus(sf::Time dt) +{ + + if (curStatus == gameStatus::Reborn) + { + mRebornNode->update(dt); + + if (mRebornCircle->isMarkedForRemoval()) + curStatus = gameStatus::Over; + } + +} + +void Game::loadMedia() +{ + mFont.loadFromFile("Media/Sansation.ttf"); + pauseTexture.loadFromFile("Media/Textures/Interface/pause.png"); + Intro1.loadFromFile("Media/Textures/Interface/intro1.png"); + Intro2.loadFromFile("Media/Textures/Interface/intro2.png"); + Intro3.loadFromFile("Media/Textures/Interface/intro3.png"); + Intro4.loadFromFile("Media/Textures/Interface/intro4.png"); + Intro5.loadFromFile("Media/Textures/Interface/intro5.png"); + mRebornTexture.loadFromFile("Media/Flash/circles.png"); +} + +void Game::initialize() +{ + + + curStatus = gameStatus::Intro; + introCount = 1; + + mStatisticsText.setFont(mFont); + mStatisticsText.setPosition(5.f, 5.f); + mStatisticsText.setCharacterSize(30); + + mGameOver.loadFromFile("Media/Textures/Interface/GameOver.png"); + GameoverSprite.setTexture(mGameOver); + GameoverSprite.setPosition(15.f, 310.f); + + mReborn.loadFromFile("Media/Textures/Interface/Reborn.png"); + RebornSprite.setTexture(mReborn); + RebornSprite.setPosition(15.f, 320.f); + + + TimePerFrame = sf::seconds(1.f /60.f); + + + pauseSprite.setTexture(pauseTexture); + pauseSprite.setPosition(210, 100); + + + introSprite.setTexture(Intro1); + introSprite.setPosition(0, 0); + + IntroTheme.play(Music::IntroTheme); + + BattleThemeShifted = false; + +} + +void Game::buildWorld() //Ⱥ˳Ҫ +{ + mPlayer = new Player; + mWindow = new sf::RenderWindow(mMode, mTitle); + mWorld = new World(*mWindow, myScore, mPlayer); + mRebornNode = new SceneNode; +} + +void Game::Restart() +{ + delete mPlayer; + delete mWindow; + delete mWorld; + delete mRebornNode; + + + + DefeatedTheme.stop(); + + initialize(); + buildWorld(); +} + +void Game::getReborn() +{ + mRebornCircle->remove(); //Ƴδcircle + + curStatus = gameStatus::Start; + BattleTheme.setPaused(false); + DefeatedTheme.stop(); +} + +void Game::drawCurScene() +{ + if (curStatus == gameStatus::Pause) + { + mWindow->draw(pauseSprite); + } + else if (curStatus == gameStatus::Intro) + { + mWindow->draw(introSprite); + } + else if (curStatus == gameStatus::Reborn) + { + mWindow->draw(*mRebornNode); + mWindow->draw(RebornSprite); + } + else if (curStatus == gameStatus::Over) + { + mWindow->draw(GameoverSprite); + } +} + + +void Game::introInterface(sf::Keyboard::Key key) +{ + if (curStatus == gameStatus::Intro) //Intro˵ + { + switch (key) + { + case sf::Keyboard::Q: + if (introCount == 1) + { + introCount = 2; + introSprite.setTexture(Intro2); + } + else if (introCount == 2) + { + introCount = 3; + introSprite.setTexture(Intro3); + } + break; + case sf::Keyboard::E: + if (introCount == 3) + { + introCount = 4; + introSprite.setTexture(Intro4); + } + else if (introCount == 4) + { + introCount = 5; + introSprite.setTexture(Intro5); + } + break; + case sf::Keyboard::Up: + if (introCount == 5) + { + IntroTheme.stop(); + BattleTheme.play(Music::BattleTheme1); + curStatus = gameStatus::Start; + clock.restart(); + } + break; + } + } +} + +void Game::startInterface(sf::Keyboard::Key key) +{ + if (key == sf::Keyboard::Escape) + { + if (curStatus == gameStatus::Pause) + { + curStatus = gameStatus::Start; + BattleTheme.setPaused(false); + PauseTheme.stop(); + clock.restart(); + } + else + { + curStatus = gameStatus::Pause; + BattleTheme.setPaused(true); + PauseTheme.play(Music::PauseTheme); + } + } +} + diff --git a/fighters/Source/MusicPlayer.cpp b/fighters/Source/MusicPlayer.cpp new file mode 100644 index 00000000..13d9d012 --- /dev/null +++ b/fighters/Source/MusicPlayer.cpp @@ -0,0 +1,44 @@ +#include "Include\MusicPlayer.h" + + +MusicPlayer::MusicPlayer() +: mMusic() +, mFilenames() +, mVolume(30.f) +{ + mFilenames[Music::BattleTheme1] = "Media/Music/SovietCombat1.ogg"; + mFilenames[Music::BattleTheme2] = "Media/Music/Japan Combat1.ogg"; + mFilenames[Music::DefeatedTheme] = "Media/Music/Celebration.ogg"; + mFilenames[Music::IntroTheme] = "Media/Music/Threatened in Mainland Europe.ogg"; + mFilenames[Music::PauseTheme] = "Media/Music/Exploring in Mainland Europe.ogg"; +} + +void MusicPlayer::play(Music::ID theme) +{ + std::string filename = mFilenames[theme]; + + if (!mMusic.openFromFile(filename)) + throw std::runtime_error("Music " + filename + " could not be loaded."); + + mMusic.setVolume(mVolume); + mMusic.setLoop(true); + mMusic.play(); +} + +void MusicPlayer::stop() +{ + mMusic.stop(); +} + +void MusicPlayer::setVolume(float volume) +{ + mVolume = volume; +} + +void MusicPlayer::setPaused(bool paused) +{ + if (paused) + mMusic.pause(); + else + mMusic.play(); +} \ No newline at end of file diff --git a/fighters/Source/Player.cpp b/fighters/Source/Player.cpp new file mode 100644 index 00000000..89bda0ee --- /dev/null +++ b/fighters/Source/Player.cpp @@ -0,0 +1,173 @@ +#include "Include\Player.hpp" +#include "Include\CommandQueue.hpp" +#include "Include\Aircraft.hpp" +#include "Include\Foreach.hpp" + +#include +#include +#include + +using namespace std::placeholders; + +struct AircraftMover +{ + AircraftMover(float vx, float vy) + : velocity(vx, vy) + { + }; + + void operator() (Aircraft& aircraft, sf::Time) const + { + aircraft.accelerate(velocity * aircraft.getMaxSpeed()); + } + sf::Vector2f velocity; + +}; + +Player::Player() + :playerAlive(true) + , RaptorPoint(2) + , AvengerPoint(3) + , EaglePoint(5) + , RaptorScore(10) + , AvengerScore(15) + , EagleScore(25) + +// : mCurrentMissionStatus(MissionRunning) +{ + // Set initial key bindings + mKeyBinding[sf::Keyboard::A] = MoveLeft; + mKeyBinding[sf::Keyboard::D] = MoveRight; + mKeyBinding[sf::Keyboard::W] = MoveUp; + mKeyBinding[sf::Keyboard::S] = MoveDown; + mKeyBinding[sf::Keyboard::Up] = Fire; + mKeyBinding[sf::Keyboard::Space ] = LaunchMissile; + mKeyBinding[sf::Keyboard::Q] = QMenu; + mKeyBinding[sf::Keyboard::E] = EMenu, + mKeyBinding[sf::Keyboard::Right] = GetMissileORUpgradeFire; //跨һ + mKeyBinding[sf::Keyboard::Left] = GetHpOrFirePile; + mKeyBinding[sf::Keyboard::Down] = CloseMenuOrUpgradeMissileSlot; + mKeyBinding[sf::Keyboard::Num1] = Continue; + mKeyBinding[sf::Keyboard::Num2] = Restart; + mKeyBinding[sf::Keyboard::Num3] = Exit; + + // Set initial action bindings + initializeActions(); + + // Assign all categories to player's aircraft + FOREACH(auto& pair, mActionBinding) + pair.second.category = Category::PlayerAircraft; +} + +void Player::handleEvent(const sf::Event& event, CommandQueue& commands) +{ + if (event.type == sf::Event::KeyPressed) + { + // Check if pressed key appears in key binding, trigger command if so, ¼¼ѹִ¼ + auto found = mKeyBinding.find(event.key.code); + if (found != mKeyBinding.end() && !isRealtimeAction(found->second)) + commands.push(mActionBinding[found->second]); + } +} + +void Player::handleRealtimeInput(CommandQueue & commands) +{ + // Traverse all assigned keys and check if they are pressed + FOREACH(auto pair, mKeyBinding) + { + // If key is pressed, lookup action and trigger corresponding command + if (sf::Keyboard::isKeyPressed(pair.first) && isRealtimeAction(pair.second)) + commands.push(mActionBinding[pair.second]); + } +} + + +void Player::assignKey(Action action, sf::Keyboard::Key key) +{ + // Remove all keys that already map to action + for (auto itr = mKeyBinding.begin(); itr != mKeyBinding.end(); ) + { + if (itr->second == action) + mKeyBinding.erase(itr++); + else + ++itr; + } + + // Insert new binding + mKeyBinding[key] = action; +} + +bool Player::isPlayerAlive() +{ + return playerAlive; +} + +void Player::setPlayerDead() +{ + playerAlive = false; +} + +void Player::setPlayerAlive() +{ + playerAlive = true; +} + +void Player::gameContinue() +{ + if (mAircraft->reborn()); + +} + +void Player::Reborn() +{ + mAircraft->reborn(); +} + +sf::Keyboard::Key Player::getAssignedKey(Action action) const +{ + FOREACH(auto pair, mKeyBinding) + { + if (pair.second == action) + return pair.first; + } + + return sf::Keyboard::Unknown; +} + +void Player::initializeActions() //뺯commandsӦ +{ + mActionBinding[MoveLeft].action = derivedAction(AircraftMover(-1, 0)); + mActionBinding[MoveRight].action = derivedAction(AircraftMover(+1, 0)); + mActionBinding[MoveUp].action = derivedAction(AircraftMover(0, -1)); + mActionBinding[MoveDown].action = derivedAction(AircraftMover(0, +1)); + mActionBinding[Fire].action = derivedAction([](Aircraft& a, sf::Time) { a.fire(); }); + mActionBinding[LaunchMissile].action = derivedAction([](Aircraft& a, sf::Time) { a.launchMissile(); }); + + mActionBinding[EMenu].action = derivedAction([](Aircraft& a,sf::Time) {a.openEMenu(); }); + mActionBinding[QMenu].action= derivedAction([](Aircraft& a, sf::Time) {a.openQMenu(); }); + mActionBinding[CloseMenuOrUpgradeMissileSlot].action= derivedAction([](Aircraft& a, sf::Time) {a.closeMenuOrUpgradeMissileSlot(); }); + mActionBinding[GetMissileORUpgradeFire].action = derivedAction([](Aircraft& a, sf::Time) {a.GetMissileORUpgradeFire(); }); + mActionBinding[GetHpOrFirePile].action= derivedAction([](Aircraft& a, sf::Time) {a.GetHpOrFirePile(); }); + + mActionBinding[Continue].action = derivedAction([](Aircraft& a, sf::Time) {a.reborn(); }); + mActionBinding[Restart].action = derivedAction([](Aircraft& a, sf::Time) {a.restart(); }); +} + +bool Player::isRealtimeAction(Action action) +{ + switch (action) + { + case MoveLeft: + case MoveRight: + case MoveDown: + case MoveUp: + case Fire: +// case EMenu: +// case QMenu: +// case GetMissileANDUpgradeFire: + return true; + + default: + return false; + } +} diff --git a/fighters/Source/PlayerStatusMenu.cpp b/fighters/Source/PlayerStatusMenu.cpp new file mode 100644 index 00000000..126243aa --- /dev/null +++ b/fighters/Source/PlayerStatusMenu.cpp @@ -0,0 +1,341 @@ +#include"Include\PlayerStatusMenu.h" +#include"Include\stringhelpers.hpp" +#include"Include\Aircraft.hpp" + +PlayerStatusMenu::PlayerStatusMenu(sf::RenderWindow& window) + :mWindow(window) + ,isQMEnuOpened(false) + , isEMenuOpened(false) + , isRingAChanged(false) + , isRingBChanged(false) + , Speedcount(1) + , Pilecount(1) + , Slotcount(1) +{ + initializeTexts(); +} + +void PlayerStatusMenu::updateMenu(sf::Vector2f position, int HP, int points, int missiles, int fireRateCost, int fireSpreadCost,int mMissileSlotCost) +{ + updateTexts(position, HP, points,missiles,fireRateCost,fireSpreadCost, mMissileSlotCost); + updateTextsColor(HP, points, missiles, fireRateCost, fireSpreadCost, mMissileSlotCost); + updateRings(position,fireRateCost, fireSpreadCost, mMissileSlotCost); + + EMenuSprite.setPosition(position.x + 15, position.y - 100); + QMenuSprite.setPosition(position.x - 200, position.y - 100); +} + +void PlayerStatusMenu::showMenu()const +{ + if (isEMenuOpened) + { + mWindow.draw(mHPCost); + mWindow.draw(mMissileCost); + mWindow.draw(Slot); + + + mWindow.draw(EMenuSprite); + mWindow.draw(mStatusText); + mWindow.draw(Missiles); + mWindow.draw(Slot); + mWindow.draw(mHPText); + mWindow.draw(mPoints); + + + + + } + else if (isQMEnuOpened) + { + mWindow.draw(mFireRateCost); + mWindow.draw(mFireSpreadCost); + mWindow.draw(mMissileSlotCost); + mWindow.draw(Slot); + + mWindow.draw(QMenuSprite); + mWindow.draw(mStatusText); + mWindow.draw(Missiles); + mWindow.draw(mHPText); + mWindow.draw(mPoints); + mWindow.draw(RingA); + mWindow.draw(RingB); + mWindow.draw(RingC); + } + + + +} + +void PlayerStatusMenu::openMenu(Menus menu) +{ + if (Menus::EMenu == menu) + { + isEMenuOpened = true; + } + else if (Menus::QMenu == menu) + { + isQMEnuOpened = true; + } +} + +void PlayerStatusMenu::closeMenus() +{ + isEMenuOpened = false; + isQMEnuOpened = false; +} + +bool PlayerStatusMenu::isEOpened() +{ + return isEMenuOpened; +} + +bool PlayerStatusMenu::isQOpened() +{ + return isQMEnuOpened; +} + +void PlayerStatusMenu::initializeTexts() +{ + + mFont.loadFromFile("Media/Sansation.ttf"); + mStatusText.setFont(mFont); + mStatusText.setCharacterSize(15); + + mHPText.setFont(mFont); + mHPText.setCharacterSize(15); + + mPoints.setFont(mFont); + mPoints.setCharacterSize(15); + + MissileTexture.loadFromFile("Media/Textures/Missiles4.png"); + Missiles.setTexture(MissileTexture); + missileSize.x= MissileTexture.getSize().x / 4; + missileSize.y= missileFrame.height = MissileTexture.getSize().y; + missileFrame.left = 0; + missileFrame.top = 0; + missileFrame.height= MissileTexture.getSize().y; + missileFrame.width= MissileTexture.getSize().x / 4; + + SlotTexture.loadFromFile("Media/Textures/Slot4.png"); + Slot.setTexture(SlotTexture); + slotSize.x = SlotTexture.getSize().x / 4; + slotSize.y = missileFrame.height = SlotTexture.getSize().y; + slotFrame.left = 0; + slotFrame.top = 0; + slotFrame.height = SlotTexture.getSize().y; + slotFrame.width = SlotTexture.getSize().x / 4; + + + EMenuTexture.loadFromFile("Media/Textures/EMenu.png"); + EMenuSprite.setTexture(EMenuTexture); + + QMenuTexture.loadFromFile("Media/Textures/QMenu.png"); + QMenuSprite.setTexture(QMenuTexture); + + mHPCost.setString("(5 Points)"); + mHPCost.setFont(mFont); + mHPCost.setCharacterSize(12); + + mMissileCost.setString("(2 Points)"); + mMissileCost.setFont(mFont); + mMissileCost.setCharacterSize(12); + + mFireRateCost.setFont(mFont); + mFireRateCost.setCharacterSize(12); + + mFireSpreadCost.setFont(mFont); + mFireSpreadCost.setCharacterSize(12); + + mMissileSlotCost.setFont(mFont); + mMissileSlotCost.setCharacterSize(12); + + RingATexture.loadFromFile("Media/Textures/RingA1.png"); + RingA.setTexture(RingATexture); + + RingBTexture.loadFromFile("Media/Textures/RingB1.png"); + RingB.setTexture(RingBTexture); + + RingCTexture.loadFromFile("Media/Textures/RingC1.png"); + RingC.setTexture(RingCTexture); + + + + +} + +void PlayerStatusMenu::updateTexts(sf::Vector2f position, int HP, int points, int missiles, int fireRateCost, int fireSpreadCost, int MissileSlotCost) +{ + mStatusText.setPosition(position.x - 65, position.y + 60); + mStatusText.setString("HP: " + toString(" Points:") + "\n\n" + " Missiles:"); + + mPoints.setString(toString(points)); + mPoints.setPosition(position.x + 65, position.y + 60); + + + mHPText.setPosition(position.x - 30, position.y + 60); + mHPText.setString(toString(HP)); + + + + mHPCost.setPosition(position.x + 13, position.y - 55); + mMissileCost.setPosition(position.x + 150, position.y - 55); + + mMissileSlotCost.setString("(" + toString(MissileSlotCost) + "Points)"); + mMissileSlotCost.setPosition(position.x - 135, position.y + 15); + + + mFireRateCost.setString("(" + toString(fireRateCost) + " Points" + ")"); + mFireRateCost.setPosition(position.x - 70, position.y - 55); + + mFireSpreadCost.setString("(" + toString(fireSpreadCost) + " Points" + ")"); + mFireSpreadCost.setPosition(position.x - 210, position.y - 55); + + + switch (missiles) //µ + { + case 0: + missileFrame.width = 0; + break; + case 1: + missileFrame.width = missileSize.x; + break; + case 2: + missileFrame.width = missileSize.x*2; + break; + case 3: + missileFrame.width = missileSize.x * 3; + slotFrame.width = slotSize.x * 3; + break; + case 4: + missileFrame.width = missileSize.x * 4; + slotFrame.width = slotSize.x * 4; + break; + } + + switch (Slotcount) // + { + case 1: + slotFrame.width = missileSize.x * 2; + break; + case 2: + slotFrame.width = slotSize.x * 3; + break; + case 3: + slotFrame.width = slotSize.x * 4; + break; + } + + Missiles.setTextureRect(missileFrame); + Missiles.setPosition(position.x + 20, position.y + 83); + + Slot.setTextureRect(slotFrame); + Slot.setPosition(position.x + 20, position.y + 83); + +} + +void PlayerStatusMenu::updateTextsColor(int HP, int points, int missiles, int fireRateCost, int fireSpreadCost,int missileSlotCost) +{ + sf::Color color; + mPoints.setFillColor(color.Green); + if (HP <= 30) + { + mHPText.setFillColor(color.Red); + } + else if (HP <= 60) + { + mHPText.setFillColor(color.Yellow); + } + else + { + mHPText.setFillColor(color.Green); + } + + + if (points < 5) + { + mHPCost.setFillColor(color.Red); + } + else + { + mHPCost.setFillColor(color.Blue); + } + + + if (points < 2) + { + mMissileCost.setFillColor(color.Red); + } + else + { + mMissileCost.setFillColor(color.Blue); + } + + if (points < fireRateCost) + { + mFireRateCost.setFillColor(color.Red); + } + else + { + mFireRateCost.setFillColor(color.Cyan); + } + + if (points < fireSpreadCost) + { + mFireSpreadCost.setFillColor(color.Red); + } + else + { + mFireSpreadCost.setFillColor(color.Cyan); + } + if (points < missileSlotCost) + { + mMissileSlotCost.setFillColor(color.Red); + } + else + { + mMissileSlotCost.setFillColor(color.Cyan); + } +} + +void PlayerStatusMenu::updateRings(sf::Vector2f position, int fireRateCost, int fireSpreadCost,int SlotCost) +{ + static int preFireSpread; + if (fireSpreadCost != 20) //20dzʼcost + { + if (fireSpreadCost != preFireSpread) + { + Speedcount++; + RingATexture.loadFromFile("Media/Textures/RingA" + toString(Speedcount) + ".png"); + RingA.setTexture(RingATexture); + + } + } + RingA.setPosition(position.x - 215, position.y - 45); + preFireSpread = fireSpreadCost; + + static int preFireRate; + if (fireRateCost != 10) //10dzʼcost + { + if (fireRateCost != preFireRate) + { + Pilecount ++; + RingBTexture.loadFromFile("Media/Textures/RingB" + toString(Pilecount) + ".png"); + RingB.setTexture(RingBTexture); + } + } + RingB.setPosition(position.x - 80, position.y - 45); + preFireRate = fireRateCost; + + static int preSlot; + if (SlotCost != 15) //10dzʼcost + { + if (SlotCost != preSlot) + { + Slotcount++; + RingCTexture.loadFromFile("Media/Textures/RingC" + toString(Slotcount) + ".png"); + RingC.setTexture(RingCTexture); + } + } + RingC.setPosition(position.x - 130, position.y +30); + preSlot = SlotCost; +} \ No newline at end of file diff --git a/fighters/Source/PostEffect.cpp b/fighters/Source/PostEffect.cpp new file mode 100644 index 00000000..cfdb2cf1 --- /dev/null +++ b/fighters/Source/PostEffect.cpp @@ -0,0 +1,32 @@ +#include "Include\PostEffect.hpp" + +#include +#include +#include + + +PostEffect::~PostEffect() +{ +} + +void PostEffect::applyShader(const sf::Shader& shader, sf::RenderTarget& output) +{ + sf::Vector2f outputSize = static_cast(output.getSize()); + + sf::VertexArray vertices(sf::TrianglesStrip, 4); + vertices[0] = sf::Vertex(sf::Vector2f(0, 0), sf::Vector2f(0, 1)); + vertices[1] = sf::Vertex(sf::Vector2f(outputSize.x, 0), sf::Vector2f(1, 1)); + vertices[2] = sf::Vertex(sf::Vector2f(0, outputSize.y), sf::Vector2f(0, 0)); + vertices[3] = sf::Vertex(sf::Vector2f(outputSize), sf::Vector2f(1, 0)); + + sf::RenderStates states; + states.shader = &shader; + states.blendMode = sf::BlendNone; + + output.draw(vertices, states); +} + +bool PostEffect::isSupported() +{ + return sf::Shader::isAvailable(); +} diff --git a/fighters/Source/Projectile.cpp b/fighters/Source/Projectile.cpp new file mode 100644 index 00000000..96de75b6 --- /dev/null +++ b/fighters/Source/Projectile.cpp @@ -0,0 +1,81 @@ +#include "Include\Projectile.hpp" +#include "Include\utility.hpp" +#include"Include\ResourceHolder.hpp" +#include"Include\Datatables.hpp" + + +#include +#include + +#include +#include + +namespace +{ + const std::vector Table = initializeProjectileData(); +} + +Projectile::Projectile(Type type, const TextureHolder& textures) + : Entity(1) + , mType(type) + , mSprite(textures.get(Table[type].texture)) + , mTargetDirection() +{ + centerOrigin(mSprite); +} + +void Projectile::guideTowards(sf::Vector2f position) +{ + assert(isGuided()); + mTargetDirection = unitVector(position - getWorldPosition()); +} + +bool Projectile::isGuided() const +{ + return mType == Missile; +} + +void Projectile::updateCurrent(sf::Time dt, CommandQueue& commands) +{ + if (isGuided()) + { + const float approachRate = 300.f; //׷ٲ + + sf::Vector2f newVelocity = unitVector(approachRate * dt.asSeconds() * mTargetDirection + getVelocity()); + newVelocity *= getMaxSpeed(); + float angle = std::atan2(newVelocity.y, newVelocity.x); + + setRotation(toDegree(angle) + 90.f); + setVelocity(newVelocity); + } + + Entity::updateCurrent(dt, commands); +} + +void Projectile::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const +{ + target.draw(mSprite, states); +} + +unsigned int Projectile::getCategory() const +{ + if (mType == EnemyBullet) + return Category::EnemyProjectile; + else + return Category::AlliedProjectile; +} + +sf::FloatRect Projectile::getBoundingRect() const +{ + return getWorldTransform().transformRect(mSprite.getGlobalBounds()); +} + +float Projectile::getMaxSpeed() const +{ + return Table[mType].speed; +} + +int Projectile::getDamage() const +{ + return Table[mType].damage; +} \ No newline at end of file diff --git a/fighters/Source/SceneNode.cpp b/fighters/Source/SceneNode.cpp new file mode 100644 index 00000000..2d535f83 --- /dev/null +++ b/fighters/Source/SceneNode.cpp @@ -0,0 +1,212 @@ +#include "Include/SceneNode.hpp" +#include "Include\Foreach.hpp" +#include"Include\Command.hpp" +#include"Include\utility.hpp" + + +#include +#include + +#include +#include +#include + + +SceneNode::SceneNode(Category::Type category) + : mChildren() + , mParent(nullptr) + , mDefaultCategory(category) +{ +} + +void SceneNode::attachChild(Ptr child) +{ + child->mParent = this; + mChildren.push_back(std::move(child)); +} + +SceneNode::Ptr SceneNode::detachChild(const SceneNode& node) +{ + auto found = std::find_if(mChildren.begin(), mChildren.end(), [&](Ptr& p) { return p.get() == &node; }); + assert(found != mChildren.end()); + + Ptr result = std::move(*found); + result->mParent = nullptr; + mChildren.erase(found); + return result; +} + +void SceneNode::update(sf::Time dt, CommandQueue& commands) +{ + updateCurrent(dt, commands); + updateChildren(dt, commands); +} + +void SceneNode::updateCurrent(sf::Time, CommandQueue&) +{ + // Do nothing by default +} + +void SceneNode::updateChildren(sf::Time dt, CommandQueue& commands) +{ + FOREACH(Ptr& child, mChildren) + child->update(dt, commands); +} + +void SceneNode::update(sf::Time dt) +{ + FOREACH(Ptr& child, mChildren) + child->updateFlash(dt); + +} + +void SceneNode::updateFlash(sf::Time dt) +{ +// +} + +bool SceneNode::toRemove() +{ + return false; +} + +void SceneNode::draw(sf::RenderTarget& target, sf::RenderStates states) const +{ + // Apply transform of current node + states.transform *= getTransform(); + + // Draw node and children with changed transform + drawCurrent(target, states); + drawChildren(target, states); + + // Draw bounding rectangle - disabled by default + //drawBoundingRect(target, states); +} + +void SceneNode::drawCurrent(sf::RenderTarget&, sf::RenderStates) const +{ + // Do nothing by default +} + +void SceneNode::drawChildren(sf::RenderTarget& target, sf::RenderStates states) const +{ + FOREACH(const Ptr& child, mChildren) + child->draw(target, states); +} + +void SceneNode::drawBoundingRect(sf::RenderTarget& target, sf::RenderStates) const +{ + sf::FloatRect rect = getBoundingRect(); + + sf::RectangleShape shape; + shape.setPosition(sf::Vector2f(rect.left, rect.top)); + shape.setSize(sf::Vector2f(rect.width, rect.height)); + shape.setFillColor(sf::Color::Transparent); + shape.setOutlineColor(sf::Color::Green); + shape.setOutlineThickness(1.f); + + target.draw(shape); +} + +sf::Vector2f SceneNode::getWorldPosition() const +{ + return getWorldTransform() * sf::Vector2f(); +} + +sf::Transform SceneNode::getWorldTransform() const +{ + sf::Transform transform = sf::Transform::Identity; + + for (const SceneNode* node = this; node != nullptr; node = node->mParent) + transform = node->getTransform() * transform; + + return transform; +} + +void SceneNode::onCommand(const Command& command, sf::Time dt) +{ + // Command current node, if category matches + if (command.category & getCategory()) + command.action(*this, dt); + + // Command children + FOREACH(Ptr& child, mChildren) + child->onCommand(command, dt); +} + +unsigned int SceneNode::getCategory() const +{ + return mDefaultCategory; +} + +void SceneNode::checkSceneCollision(SceneNode& sceneGraph, std::set& collisionPairs) +{ + checkNodeCollision(sceneGraph, collisionPairs); + + FOREACH(Ptr& child, sceneGraph.mChildren) + checkSceneCollision(*child, collisionPairs); +} + +void SceneNode::checkNodeCollision(SceneNode& node, std::set& collisionPairs) +{ + if (this != &node && collision(*this, node) && !isDestroyed() && !node.isDestroyed()) + collisionPairs.insert(std::minmax(this, &node)); + + FOREACH(Ptr& child, mChildren) + child->checkNodeCollision(node, collisionPairs); +} + +void SceneNode::removeWrecks() +{ + // Remove all children which request so + auto wreckfieldBegin = std::remove_if(mChildren.begin(), mChildren.end(), std::mem_fn(&SceneNode::isMarkedForRemoval)); + mChildren.erase(wreckfieldBegin, mChildren.end()); + + // Call function recursively for all remaining children + std::for_each(mChildren.begin(), mChildren.end(), std::mem_fn(&SceneNode::removeWrecks)); +} + +void SceneNode::removeBlooms() +{ + + FOREACH(Ptr& child, mChildren) + { + if (child->toRemove()) + { + this->detachChild(*child); + } + } + +} + +sf::FloatRect SceneNode::getBoundingRect() const +{ + return sf::FloatRect(); +} + +bool SceneNode::isMarkedForRemoval() const +{ + // By default, remove node if entity is destroyed + return isDestroyed(); +} + +bool SceneNode::isDestroyed() const +{ + // By default, scene node needn't be removed + return false; +} + +bool SceneNode::toRemove()const +{ + return false; +} + +bool collision(const SceneNode& lhs, const SceneNode& rhs) +{ + return lhs.getBoundingRect().intersects(rhs.getBoundingRect()); +} + +float distance(const SceneNode& lhs, const SceneNode& rhs) +{ + return length(lhs.getWorldPosition() - rhs.getWorldPosition()); +} \ No newline at end of file diff --git a/fighters/Source/ShadersEffect.cpp b/fighters/Source/ShadersEffect.cpp new file mode 100644 index 00000000..23d3e0cc --- /dev/null +++ b/fighters/Source/ShadersEffect.cpp @@ -0,0 +1,98 @@ +#include"Include\ShadersEffect.h" + +ShadersEffect::ShadersEffect() + : mShaders() + , mBrightnessTexture() + , mFirstPassTextures() + , mSecondPassTextures() +{ + mShaders.load(Shaders::BrightnessPass, "Media/Shaders/Fullpass.vert", "Media/Shaders/Brightness.frag"); + mShaders.load(Shaders::DownSamplePass, "Media/Shaders/Fullpass.vert", "Media/Shaders/DownSample.frag"); + mShaders.load(Shaders::GaussianBlurPass, "Media/Shaders/Fullpass.vert", "Media/Shaders/GuassianBlur.frag"); + mShaders.load(Shaders::AddPass, "Media/Shaders/Fullpass.vert", "Media/Shaders/Add.frag"); +} + +void ShadersEffect::apply(const sf::RenderTexture& input, sf::RenderTarget& output) +{ + prepareTextures(input.getSize()); + + filterBright(input, mBrightnessTexture); + + downsample(mBrightnessTexture, mFirstPassTextures[0]); + blurMultipass(mFirstPassTextures); + + downsample(mFirstPassTextures[0], mSecondPassTextures[0]); + blurMultipass(mSecondPassTextures); + + add(mFirstPassTextures[0], mSecondPassTextures[0], mFirstPassTextures[1]); + mFirstPassTextures[1].display(); + add(input, mFirstPassTextures[1], output); +} + +void ShadersEffect::prepareTextures(sf::Vector2u size) +{ + if (mBrightnessTexture.getSize() != size) + { + mBrightnessTexture.create(size.x, size.y); + mBrightnessTexture.setSmooth(true); + + mFirstPassTextures[0].create(size.x / 2, size.y / 2); + mFirstPassTextures[0].setSmooth(true); + mFirstPassTextures[1].create(size.x / 2, size.y / 2); + mFirstPassTextures[1].setSmooth(true); + + mSecondPassTextures[0].create(size.x / 4, size.y / 4); + mSecondPassTextures[0].setSmooth(true); + mSecondPassTextures[1].create(size.x / 4, size.y / 4); + mSecondPassTextures[1].setSmooth(true); + } +} + +void ShadersEffect::filterBright(const sf::RenderTexture& input, sf::RenderTexture& output) +{ + sf::Shader& brightness = mShaders.get(Shaders::BrightnessPass); + + brightness.setParameter("source", input.getTexture()); + applyShader(brightness, output); + output.display(); +} + +void ShadersEffect::blurMultipass(RenderTextureArray& renderTextures) +{ + sf::Vector2u textureSize = renderTextures[0].getSize(); + + for (std::size_t count = 0; count < 2; ++count) + { + blur(renderTextures[0], renderTextures[1], sf::Vector2f(0.f, 1.f / textureSize.y)); + blur(renderTextures[1], renderTextures[0], sf::Vector2f(1.f / textureSize.x, 0.f)); + } +} + +void ShadersEffect::blur(const sf::RenderTexture& input, sf::RenderTexture& output, sf::Vector2f offsetFactor) +{ + sf::Shader& gaussianBlur = mShaders.get(Shaders::GaussianBlurPass); + + gaussianBlur.setParameter("source", input.getTexture()); + gaussianBlur.setParameter("offsetFactor", offsetFactor); + applyShader(gaussianBlur, output); + output.display(); +} + +void ShadersEffect::downsample(const sf::RenderTexture& input, sf::RenderTexture& output) +{ + sf::Shader& downSampler = mShaders.get(Shaders::DownSamplePass); + + downSampler.setParameter("source", input.getTexture()); + downSampler.setParameter("sourceSize", sf::Vector2f(input.getSize())); + applyShader(downSampler, output); + output.display(); +} + +void ShadersEffect::add(const sf::RenderTexture& source, const sf::RenderTexture& bloom, sf::RenderTarget& output) +{ + sf::Shader& adder = mShaders.get(Shaders::AddPass); + + adder.setParameter("source", source.getTexture()); + adder.setParameter("bloom", bloom.getTexture()); + applyShader(adder, output); +} diff --git a/fighters/Source/SoundHolder.cpp b/fighters/Source/SoundHolder.cpp new file mode 100644 index 00000000..9fcbaa5f --- /dev/null +++ b/fighters/Source/SoundHolder.cpp @@ -0,0 +1,35 @@ +#include"Include\SoundHolder.hpp" + +SoundHolder::SoundHolder() +{ + mSounds.load(SoundEffect::AlliedGunfire, "Media/Sound/AlliedGunfire.wav"); + mSounds.load(SoundEffect::EnemyGunfire, "Media/Sound/EnemyGunfire.wav"); + mSounds.load(SoundEffect::Explosion1, "Media/Sound/Explosion1.wav"); + mSounds.load(SoundEffect::Explosion2, "Media/Sound/Explosion2.wav"); + mSounds.load(SoundEffect::LaunchMissile, "Media/Sound/LaunchMissile.wav"); + mSounds.load(SoundEffect::CollectPickup, "Media/Sound/CollectPickup.wav"); + mSounds.load(SoundEffect::Upgrade, "Media/Sound/Upgrade.wav"); + mSounds.load(SoundEffect::Purchase, "Media/Sound/Purchase.wav"); +} + +void SoundHolder::play(SoundEffect::ID type) +{ + sf::Sound toQueue; + toQueue.setBuffer(mSounds.get(type)); + soundQueue.push(toQueue); + + sf::Sound& sound = soundQueue.back(); + sound.play(); + +} +void SoundHolder::emptyQueue() +{ + if (!soundQueue.empty()) + { + if (soundQueue.front().getStatus() == sf::Sound::Stopped) + { + soundQueue.pop(); + } + } + +} diff --git a/fighters/Source/SpriteNode.cpp b/fighters/Source/SpriteNode.cpp new file mode 100644 index 00000000..ef8ceb58 --- /dev/null +++ b/fighters/Source/SpriteNode.cpp @@ -0,0 +1,19 @@ +#include "Include/SpriteNode.hpp" + +#include + + +SpriteNode::SpriteNode(const sf::Texture& texture) +: mSprite(texture) +{ +} + +SpriteNode::SpriteNode(const sf::Texture& texture, const sf::IntRect& textureRect) +: mSprite(texture, textureRect) +{ +} + +void SpriteNode::drawCurrent(sf::RenderTarget& target, sf::RenderStates states) const +{ + target.draw(mSprite, states); +} \ No newline at end of file diff --git a/fighters/Source/Utility.cpp b/fighters/Source/Utility.cpp new file mode 100644 index 00000000..c54ca86c --- /dev/null +++ b/fighters/Source/Utility.cpp @@ -0,0 +1,173 @@ +#include "Include\utility.hpp" + +#include +#include + +#include +#include +#include +#include + + +namespace +{ + std::default_random_engine createRandomEngine() + { + auto seed = static_cast(std::time(nullptr)); + return std::default_random_engine(seed); + } + + auto RandomEngine = createRandomEngine(); +} + +std::string toString(sf::Keyboard::Key key) +{ + #define BOOK_KEYTOSTRING_CASE(KEY) case sf::Keyboard::KEY: return #KEY; + + switch (key) + { + BOOK_KEYTOSTRING_CASE(Unknown) + BOOK_KEYTOSTRING_CASE(A) + BOOK_KEYTOSTRING_CASE(B) + BOOK_KEYTOSTRING_CASE(C) + BOOK_KEYTOSTRING_CASE(D) + BOOK_KEYTOSTRING_CASE(E) + BOOK_KEYTOSTRING_CASE(F) + BOOK_KEYTOSTRING_CASE(G) + BOOK_KEYTOSTRING_CASE(H) + BOOK_KEYTOSTRING_CASE(I) + BOOK_KEYTOSTRING_CASE(J) + BOOK_KEYTOSTRING_CASE(K) + BOOK_KEYTOSTRING_CASE(L) + BOOK_KEYTOSTRING_CASE(M) + BOOK_KEYTOSTRING_CASE(N) + BOOK_KEYTOSTRING_CASE(O) + BOOK_KEYTOSTRING_CASE(P) + BOOK_KEYTOSTRING_CASE(Q) + BOOK_KEYTOSTRING_CASE(R) + BOOK_KEYTOSTRING_CASE(S) + BOOK_KEYTOSTRING_CASE(T) + BOOK_KEYTOSTRING_CASE(U) + BOOK_KEYTOSTRING_CASE(V) + BOOK_KEYTOSTRING_CASE(W) + BOOK_KEYTOSTRING_CASE(X) + BOOK_KEYTOSTRING_CASE(Y) + BOOK_KEYTOSTRING_CASE(Z) + BOOK_KEYTOSTRING_CASE(Num0) + BOOK_KEYTOSTRING_CASE(Num1) + BOOK_KEYTOSTRING_CASE(Num2) + BOOK_KEYTOSTRING_CASE(Num3) + BOOK_KEYTOSTRING_CASE(Num4) + BOOK_KEYTOSTRING_CASE(Num5) + BOOK_KEYTOSTRING_CASE(Num6) + BOOK_KEYTOSTRING_CASE(Num7) + BOOK_KEYTOSTRING_CASE(Num8) + BOOK_KEYTOSTRING_CASE(Num9) + BOOK_KEYTOSTRING_CASE(Escape) + BOOK_KEYTOSTRING_CASE(LControl) + BOOK_KEYTOSTRING_CASE(LShift) + BOOK_KEYTOSTRING_CASE(LAlt) + BOOK_KEYTOSTRING_CASE(LSystem) + BOOK_KEYTOSTRING_CASE(RControl) + BOOK_KEYTOSTRING_CASE(RShift) + BOOK_KEYTOSTRING_CASE(RAlt) + BOOK_KEYTOSTRING_CASE(RSystem) + BOOK_KEYTOSTRING_CASE(Menu) + BOOK_KEYTOSTRING_CASE(LBracket) + BOOK_KEYTOSTRING_CASE(RBracket) + BOOK_KEYTOSTRING_CASE(SemiColon) + BOOK_KEYTOSTRING_CASE(Comma) + BOOK_KEYTOSTRING_CASE(Period) + BOOK_KEYTOSTRING_CASE(Quote) + BOOK_KEYTOSTRING_CASE(Slash) + BOOK_KEYTOSTRING_CASE(BackSlash) + BOOK_KEYTOSTRING_CASE(Tilde) + BOOK_KEYTOSTRING_CASE(Equal) + BOOK_KEYTOSTRING_CASE(Dash) + BOOK_KEYTOSTRING_CASE(Space) + BOOK_KEYTOSTRING_CASE(Return) + BOOK_KEYTOSTRING_CASE(BackSpace) + BOOK_KEYTOSTRING_CASE(Tab) + BOOK_KEYTOSTRING_CASE(PageUp) + BOOK_KEYTOSTRING_CASE(PageDown) + BOOK_KEYTOSTRING_CASE(End) + BOOK_KEYTOSTRING_CASE(Home) + BOOK_KEYTOSTRING_CASE(Insert) + BOOK_KEYTOSTRING_CASE(Delete) + BOOK_KEYTOSTRING_CASE(Add) + BOOK_KEYTOSTRING_CASE(Subtract) + BOOK_KEYTOSTRING_CASE(Multiply) + BOOK_KEYTOSTRING_CASE(Divide) + BOOK_KEYTOSTRING_CASE(Left) + BOOK_KEYTOSTRING_CASE(Right) + BOOK_KEYTOSTRING_CASE(Up) + BOOK_KEYTOSTRING_CASE(Down) + BOOK_KEYTOSTRING_CASE(Numpad0) + BOOK_KEYTOSTRING_CASE(Numpad1) + BOOK_KEYTOSTRING_CASE(Numpad2) + BOOK_KEYTOSTRING_CASE(Numpad3) + BOOK_KEYTOSTRING_CASE(Numpad4) + BOOK_KEYTOSTRING_CASE(Numpad5) + BOOK_KEYTOSTRING_CASE(Numpad6) + BOOK_KEYTOSTRING_CASE(Numpad7) + BOOK_KEYTOSTRING_CASE(Numpad8) + BOOK_KEYTOSTRING_CASE(Numpad9) + BOOK_KEYTOSTRING_CASE(F1) + BOOK_KEYTOSTRING_CASE(F2) + BOOK_KEYTOSTRING_CASE(F3) + BOOK_KEYTOSTRING_CASE(F4) + BOOK_KEYTOSTRING_CASE(F5) + BOOK_KEYTOSTRING_CASE(F6) + BOOK_KEYTOSTRING_CASE(F7) + BOOK_KEYTOSTRING_CASE(F8) + BOOK_KEYTOSTRING_CASE(F9) + BOOK_KEYTOSTRING_CASE(F10) + BOOK_KEYTOSTRING_CASE(F11) + BOOK_KEYTOSTRING_CASE(F12) + BOOK_KEYTOSTRING_CASE(F13) + BOOK_KEYTOSTRING_CASE(F14) + BOOK_KEYTOSTRING_CASE(F15) + BOOK_KEYTOSTRING_CASE(Pause) + } + + return ""; +} + +void centerOrigin(sf::Sprite& sprite) +{ + sf::FloatRect bounds = sprite.getLocalBounds(); + sprite.setOrigin(std::floor(bounds.width / 2.f), std::floor(bounds.height / 2.f)); +} + +void centerOrigin(sf::Text& text) +{ + sf::FloatRect bounds = text.getLocalBounds(); + text.setOrigin(std::floor(bounds.width / 2.f), std::floor(bounds.height / 2.f)); +} + +float toDegree(float radian) +{ + return 180.f / 3.141592653589793238462643383f * radian; +} + +float toRadian(float degree) +{ + return 3.141592653589793238462643383f / 180.f * degree; +} + +int randomInt(int exclusiveMax) +{ + std::uniform_int_distribution<> distr(0, exclusiveMax - 1); + return distr(RandomEngine); +} + +float length(sf::Vector2f vector) +{ + return std::sqrt(vector.x * vector.x + vector.y * vector.y); +} + +sf::Vector2f unitVector(sf::Vector2f vector) +{ + assert(vector != sf::Vector2f(0.f, 0.f)); + return vector / length(vector); +} \ No newline at end of file diff --git a/fighters/Source/World.cpp b/fighters/Source/World.cpp new file mode 100644 index 00000000..a05aeabd --- /dev/null +++ b/fighters/Source/World.cpp @@ -0,0 +1,973 @@ +#include "Include\World.hpp" +#include"Include\Projectile.hpp" +#include "Include\Foreach.hpp" +#include"Include\Player.hpp" + +#include + +#include +#include +#include +#include + +bool matchesCategories(SceneNode::Pair& colliders, Category::Type type1, Category::Type type2); + +World::World(sf::RenderWindow& window, int& mScore, Player* player) + : mWindow(window) + , mWorldView(window.getDefaultView()) + , mFonts(mFonts) + , mWorldLength(20000.f) + , mSounds() + , mTextures() + , mSceneGraph() + , mSceneLayers() + , mWorldBounds(0.f, 0.f, mWorldView.getSize().x, mWorldLength) + , mSpawnPosition(mWorldView.getSize().x / 2.f, mWorldBounds.height - mWorldView.getSize().y / 2.f) + , mViewCenter(mSpawnPosition) + , mScrollSpeed(-50.f) + , mPlayerAircraft(nullptr) + , mEnemySpawnPoints() + , mAllies() + , mActiveEnemies() + , mRandomEvents(sf::seconds(5), sf::seconds(10), sf::seconds(0)) + , mScore(mScore) + , mPlayer(player) +{ + + srand(time(0)); + + loadTextures(); + buildScene(); + + // Prepare the view + mWorldView.setCenter(mSpawnPosition); +} + +void World::update(sf::Time dt) +{ + // Scroll the world, reset player velocity + mWorldView.move(0.f, mScrollSpeed * dt.asSeconds()); + mViewCenter.y -= mScrollSpeed * dt.asSeconds(); + randomEvents(dt); + + mPlayerAircraft->setVelocity(0.f, 0.f); + + + + // Setup commands to destroy entities, and guide missiles + destroyEntitiesOutsideView(); + guideMissiles(); + + // Forward commands to scene graph, adapt velocity (scrolling, diagonal correction) + while (!mCommandQueue.isEmpty()) + mSceneGraph.onCommand(mCommandQueue.pop(), dt); + + //adjust the velocity of diagonal movements + sf::Vector2f velocity = mPlayerAircraft->getVelocity(); + if (velocity.x != 0.f && velocity.y != 0.f) + mPlayerAircraft->setVelocity(velocity / std::sqrt(2.f)); + + mPlayerAircraft->accelerate(0.f, mScrollSpeed); //ʹĻԾֹ + + // Collision detection and response (may destroy entities) + handleCollisions(); + + // Remove all destroyed entities, create new ones + mSceneGraph.removeWrecks(); + spawnEnemies(); + + // Regular update step, adapt position (correct if outside view) + mSceneGraph.update(dt, mCommandQueue); //˺ʵַɻλƣentity virtual void updateCurrent(sf::Time dt, CommandQueue& commands); + + adaptPlayerPosition(); + mSounds.emptyQueue(); + + + mFlashNode.update(dt); + mFlashNode.removeWrecks(); //ƳFlashڵ + + + mScore = mPlayerAircraft->getScore(); + +} + +void World::draw() +{ + mWindow.setView(mWorldView); + mWindow.draw(mSceneGraph); + + mWindow.draw(mFlashNode); + +} + +CommandQueue& World::getCommandQueue() +{ + return mCommandQueue; +} + +bool World::hasAlivePlayer() const +{ + return !mPlayerAircraft->isMarkedForRemoval(); +} + +bool World::hasPlayerReachedEnd() const +{ + return !mWorldBounds.contains(mPlayerAircraft->getPosition()); +} + +void World::loadTextures() +{ + mTextures.load(Textures::Eagle, "Media/Textures/Eagle.png"); + mTextures.load(Textures::Raptor, "Media/Textures/Raptor.png"); + mTextures.load(Textures::Avenger, "Media/Textures/Avenger.png"); + mTextures.load(Textures::Desert, "Media/Textures/Desert.png"); + mTextures.load(Textures::Jungle, "Media/Textures/Jungle.png"); + mTextures.load(Textures::UpCloud, "Media/Textures/UpCloud.png"); + mTextures.load(Textures::DownCloud, "Media/Textures/DownCloud.png"); + mTextures.load(Textures::MidCloud, "Media/Textures/MidCloud.png"); + + mTextures.load(Textures::Bullet, "Media/Textures/Bullet.png"); + mTextures.load(Textures::Missile, "Media/Textures/Missile.png"); + + mTextures.load(Textures::HealthRefill, "Media/Textures/HealthRefill.png"); + mTextures.load(Textures::MissileRefill, "Media/Textures/MissileRefill.png"); + mTextures.load(Textures::FireSpread, "Media/Textures/FireSpread.png"); + mTextures.load(Textures::FireRate, "Media/Textures/FireRate.png"); + + mTextures.load(Textures::Explosion, "Media/Textures/Explosion.png"); + mTextures.load(Textures::Spark, "Media/Textures/Spark.png"); + mTextures.load(Textures::Explosion_missile, "Media/Textures/Explosion_missile.png"); +} + +void World::adaptPlayerPosition() +{ + // Keep player's position inside the screen bounds, at least borderDistance units from the border + sf::FloatRect viewBounds = getViewBounds(); + const float borderDistance = 40.f; + + sf::Vector2f position = mPlayerAircraft->getPosition(); + position.x = std::max(position.x, viewBounds.left + borderDistance-30); + position.x = std::min(position.x, viewBounds.left + viewBounds.width - borderDistance+30); + position.y = std::max(position.y, viewBounds.top + borderDistance); + position.y = std::min(position.y, viewBounds.top + viewBounds.height - borderDistance+10); + mPlayerAircraft->setPosition(position); +} + + + +bool matchesCategories(SceneNode::Pair& colliders, Category::Type type1, Category::Type type2) +{ + unsigned int category1 = colliders.first->getCategory(); + unsigned int category2 = colliders.second->getCategory(); + + // Make sure first pair entry has category type1 and second has type2 + if (type1 & category1 && type2 & category2) + { + return true; + } + else if (type1 & category2 && type2 & category1) + { + std::swap(colliders.first, colliders.second); + return true; + } + else + { + return false; + } +} + + +void World::buildScene() +{ + // Initialize the different layers + for (std::size_t i = 0; i < LayerCount; ++i) + { + Category::Type category = (i == Air) ? Category::SceneAirLayer : Category::None; + + SceneNode::Ptr layer(new SceneNode(category)); + mSceneLayers[i] = layer.get(); + + mSceneGraph.attachChild(std::move(layer)); + } + + // Prepare the tiled background + + sf::Texture& texture1 = mTextures.get(Textures::Desert); + sf::Texture& texture2 = mTextures.get(Textures::Jungle); + sf::Texture& DowncloudsTexture = mTextures.get(Textures::DownCloud ); + sf::Texture& UpcloudsTexture = mTextures.get(Textures::UpCloud); + sf::Texture& MidCloudTexture = mTextures.get(Textures::MidCloud); + + sf::IntRect textureRect(mWorldBounds); + + texture1.setRepeated(true); + texture2.setRepeated(true); + DowncloudsTexture.setRepeated(true); + UpcloudsTexture.setRepeated(false); + MidCloudTexture.setRepeated(false); + + // Add the background sprite to the scene + + std::unique_ptr backgroundSprite2(new SpriteNode(texture2, textureRect)); + backgroundSprite2->setPosition(mWorldBounds.left, mWorldBounds.top); + mSceneLayers[Background]->attachChild(std::move(backgroundSprite2)); + + std::unique_ptr backgroundSprite1(new SpriteNode(texture1, textureRect)); + backgroundSprite1->setPosition(mWorldBounds.left, mWorldBounds.top+ mWorldLength/2); + mSceneLayers[Background]->attachChild(std::move(backgroundSprite1)); + + std::unique_ptr mDownCloud(new SpriteNode(DowncloudsTexture, textureRect)); + mDownCloud->setPosition(mWorldBounds.left, mWorldBounds.top ); + mSceneLayers[DownCloud]->attachChild(std::move(mDownCloud)); + + for (float y = 0; y < mWorldBounds.top + mWorldLength / 2- UpcloudsTexture.getSize().y/2; y += UpcloudsTexture.getSize().y) //ؿϲ + { + std::unique_ptr mUpCloud(new SpriteNode(UpcloudsTexture, textureRect)); + mUpCloud->setPosition(mWorldBounds.left, y); + mSceneLayers[UpCloud]->attachChild(std::move(mUpCloud)); + } + + std::unique_ptr mMidCloud(new SpriteNode(MidCloudTexture, textureRect)); + mMidCloud->setPosition(mWorldBounds.left, mWorldBounds.top + mWorldLength / 2- MidCloudTexture.getSize().y/2); + mSceneLayers[UpCloud]->attachChild(std::move(mMidCloud)); + + + + + + // Add player's aircraft + std::unique_ptr player(new Aircraft(mWindow,Aircraft::Eagle, mTextures, mFonts,mSounds,true,mPlayer)); + mPlayerAircraft = player.get(); + mPlayerAircraft->setPosition(mSpawnPosition); + mSceneLayers[Air]->attachChild(std::move(player)); + + // Add enemy aircraft + addEnemies(); + +} + +void World::updateScore(Aircraft& mAircraft) +{ + + if (!mAircraft.isAllied() && mAircraft.isDestroyed()) + { + switch (mAircraft.getType()) + { + case Aircraft::Type::Raptor: + case Aircraft::Type::RaptorA1: + case Aircraft::Type::RaptorA2: + case Aircraft::Type::RaptorB1: + case Aircraft::Type::RaptorB2: + case Aircraft::Type::RaptorC1: + case Aircraft::Type::RaptorC2: + case Aircraft::Type::RaptorD1: + case Aircraft::Type::RaptorD2: + mScore += mPlayer->RaptorScore; + mPlayerAircraft->addPoints(mPlayer->RaptorPoint); + break; + case Aircraft::Type::Avenger: + case Aircraft::Type::AvengerA1: + case Aircraft::Type::AvengerA2: + case Aircraft::Type::AvengerB1: + case Aircraft::Type::AvengerB2: + case Aircraft::Type::AvengerC1: + case Aircraft::Type::AvengerC2: + case Aircraft::Type::AvengerD1: + case Aircraft::Type::AvengerD2: + mScore += mPlayer->AvengerScore; + mPlayerAircraft->addPoints(mPlayer->AvengerPoint); + break; + case Aircraft::Type::EagleA1: + case Aircraft::Type::EagleA2: + case Aircraft::Type::EagleB1: + case Aircraft::Type::EagleB2: + mScore += mPlayer->EagleScore; + mPlayerAircraft->addPoints(mPlayer->EaglePoint); + break; + } + mSounds.play(SoundEffect::Explosion2); + mPlayerAircraft->updateScore(mScore); + addFlash(Textures::Explosion,mAircraft.getPosition().x, mAircraft.getPosition().y); + } + +} + +void World::addEnemies() +{ + + addEagleA1(2000); + addEagleA1(4000); + addEagleB1(6000); + addEagleB1(8000); + + addEagleA1(12000); + addEagleA1(14000); + addEagleB1(16000); + addEagleB1(18000); + + + // Add enemies to the spawn point container + addEnemy(Aircraft::Raptor, 0.f, 500.f); + addEnemy(Aircraft::Raptor, 0.f, 700.f); + addEnemy(Aircraft::Raptor, 0.f, 700.f); + addEnemy(Aircraft::Raptor, 0.f, 1000.f); + + + addTroopA1(1500); + + + addEnemy(Aircraft::Raptor, +300.f, 2000.f); + addEnemy(Aircraft::Raptor, -300.f, 2000.f); + addEnemy(Aircraft::Raptor, 0.f, 2100.f); + + addEnemy(Aircraft::Avenger, +140.f, 2600.f); + addEnemy(Aircraft::Avenger, -140.f, 2600.f); + + addTroopA2(3000); + + addEnemy(Aircraft::Raptor, +200.f, 3300.f); + addEnemy(Aircraft::Raptor, -200.f, 3300.f); + addEnemy(Aircraft::Raptor, 0.f, 3500.f); + addEnemy(Aircraft::Avenger, +240.f, 3500.f); + addEnemy(Aircraft::Avenger, -240.f, 3500.f); + addEnemy(Aircraft::Raptor, +400.f, 3700.f); + addEnemy(Aircraft::Raptor, -400.f, 3700.f); + addEnemy(Aircraft::Raptor, 0.f, 3900.f); + + + addEnemy(Aircraft::Avenger, +70.f, 4500.f); + addEnemy(Aircraft::Avenger, -70.f, 4500.f); + addEnemy(Aircraft::Avenger, +140.f, 4700.f); + addEnemy(Aircraft::Avenger, -140.f, 4700.f); + + addTroopE2(5500); + + + + + + addEnemy(Aircraft::Raptor, +100.f, 7000.f); + addEnemy(Aircraft::Raptor, -100.f, 7500.f); + addEnemy(Aircraft::Avenger, -70.f, 7800.f); + + + addTroopA1(8000); + addTroopA2(8000); + + + addTroopD1(9000); + + + + addEnemy(Aircraft::Raptor, 0.f, 500.f+9000); + addEnemy(Aircraft::Raptor, 0.f, 700.f + 9000); + + + + addTroopA1(1500 + 9000); + + + addEnemy(Aircraft::Raptor, +300.f, 2000.f + 9000); + addEnemy(Aircraft::Raptor, -300.f, 2000.f + 9000); + addEnemy(Aircraft::Raptor, 0.f, 2100.f + 9000); + + + + addTroopA2(3000 + 9000); + + + addEnemy(Aircraft::Raptor, 0.f, 3500.f + 9000); + addEnemy(Aircraft::Avenger, +240.f, 3500.f + 9000); + addEnemy(Aircraft::Avenger, -240.f, 3500.f + 9000); + addEnemy(Aircraft::Raptor, +400.f, 3700.f + 9000); + + + + + addEnemy(Aircraft::Avenger, -70.f, 4500.f + 9000); + addEnemy(Aircraft::Avenger, +140.f, 4700.f + 9000); + + + addTroopE2(5500 + 9000); + + + + + + addEnemy(Aircraft::Raptor, +100.f, 7000.f + 9000); + addEnemy(Aircraft::Raptor, -100.f, 7500.f + 9000); + addEnemy(Aircraft::Avenger, -70.f, 7800.f + 9000); + + + addTroopA1(8000 + 9000); + addTroopA2(8000 + 9000); + + + addTroopD1(9000 + 9000); + + + addTroopE2(5000 + 9000 + 9000); + + + + + + addEnemy(Aircraft::Raptor, +100.f, 6500.f + 9000); + addEnemy(Aircraft::Raptor, -100.f, 6500.f + 9000); + addEnemy(Aircraft::Avenger, -70.f, 6800.f + 9000); + + + addTroopA1(8000 + 9000); + addTroopA2(8000 + 9000); + + + addTroopD1(9000 + 9000); + + + + + + // Sort all enemies according to their y value, such that lower enemies are checked first for spawning + std::sort(mEnemySpawnPoints.begin(), mEnemySpawnPoints.end(), [](SpawnPoint lhs, SpawnPoint rhs) + { + return lhs.y < rhs.y; + }); +} + +void World::addTroopA1(float y) +{ + for (int i = 0; i < 6; i++) + { + addEnemy(Aircraft::RaptorA1,100 + i * 50, y + i * 15); + } +} + +void World::addTroopA2(float y) +{ + for (int i = 0; i < 6; i++) + { + addEnemy(Aircraft::RaptorA2, -100 - i * 50, y + i * 15); + } +} + +void World::addTroopA1() +{ + for (int i = 0; i < 6; i++) + { + addEnemy(Aircraft::RaptorA1,100+i*50, mViewCenter.y + 500 + i*15); + } +} + +void World::addTroopA2() +{ + for (int i = 0; i < 6; i++) + { + addEnemy(Aircraft::RaptorA2, -100 - i * 50, mViewCenter.y + 500 + i * 15); + } +} + +void World::addTroopB1() +{ + addEnemy(Aircraft::RaptorA1, 100 + 1 * 50, mViewCenter.y + 500); + addEnemy(Aircraft::RaptorA1, 100 + 3 * 50, mViewCenter.y + 500); + addEnemy(Aircraft::AvengerA1, 100 + 2 * 30, mViewCenter.y + 500 + 40); +} + +void World::addTroopB2() +{ + addEnemy(Aircraft::RaptorA2, -100 - 1 * 50, mViewCenter.y+500); + addEnemy(Aircraft::RaptorA2, -100 - 3 * 50, mViewCenter.y+500); + addEnemy(Aircraft::AvengerA2, -100 - 2 * 30, mViewCenter.y + 500+40); +} + +void World::addTroopC1() +{ + addEnemy(Aircraft::RaptorB1, 50 + 0 * 50, mViewCenter.y + 500+40); + addEnemy(Aircraft::RaptorB1, 50 + 2 * 50, mViewCenter.y + 500); + addEnemy(Aircraft::RaptorB1, 50 + 4 * 50, mViewCenter.y + 500+40); + + addEnemy(Aircraft::AvengerB1, 50 - 1 * 50, mViewCenter.y + 500 + 100); + addEnemy(Aircraft::AvengerB1, 50 + 2 * 50, mViewCenter.y + 500+70); + addEnemy(Aircraft::AvengerB1, 50 + 5 * 50, mViewCenter.y + 500 + 100); +} + +void World::addTroopC2() +{ + addEnemy(Aircraft::RaptorB1, -50 - 0 * 50, mViewCenter.y + 500 + 40); + addEnemy(Aircraft::RaptorB1, -50 - 2 * 50, mViewCenter.y + 500); + addEnemy(Aircraft::RaptorB1, -50 - 4 * 50, mViewCenter.y + 500 + 40); + + addEnemy(Aircraft::AvengerB1, -50 + 1 * 50, mViewCenter.y + 500 + 100); + addEnemy(Aircraft::AvengerB1, -50 - 2 * 50, mViewCenter.y + 500 + 70); + addEnemy(Aircraft::AvengerB1, -50 - 5 * 50, mViewCenter.y + 500 + 100); +} + +void World::addTroopD1() +{ + addEnemy(Aircraft::RaptorC1, 0 , mViewCenter.y + 500 + 30); + addEnemy(Aircraft::RaptorC1, 0 , mViewCenter.y + 500); + addEnemy(Aircraft::RaptorC1, 0 , mViewCenter.y + 500 + 60); + + addEnemy(Aircraft::AvengerC1, 50 + 1 * 25, mViewCenter.y + 500 + 90); + addEnemy(Aircraft::AvengerC1, 50 + 3 * 25, mViewCenter.y + 500 + 50); + addEnemy(Aircraft::AvengerC1, 50 + 5 * 25, mViewCenter.y + 500 + 10); + + addEnemy(Aircraft::AvengerC2, -50 - 1 * 25, mViewCenter.y + 500 + 90); + addEnemy(Aircraft::AvengerC2, -50 - 3 * 25, mViewCenter.y + 500 + 50); + addEnemy(Aircraft::AvengerC2, -50 - 5 * 25, mViewCenter.y + 500 + 10); +} + +void World::addTroopE1() +{ + addEnemy(Aircraft::RaptorD1, +150 , mViewCenter.y + 500 ); + addEnemy(Aircraft::RaptorD1, +150 , mViewCenter.y + 500+40 ); + addEnemy(Aircraft::RaptorD1, +150 , mViewCenter.y + 500 +80); + addEnemy(Aircraft::RaptorD1, +150 , mViewCenter.y + 500 +120); + addEnemy(Aircraft::RaptorD1, +150 , mViewCenter.y + 500 +160); + addEnemy(Aircraft::RaptorD1, +150 , mViewCenter.y + 500 + 200); + addEnemy(Aircraft::RaptorD1, +150 , mViewCenter.y + 500 + 240); + addEnemy(Aircraft::RaptorD1, +150 , mViewCenter.y + 500 + 280); + + addEnemy(Aircraft::AvengerD1, +150 -100, mViewCenter.y + 500 + 73); + addEnemy(Aircraft::AvengerD1, +150 - 100, mViewCenter.y + 500 + 25); + + + +} + +void World::addTroopE2() +{ + addEnemy(Aircraft::RaptorD2, -150, mViewCenter.y + 500); + addEnemy(Aircraft::RaptorD2, -150, mViewCenter.y + 500 + 40); + addEnemy(Aircraft::RaptorD2, -150, mViewCenter.y + 500 + 80); + addEnemy(Aircraft::RaptorD2, -150, mViewCenter.y + 500 + 120); + addEnemy(Aircraft::RaptorD2, -150, mViewCenter.y + 500 + 160); + addEnemy(Aircraft::RaptorD2, -150, mViewCenter.y + 500 + 200); + addEnemy(Aircraft::RaptorD2, -150, mViewCenter.y + 500 + 240); + addEnemy(Aircraft::RaptorD2, -150, mViewCenter.y + 500 + 280); + + addEnemy(Aircraft::AvengerD2, -150 + 100, mViewCenter.y + 500 + 73); + addEnemy(Aircraft::AvengerD2, -150 + 100, mViewCenter.y + 500 + 25); +} + +void World::addEagleA1() +{ + addEnemy(Aircraft::EagleA1, 0, mViewCenter.y + 300 ); +} + +void World::addEagleA2() +{ + addEnemy(Aircraft::EagleA2, 0, mViewCenter.y + 300); +} + +void World::addEagleB1() +{ + addEnemy(Aircraft::EagleB1, 0, mViewCenter.y + 500); +} + +void World::addEagleB2() +{ + addEnemy(Aircraft::EagleB2, 0, mViewCenter.y + 500); +} + +void World::addEagleA1(float y) +{ + addEnemy(Aircraft::EagleA1, 0, y); +} + +void World::addEagleA2(float y) +{ + addEnemy(Aircraft::EagleA2, 0, y); +} + +void World::addEagleB1(float y) +{ + addEnemy(Aircraft::EagleB1, 0, y); +} + +void World::addEagleB2(float y) +{ + addEnemy(Aircraft::EagleB2, 0, y); +} + + +void World::addTroopB1(float y) +{ + addEnemy(Aircraft::RaptorA1, 100 + 1 * 50, y ); + addEnemy(Aircraft::RaptorA1, 100 + 3 * 50, y ); + addEnemy(Aircraft::AvengerA1, 100 + 2 * 37, y + 25); //x+2*38,y+25Ҫ +} + +void World::addTroopB2(float y) +{ + addEnemy(Aircraft::RaptorA2, -100 - 1 * 50, y); + addEnemy(Aircraft::RaptorA2, -100 - 3 * 50, y); + addEnemy(Aircraft::AvengerA2, -100 - 2 * 37, y + 25); //y+25Ҫ +} + +void World::addTroopC1(float y) +{ + addEnemy(Aircraft::RaptorB1, 50 + 0 * 50, y + 40); + addEnemy(Aircraft::RaptorB1, 50 + 2 * 50, y); + addEnemy(Aircraft::RaptorB1, 50 + 4 * 50, y + 40); + + addEnemy(Aircraft::AvengerB1, 50 - 1 * 50, y + 100); + addEnemy(Aircraft::AvengerB1, 50 + 2 * 50, y + 70); + addEnemy(Aircraft::AvengerB1, 50 + 5 * 50, y + 100); +} + +void World::addTroopC2(float y) +{ + addEnemy(Aircraft::RaptorB1, -50 - 0 * 50, y + 40); + addEnemy(Aircraft::RaptorB1, -50 - 2 * 50, y); + addEnemy(Aircraft::RaptorB1, -50 - 4 * 50, y + 40); + + addEnemy(Aircraft::AvengerB1, -50 + 1 * 50, y + 100); + addEnemy(Aircraft::AvengerB1, -50 - 2 * 50, y + 70); + addEnemy(Aircraft::AvengerB1, -50 - 5 * 50, y + 100); +} + +void World::addTroopD1(float y) +{ + addEnemy(Aircraft::RaptorC1, 0, y + 30); + addEnemy(Aircraft::RaptorC1, 0, y); + addEnemy(Aircraft::RaptorC1, 0, y + 60); + + addEnemy(Aircraft::AvengerC1, 50 + 1 * 25, y + 90); + addEnemy(Aircraft::AvengerC1, 50 + 3 * 25, y + 50); + addEnemy(Aircraft::AvengerC1, 50 + 5 * 25, y + 10); + + addEnemy(Aircraft::AvengerC2, -50 - 1 * 25, y + 90); + addEnemy(Aircraft::AvengerC2, -50 - 3 * 25, y + 50); + addEnemy(Aircraft::AvengerC2, -50 - 5 * 25, y + 10); +} + +void World::addTroopE1(float y) +{ + addEnemy(Aircraft::RaptorD1, +150, y); + addEnemy(Aircraft::RaptorD1, +150, y + 40); + addEnemy(Aircraft::RaptorD1, +150, y + 80); + addEnemy(Aircraft::RaptorD1, +150, y + 120); + addEnemy(Aircraft::RaptorD1, +150, y + 160); + addEnemy(Aircraft::RaptorD1, +150, y + 200); + addEnemy(Aircraft::RaptorD1, +150, y + 240); + addEnemy(Aircraft::RaptorD1, +150, y + 280); + + addEnemy(Aircraft::AvengerD1, +150 - 100, y + 73); + addEnemy(Aircraft::AvengerD1, +150 - 100, y + 25); +} + +void World::addTroopE2(float y) +{ + addEnemy(Aircraft::RaptorD2, -150, y); + addEnemy(Aircraft::RaptorD2, -150, y + 40); + addEnemy(Aircraft::RaptorD2, -150, y + 80); + addEnemy(Aircraft::RaptorD2, -150, y + 120); + addEnemy(Aircraft::RaptorD2, -150, y + 160); + addEnemy(Aircraft::RaptorD2, -150, y + 200); + addEnemy(Aircraft::RaptorD2, -150, y + 240); + addEnemy(Aircraft::RaptorD2, -150, y + 280); + + addEnemy(Aircraft::AvengerD2, -150 + 100, y + 73); + addEnemy(Aircraft::AvengerD2, -150 + 100, y + 25); +} + + + +void World::addEnemy(Aircraft::Type type, float relX, float relY) +{ + SpawnPoint spawn(type, mSpawnPosition.x + relX, mSpawnPosition.y - relY); + mEnemySpawnPoints.push_back(spawn); +} + +void World::spawnEnemies() +{ + // Spawn all enemies entering the view area (including distance) this frame + while (!mEnemySpawnPoints.empty() + && mEnemySpawnPoints.back().y > getBattlefieldBounds().top+85) + { + SpawnPoint spawn = mEnemySpawnPoints.back(); + + std::unique_ptr enemy(new Aircraft(mWindow,spawn.type, mTextures, mFonts,mSounds,false)); + enemy->setPosition(spawn.x, spawn.y); + enemy->setRotation(180.f); + + mSceneLayers[Air]->attachChild(std::move(enemy)); + + // Enemy is spawned, remove from the list to spawn + mEnemySpawnPoints.pop_back(); + } +} + +void World::destroyEntitiesOutsideView() +{ + Command command; + command.category = Category::Projectile | Category::EnemyAircraft; + command.action = derivedAction([this](Entity& e, sf::Time) + { + if (!getBattlefieldBounds().intersects(e.getBoundingRect())) + e.destroy(); + }); + + mCommandQueue.push(command); +} + +void World::guideMissiles() +{ + // Setup command that stores all enemies in mActiveEnemies + Command enemyCollector; + enemyCollector.category = Category::EnemyAircraft; + enemyCollector.action = derivedAction([this](Aircraft& enemy, sf::Time) + { + if (!enemy.isDestroyed()) + mActiveEnemies.push_back(&enemy); + }); + + // Setup command that guides all missiles to the enemy which is currently closest to the player + Command missileGuider; + missileGuider.category = Category::AlliedProjectile; + missileGuider.action = derivedAction([this](Projectile& missile, sf::Time) + { + // Ignore unguided bullets + if (!missile.isGuided()) + return; + + float minDistance = std::numeric_limits::max(); + Aircraft* closestEnemy = nullptr; + + // Find closest enemy + FOREACH(Aircraft* enemy, mActiveEnemies) + { + float enemyDistance = distance(missile, *enemy); + + if (enemyDistance < minDistance) + { + closestEnemy = enemy; + minDistance = enemyDistance; + } + } + + if (closestEnemy) + missile.guideTowards(closestEnemy->getWorldPosition()); + }); + + // Push commands, reset active enemies + mCommandQueue.push(enemyCollector); + mCommandQueue.push(missileGuider); + mActiveEnemies.clear(); +} + +sf::FloatRect World::getViewBounds() const +{ + return sf::FloatRect(mWorldView.getCenter() - mWorldView.getSize() / 2.f, mWorldView.getSize()); +} + +sf::FloatRect World::getBattlefieldBounds() const +{ + // Return view bounds + some area at top, where enemies spawn + sf::FloatRect bounds = getViewBounds(); + bounds.top -= 100.f; + bounds.height += 100.f; + + return bounds; +} + +void World::handleCollisions() +{ + std::set collisionPairs; + mSceneGraph.checkSceneCollision(mSceneGraph, collisionPairs); + + FOREACH(SceneNode::Pair pair, collisionPairs) //ɻײ + { + if (matchesCategories(pair, Category::PlayerAircraft, Category::EnemyAircraft)) + { + auto& player = static_cast(*pair.first); + auto& enemy = static_cast(*pair.second); + + // Collision: Player damage = enemy's remaining HP + player.damage(enemy.getHitpoints()*3); + enemy.destroy(); + + updateScore(enemy); + + if (player.getHitpoints() <= 0) + { + addFlash(Textures::Explosion,player.getPosition().x, player.getPosition().y); + } + + } + + else if (matchesCategories(pair, Category::EnemyAircraft, Category::AlliedProjectile) + || matchesCategories(pair, Category::PlayerAircraft, Category::EnemyProjectile)) + { + auto& aircraft = static_cast(*pair.first); + auto& projectile = static_cast(*pair.second); + + // Apply projectile damage to aircraft, destroy projectile + aircraft.damage(projectile.getDamage()); + projectile.destroy(); + mSounds.play(SoundEffect::Explosion1); + + if (projectile.isGuided()) + { + addFlash(Textures::Explosion_missile, projectile.getPosition().x, projectile.getPosition().y); + } + else + { + addFlash(Textures::Spark, projectile.getPosition().x, projectile.getPosition().y); + } + + updateScore(aircraft); + } + } +} + + + +void World::randomEvents(sf::Time dt) +{ + randomEnemys(dt); +} + +void World::randomEnemys(sf::Time dt) +{ + + static int randomLevel = 1; + + if (mPlayerAircraft->getPosition().y < mWorldLength-5000 && randomLevel == 1) + { + mRandomEvents.RandomEnemyInterval -= sf::seconds(0.3); + randomLevel++; + } + else if (mPlayerAircraft->getPosition().y < mWorldLength - 10000 && randomLevel == 2) + { + mRandomEvents.RandomEnemyInterval -= sf::seconds(0.4); + randomLevel++; + } + else if (mPlayerAircraft->getPosition().y < mWorldLength - 15000 && randomLevel == 3) + { + mRandomEvents.RandomEnemyInterval -= sf::seconds(0.5); + randomLevel++; + } + + + mRandomEvents.RandomEventsCountdown += dt; + + if (mRandomEvents.RandomEventsCountdown > mRandomEvents.RandomEnemyInterval) + { + + int Rand = rand(); + + if (Rand % 6 == 0) + { + int Rand = rand(); + if (Rand % 3 == 0) + { + if (rand() % 2 == 0) + { + addTroopA2(); + } + else + { + addTroopA1(); + } + } + else + { + if (rand() % 2 == 0) + { + addTroopB1(); + } + else + { + addTroopB2(); + } + } + } + else if(Rand%6>2) + { + addEnemy(Aircraft::Raptor, rand() % 600 - 300, mViewCenter.y + 500); + } + else + { + addEnemy(Aircraft::Avenger, rand() % 600 - 300, mViewCenter.y + 500); + } + + if (mPlayerAircraft->getPosition().y<10000) //Troop + { + + + int Rand = rand(); + if (Rand % 2 == 0) + { + if (Rand % 9 == 0) + { + if (rand() % 2 == 0)addTroopE1(); + else addTroopE2(); + + } + else if (Rand % 9 > 6) + { + if (rand() % 2 == 0)addTroopA1(); + else addTroopA2(); + } + else if (Rand % 9 > 4) + { + if (rand() % 2 == 0)addTroopB1(); + else addTroopB2(); + } + else if (Rand % 9 > 2) + { + if (rand() % 2 == 0)addTroopC1(); + else addTroopC2(); + } + else if (Rand % 9 > 0) + { + addTroopD1(); + } + } + } + + + mRandomEvents.RandomEventsCountdown -= mRandomEvents.RandomEnemyInterval; + + std::sort(mEnemySpawnPoints.begin(), mEnemySpawnPoints.end(), [](SpawnPoint lhs, SpawnPoint rhs) //л󣬸ɻWorld::spawnEnemies + { + return lhs.y < rhs.y; + }); + } + + +} + +void World::randomTroop(sf::Time dt) +{ + +} + + + +void World::addAlly() +{ + +} + +void World :: addFlash(Textures::ID type,float x,float y) +{ + sf::Texture& texture = mTextures.get(type); + std::unique_ptr mflash(new Flash(texture,type)); + + mflash->setPosition(x,y); + mFlashNode.attachChild(std::move(mflash)); + +} + +float World::getWorldLength() +{ + return mWorldLength; +} + +sf::Vector2f World::getViewCenter() +{ + return mSpawnPosition- mViewCenter; +} diff --git a/fighters/Source/main.cpp b/fighters/Source/main.cpp new file mode 100644 index 00000000..566ef59d --- /dev/null +++ b/fighters/Source/main.cpp @@ -0,0 +1,13 @@ +#include +#include "Include\Game.h" + + + +int main() +{ + + Game game; + game.run(); +} + + diff --git a/p03_Diophantus.c b/p03_Diophantus.c new file mode 100644 index 00000000..55ca623c --- /dev/null +++ b/p03_Diophantus.c @@ -0,0 +1,14 @@ +#include +#include + +void main() +{ + int i; + for (i = 1; 28 * i != 21 * i + 4 * i + 252; i++) + { + ; + } + printf("丢番图的年纪是%d\n", i); + system("pause"); +} + diff --git a/p04_ narcissus.c b/p04_ narcissus.c new file mode 100644 index 00000000..cebd1446 --- /dev/null +++ b/p04_ narcissus.c @@ -0,0 +1,19 @@ +#include +#include +int main() +{ + int a, b, c; + for (a = 0; a <= 9; a++) + { + for (b = 0; b <= 9; b++) + { + for (c = 0; c <= 9; c++) + { + if (a*a*a + b*b*b + c*c*c == a + 10 * b + 100 * c && !( b == 0 && c == 0)) //排除非三位数(0开头)的情况 + printf("%d%d%d\n", c, b, a); + } + } + } + system("pause"); + return 0; +} \ No newline at end of file diff --git a/p05_allPrimes.c b/p05_allPrimes.c new file mode 100644 index 00000000..c87b4add --- /dev/null +++ b/p05_allPrimes.c @@ -0,0 +1,40 @@ +#include +#include +#include +int isPrinme(int n); +int IS(int); +int main() +{ + clock_t t1, t2; + t1 = clock(); + + for(int i=2;i<=1000;i++) + { + if (isPrime(i)) + { + printf("%5d", i); + } + } + t2 = clock(); + printf("打印时间:%f秒",(double)(t2-t1)/CLOCKS_PER_SEC); + + system("pause"); + return 0; +} +int isPrime(int n) +{ + int mark = 0; + + for (int i = 2; i < n; i++) + { + if (n%i == 0) //用mark标记a已被整除 + { + mark = 1; + break; + } + + } + if (mark == 1) //检查标记 + return 0; + else return 1; +} diff --git a/p06_Goldbach.c b/p06_Goldbach.c new file mode 100644 index 00000000..5745fcda --- /dev/null +++ b/p06_Goldbach.c @@ -0,0 +1,60 @@ +#include +#include +#include +int loadPrime(int* a); +int isPrime(int x); +int main() +{ + int prime[100] = {0}; + int n; + n=loadPrime(prime); + + for (int a = 4; a <= 100;a+=2 ) + { + for (int i = 0; i < n; i++) + { + for (int j = 0; j < n; j++) + { + if (a == prime[i] + prime[j]) //遍历两个100以内的素数组合之和,与a作比较 + { + printf("%d满足哥德巴赫猜想\n",a); + goto b; //跳出遍历循环 + } + } + } + + b: ; + } + system("pause"); + return 0; +} +int isPrime(int x) +{ + int i; + int mark = 0; //创建标记 + + for (i = 2; i < x; i++) + { + if (x%i == 0) + { + mark = 1; //若被整除,标记mark为1 + break; + } + } + if (mark == 1) + return 0; + else return 1; +} +int loadPrime(int* a) +{ + int x = 0; + for (int i = 1; i < 100; i++) + { + if (isPrime(i)) + { + a[x] = i; //把素数赋值给数组 + x++; + } + } + return x; //返回100以内的素数个数 +} diff --git a/p07_encrypt_decrypt.c b/p07_encrypt_decrypt.c new file mode 100644 index 00000000..5176a258 --- /dev/null +++ b/p07_encrypt_decrypt.c @@ -0,0 +1,59 @@ +#include +#include +#include +#define WIDTH 500 +void encrypt(char* pt, int* pt2, int n); //加密函数 +void decrypt(char* pt, int* pt2, int n); //解密函数 +char* s_gets(char* st, int n); //获取输入 +int main() +{ + char input[WIDTH] = { " " }; + char num[WIDTH] = { 0 }; + srand(time(NULL)); //用时间初始化随机数种子 + for (int i = 0; i < WIDTH - 1; i++) //随机数组,供加密解密使用 + { + num[i] = (int)rand()%10; + } + + printf("输入待加密内容:"); + s_gets(input, WIDTH - 1); + encrypt(input,num,WIDTH-1); + printf("加密后内容:%s\n", input); + decrypt(input, num,WIDTH - 1); + printf("解密后内容:%s\n", input); + system("pause"); + return 0; +} +void encrypt(char* pt,int* pt2,int n) +{ + for (int i = 0; i < n; i++) + { + pt[i]+=pt2[i]; + } +} +void decrypt(char* pt, int* pt2, int n) +{ + for (int i = 0; i < n; i++) + { + pt[i] -=pt2[i]; + } +} +char* s_gets(char* st, int n) +{ + char* ret_val; + int i = 0; + ret_val = fgets(st, n, stdin); + if (ret_val) + { + while (st[i] != '\n'&&st[i] != '\0') + { + i++; + } + if (st[i] == '\n') + st[i] = '\0'; + else + while (getchar() != '\n') + continue; + } + return ret_val; +} diff --git a/p08_hanoi.c b/p08_hanoi.c new file mode 100644 index 00000000..8190e4ea --- /dev/null +++ b/p08_hanoi.c @@ -0,0 +1,27 @@ +#include +#include +#define WIDTH 11 + +void hanoi(char a, char b, char c, int n); +int n = 0; + +void main() +{ + freopen_s("out.txt", "w", stdout); + hanoi('A','B','C',WIDTH); + printf("%d steps", n); + system("pause"); +} +void hanoi(char a, char b, char c, int n) +{ + if (n == 1) + { + printf("move %d from %c to %c\n", n, a, c); + n++; + return; + } + hanoi(a, c, b, n - 1); + printf("move %d from %c to %c\n", n, a, c); + n++; + hanoi(b, a, c, n - 1); +} diff --git a/p08_hanoiGAME.c b/p08_hanoiGAME.c new file mode 100644 index 00000000..009ef2f5 --- /dev/null +++ b/p08_hanoiGAME.c @@ -0,0 +1,528 @@ +#include +#include +#include +#include +#include +#include +#define WIDTH 5 +void background(); +void pole(char space[WIDTH]); +void button(); +void to_xy(int x, int y); +void start(char A[WIDTH][WIDTH*2+1]); +void show_disk(char A[WIDTH][WIDTH * 2 + 1], int x, int y, int h); +void show_arrow(int x, int y); +void control_ar(char input); +void show_top(); +void to_up(char A[WIDTH][WIDTH * 2 + 1], int D[WIDTH], int h); +void to_down(char A[WIDTH][WIDTH * 2 + 1], int D[WIDTH], int* h); +void to_right(char A[WIDTH][WIDTH * 2 + 1], char B[WIDTH][WIDTH * 2 + 1]); +void to_left(char A[WIDTH][WIDTH * 2 + 1], char B[WIDTH][WIDTH * 2 + 1]); +int victory(); +void panel_score(double t); +void panel_main(); +void reset_disk(char A[WIDTH][WIDTH * 2 + 1], int a[WIDTH]); +void reset_arrow(); + + +int locat1[2] = { 20,6 }; //圆盘A起始 +int locat2[2] = { (20 + (WIDTH * 2 + 1 + 2)),6 }; //圆盘B起始 +int locat3[2] = { (20 + (WIDTH * 2 + 1 + 2) * 2),6 }; //圆盘C起始 +int locat4[2] = { 20,(6 + WIDTH) }; //底座起始 +int locat5[2] = { 18 + WIDTH,(8 + WIDTH) }; //箭头起始 + +int doc_A[WIDTH] = { 0}; +int doc_B[WIDTH] = { 0 }; +int doc_C[WIDTH] = { 0}; +int doc_top; + +int a, b, c; +int* pa = &a; +int* pb = &b; +int* pc = &c; + + +bool move_y = false; +int move_x = 0; +int step = 0; +int win = 1; + +char top[WIDTH * 2 + 1] = { 0 }; +char A[WIDTH][WIDTH * 2 + 1] = { 0 }; +char B[WIDTH][WIDTH * 2 + 1] = { 0 }; +char C[WIDTH][WIDTH * 2 + 1] = { 0 }; + +void main() +{ + + CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; + SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); + + clock_t t1, t2; + char input; + + system("color 0f"); + + start(A); + + while (1) + { + if (win) + { + panel_main(); + system("cls"); + win = 0; + t1 = clock(); + } + + background(); + show_top(); + show_disk(A,locat1[0], locat1[1],a); + show_disk(B,locat2[0], locat2[1], b); + show_disk(C,locat3[0], locat3[1], c); + show_arrow(locat5[0], locat5[1]); + input = _getch(); + t2 = clock(); + control_ar(input); + if (win=victory()) + { + t2 = clock(); + panel_score((double)(t2-t1)/CLOCKS_PER_SEC); + start(A); + reset_disk(B,doc_B); + reset_disk(C,doc_C); + reset_arrow(); + step = 0; + system("color 0f"); + } + + + system("cls"); + } + _getch(); +} + + + +void background() +{ + char space[WIDTH] = { 0 }; + + puts("\n\n\n\n"); + pole(space); + to_xy(locat4[0], locat4[1]); + button(); + +} +void pole(char space[WIDTH]) +{ + for (int i = 0; i < WIDTH+1; i++) //杆高度 + { + printf(" "); + for (int i = 0; i < 3; i++) //杆个数 + { + for (int i = 0; i < WIDTH; i++) + printf("%c", space[i]); + printf("|"); + for (int i = 0; i < WIDTH; i++) + printf("%c", space[i]); + printf(" "); + } + printf("\n"); + } +} +void button() +{ + for (int i = 0; i < 3; i++) + { + for (int i = 0; i < WIDTH; i++) + { + printf("="); + } + printf("|"); + for (int i = 0; i < WIDTH; i++) + { + printf("="); + } + printf(" "); + } +} +void to_xy(int x,int y) //到指定坐标 +{ + HANDLE hout; + COORD coord; + coord.X = x; + coord.Y = y; + hout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(hout, coord); +} + +void start(char A[WIDTH][WIDTH * 2 + 1]) +{ + a = WIDTH; + b = 0; + c = 0; + + int count = 3; + for (int i = 0; i < WIDTH; i++) + { + for (int x = 0; x i) + continue; + else + { + to_xy(x, y + i); + for (int j = 0; j < WIDTH * 2 + 1; j++) + { + printf("%c", A[i][j]); + } + } + } +} +void show_arrow(int x,int y) +{ + char arrow[9][5] = + { + { ' ', ' ', '*', ' ', ' ' }, + { ' ', '*', '*', '*', ' ' }, + { '*', '*', '*', '*', '*' }, + { ' ', '|', '*', '|', ' ' }, + { ' ', '|', '*', '|', ' ' }, + { ' ', '|', '*', '|', ' ' }, + }; + for (int i = 0; i < 9; i++) + { + to_xy(x, y + i); + for (int j = 0; j < 5; j++) + { + printf("%c", arrow[i][j]); + } + } +} +void show_top() +{ + to_xy(locat5[0]+2-WIDTH,3); + for (int i = 0; i < WIDTH*2+1; i++) + { + printf("%c", top[i]); + } +} + + +void control_ar(char input) +{ + switch (input) + { + case'a': + if (move_x > 0) + { + if (move_x == 1) //箭头在B + { + + to_left(A, B); + move_x--; + } + + else if (move_x == 2) //箭头在C + { + to_left(B, C); + move_x--; + } + + + } + else //箭头在A + ; + break; + case'd': + if (move_x < 2) + { + if (move_x == 0) //箭头在A + { + + to_right(B, A); + move_x++; + } + + else if (move_x == 1) //箭头在B + { + to_right(C, B); + move_x++; + } + + + } + else //箭头在C + ; + break; + case'w': + if (move_y == false) + { + if (move_x == 1) //箭头在B + { + if (b != 0) + { + to_up(B, doc_B,b); + move_y = true; + b--; + } + } + + else if (move_x==0) //箭头在A + { + if (a != 0) + { + to_up(A, doc_A, a); + move_y = true; + a--; + } + } + else //箭头在C + { + if (c != 0) + { + to_up(C, doc_C, c); + move_y = true; + c--; + } + } + } + else + ; + break; + case's': + if (move_y == true) + { + if (move_x == 1) //箭头在B + { + to_down(B, doc_B, pb); + } + else if (move_x == 0) //箭头在A + { + to_down(A, doc_A, pa); + } + else //箭头在C + { + to_down(C, doc_C, pc); + } + + } + else + ; //没有盘子在顶层 + break; + } +} + +void to_up(char A[WIDTH][WIDTH * 2 + 1],int D[WIDTH],int h) +{ + for (int i = 0; i < WIDTH; i++) + { + if (i < WIDTH - h) //找到顶层 + continue; + else + { + for (int j = 0; j < WIDTH * 2 + 1; j++) + { + if (A[i][j] != 0) + { + top[j] = A[i][j]; + if (j == WIDTH) + A[i][j] = '|'; + else + A[i][j] = 0; + } + } + doc_top = D[i]; //交换数据 + D[i] = 0; + break; + } + } +} + +void to_down(char A[WIDTH][WIDTH * 2 + 1],int D[WIDTH], int * h) +{ + for (int i = 0; i < WIDTH; i++) + { + if (i < WIDTH - *h-1 ) //找到顶层,针对行 + continue; + + else + { + if (*h == 0) //当顶层是底座时 + { + move_y = false; + (*h)++; + step++; + D[i] = doc_top; //交换数据 + doc_top = 0; + for (int j = 0; j < WIDTH * 2 + 1; j++) //针对列 + { + if (top[j] != 0) + { + A[i][j] = top[j]; + top[j] = 0; + } + } + } + else if (doc_top < D[i + 1]) //判断能否放下 + { + move_y = false; + (*h)++; + step++; + D[i] = doc_top; //交换数据 + doc_top = 0; + for (int j = 0; j < WIDTH * 2 + 1; j++) //针对列 + { + if (top[j] != 0) + { + A[i][j] = top[j]; + top[j] = 0; + } + } + } + else + ; //放不下 + break; + } + } +} +void to_right(char A[WIDTH][WIDTH * 2 + 1], char B[WIDTH][WIDTH * 2 + 1]) +{ + locat5[0] += WIDTH * 2 + 3; +} +void to_left(char A[WIDTH][WIDTH * 2 + 1], char B[WIDTH][WIDTH * 2 + 1]) +{ + locat5[0] -= WIDTH * 2 + 3; +} + + +void reset_disk(char A[WIDTH][WIDTH * 2 + 1],int a[WIDTH]) +{ + for (int i = 0; i < WIDTH; i++) + { + for (int j = 0; j < WIDTH * 2 + 1; j++) + A[i][j] = 0; + a[i] = 0; + } +} +void reset_arrow() +{ + move_x = 0; + locat5[0] = 18 + WIDTH; +} +void panel_score(double t) +{ + + int a[2] = { 20 + (WIDTH * 2 + 1 + 2) ,5 }; + + printf("\a"); + to_xy(a[0], a[1]); + printf("*******************************************\n"); + to_xy(a[0], a[1] + 1); + printf("* *\n"); + to_xy(a[0], a[1] + 2); + printf("* -- VICTORY -- *\n"); + to_xy(a[0], a[1] + 3); + printf("* *\n"); + to_xy(a[0], a[1] + 4); + printf("* level: %-10d *\n", WIDTH); + to_xy(a[0], a[1] + 5); + printf("* step : %-10d *\n", step); + to_xy(a[0], a[1] + 6); + printf("* time : %-10.2f *\n", t); + to_xy(a[0], a[1] + 7); + printf("* *\n"); + to_xy(a[0], a[1] + 8); + printf("* *\n"); + to_xy(a[0], a[1] + 9); + printf("*******************************************\n"); + + for (int i = 0; i<3; i++) + { + to_xy(a[0] + 1, a[1] + 8); + printf(" Have a rest... "); + Sleep(500); + to_xy(a[0] + 1, a[1] + 8); + printf(" "); + Sleep(500); + + } + to_xy(a[0] + 1, a[1] + 8); + printf(" Press any key to continue... "); + _getch(); + +} +void panel_main() +{ + int a[2] = { 13 + (WIDTH * 2 + 1 + 2) ,5 }; + int go = 0; + to_xy(a[0], a[1]); + printf("*************************************************************************\n"); + to_xy(a[0], a[1] + 1); + printf("* # # ## # # ### ##### *\n"); + to_xy(a[0], a[1] + 2); + printf("* # # # # # # # # # # *\n"); + to_xy(a[0], a[1] + 3); + printf("* ###### ###### # # # # # # *\n"); + to_xy(a[0], a[1] + 4); + printf("* # # # # # # # # # # *\n"); + to_xy(a[0], a[1] + 5); + printf("* # # # # # # ### ##### *\n"); + to_xy(a[0], a[1] + 6); + printf("* *\n"); + to_xy(a[0], a[1] + 7); + printf("* - A Philosjay Product - *\n"); + to_xy(a[0], a[1] + 8); + printf("* *\n"); + to_xy(a[0], a[1] + 9); + printf("* *\n"); + to_xy(a[0], a[1] + 10); + printf("* *\n"); + to_xy(a[0], a[1] + 11); + printf("*************************************************************************\n"); + + for (int i = 0; i<3; i++) + { + + to_xy(a[0] + 1, a[1] + 10); + printf(" Now loading... "); + Sleep(500); + to_xy(a[0] + 1, a[1] + 10); + printf(" "); + Sleep(500); + + } + to_xy(a[0] + 1, a[1] + 10); + printf(" Press any key to start... "); + _getch(); + +} +int victory() +{ + for (int i = 0; i < WIDTH && doc_C[i] == i + 1; i++) + { + if (i == WIDTH - 1) + { + show_disk(C, locat3[0], locat3[1], c); + show_top(); + system("color 0e"); + + return 1; + } + } + return 0; +} \ No newline at end of file diff --git a/p11_linkedList.c b/p11_linkedList.c new file mode 100644 index 00000000..8bea63e2 --- /dev/null +++ b/p11_linkedList.c @@ -0,0 +1,123 @@ +#include +#include + +void turn(struct node* pt); +void AddValue(struct node* pt ,int n); +void AddNode(struct queue* pq); +void InitializeQueue(struct queue* pq); +int find(struct node* pt, int n, int* pn); + +typedef struct node +{ + int value; + struct node* next; +}Node; + + typedef struct queue +{ + struct node* front; + struct node* rear; +}Queue; + +Queue queue; + +void main() +{ + + + int lens; + int value; + int* locat; + + printf("enter a number to determine the lens of your link:"); + scanf_s("%d", &lens); + + InitializeQueue(&queue); + locat = (int*)malloc(sizeof(int)*lens); + + for (int i = 0; i next) + { + printf("enter the value for node:"); + scanf_s("%d", &value); + AddValue(pt,value); + } + + system("pause"); + turn(queue.front); + printf("turn:\n"); + + for (struct node* pt = queue.front; pt != NULL; pt = pt->next) + { + printf(" the value of node %d \n", pt->value); + + } + + find(queue.front,lens,locat); + + for (int i = 0; i < lens; i++) + printf("%d\n", locat[i]); + + system("pause"); +} + +void InitializeQueue(struct queue* pq) +{ + pq->front = pq->rear = NULL; +} +void AddNode(struct queue* pq) +{ + Node* pt = (Node*)malloc(sizeof(Node)); + if (pq->front == NULL) + pq->front = pt; + else + pq->rear->next = pt; + pq->rear= pt; + pt->next = NULL; + +} +void AddValue(struct node* pt, int n) +{ + pt->value = n; +} +void turn( struct node* pt) +{ + + if (pt->next->next == NULL) //最后一层递归因提前跳出故不完整,要用下列语句补充 + { + pt->next->next = pt; + queue.front = pt->next; + return; + } + + turn(pt->next); + + pt->next->next = pt; + queue.rear = pt; + pt->next = NULL; + +} + +int find(struct node* pt, int n, int* pn) +{ + int temp = 0; + + for (int i = 0; i < n; i++) + { + if (pt->value == 5) + { + pn[temp] = pt; + temp++; + } + else + { + pn[temp] = -1; + temp++; + } + pt = pt->next; + } +} \ No newline at end of file diff --git a/p12_warehouse.c b/p12_warehouse.c new file mode 100644 index 00000000..ee5f7b0f --- /dev/null +++ b/p12_warehouse.c @@ -0,0 +1,184 @@ +#include +#include + + +char menu(void); +void AddItem(); +void show_list(); +void DeItem(); +void save(); +void load(); +void Add(int type, int num); + +typedef struct item +{ + int type; + int num; +}Item; + +typedef struct node +{ + Item item; + struct node * next; +} Node; + +typedef struct queue +{ + struct node* front; + struct node* rear; + +}Queue; + +Item temp; +Queue queue; + +void main() +{ + char input; + queue.front = queue.rear = NULL; + + load(); + + input = 0; + while (input != '4') + { + input = menu(); + switch (input) + { + case'1': + show_list(); + break; + case'2': + AddItem(); + break; + case'3': + DeItem(); + break; + case'4': + save(); + break; + } + + + + + } + + system("pause"); + +} + + + + +void AddItem() +{ + + puts("enter type of item:"); + scanf_s("%d", &(temp.type)); + puts("enter number of item:"); + scanf_s("%d", &(temp.num)); + while (getchar() != '\n') + continue; + Add(temp.type,temp.num); + + +} +char menu(void) +{ + char ch; + puts("enter the following letter to operate:"); + puts("1. show list"); + puts("2. add item"); + puts("3. delete item"); + puts("4. save and quit"); + + ch = getchar(); + + while (getchar() != '\n') + continue; + return ch; + +} +void show_list() +{ + for (Node* pt = queue.front; pt != NULL; pt = pt->next) + { + printf("type:%d number:%d\n", pt->item.type, pt->item.num); + + } + +} +void DeItem() +{ + int type; + Node* pr = NULL; + Node* pt = queue.front; + puts("enter the type to be deleted:"); + scanf_s("%d", &type); + + while (getchar() != '\n') + continue; + for (Node* pt = queue.front; pt != NULL; pr=pt,pt = pt->next) + { + + + + if (pt->item.type == type) + { + if (pr == NULL) + { + queue.front = pt->next; + break; + } + else + { + pr->next = pt->next; + free(pt); + break; + } + } + + } +} + +void save() +{ + FILE* pf; + fopen_s(&pf, "file.txt", "w+"); + + for (Node*pt = queue.front; pt != NULL; pt = pt->next) + { + fprintf(pf, "%d %d ", pt->item.type, pt->item.num); + + } + fclose(pf); +} +void load() +{ + FILE * pf; + if (fopen_s(&pf, "file.txt", "r") != 0) + puts("cannot open file"); + ; + while (fscanf_s(pf, "%d", &(temp.type)) == 1) + { + while (fscanf_s(pf, "%d", &(temp.num)) == 1) + { + Add(temp.type, temp.num); + break; + } + } + fclose(pf); +} +void Add(int type,int num) +{ + Node * pnew = (Node*)malloc(sizeof(Node)); + pnew->item = temp; + pnew->next = NULL; + + if (queue.front == NULL) + queue.front = pnew; + else + queue.rear->next = pnew; + queue.rear = pnew; +} \ No newline at end of file diff --git a/pushboxes/map1.txt b/pushboxes/map1.txt new file mode 100644 index 00000000..157110d1 --- /dev/null +++ b/pushboxes/map1.txt @@ -0,0 +1,10 @@ +********** +* @ * +* # * +* * +*@ * +* # * +* * +* # * +* @ * +********** 6 1 1 4 6 8 4 5 \ No newline at end of file diff --git a/pushboxes/map2.txt b/pushboxes/map2.txt new file mode 100644 index 00000000..b6db29d1 --- /dev/null +++ b/pushboxes/map2.txt @@ -0,0 +1,10 @@ +********** +****@ ** +******# ** +**** * +*@** * +* ** # * +* **** +* ** **** +* # @* +********** 4 1 1 4 8 8 5 5 \ No newline at end of file diff --git a/pushboxes/map3.txt b/pushboxes/map3.txt new file mode 100644 index 00000000..35e9b080 --- /dev/null +++ b/pushboxes/map3.txt @@ -0,0 +1,10 @@ +********** +**** ** +****** ** +**** * +*@** # ** +*@** # ** +*@ **** +* **# **** +* * +********** 1 5 1 4 1 6 5 5 \ No newline at end of file diff --git a/pushboxes/p10_pushboxes.c b/pushboxes/p10_pushboxes.c new file mode 100644 index 00000000..a4b8c9aa --- /dev/null +++ b/pushboxes/p10_pushboxes.c @@ -0,0 +1,386 @@ +#include +#include +#include +#include + +void to_xy(int x, int y); +void panel_score(); +void show_pos(); +void MoveBox(int x, int y, int xt, int yt); +int isfree(int x, int y, char ch); +int victory(); +void MainMenu(FILE* fp); +void load(FILE* fp); +void show_map(); +void show_goal(); +void reset(); + +char maze[10][10]; +int locat1[2] = { 10,10 }; //迷宫开始坐标 +int locat2[2] = {0 }; //当前坐标 +int goal[3][2] = {0}; +int win = 0; +int step = 0; +int complete[3] = { 0 }; + +clock_t t1, t2; + + +void main() +{ + char input; + int des = 0; + + FILE* fp = NULL; + + CONSOLE_CURSOR_INFO cursor_info = { 1, 0 }; + SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info); + + MainMenu(fp); + + + while (1) + { + + + if (win) + { + + reset(); + MainMenu(fp); + + } + + show_map(); + show_goal(); + show_pos(); + + input = _getch(); + switch (input) + { + case'w': + if(isfree(locat2[0] , locat2[1] - 1,'*')) //人不靠墙 + { + if (isfree(locat2[0], locat2[1] - 1, '#')) //不靠箱子且不靠墙 + { + + to_xy(locat2[0], locat2[1]); + printf(" "); + locat2[1]--; + step++; + } + else if (isfree(locat2[0], locat2[1] - 2, '*') && isfree(locat2[0], locat2[1] - 2, '#')) //靠箱子且可移动 + { + + MoveBox(locat2[0], locat2[1] - 1, locat2[0], locat2[1] - 2); + to_xy(locat2[0], locat2[1]); + printf(" "); + locat2[1]--; + step++; + + } + } + + break; + case's': + if (isfree(locat2[0] , locat2[1] + 1, '*')) //人不靠墙 + { + if (isfree(locat2[0], locat2[1] + 1, '#')) //不靠箱子且不靠墙 + { + + to_xy(locat2[0], locat2[1]); + printf(" "); + locat2[1]++; + step++; + } + else if (isfree(locat2[0], locat2[1] + 2, '*') && isfree(locat2[0], locat2[1] + 2, '#')) //靠箱子且可移动 + { + + MoveBox(locat2[0], locat2[1] + 1, locat2[0], locat2[1] + 2); + to_xy(locat2[0], locat2[1]); + printf(" "); + locat2[1]++; + step++; + } + } + + break; + case'a': + if (isfree(locat2[0] - 1, locat2[1], '*')) //人不靠墙 + { + if (isfree(locat2[0]-1, locat2[1] , '#')) //不靠箱子且不靠墙 + { + + to_xy(locat2[0], locat2[1]); + printf(" "); + locat2[0]--; + step++; + } + else if (isfree(locat2[0]-2, locat2[1] , '*') && isfree(locat2[0]-2, locat2[1], '#')) //靠箱子且可移动 + { + + MoveBox(locat2[0]-1, locat2[1], locat2[0]-2, locat2[1]); + to_xy(locat2[0], locat2[1]); + printf(" "); + locat2[0]--; + step++; + } + } + + break; + case'd': + if (isfree(locat2[0] + 1, locat2[1] , '*')) //人不靠墙 + { + if (isfree(locat2[0] + 1, locat2[1], '#')) //不靠箱子且不靠墙 + { + + to_xy(locat2[0], locat2[1]); + printf(" "); + locat2[0]++; + step++; + } + else if (isfree(locat2[0] + 2, locat2[1], '*') && isfree(locat2[0] + 2, locat2[1], '#')) //靠箱子且可移动 + { + + MoveBox(locat2[0] + 1, locat2[1], locat2[0] + 2, locat2[1]); + to_xy(locat2[0], locat2[1]); + printf(" "); + locat2[0]++; + step++; + } + } + break; + case'm': + MainMenu(fp); + break; + + + } + + show_map(); + show_goal(); + show_pos(); + if (victory()) + { + panel_score(); + } + } + +} + + +void to_xy(int x, int y) //到指定坐标 +{ + HANDLE hout; + COORD coord; + coord.X = x; + coord.Y = y; + hout = GetStdHandle(STD_OUTPUT_HANDLE); + SetConsoleCursorPosition(hout, coord); +} + + + +void panel_score() +{ + system("color 0e"); + + to_xy(locat1[0] + 8, locat1[1] + 4); + printf("#################################"); + to_xy(locat1[0] + 8, locat1[1] + 5); + printf("# #"); + to_xy(locat1[0] + 8, locat1[1] + 6); + printf("# - VICTORY - #"); + to_xy(locat1[0] + 8, locat1[1] + 7); + printf("# #"); + to_xy(locat1[0] + 8, locat1[1] + 8); + printf("# time:%3.1f #", (double)((t2 - t1) / CLOCKS_PER_SEC)); + to_xy(locat1[0] + 8, locat1[1] + 9); + printf("# step:%-3d #",step); + to_xy(locat1[0] + 8, locat1[1] + 10); + printf("# Press any key to continue... #"); + to_xy(locat1[0] + 8, locat1[1] + 11); + printf("#################################"); + + _getch(); + + to_xy(locat1[0] + 8, locat1[1] + 4); + printf("#################################"); + to_xy(locat1[0] + 8, locat1[1] + 5); + printf("# #"); + to_xy(locat1[0] + 8, locat1[1] + 6); + printf("# #"); + to_xy(locat1[0] + 8, locat1[1] + 7); + printf("# - A Philosjay Product - #"); + to_xy(locat1[0] + 8, locat1[1] + 8); + printf("# #"); + to_xy(locat1[0] + 8, locat1[1] + 9); + printf("# #"); + to_xy(locat1[0] + 8, locat1[1] + 10); + printf("# #"); + to_xy(locat1[0] + 8, locat1[1] + 11); + printf("#################################"); + Sleep(900); +} + + +void show_pos() +{ + to_xy(locat2[0], locat2[1]); + printf("O"); +} + + + +int isfree(int y, int x,char ch) +{ + if (maze[x-10][y-10] == ch) + return 0; + else + return 1; +} +void MoveBox(int y, int x,int yt,int xt) +{ + maze[x-10][y-10] = ' '; + maze[xt-10][yt-10] = '#'; + +} + +int victory() +{ + if (complete[0]==1&& complete[1] == 1&& complete[2] == 1) + { + t2 = clock(); + win = 1; + return 1; + } + else + return 0; +} +void load(FILE* fp) +{ + char ch; + + + for (int i = 0; i < 10; i++) + { + for (int j = 0; j < 10; j++) + { + fscanf_s(fp, "%c", &ch); + while (ch == '\n') + fscanf_s(fp, "%c", &ch); + maze[i][j] = ch; + } + } + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 2; j++) + { + fscanf_s(fp, "%d", &goal[i][j]); + } + } + fscanf_s(fp, "%d", &locat2[0]); + fscanf_s(fp, "%d", &locat2[1]); + locat2[0] += 10; + locat2[1] += 10; +} +void show_map() +{ + to_xy(locat1[0], locat1[1]); + + for (int i = 0; i < 10; i++) + { + for (int j = 0; j < 10; j++) + { + printf("%c", maze[i][j]); + if (j == 9) + { + to_xy(locat1[0], locat1[1] + i + 1); + } + } + } + to_xy(1, 1); + printf("WSAD:direction"); + to_xy(1,2); + printf("M:main menu"); + to_xy(1, 4); + printf("O:you"); + to_xy(1, 5); + printf("*:wall"); + to_xy(1, 6); + printf("#:box"); + to_xy(1,7); + printf("@:terminal"); +} +void show_goal() +{ + for (int i = 0; i < 3; i++) + { + if (maze[goal[i][1]][goal[i][0]] == '#') + { + to_xy(goal[i][0] + 10, goal[i][1] + 10); + printf("%c", '#'); + complete[i] = 1; + } + else + { + to_xy(goal[i][0] + 10, goal[i][1] + 10); + printf("%c", '@'); + complete[i] = 0; + } + } +} +void MainMenu(FILE* fp) +{ + int ch = 0; + system("color 0f"); + system("cls"); + to_xy(locat1[0]+8, locat1[1] -5); + printf("#################################"); + to_xy(locat1[0]+8, locat1[1] -4); + printf("# #"); + to_xy(locat1[0]+8 , locat1[1] - 3); + printf("# - A Push Box Game - #"); + to_xy(locat1[0]+8 , locat1[1] -2); + printf("# #"); + to_xy(locat1[0]+8, locat1[1] -1); + printf("# Enter #"); + to_xy(locat1[0]+8 , locat1[1] ); + printf("# to choose the map 1~3 : #"); + to_xy(locat1[0]+8 , locat1[1] + 1); + printf("# #"); + to_xy(locat1[0]+8, locat1[1] + 2); + printf("#################################"); + + while (!(ch == 49 || ch == 50 || ch == 51)) + { + ch = _getch(); + + } + switch (ch) + { + case'1': + if (fopen_s(&fp, "map1.txt", "r") != 0) + puts("cannot open file"); + break; + case'2': + if (fopen_s(&fp, "map2.txt", "r") != 0) + puts("cannot open file"); + break; + case'3': + if (fopen_s(&fp, "map3.txt", "r") != 0) + puts("cannot open file"); + break; + + } + load(fp); + fclose(fp); + system("cls"); + t1 = clock(); +} +void reset() +{ + win = 0; + step = 0; + t2 = t1 = 0; +} \ No newline at end of file