浪漫星空:
浪漫星空的思路:
1.定义一个结构体,表示星星的各种属性
2.定义一个数组,里面存放100个星星结构体
3.运用随机函数进行对每个星星的属性初始化
4.显示星星
5.移动星星
未优化前的代码:
(这部分代码是转载的)
#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
using namespace std;
#define MAX_STAR 100
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define MAX_STEP 5
#define MAX_RADIUS 3
#define BOTTOM_MARGIN 100
//星星状态
enum STATUS {
STOP = 0,
UP,
DOWN,
LEFT,
RIGHT,
RANDOM,
ALL_STATUS
};
/*
1.定义一个结构体,表示星星的各种属性
2.定义一个数组,里面存放100个星星结构体
3.运用随机函数进行对每个星星的属性初始化
4.显示星星
5.移动星星
*/
struct STAR {
int x; //星星的 x 坐标
int y; //星星的 y 坐标
enum STATUS stat; //状态
unsigned radius; //星星的半径
int step; //每次跳跃的间隔
int color; //星星的颜色
};
struct STAR star[MAX_STAR];
bool isQuit() {
for (int i = 0; i < MAX_STAR; i++) {
if (star[i].x > 0 && star[i].x < SCREEN_WIDTH && star[i].y>0 &&
star[i].y < SCREEN_HEIGHT) {
return false;
}
}
return true;
}
void MoveStar(int i) {
if (star[i].stat == STOP) return;
//擦除原来的星星
setfillcolor(BLACK);
solidcircle(star[i].x, star[i].y, star[i].radius);
if (star[i].stat == DOWN) {
star[i].y = star[i].y + star[i].step;
//if(star[i].y>SCREEN_HEIGHT) star[i].y = 0;
}
else if (star[i].stat == UP) {
star[i].y -= star[i].step;
//if(star[i].y<0) star[i].y = SCREEN_HEIGHT;
}
else if (star[i].stat == LEFT) {
star[i].x -= star[i].step;
//if(star[i].x<0) star[i].x = SCREEN_WIDTH;
}
else if (star[i].stat == RIGHT) {
star[i].x += star[i].step;
//if(star[i].x>SCREEN_WIDTH) star[i].x = 0;
}
setfillcolor(star[i].color);
solidcircle(star[i].x, star[i].y, star[i].radius);
}
/************************************
* 功能:初始化星星
* 输入参数:
* i - 星星在全局数组中的下标
* 返回值:无
************************************/
void initStar(int i) {
int rgb = 0;
if (i<0 || i>MAX_STAR) {
fprintf(stderr, "老司机,你传的值 i[%d]我受不了!", i);
return;
}
//rand() 得到随机数范围 0 - 32767 RAND_MAX
star[i].x = rand() % SCREEN_WIDTH; // x 范围 0 -639
star[i].y = rand() % (SCREEN_HEIGHT - BOTTOM_MARGIN);// y 范围 0 - 379
star[i].stat = (STATUS)(rand()%4+1);
star[i].radius = 1 + rand() % MAX_RADIUS; //半径控制 1 - 3
star[i].step = rand() % MAX_STEP + 1; //步长 1 - 5
rgb = 255 * star[i].step / MAX_STEP; // 0 - 255
star[i].color = RGB(rgb, rgb, rgb);
}
int main() {
bool quit = false;
initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
for (int i = 0; i < MAX_STAR; i++) {
initStar(i); //初始化星星
}
for (int i = 0; i < MAX_STAR; i++) {
//显示星星
setfillcolor(star[i].color);
solidcircle(star[i].x, star[i].y, star[i].radius);
}
while (quit == false) {
//循环移动星星
for (int i = 0; i < MAX_STAR; i++) {
MoveStar(i);
}
if (isQuit()) {
quit = true;
}
Sleep(50);
}
system("pause");
closegraph();
return 0;
}
优化:
上面的代码因为引用数组,等有些星星已经在外面了但仍然系统对他进行操作,浪费内存空间,所以解决方法就是通过顺序表,将已经排除在外的星星删除,这个操作会越来越简单。
思想:
把原来的数组改成顺序表,然后如果已经超出范围了就删除
list.cpp:顺序表的操作(初始化,添加,删除):
#include<iostream>
#include<Windows.h>
#include"star.h"
using namespace std;
bool initlist(list& my_list) {
my_list.elmes = new struct STAR[MAX_STAR];
if (!my_list.elmes) {
cout << "分配内存失败!" << endl;
return false;
}
my_list.length = 0;
my_list.size = MAX_STAR;
return true;
}
bool Append(list &my_list, struct STAR e) {
if (my_list.length == my_list.size) {
cout << "空间已满!" << endl;
return false;
}
my_list.elmes[my_list.length] = e;
my_list.length++;
return true;
}
bool listDelete(list &list,int pos) {
if (pos < 0 || pos >= list.length) {
return false;
}
for (int i = pos;i < list.length - 1;i++) {
list.elmes[i] = list.elmes[i + 1];
}
list.length--;
return true;
}
void destroyList(list &list) {
if (list.elmes) delete[] list.elmes;
list.length = 0;
list.size = 0;
}
star.h:将一些宏定义和函数说明放到里面:
#pragma once
#define MAX_STAR 100
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define MAX_STEP 5
#define MAX_RADIUS 3
#define BOTTOM_MARGIN 100
//星星状态
enum STATUS {
STOP = 0,
UP,
DOWN,
LEFT,
RIGHT,
RANDOM,
ALL_STATUS
};
struct STAR {
int x; //星星的 x 坐标
int y; //星星的 y 坐标
enum STATUS stat; //状态
unsigned radius; //星星的半径
int step; //每次跳跃的间隔
int color; //星星的颜色
};
typedef struct sq_list {
struct STAR* elmes; //顺序表的首地址
int length; //顺序表的长度
int size; //顺序表的大小
}list;
bool initlist(list& my_list);
bool Append(list& my_list, struct STAR e);
bool listDelete(list& list, int pos);
void destroyList(list& list);
主文件:
定义一个顺序表,先对它分配内存空间,再将不同状态的星星添加到顺序表中,然后开始移动,移动的时候判断是否已经超出了范围,如果超出了就删除这个星,最后判断,只需要判断是否顺序表中还拥有星星就行:
#include <graphics.h>
#include <conio.h>
#include <stdlib.h>
#include <stdio.h>
#include <string>
#include"star.h"
using namespace std;
void MoveStar(list &list_star,int i) {
if (list_star.elmes[i].stat == STOP) return;
//擦除原来的星星
setfillcolor(BLACK);
solidcircle(list_star.elmes[i].x, list_star.elmes[i].y, list_star.elmes[i].radius);
if (list_star.elmes[i].stat == DOWN) {
list_star.elmes[i].y = list_star.elmes[i].y + list_star.elmes[i].step;
if (list_star.elmes[i].y > SCREEN_HEIGHT) listDelete(list_star, i);
}
else if (list_star.elmes[i].stat == UP) {
list_star.elmes[i].y -= list_star.elmes[i].step;
if (list_star.elmes[i].y < 0) listDelete(list_star, i);
}
else if (list_star.elmes[i].stat == LEFT) {
list_star.elmes[i].x -= list_star.elmes[i].step;
if(list_star.elmes[i].x<0) listDelete(list_star, i);
}
else if (list_star.elmes[i].stat == RIGHT) {
list_star.elmes[i].x += list_star.elmes[i].step;
if(list_star.elmes[i].x>SCREEN_WIDTH) listDelete(list_star, i);
}
setfillcolor(list_star.elmes[i].color);
solidcircle(list_star.elmes[i].x, list_star.elmes[i].y, list_star.elmes[i].radius);
}
/************************************
* 功能:初始化星星
* 输入参数:
* i - 星星在全局数组中的下标
* 返回值:无
************************************/
void initStar(struct STAR &chu_star) {
int rgb = 0;
//rand() 得到随机数范围 0 - 32767 RAND_MAX
chu_star.x = rand() % SCREEN_WIDTH; // x 范围 0 -639
chu_star.y = rand() % (SCREEN_HEIGHT - BOTTOM_MARGIN);// y 范围 0 - 379
chu_star.stat = (STATUS)(rand()%4+1);
chu_star.radius = 1 + rand() % MAX_RADIUS; //半径控制 1 - 3
chu_star.step = rand() % MAX_STEP + 1; //步长 1 - 5
rgb = 255 * chu_star.step / MAX_STEP; // 0 - 255
chu_star.color = RGB(rgb, rgb, rgb);
}
int main() {
list list_star;
struct STAR chu_star;
bool quit = false;
initlist(list_star);
initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
for (int i = 0; i < MAX_STAR; i++) {
initStar(chu_star);
Append(list_star, chu_star);
}
for (int i = 0; i < MAX_STAR; i++) {
setfillcolor(list_star.elmes[i].color);
solidcircle(list_star.elmes[i].x, list_star.elmes[i].y, list_star.elmes[i].radius);
}
while (quit == false) {
for (int i = 0; i < list_star.length; i++) {
MoveStar(list_star,i);
}
if (list_star.length == 0) {
quit = true;
}
Sleep(50);
}
system("pause");
closegraph();
return 0;
}