📄 小新俄罗斯方块0.1.c
字号:
#include <stdio.h>
#include <graphics.h>
#include <stdio.h>
#include <dos.h>
#include <time.h>
typedef unsigned int word;
#define BOARDLEN 12
#define HORI_COUNT 12
#define VERTI_COUNT 20
#define MAXWIDTH 640
#define MAXHEIGTH 480
#define BLANK 2
#define BGCOLOR BLACK
#define BGBTMCOLOR 7
#define LEFTEDGE BG_X
#define STATICCOLOR DARKGRAY
#define TIMER 0x1c
#define VK_LEFT 0x4b00
#define VK_RIGHT 0x4d00
#define VK_DOWN 0x5000
#define VK_UP 0x4800
#define VK_ESC 0x011b
#define VK_ENTER 0x1c0d
#define RIGHTEDGE ((BG_X) + ((HORI_COUNT) * ((BOARDLEN) + (BLANK))) - BLANK)
#define TOPEDGE BG_Y
#define BOTMEDGE ((BG_Y) + ((VERTI_COUNT) * ((BOARDLEN) + (BLANK))) - BLANK)
#define HORI_LEN (((BOARDLEN) + (BLANK)) * (HORI_COUNT))
#define VERTI_LEN (((BOARDLEN) + (BLANK)) * (VERTI_COUNT))
#define BLOCK_COUNT ((HORI_COUNT) * (VERTI_COUNT))
#define BG_X (((MAXWIDTH) - (HORI_LEN)) /2)
#define BG_Y (((MAXHEIGTH) - (VERTI_LEN)) /2)
typedef struct point {
int x;
int y;
} point_t;
typedef struct shape {
point_t coord[4];
int color;
char next;
} shape_t;
char allblocks[BLOCK_COUNT];
char gameover;
long speed;
long score;
shape_t shapes[19] = {
{ 0,-2, 0,-1, 0, 0, 1, 0, 5, 1}, {-1, 0, 0, 0, 1,-1, 1, 0, 5, 2}, { 0,-2, 1,-2, 1,-1, 1, 0, 5, 3},
{-1,-1,-1, 0, 0,-1, 1,-1, 5, 0},{ 0,-2, 0,-1, 0, 0, 1,-2, 3, 5}, {-1,-1,-1, 0, 0, 0, 1, 0, 3, 6},
{ 0, 0, 1,-2, 1,-1, 1, 0, 3,7}, {-1,-1, 0,-1, 1,-1, 1, 0, 3, 4}, {-1, 0, 0,-1, 0, 0, 1, 0, 10, 9},
{-1,-1, 0,-2, 0,-1, 0, 0, 10, 10},{-1,-1, 0,-1, 0, 0, 1,-1, 10, 11}, { 0,-2, 0,-1, 0, 0, 1,-1, 10, 8},
{-1, 0, 0,-1, 0, 0, 1,-1, 6, 13}, { 0,-2, 0,-1, 1,-1, 1, 0, 6, 12},{-1,-1, 0,-1, 0, 0, 1, 0, 1, 15},
{ 0,-1, 0, 0, 1,-2, 1,-1, 1, 14},{ 0,-3, 0,-2, 0,-1, 0, 0, 4, 17}, {-1, 0, 0, 0, 1, 0, 2, 0, 4, 16},{ 0,-1, 0, 0, 1,-1, 1, 0, 15, 18},
};
typedef enum {
UP = 1,
DOWN = 2,
LEFT = 3,
RIGHT = 4
} direction;
int timercounter=0;
void interrupt ( *oldhandler)();
void interrupt newhandler()
{
timercounter++;
oldhandler();
}
void settimer(void interrupt (*IntProc)())
{
oldhandler = getvect(TIMER);
disable();
setvect(TIMER,IntProc);
enable();
}
void killtimer()
{
disable();
setvect(TIMER,oldhandler);
enable();
}
void initgraphmode()
{
int gdriver;
int gmode;
gdriver = DETECT;
registerbgidriver(EGAVGA_driver);
initgraph(&gdriver, &gmode, "");
cleardevice();
}
void numboard(int x, int y, long num)
{
char string[20];
setfillstyle(SOLID_FILL, BLACK);
bar(x, y, x + 16 * 3, y + 16);
setcolor(DARKGRAY);
rectangle(x, y, x + 16 * 3, y + 16);
sprintf(string, "%ld", num);
setcolor(LIGHTGREEN);
settextjustify(RIGHT_TEXT,TOP_TEXT);
outtextxy(x + 10, y + 5, string);
}
void initbkgound()
{
int i, j;
for (i = 0; i < BLOCK_COUNT; i++)
allblocks = 0;
setcolor(LIGHTGREEN);
settextjustify(RIGHT_TEXT,TOP_TEXT);
outtextxy(LEFTEDGE - 46 -50 -1 - 20 + 10, TOPEDGE + 5, "NEXT");
outtextxy(LEFTEDGE - 46 -50 -1 - 20 + 10, TOPEDGE + 60 + 5, "SCORE");
outtextxy(LEFTEDGE - 46 -50 -1 - 20 + 10, TOPEDGE + 90 + 5, "SPEED");
numboard(LEFTEDGE - 46 -50 -1, TOPEDGE + 60, 0);
numboard(LEFTEDGE - 46 -50 -1, TOPEDGE + 90, 1);
setfillstyle(SOLID_FILL, BLACK);
bar(LEFTEDGE - 1, TOPEDGE - 1, RIGHTEDGE + 1, BOTMEDGE + 1);
setcolor(DARKGRAY);
rectangle(LEFTEDGE - 1, TOPEDGE - 1, RIGHTEDGE + 1, BOTMEDGE + 1);
}
void drawblock(point_t pt, int len, int color)
{
setfillstyle(SOLID_FILL, color);
bar(pt.x, pt.y, pt.x + len, pt.y + len);
}
void drawblock2(int startx, int starty, int x, int y, int len, int space, int color)
{
point_t pt;
if (x < 0 || y < 0 || x >= VERTI_COUNT || y >= HORI_COUNT)
return;
pt.x = startx + y * (len + space);
pt.y = starty + x * (len + space);
drawblock(pt, len, color);
}
void drawshape(shape_t sp, point_t pt, int len)
{
point_t parray[4];
int i;
for (i = 0; i < 4; i++) {
parray.x = pt.x + len * sp.coord.y;
parray.y = pt.y + len * sp.coord.x;
drawblock(parray, len, sp.color);
}
}
void drawshape2(shape_t sp, int startx, int starty, int x, int y, int len, int space, int color)
{
int tx, ty, i;
for (i = 0; i < 4; i++) {
tx = x + sp.coord.y;
ty = y + sp.coord.x;
drawblock2(startx, starty, tx, ty, len, space, color);
}
}
void nextboard(shape_t sp)
{
int i, j;
setfillstyle(SOLID_FILL, BLACK);
bar(LEFTEDGE - 46 -50 -1, TOPEDGE - 1, LEFTEDGE - 50 + 1, TOPEDGE + 46 + 1);
setcolor(DARKGRAY);
rectangle(LEFTEDGE - 46 - 50 - 1, TOPEDGE - 1, LEFTEDGE - 50 + 1, TOPEDGE + 46 + 1);
drawshape2(sp, LEFTEDGE - 46 - 50, TOPEDGE, 3, 1, 10, 2, sp.color);
}
void initnewgame()
{
initgraphmode();
initbkgound();
timercounter = 0;
gameover = 0;
speed = 1;
score = 0;
settimer(newhandler);
}
void move(shape_t sp, point_t *ptp, direction d)
{
drawshape2(sp, LEFTEDGE, TOPEDGE, ptp->x, ptp->y, BOARDLEN, BLANK, BGCOLOR);
switch(d) {
case DOWN:
ptp->x++;
break;
case LEFT:
ptp->y--;
break;
case RIGHT:
ptp->y++;
break;
default:
break;
}
drawshape2(sp, LEFTEDGE, TOPEDGE, ptp->x, ptp->y, BOARDLEN, BLANK, sp.color);
}
int canmove(shape_t sp, point_t pt, direction d)
{
int i, tx, ty, index;
switch(d) {
case DOWN:
for (i = 0; i < 4; i++) {
tx = pt.x + sp.coord.y + 1;
ty = pt.y + sp.coord.x;
index = tx * HORI_COUNT + ty;
if (tx >= VERTI_COUNT || (index >= 0 && index < BLOCK_COUNT &&allblocks[index] == 1))
return 0;
}
return 1;
case LEFT:
for (i = 0; i < 4; i++) {
tx = pt.x + sp.coord.y;
ty = pt.y + sp.coord.x - 1;
index = tx * HORI_COUNT + ty;
if (ty < 0 || (index >= 0 && index < BLOCK_COUNT &&allblocks[index] == 1))
return 0;
}
return 1;
case RIGHT:
for (i = 0; i < 4; i++) {
tx = pt.x + sp.coord.y;
ty = pt.y + sp.coord.x + 1;
index = tx * HORI_COUNT + ty;
if (ty >= HORI_COUNT || (index >= 0 && index < BLOCK_COUNT &&allblocks[index] == 1))
return 0;
}
return 1;
default:
break;
}
return 0;
}
void rotate(shape_t *spp, point_t pt)
{
drawshape2(*spp, LEFTEDGE, TOPEDGE, pt.x, pt.y, BOARDLEN, BLANK, BGCOLOR);
*spp = shapes[spp->next];
drawshape2(*spp, LEFTEDGE, TOPEDGE, pt.x, pt.y, BOARDLEN, BLANK, spp->color);
}
int canrotate(shape_t sp, point_t pt)
{
int i, tx, ty, index;
shape_t tsp = shapes[sp.next];
for (i = 0; i < 4; i++) {
tx = pt.x + tsp.coord.y;
ty = pt.y + tsp.coord.x;
index = tx * HORI_COUNT + ty;
if (ty < 0 || tx >= VERTI_COUNT || ty >= HORI_COUNT || (index >= 0 && index < BLOCK_COUNT &&allblocks[index] == 1)) return 0;
}
return 1;
}
int needremove()
{
int i, j, index, line;
for (i = VERTI_COUNT - 1; i >= 0; i --) {
for (j = 0; j < HORI_COUNT; j++) {
index = i * HORI_COUNT + j;
if (allblocks[index] == 0) break;
}
if (HORI_COUNT == j) {
line = i;
return line;
}
}
return -1;
}
void removeline(int line)
{
int i, j, index_up, index_dn, color;
for (i = line; i >= 0; i--) {
if (0 == i) {
for (j = 0; j < HORI_COUNT; j++) {
drawblock2(LEFTEDGE, TOPEDGE, i, j, BOARDLEN, BLANK, BGCOLOR);
allblocks[j] = 0;
}
return;
}
for (j = 0; j < HORI_COUNT; j++) {
index_up = (i - 1) * HORI_COUNT + j;
index_dn = i * HORI_COUNT + j;
if (allblocks[index_up] == allblocks[index_dn])
continue;
color = (1 == allblocks[index_up]) ? STATICCOLOR : BGCOLOR;
drawblock2(LEFTEDGE, TOPEDGE, i, j, BOARDLEN, BLANK, color);
allblocks[index_dn] = allblocks[index_up];
}
}
}
int main()
{
point_t pt;
shape_t sp;
int i, j ,next, current, indexblocks, keyhitten;
initnewgame();
next = -1;
while (1) {
srand(time(NULL) + 1000);
current = (next >= 0) ? next : rand() % 19;
next = rand() % 19;
nextboard(shapes[next]);
sp = shapes[current];
pt.x = 0;
pt.y = 6;
indexblocks = pt.x * HORI_COUNT + pt.y;
if (1 == allblocks[indexblocks]) {
gameover = 1;
break;
}
drawshape2(sp, LEFTEDGE, TOPEDGE, pt.x, pt.y, BOARDLEN, BLANK, sp.color);
while (1) {
keyhitten = 0;
if (bioskey(1)) {
keyhitten = bioskey(0);
}
switch(keyhitten) {
case VK_LEFT:
if (1 == canmove(sp, pt, LEFT))
move(sp, &pt, LEFT);
break;
case VK_RIGHT:
if (1 == canmove(sp, pt, RIGHT))
move(sp, &pt, RIGHT);
break;
case VK_UP:
if (1 == canrotate(sp, pt))
rotate(&sp, pt);
break;
case VK_DOWN:
while (canmove(sp , pt, DOWN))
move(sp, &pt, DOWN);
break;
case VK_ESC:
gameover = 1;
break;
default:
break;
}
if (0 == canmove(sp , pt, DOWN)) {
drawshape2(sp, LEFTEDGE, TOPEDGE, pt.x, pt.y, BOARDLEN, BLANK, STATICCOLOR);
}
if (timercounter > 20 - speed * 2) {
timercounter = 0;
if (1 == canmove(sp , pt, DOWN)) {
move(sp, &pt, DOWN);
} else {
for (i = 0; i < 4; i++) {
indexblocks = ( pt.x + sp.coord.y ) * HORI_COUNT + pt.y + sp.coord.x;
allblocks[indexblocks] = 1;
}
while ((i = needremove()) >= 0) {
removeline(i);
score += speed * 1;
numboard(LEFTEDGE - 46 -50 -1, TOPEDGE + 60, score);
if (score > speed * 100)
speed++;
numboard(LEFTEDGE - 46 -50 -1, TOPEDGE + 90, speed);
}
break;
}
}
if (1 == gameover)
break;
}
if (1 == gameover)
break;
}
bioskey(0);
killtimer();
closegraph();
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -