其中多处坐标的代码是经过运算移项推导出的
#include<easyx.h>
#include<conio.h>
#include<time.h>
#include<stdio.h>
bool Timer(int id, int ms)//计时器,过了多少毫秒就会返回真
{
static long start[3] = { 0 };
long last = clock();
if (last - start[id] >= ms)
{
start[id] = last;
return true;
}
else return false;
}
void fail()
{
settextstyle(600, 0, 0);
settextcolor(RED);
outtextxy(800, 500, "你死了!");
EndBatchDraw();
_getch();
}
class Car {
public:
short x, y;
COLORREF color;
void isHit(short objx, short objy)
{
if (!(x > objx + 65 || x + 65 < objx || 715 > objy || 885 < objy))
fail();
}
void show()
{
setfillcolor(color);
solidcircle(x + 10, y + 10, 10);
solidcircle(x + 55, y + 10, 10);
solidrectangle(x + 20, y + 20, x + 45, y + 65);
solidcircle(x + 10, y + 75, 10);
solidcircle(x + 55, y + 75, 10);//长度65,宽度85
}
};
class Npc :public Car
{
public:
bool isLive = false;
static Npc* p;
static int* a;
bool overLap(int j)
{
for (int i = 0; i < 6; i++)
{
if (i == j || p[i].isLive == false)
continue;
if (!(x > p[i].x + 65 || x + 65 < p[i].x || 86 < p[i].y))
return true;
}
return false;
}
static void loop(Car*player,int j) {
for (int i = 0; i < 6; i++)
{
int c = 0;
if (p[i].isLive == false && rand() % 100 == 0)
{
short n1 = a[j], n2 = a[j + 1 > 53 ? 0 : j + 1], n3 = a[j + 2 > 53 ? j - 52 : 2], length;
short max = (n1 > n2 ? n1 : n2) > n3 ? (n1 > n2 ? n1 : n2) : n3;
short min = (n1 < n2 ? n1 : n2) < n3 ? (n1 < n2 ? n1 : n2) : n3;
length = min + 835 - max;//max-min+900-65,算出车辆x坐标可出现的变动值
do { p[i].x = rand() % length + 10 + max; }//随机偏移量加上最右边的道路方块起始坐标
while (p[i].overLap(i) && c++ < 1000);
p[i].isLive = true;
p[i].y = 1;
p[i].color = RGB(rand() % 200 + 56, rand() % 200 + 56, rand() % 200 + 56);
}
}
for (int i = 0; i < 6; i++)
{
if (p[i].isLive)
{
if (p[i].y >= 1080)
p[i].isLive = false;
p[i].y += 20;
p[i].show();
player->isHit(p[i].x, p[i].y);//判断有没有撞击敌机
}
}
}
};
Npc* Npc::p = 0;
int* Npc::a = 0;
int main()
{
short a[54] = { 0 };//道路两旁横坐标数组,为了生成蜿蜒曲折的路,用数组模拟双向循环链表
short dire = 0, lastdire = 0, c = 0, t = 30, change = 0, behind = 0, j = 0, metre = 0;//c为道路绵延相同方向的次数
ExMessage ex = { 0 }; bool mouseclick = 0; char str[128];
Car player;
player.x = 500, player.y = 800, player.color = RGB(0, 255, 255);
Npc npc[6];
Npc::p = npc;
srand(time(0));
//车路宽度为920
initgraph(1920, 1080);
setbkmode(TRANSPARENT);
settextstyle(100, 0, 0);
settextcolor(GREEN);
_getch();
while (1)
{
if (peekmessage(&ex, EX_MOUSE))//监听鼠标事件
{
switch (ex.message)
{
case WM_LBUTTONDOWN:
if (ex.x > player.x && ex.x < player.x + 45)
mouseclick = 1;
break;
case WM_LBUTTONUP:
mouseclick = 0;
}
if (mouseclick)//只有拖拽不放才能移动,不能单击任意位置实现瞬移
player.x = ex.x - 22;
}
if (Timer(1, 3000) && t > 5)
t--;
if (Timer(2, t * 4))
{
metre++;
sprintf_s(str, "%d米", metre);
}
if (Timer(0, t))
{
BeginBatchDraw();
cleardevice();
int color = 255;
for (int i = 0; i < 54; i++)
{
int index, x;
if (j + i > 53)
index = j + i - 54;
else index = j + i;
x = a[index];
setfillcolor(RGB(color, color, 0));
color -= 4;//道路颜色变淡
solidrectangle(x, i * 20 + 1, x + 10, i * 20 + 21);
x += 910;
solidrectangle(x, i * 20 + 1, x + 10, i * 20 + 21);
}
player.show();
Npc::loop(npc, j);
for (int i = 3, y = 40 + j; i < 6; i++)//检测主角是否撞到道路
{
int index, x;
if (y + i > 53)
index = y + i - 54;
else index = y + i;
x = a[index];
if (x + 10 > player.x || x + 865 < player.x)
fail();
}
outtextxy(0, 0, str);
if (j-- == -1)//j为道路最前面对应的数组下标,自减后是新一轮的下标
{
behind = 0;
j = 53;
}
else behind = j + 1;
if (c >= 13)
dire = rand() % 3 - 1;
if (dire == lastdire)
c++;
else c = 1;
lastdire = dire;
change = dire * 2 * (rand() % 4 + 1);
int tmp = a[behind] + change;
if (tmp > 0 && tmp <= 1000)
a[j] = tmp;
else a[j] = a[behind];
//前面的路受后面影响
EndBatchDraw();
}
}
}