用c语言实现小游戏--俄罗斯方块

8 篇文章 1 订阅

基于我们已经实现了相对来说比较完整可以经行娱乐的贪吃蛇游戏,用C语言实现小游戏–贪吃蛇我们接下来,可以再实现一个比贪吃蛇更加复杂的游戏。俄罗斯方块。

这里写图片描述
同样先是完成界面显示的文件,对应的.h 和.c文件

#ifndef __UI_H__
#define __UI_H__

typedef struct pos
{
    int x;
    int y;
}pos;


enum Shapetype
{
    SHAPE1 = 0,
    SHAPE2,
    SHAPE3,
    SHAPE4,
    SHAPE5,
    SHAPE6
};
struct UI {
    // 边缘宽度
    int marginTop;
    int marginLeft;

    // 游戏区域的个数
    int gameWidth;
    int gameHeight;

    // 整个窗口大小宽度
    int windowWidth;
    int windowHeight;

    char *Block;    // 显示块
    int blockWidth;     // 每个块的宽度,注意,上面几个块的宽度要相等,否则就对不齐了
    int *_a;
};
struct Shape
{
    pos* postion;
    enum Shapetype shapetype;
};
// UI 初始化
struct UI * UIInitialize(int width, int height);
void UICleanBlock(const struct UI *pUI, struct Shape*shape);

int InsertScore(struct UI *pUI);
// 显示游戏向导
void UIDisplayWizard(const struct UI *pUI);
// 显示游戏整体,包括墙、右边的信息
void UIDisplayGameWindow(const struct UI *pUI, int score);

void _CoordinatePosAtXY(const struct UI *pUI, int x,int y);

void _ResetCursorPosition(const struct UI *pUI);

void UIDisplayBlock(const struct UI *pUI, struct Shape *shape);
// 清空x,y处的显示块
void UICleanBlockAtY(const struct UI *pUI, int y);
// 显示分数信息
void UIDisplayScore(const struct UI *pUI, int score);
// 销毁 UI 资源
void UIDeinitialize(struct UI *pUI);
int IsGameOver(const struct UI*pUI);
int IsRightHaveShape(const int *a, struct Shape *shape,int width);
int IsLeftHaveShape(const int *a, struct Shape*shape, int width);
#endif
#define _CRT_SECURE_NO_WARNINGS

#include "UI.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

// 移动光标到x,y处,注意,这里是相对整个屏幕的,而不是游戏盘的
static void _SetPos(int x, int y);
// 显示墙
static void _DisplayWall(const struct UI *pUI);
// 显示右侧信息
static void _DisplayDesc(const struct UI *pUI);
// 将游戏盘的x,y坐标转换为相对整个屏幕的x,y
void _CoordinatePosAtXY(const struct UI *pUI, int x, int y);
// 重置光标到屏幕下方,主要是为了显示的美观
void _ResetCursorPosition(const struct UI *pUI);
//数组整体下移
void GetDown(int i, int *a, int width);
//显示,清理图形
static void  _DisplayShape(const struct UI *pUI, struct Shape*shape);
static void  _ClearShape(const struct UI *pUI, struct Shape *shape);

//设置单块颜色
void SetColor(unsigned short ForeColor, unsigned short BackGroundColor)
{
    //forecolor 字体颜色backgroundcolor底色
    HANDLE hCon = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleTextAttribute(hCon, (ForeColor % 16) | (BackGroundColor % 16 * 16));
}
struct UI * UIInitialize(int width, int height)
{
    const int left = 2;
    const int top = 2;
    const int blockWidth = 2;   // @杨祥钰指出
    const int descWidth = 50;

    struct UI *pUI = (struct UI *)malloc(sizeof(struct UI));
    pUI->gameWidth = width;
    pUI->gameHeight = height;
    pUI->marginLeft = left;
    pUI->marginTop = top;
    pUI->windowWidth = left + (width + 2) * blockWidth + descWidth;
    pUI->windowHeight = top + height + 2 + 3;
    pUI->Block = "█";
    pUI->blockWidth = strlen(pUI->Block);
    pUI->_a = (int *)malloc(sizeof(int)*(pUI->gameHeight)*(pUI->gameWidth));
    memset(pUI->_a, 0, sizeof(int)*(pUI->gameHeight)*(pUI->gameWidth));
    char modeCommand[1024];
    sprintf(modeCommand, "mode con cols=%d lines=%d", pUI->windowWidth, pUI->windowHeight);
    system(modeCommand);

    return pUI;
} 

void UIDisplayWizard(const struct UI *pUI)
{
    int i;
    const char *messages[3] = {
        "欢迎来到俄罗斯方块小游戏",
        "用↑旋转, ←→移动,↓加速。",
        "加速将能得到更高的分数。"
    };

    i = 0;
    _SetPos(pUI->windowWidth / 2 - strlen(messages[i]) / 2, pUI->windowHeight / 2);
    printf("%s\n", messages[i]);
    _SetPos(pUI->windowWidth / 2 - strlen(messages[i]) / 2, pUI->windowHeight / 2 + 2);
    system("pause");
    system("cls");

    i = 1;
    _SetPos(pUI->windowWidth / 2 - strlen(messages[i]) / 2, pUI->windowHeight / 2);
    printf("%s\n", messages[i]);

    i = 2;
    _SetPos(pUI->windowWidth / 2 - strlen(messages[i]) / 2, pUI->windowHeight / 2 + 2);
    printf("%s\n", messages[i]);
    _SetPos(pUI->windowWidth / 2 - strlen(messages[i]) / 2, pUI->windowHeight / 2 + 4);
    system("pause");
    system("cls");
}

void UIDisplayGameWindow(const struct UI *pUI, int score)
{
    _DisplayWall(pUI);
    UIDisplayScore(pUI, score);
    _DisplayDesc(pUI);

    _ResetCursorPosition(pUI);
}
//显示图形块
void UIDisplayBlock(const struct UI *pUI,struct Shape* shape)
{
    //不同形状
    _DisplayShape(pUI, shape);
    _ResetCursorPosition(pUI);
}
//清理一行的块
void UICleanBlockAtY(const struct UI *pUI, int y)
{
        _CoordinatePosAtXY(pUI, 0, y);
        int i;
        for (i = 0; i < pUI->gameWidth; i++) {
            printf("  ");
        }

    _ResetCursorPosition(pUI);
}
//清理图形块
void UICleanBlock(const struct UI *pUI,struct Shape*shape) 
{
    _ClearShape(pUI, shape);
    _ResetCursorPosition(pUI);
}
void UIDisplayScore(const struct UI *pUI, int score)

{
    int blockWidth = strlen(pUI->Block);
    int left = pUI->marginLeft + (pUI->gameWidth + 2) * blockWidth + 2;
    _SetPos(left, pUI->marginTop + 8);
    printf("得分: %3d", score);

    _ResetCursorPosition(pUI);
}

void UIDeinitialize(struct UI *pUI)
{
    free(pUI);
}

static void _DisplayWall(const struct UI *pUI)
{
    int left = pUI->marginLeft;
    int top = pUI->marginTop;
    int width = pUI->gameWidth;
    int height = pUI->gameHeight;
    int blockWidth = pUI->blockWidth;
    int i;

    // 上
    _SetPos(left, top);
    for (i = 0; i < width + 2; i++) {
        printf("%s", pUI->Block);
    }

    // 下
    _SetPos(left, top + 1 + height);
    for (i = 0; i < width + 2; i++) {
        printf("%s", pUI->Block);
    }

    // 左
    for (i = 0; i < height + 2; i++) {
        _SetPos(left, top + i);
        printf("%s", pUI->Block);
    }

    // 右
    for (i = 0; i < height + 2; i++) {
        _SetPos(left + (1 + width) * blockWidth, top + i);
        printf("%s", pUI->Block);
    }
}

static void _DisplayDesc(const struct UI *pUI)
{
    int left = pUI->marginLeft + (pUI->gameWidth + 2) * pUI->blockWidth + 2;
    const char *messages[] = {
        "用↑旋转。",
        "用↓加速。",
        "用 ← → 分别控制方块的移动。",
        "ESC 退出游戏, SPACE 暂停游戏。",
    };
    int i;

    for (i = 0; i < sizeof(messages) / sizeof(char *); i++) {
        _SetPos(left, pUI->marginTop + 10 + i);
        printf("%s\n", messages[i]);
    }
}

static void _SetPos(int x, int y)
{
    COORD position = { x, y };
    HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);

    SetConsoleCursorPosition(hOutput, position);
}

void _CoordinatePosAtXY(const struct UI *pUI, int x, int y)
{
    _SetPos(pUI->marginLeft + (1 + x) * pUI->blockWidth,
        pUI->marginTop + 1 + y);
}
void _ResetCursorPosition(const struct UI *pUI)
{
    _SetPos(0, pUI->windowHeight - 1);
}
//显示一行
static void  _DisplayY(const struct UI *pUI,int j )
{
    char *s = pUI->Block;
    int i = 0;
    int coust = 0;
    for (; j > 0; j--) {
        for (i = 0; i < pUI->gameWidth; i++)
        {
            int b = pUI->_a[j*pUI->gameWidth + i];
            _CoordinatePosAtXY(pUI, i, j);
            if (b == 0)
            {
                SetColor(7, 0);
                printf("  ");
            }
            else {
                coust = 1;
                SetColor(b, 0);
                printf(pUI->Block);
                SetColor(7, 0);
            }

        }
        if (coust == 0)break;
    }
}
static void  _DisplayShape(const struct UI *pUI,struct Shape*shape)
{
    SetColor(shape->shapetype+1, 0);
    char *s = pUI->Block;
    int i = 0;
    for (i = 0; i < 4; i++)
    {
        _CoordinatePosAtXY(pUI, shape->postion[i].x, shape->postion[i].y);
        pUI->_a[shape->postion[i].x + shape->postion[i].y*pUI->gameWidth] = shape->shapetype + 1;
        printf(pUI->Block);
    }
    SetColor(7, 0);
}
static void  _ClearShape(const struct UI *pUI, struct Shape *shape)
{
    SetColor(7, 0);
    int i = 0;
    for (i = 0; i < 4; i++)
    {
        pUI->_a[shape->postion[i].x + shape->postion[i].y*pUI->gameWidth] = 0;
        _CoordinatePosAtXY(pUI, shape->postion[i].x, shape->postion[i].y);
        printf("  ");
    }
}
//判断游戏结束
int IsGameOver(const struct UI*pUI)
{
    int x = pUI->gameWidth;
    int i = 0;
    for (i = 0; i < pUI->gameWidth; i++)
    {
        if (pUI->_a[i + x] != 0)
            return 1;
    }
    return 0;
}
//左边有没有图形是否可以左移
int IsRightHaveShape(const int *a, struct Shape *shape, int width)
{
    if (a[shape->postion[3].x + 1 + shape->postion[3].y*width] != 0 ||
        a[shape->postion[2].x + 1 + shape->postion[2].y*width] != 0 || 
        a[shape->postion[1].x + 1 + shape->postion[1].y*width] != 0 ||
        a[shape->postion[0].x + 1 + shape->postion[0].y*width] != 0 )
        return 1;
    return 0;
}
//是否可以右移
int IsLeftHaveShape(const int *a,struct Shape*shape,int width)
{
    if (a[shape->postion[3].x - 1 + shape->postion[3].y*width] != 0 ||
        a[shape->postion[2].x - 1 + shape->postion[2].y*width] != 0 ||
        a[shape->postion[1].x - 1 + shape->postion[1].y*width] != 0 ||
        a[shape->postion[0].x - 1 + shape->postion[0].y*width] != 0)
        return 1;
    return 0;
}
//加分下移显示
int InsertScore(struct UI *pUI)
{
    int i = 0;
    int cur = 0;
    for (i = pUI->gameHeight-1; i >0; i--)
    {
        int j = 0;
        for (j = 0; j < pUI->gameWidth; j++)
        {
            if (pUI->_a[i*pUI->gameWidth + j] == 0)
                break;
        }
        if (j == pUI->gameWidth)
        {
            cur++;
            UICleanBlockAtY(pUI,i);
            GetDown(i, pUI->_a, pUI->gameWidth);
            _DisplayY(pUI, i);
            i++;
        }
    }
    return cur;
}
void GetDown(int i,int *a,int width)
{
    int j = 0;
    for (j = i; j > 0; j--)
    {
        int m = 0;
        for (m = 0; m < width; m++)
        {
            a[j*width + m] = a[(j - 1)*width + m];
        }
    }
}

相比较贪吃蛇这个游戏,俄罗斯方块对应的游戏内的编写复杂程度就稍有些大。我们要设计5到6种俄罗斯方块种类,以及他们要进行旋转,下移,消除等等。对应的game的.h和.c文件如下

#pragma once
#ifndef GAME
#define GAME
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<windows.h>
#include"UI.h"

enum Status
{
    QUIT,
    OVER,
    GOOD
}; 
enum Direction
{
    UP,
    DOWN,
    LEFT,
    RIGHT
};


struct Game
{
    int width;
    int height;
    int score;
    enum Direction direction;
    enum Status status;
    struct Shape *shape;
    int sleeptime;
    int twist;
};
struct Game *CreateGame();
void StartGame(struct Game *pGame);
void DestoryGame(struct Game *pGame);
#endif // !Game
#pragma once
#include"Game.h"
//暂停
static void _Pause();
//获取方向
static void _HandleDirective(struct Game *pGame);
//产生新图形
static void ChanceShape(struct Game *pGame);
//确定新图形的样子
static void IsShape(int twist,struct Shape* shape);


struct Game *CreateGame()
{
    struct Game *pGame = (struct Game *)malloc(sizeof(struct Game));
    pGame->width = 10;
    pGame->height = 20;
    pGame->score = 0;
    pGame->direction = DOWN;
    pGame->status = GOOD;
    pGame->shape = (struct Shape*)malloc(sizeof(struct Shape));
    pGame->shape->postion = (pos *)malloc(sizeof(pos) * 4);
    pGame->shape->postion[0].x = 3;
    pGame->shape->postion[0].y = 0;
    pGame->shape->shapetype = SHAPE1;
    pGame->sleeptime = 500;
    pGame->twist = 0;
    return pGame;
}
static void ChanceShape(struct Game *pGame)
{
    pGame->sleeptime = 500;
    pGame->shape->shapetype=rand() % 6;//0-5
    //pGame->shape->shapetype = 1;//0-5
    pGame->shape->postion[0].x = 3;
    pGame->shape->postion[0].y = 0;
    IsShape(pGame->twist,pGame->shape);
}
static void IsShape(int twist,struct Shape* shape)
{
    int x = shape->postion[0].x;
    int y = shape->postion[0].y;
        switch (shape->shapetype)
        {
        case SHAPE1:
        {
            //o o
            //o o
            shape->postion[1].x = x + 1;
            shape->postion[1].y = y;
            shape->postion[2].x = x;
            shape->postion[2].y = y + 1;
            shape->postion[3].x = x + 1;
            shape->postion[3].y = y + 1;
            break;
        }
        case SHAPE2:
        {
            if (twist == 0)
            {
                //o o o
                //o
                shape->postion[1].x = x + 1;
                shape->postion[1].y = y;
                shape->postion[2].x = x + 2;
                shape->postion[2].y = y;
                shape->postion[3].x = x;
                shape->postion[3].y = y + 1;
            }
            else if (twist == 3)
            {
                //0
                //0
                //0 0
                shape->postion[1].x = x;
                shape->postion[1].y = y + 1;
                shape->postion[2].x = x;
                shape->postion[2].y = y + 2;
                shape->postion[3].x = x + 1;
                shape->postion[3].y = y + 2;
            }
            else if (twist == 2)
            {
                //    0
                //0 0 0
                shape->postion[1].x = x;
                shape->postion[1].y = y + 1;
                shape->postion[2].x = x - 1;
                shape->postion[2].y = y + 1;
                shape->postion[3].x = x - 2;
                shape->postion[3].y = y + 1;
            }
            else if (twist == 1)
            {
                //0 0
                //  0
                //  0
                shape->postion[1].x = x + 1;
                shape->postion[1].y = y;
                shape->postion[2].x = x + 1;
                shape->postion[2].y = y + 1;
                shape->postion[3].x = x + 1;
                shape->postion[3].y = y + 2;
            }
            break;
        }
        case SHAPE3:
        {
            if (twist == 0 || twist == 2)
            {//o o o o
                shape->postion[1].x = x + 1;
                shape->postion[1].y = y;
                shape->postion[2].x = x + 2;
                shape->postion[2].y = y;
                shape->postion[3].x = x + 3;
                shape->postion[3].y = y;
            }
            else if (twist == 1 || twist == 3)
            {
                //0
                //0
                //0
                //0
                shape->postion[1].x = x;
                shape->postion[1].y = y + 1;
                shape->postion[2].x = x;
                shape->postion[2].y = y + 2;
                shape->postion[3].x = x;
                shape->postion[3].y = y + 3;
            }
            break;

        }
        case SHAPE4:
        {
            if (twist == 0 || twist == 2)
            {
                //o
                //o
                //o
                //o
                shape->postion[1].x = x;
                shape->postion[1].y = y + 1;
                shape->postion[2].x = x;
                shape->postion[2].y = y + 2;
                shape->postion[3].x = x;
                shape->postion[3].y = y + 3;
            }
            else if (twist == 1 || twist == 3)
            {
                //o o o o
                shape->postion[1].x = x + 1;
                shape->postion[1].y = y;
                shape->postion[2].x = x + 2;
                shape->postion[2].y = y;
                shape->postion[3].x = x + 3;
                shape->postion[3].y = y;
            }
            break;
        }
        case SHAPE5:
        {
            if (twist == 0)
            {
                //o o o
                //  o
                shape->postion[1].x = x + 1;
                shape->postion[1].y = y;
                shape->postion[2].x = x + 2;
                shape->postion[2].y = y;
                shape->postion[3].x = x + 1;
                shape->postion[3].y = y + 1;
            }
            else if (twist == 1)
            {
                //  0
                //0 0
                //  0
                shape->postion[1].x = x - 1;
                shape->postion[1].y = y + 1;
                shape->postion[2].x = x;
                shape->postion[2].y = y + 1;
                shape->postion[3].x = x;
                shape->postion[3].y = y + 2;
            }
            else if (twist == 2)
            {
                //  o
                //o o o
                shape->postion[1].x = x - 1;
                shape->postion[1].y = y + 1;
                shape->postion[2].x = x;
                shape->postion[2].y = y + 1;
                shape->postion[3].x = x + 1;
                shape->postion[3].y = y + 1;
            }
            else if (twist == 3)
            {
                //0
                //0 0
                //0
                shape->postion[1].x = x;
                shape->postion[1].y = y + 1;
                shape->postion[2].x = x + 1;
                shape->postion[2].y = y + 1;
                shape->postion[3].x = x;
                shape->postion[3].y = y + 2;
            }
            break;
        }
        case SHAPE6:
        {
            if (twist == 0 || twist == 2)
            {
                //o o
                //  o o
                shape->postion[1].x = x + 1;
                shape->postion[1].y = y;
                shape->postion[2].x = x + 1;
                shape->postion[2].y = y + 1;
                shape->postion[3].x = x + 2;
                shape->postion[3].y = y + 1;
            }
            else if (twist == 1 || twist == 3)
            {   //   0
                // 0 0
                // 0 
                shape->postion[1].x = x;
                shape->postion[1].y = y + 1;
                shape->postion[2].x = x - 1;
                shape->postion[2].y = y + 1;
                shape->postion[3].x = x - 1;
                shape->postion[3].y = y + 2;
            }

            break;
        }
        default:
            break;
        }
}
static int CanGoRight(int *a,struct Shape *shape,int width) 
{
    if (shape->postion[0].x + 1 >= width||shape->postion[1].x + 1 >= width||
        shape->postion[2].x + 1 >= width||shape->postion[3].x + 1 >= width)
        return 1;
    if (IsRightHaveShape(a, shape,width) == 1)
        return 1;
    return 0;
}
static int IsRightWell(int *a, struct Shape *shape, int width)
{
    if (shape->postion[0].x + 1 > width || shape->postion[1].x + 1 > width ||
        shape->postion[2].x + 1 > width || shape->postion[3].x + 1 > width)
        return 1;
    if (IsRightHaveShape(a, shape, width) == 1)
        return 1;
    return 0;
}
int CanGoLift(int *a,struct Game*pGame)
{
    if (pGame->shape->postion[0].x > 0 &&
        pGame->shape->postion[1].x > 0 &&
        pGame->shape->postion[2].x > 0 &&
        pGame->shape->postion[3].x > 0 &&
        IsLeftHaveShape(a, pGame->shape, pGame->width) == 0)
        return 0;
    else return 1;
}
int IsLiftWell(int *a, struct Game*pGame)
{
    if (pGame->shape->postion[0].x >= 0 &&
        pGame->shape->postion[1].x >= 0 &&
        pGame->shape->postion[2].x >= 0 &&
        pGame->shape->postion[3].x >= 0 &&
        IsLeftHaveShape(a, pGame->shape, pGame->width) == 0)
        return 0;
    else return 1;
}
static void GoNextPos(int *a,struct Game *pGame)
{
    if (pGame->direction == UP)
    {
        int cur= (pGame->twist + 1) % 4;
            IsShape(cur, pGame->shape);
            if (IsLiftWell(a, pGame) == 0 && IsRightWell(a,pGame->shape,pGame->width)==0)
            {
                pGame->twist = cur;
            }
            else {
                pGame->direction = DOWN;
            }
        pGame->sleeptime = 500;
    }
    else if (pGame->direction==LEFT)
    {
        if(CanGoLift(a,pGame) == 0)
            pGame->shape->postion[0].x--;
        else pGame->direction = DOWN;
        pGame->sleeptime = 500;
        IsShape(pGame->twist, pGame->shape);

    }
    else if (pGame->direction==RIGHT)
    {
        if(CanGoRight(a,pGame->shape,pGame->width)==0)
            pGame->shape->postion[0].x++;
        else pGame->direction = DOWN;
        pGame->sleeptime = 500;
        IsShape(pGame->twist, pGame->shape);

    }
    if (pGame->direction == DOWN)
    {
        pGame->shape->postion[0].y++;
        IsShape(pGame->twist, pGame->shape);

    }
    pGame->direction = DOWN;
}
static int IsShapeWELL(struct Game *pGame, int *a)
{
    int i = 0;
    for (i = 0; i < 4; i++)
    {
        if (pGame->shape->postion[i].y + 1 >= pGame->height)
            return 1;
    }
    for (i = 0; i < 4; i++)
    {
        int x = pGame->shape->postion[i].x;
        int y = pGame->shape->postion[i].y;
        int j = 0;
        for (j = 0; j < 4; j++)
        {
            if (i == j)
                continue;
            if (x == pGame->shape->postion[j].x && y + 1 == pGame->shape->postion[j].y)
                break;
        }
        if (j==4 && a[x + (y + 1)*pGame->width] != 0 )
            return 1;
    }
    return 0;
}

static int ThisShapeDown(struct Game *pGame,int *a)
{
    int x = pGame->shape->postion[0].x;
    int y = pGame->shape->postion[0].y;
    if (IsShapeWELL(pGame, a) == 1)
        return 1;
    return 0;
}
void StartGame(struct Game *pGame)
{
    struct UI* UI = UIInitialize(pGame->width, pGame->height);
    UIDisplayWizard(UI);
    UIDisplayGameWindow(UI, 0);
    ChanceShape(pGame);
    while (1) {
        if (IsGameOver(UI) == 1)
        {
            break;
        }
        if (GetAsyncKeyState(VK_ESCAPE)) {
            break;
        }
        else if (GetAsyncKeyState(VK_SPACE)) {
            _Pause();
        }
        UIDisplayBlock(UI, pGame->shape);
        _HandleDirective(pGame);

        Sleep(pGame->sleeptime);
        if (ThisShapeDown(pGame,UI->_a) ==1)
        {
            pGame->score+=10*InsertScore(UI);
            UIDisplayScore(UI, pGame->score);
            ChanceShape(pGame);
        }
        else
        {
            UICleanBlock(UI, pGame->shape);
        }
        GoNextPos(UI->_a,pGame);
    }
    _CoordinatePosAtXY(UI,3, 10);
    printf("游戏结束");
    _ResetCursorPosition(UI);
    UIDeinitialize(UI);
}
void DestoryGame(struct Game *pGame)
{
}

static void _Pause()
{
    while (1)
    {
        Sleep(300);
        if (GetAsyncKeyState(VK_SPACE))
        {
            break;
        }
    }
}
static void _HandleDirective(struct Game *pGame)
{
    if (GetAsyncKeyState(VK_UP)) {
        pGame->direction = UP;
    }
    else if (GetAsyncKeyState(VK_DOWN) ) {
        pGame->direction = DOWN;
        if(pGame->sleeptime>100)
        pGame->sleeptime -= 100;
    }
    else if (GetAsyncKeyState(VK_LEFT)) {
        pGame->direction = LEFT;
    }
    else if (GetAsyncKeyState(VK_RIGHT)) {
        pGame->direction = RIGHT;
    }
}

完成了函数的游戏和界面部分,我们可以接下来用一个int main 游戏开启点即可。

#include"Game.h"
#include<time.h>

int main()
{
    srand((unsigned int) time(NULL));
    struct Game* game;
    game=CreateGame();
    StartGame(game);
    system("pause");
}
  • 39
    点赞
  • 229
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
当然可以!以下是一个简单的用C语言实现俄罗斯方块小游戏的代码示例: ```c #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <Windows.h> #define WIDTH 10 #define HEIGHT 20 int board[HEIGHT][WIDTH] = {0}; int currentPiece[4][4] = {0}; int currentX = 0, currentY = 0; void drawBoard() { int i, j; for (i = 0; i < HEIGHT; i++) { for (j = 0; j < WIDTH; j++) { if (board[i][j] == 0) printf(" "); else printf("*"); } printf("\n"); } } void drawPiece() { int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (currentPiece[i][j] == 1) { board[currentY + i][currentX + j] = 1; } } } } int checkCollision() { int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if (currentPiece[i][j] == 1 && (currentX + j >= WIDTH || currentX + j < 0 || currentY + i >= HEIGHT || board[currentY + i][currentX + j] == 1)) return 1; } } return 0; } void rotatePiece() { int tempPiece[4][4]; int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { tempPiece[i][j] = currentPiece[i][j]; } } for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { currentPiece[i][j] = tempPiece[3 - j][i]; } } } void clearLines() { int i, j; for (i = HEIGHT - 1; i >= 0; i--) { int lineComplete = 1; for (j = 0; j < WIDTH; j++) { if (board[i][j] == 0) { lineComplete = 0; break; } } if (lineComplete) { int k; for (k = i; k > 0; k--) { for (j = 0; j < WIDTH; j++) { board[k][j] = board[k - 1][j]; } } for (j = 0; j < WIDTH; j++) { board[0][j] = 0; } } } } int main() { char action; int gameOver = 0; // 初始化随机数种子 srand((unsigned int)time(NULL)); // 初始化方块形状 int pieces[7][4][4] = { {{1, 1, 0, 0}, {1, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, {{1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, {{1, 1, 1, 0}, {1, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, {{1, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, {{1, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}}, {{1, 1, 1, 0}, {0, 0, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}}, {{1, 1, 1, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}} }; // 游戏循环 while (!gameOver) { // 清空当前方块 int i, j; for (i = currentY; i < currentY + 4; i++) { for (j = currentX; j < currentX + 4; j++) { if (i >= 0 && i < HEIGHT && j >= 0 && j < WIDTH) { if (currentPiece[i - currentY][j - currentX] == 1) { board[i][j] = 0; } } } } // 生成新的方块 int nextPiece = rand() % 7; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { currentPiece[i][j] = pieces[nextPiece][i][j]; } } currentX = WIDTH / 2 - 2; currentY = 0; // 绘制当前方块 drawPiece(); // 绘制游戏界面 system("cls"); drawBoard(); // 等待用户输入 action = getch(); // 处理用户输入 switch (action) { case 'a': currentX--; if (checkCollision()) currentX++; break; case 'd': currentX++; if (checkCollision()) currentX--; break; case 's': currentY++; if (checkCollision()) { currentY--; drawPiece(); clearLines(); if (checkCollision()) { gameOver = 1; } } break; case 'w': rotatePiece(); if (checkCollision()) rotatePiece(); break; case 'q': gameOver = 1; break; } } printf("Game Over!\n"); return 0; } ``` 这是一个基本的俄罗斯方块游戏代码,使用了Windows.h头文件中的conio.h库来获取用户输入,使用了Windows的命令行窗口来进行绘制。你可以使用gcc编译器来编译运行该代码。 注意:这只是一个简单的示例,可能还需要进行进一步的优化和改进,比如添加计分系统、游戏结束判断等。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值