使用EasyX和C++写一个消砖块游戏

第一次玩EasyX,写一个比较简单的消砖块游戏。

主函数包括Game的类的开始,运行和结束。

#include "BrickElimination.h"

int main()
{
    GameBrickElimination NewGame;

    NewGame.game_start();
    NewGame.game_run();
    NewGame.game_over();

    return 0;
}

game_start()是所有元素的初始化,包括图像,砖块,弹球和挡板。

game_run()是游戏的主体,包括刷新界面,更新球的运动情况等。

game_over()是游戏的结束,停掉绘制。

头文件,定义了所有使用的类。

#ifndef _BRICK_ELIMINATION_
#define _BRICK_ELIMINATION_

/* Settings */
#define GRAPH_HEIGHT                    480
#define GRAPH_WIDTH                     720
#define BRICK_NUM                       20
#define BAR_MOVE_SPEED                  15
#define BAR_WIDTH                       (GRAPH_WIDTH/5)
#define BALL_MOVE_SPEED                 1
#define BALL_RADIUS                     20

#define BRICK_EXIST                     1
#define BRICK_NOT_EXIST                 0

/* type define */
typedef enum
{
    Ball_Hit_Wall = 0,
    Ball_Hit_Bar,
    Ball_Hit_Brick,
    Ball_Sill_Moving
}Ball_Hit_Type;

typedef struct
{
    int left;
    int right;
    int top;
    int bottom;
}Brick_Group;

/* class ball define */
class CBall
{
private:
    int m_ball_x, m_ball_y;
    int m_ball_vx, m_ball_vy;
    int m_radius;

public:
    CBall();
    ~CBall();
    void ball_init_v();
    void ball_clean_v();
    void ball_show_v();
    void ball_move_v();
    int get_x() { return m_ball_x; };
    int get_y() { return m_ball_y; };
    int get_r() { return m_radius; };
    int get_vx() { return m_ball_vx; };
    int get_vy() { return m_ball_vy; };
    void set_vx(int vx) { m_ball_vx = vx; };
    void set_vy(int vy) { m_ball_vy = vy; };

};

/* class brick define */
class CBrick
{
private:
    Brick_Group Bricks[BRICK_NUM];
    int m_isBrickExisted[BRICK_NUM];
    int m_brick_height, m_brick_width;

public:
    CBrick();
    ~CBrick();
    void brick_init_v();
    void brick_clean_v();
    void brick_show_v();
    int isBrickExist(int i) { return m_isBrickExisted[i]; };
    void setBrickExist(int i, int state) { m_isBrickExisted[i] = state; };
    int bricks_left(int i) { return Bricks[i].left; };
    int bricks_right(int i) { return Bricks[i].right; };
    int bricks_top(int i) { return Bricks[i].top; };
    int bricks_bottom(int i) { return Bricks[i].bottom; };
};

/* class bar define */
class CBar
{
private:
    int m_bar_x, m_bar_y;
    int m_bar_width, m_bar_height;
    int m_bar_left, m_bar_right, m_bar_top, m_bar_bottom;

public:
    CBar();
    ~CBar();
    void bar_init_v();
    void bar_clean_v();
    void bar_show_v();
    void bar_move_v();
    int get_left() { return m_bar_left; };
    int get_right() { return m_bar_right; };
    int get_top() { return m_bar_top; };
    int get_bottom() { return m_bar_bottom; };
    int get_width() { return m_bar_width; };
    int get_height() { return m_bar_height; };
};

/* class game define */
class GameBrickElimination
{
private:
    CBall ball;
    CBar bar;
    CBrick brick;

public:
    GameBrickElimination();
    ~GameBrickElimination();
    Ball_Hit_Type check_ball_hit(Ball_Hit_Type isHit);
    void game_start();
    void game_run();
    void game_over();
};

#endif 

类的实现,有几个关键点。

1.使用BeginBatchDraw(),FlushBatchDraw(),EndBatchDraw()来不闪屏地刷新界面,原理是在旧位置上画黑色图形覆盖掉旧位置,同时画出新位置,然后批量绘制。

2.判断球的相撞,其实就是比较球和砖块,挡板的坐标。

3.球的位置通过坐标和速度更新,球反弹的效果通过撞击以后速度设为反方向来实现。使用一个标志量来判断某个砖块是否消失。

/* BrickEliminationElements.cpp */

#include "BrickElimination.h"
#include <graphics.h>
#include <conio.h>
#include "windows.h"

/* class ball realization */
CBall::CBall()
{
}

CBall::~CBall()
{
}

void CBall::ball_init_v()
{
    m_ball_x = GRAPH_WIDTH / 2;
    m_ball_y = GRAPH_HEIGHT / 2;
    m_ball_vx = BALL_MOVE_SPEED;
    m_ball_vy = BALL_MOVE_SPEED;
    m_radius = BALL_RADIUS;
}

void CBall::ball_clean_v()
{
    setcolor(BLACK);
    setfillcolor(BLACK);
    fillcircle(m_ball_x, m_ball_y, m_radius);
}

void CBall::ball_show_v()
{
    setcolor(YELLOW);
    setfillcolor(GREEN);
    fillcircle(m_ball_x, m_ball_y, m_radius);
}

void CBall::ball_move_v()
{
    m_ball_x += m_ball_vx;
    m_ball_y += m_ball_vy;
}

/* class brick realization */
CBrick::CBrick()
{
}

CBrick::~CBrick()
{
}

void CBrick::brick_init_v()
{
    m_brick_width = GRAPH_WIDTH / BRICK_NUM;
    m_brick_height = GRAPH_HEIGHT / BRICK_NUM;

    for (int i = 0; i < BRICK_NUM; i++)
    {
        Bricks[i].left = i * m_brick_width;
        Bricks[i].right = Bricks[i].left + m_brick_width;
        Bricks[i].top = 0;
        Bricks[i].bottom = m_brick_height;
        m_isBrickExisted[i] = BRICK_EXIST;
    }
}

void CBrick::brick_clean_v()
{
    setcolor(BLACK);
    setfillcolor(BLACK);

    for (int i = 0; i < BRICK_NUM; i++)
    {
        if (m_isBrickExisted[i] == BRICK_NOT_EXIST)
        {
            fillrectangle(Bricks[i].left, Bricks[i].top, Bricks[i].right, Bricks[i].bottom);
        }
        else
        {
            /* do thing */
        }
    }
}

void CBrick::brick_show_v()
{
    for (int i = 0; i < BRICK_NUM; i++)
    {
        if (m_isBrickExisted[i])
        {
            setcolor(WHITE);
            setfillcolor(RED);
            fillrectangle(Bricks[i].left, Bricks[i].top, Bricks[i].right, Bricks[i].bottom);
        }
        else
        {
            /* do thing */
        }
    }
}

/* class bar realization */
CBar::CBar()
{
}

CBar::~CBar()
{
}

void CBar::bar_init_v()
{
    m_bar_width = BAR_WIDTH;
    m_bar_height = GRAPH_HEIGHT / 20;
    m_bar_x = GRAPH_WIDTH / 2;
    m_bar_y = GRAPH_HEIGHT - m_bar_height / 2;
    m_bar_left = m_bar_x - m_bar_width / 2;
    m_bar_right = m_bar_x + m_bar_width / 2;
    m_bar_top = m_bar_y - m_bar_height / 2;
    m_bar_bottom = m_bar_y + m_bar_height / 2;
}

void CBar::bar_clean_v()
{
    setcolor(BLACK);
    setfillcolor(BLACK);
    bar(m_bar_left, m_bar_top, m_bar_right, m_bar_bottom);
}

void CBar::bar_show_v()
{
    setcolor(YELLOW);
    setfillcolor(GREEN);
    bar(m_bar_left, m_bar_top, m_bar_right, m_bar_bottom);
}

void CBar::bar_move_v()
{
    char input;
    if (_kbhit())
    {
        input = _getch();
        if (input == ‘a‘ && m_bar_left > 0)
        {
            m_bar_x -= BAR_MOVE_SPEED;
            m_bar_left = m_bar_x - m_bar_width / 2;
            m_bar_right = m_bar_x + m_bar_width / 2;
        }
        else if (input == ‘d‘ && m_bar_right < GRAPH_WIDTH)
        {
            m_bar_x += BAR_MOVE_SPEED;
            m_bar_left = m_bar_x - m_bar_width / 2;
            m_bar_right = m_bar_x + m_bar_width / 2;
        }
        else
        {
            /* do thing */
        }
    }
    else
    {
        /* do thing */
    }
}

GameBrickElimination::GameBrickElimination()
{
}

GameBrickElimination::~GameBrickElimination()
{
}

Ball_Hit_Type GameBrickElimination::check_ball_hit(Ball_Hit_Type isHit)
{
    switch (isHit)
    {
    case Ball_Hit_Wall:
    {
        //check ball hit wall or not
        if ((ball.get_x() <= ball.get_r()) || (ball.get_x() >= GRAPH_WIDTH - ball.get_r()))
        {
            ball.set_vx(-ball.get_vx());
            return Ball_Hit_Wall;
        }
        else
        {
            /* do nothing */
        }

        if ((ball.get_y() <= ball.get_r()) || (ball.get_y() >= GRAPH_HEIGHT - ball.get_r()))
        {
            ball.set_vy(-ball.get_vy());
            return Ball_Hit_Wall;
        }
        else
        {
            /* do nothing */
        }
        break;
    }
    case Ball_Hit_Bar:
    {
        if (((ball.get_y() + ball.get_r() >= bar.get_top())
            && (ball.get_y() + ball.get_r() < bar.get_bottom() - bar.get_height() / 3))
            || ((ball.get_y() - ball.get_r() <= bar.get_bottom())
                && (ball.get_y() - ball.get_r() > bar.get_top() - bar.get_height() / 3)))
        {
            if ((ball.get_x() > bar.get_left()) && (ball.get_x() < bar.get_right()))
            {
                ball.set_vy(-ball.get_vy());
                return Ball_Hit_Bar;
            }
            else
            {
                /* do nothing */
            }
        }
        else
        {
            /* do nothing */
        }
        break;
    }
    case Ball_Hit_Brick:
    {
        for (int i = 0; i < BRICK_NUM; i++)
        {
            if (brick.isBrickExist(i) == BRICK_EXIST)
            {
                if ((ball.get_y() <= brick.bricks_bottom(i) + ball.get_r())
                    && (ball.get_x() >= brick.bricks_left(i))
                    && (ball.get_x() <= brick.bricks_right(i)))
                {
                    brick.setBrickExist(i, BRICK_NOT_EXIST);
                    ball.set_vy(-ball.get_vy());
                    return Ball_Hit_Brick;
                }
                else
                {
                    /* do nothing */
                }
            }
            else
            {
                /* do nothing */
            }
        }
        break;
    }
    default:
    {
        break;
    }
    }
}

/* class game realization */
void GameBrickElimination::game_start()
{
    ball.ball_init_v();
    bar.bar_init_v();
    brick.brick_init_v();

    initgraph(GRAPH_WIDTH, GRAPH_HEIGHT);
    BeginBatchDraw();
}

void GameBrickElimination::game_run()
{
    while (1)
    {
        ball.ball_clean_v();
        bar.bar_clean_v();
        brick.brick_clean_v();

        check_ball_hit(Ball_Hit_Wall);
        ball.ball_move_v();

        check_ball_hit(Ball_Hit_Bar);
        bar.bar_move_v();

        check_ball_hit(Ball_Hit_Brick);

        ball.ball_show_v();
        bar.bar_show_v();
        brick.brick_show_v();

        FlushBatchDraw();
        Sleep(3);
    }
}

void GameBrickElimination::game_over()
{
    EndBatchDraw();
    closegraph();
}

效果:

原文地址:https://www.cnblogs.com/banmei-brandy/p/12500087.html

时间: 2024-08-02 08:34:58

使用EasyX和C++写一个消砖块游戏的相关文章

JavaScript写一个连连看的游戏

天天看到别人玩连连看, 表示没有认真玩过, 不就把两个一样的图片连接在一起么, 我自己写一个都可以呢. 使用Javascript写了一个, 托管到github, 在线DEMO地址查看:打开 最终的效果图: 写连连看之前要先考虑哪些呢? 1:如何判断两个元素可以连接呢, 刚刚开始的时候我也纳闷, 可以参考这里:打开: 2:模板引擎怎么选择呢, 我用了底线库的template,因为语法简单. 本来想用Handlebars,但是这个有点大啊, 而且底线库也提供很多常用工具方法( •? ω •? )y:

用Canvas写一个简单的游戏--别踩白块儿

第一次写博客也不知怎么写,反正就按照我自己的想法来吧!怎么说呢?还是不要扯那些多余的话了,直接上正题吧! 第一次用canvas写游戏,所以挑个简单实现点的来干:别踩白块儿,其他那些怎么操作的那些就不用再扯了,大家应该都懂,不懂的看到黑色的就点就是了,扯多了我打字手也累,大概.链接给你们:http://nowtd.cn/white/ 咱不是理论派,所以在这里不会扯多少理论. 首先看看html的结构吧 1 <header class="container"> 2 <art

用canvas写一个h5小游戏

这篇文章我们来讲一讲用canvas画一个躲水果的小游戏.就是通过手指控制一个人物移动来躲避水果,若发生碰撞,则游戏结束. 我们定义一个game_control对象来处理初始化,事件绑定,游戏开始,游戏结果判定,游戏结束等判定. 在游戏中,我们需要一个人物以及三种水果的图片,我们做成了雪碧图. 接下来直接上代码吧~ 首先我们定义一个ship对象,3个水果.一个人物都是基于这个对象的. function ship(options){ if (options) { var width=options.

用Python写一个猜数字游戏

2015.5.25第一天下载Python IDLE,写个猜数字的小游戏来熟悉这门语言: 1 times=6 2 letters=[100] 3 for i in range(1,times): 4 a = input("input the number you guess:") 5 try: 6 b = int(a) 7 if isinstance(b,int): 8 if i <5: 9 if int(a) in letters: 10 print("%s is th

使用Swift和SpriteKit写一个忍者游戏

这篇文章的游戏使用SpriteKit和Swift语言来完毕. SpriteKit是苹果自己的游戏引擎,更能贴合iOS系统底层的API,只是架构和实现上都是模仿了Cocos2D.所以使用上事实上区别不大,只是SpriteKit更轻量级一些. 程序入口 main函数跟OC一样,将入口指向了appdelegate,而cocoa touch框架差点儿跟OC一样,仅仅只是用Swift重写了一遍. 这些模板自带的方法跟OC项目并无差异... 開始编写游戏 假设你了解CCNode,CCSprite,CCSce

【python学习】使用python写一个2048小游戏

个人博客:jerwang.cn 没有参考其他代码,效果图: 话不多少,源代码: https://github.com/jerustc/Python/blob/master/2048.py

运用python写一个猜数字游戏,学自小甲鱼老师

代码 """用python设计第一个游戏""" temp = input("猜猜小甲鱼心里想的是那个数字:")guess = int(temp) if guess == 8: print("你是小甲鱼心里的蛔虫吗?!") print("哼,猜中了也没奖励!")else: print("猜错了,小甲鱼心里想的是8!") print("游戏结束,不玩啦"

请写一个算法,用于将list集合内重复元素剔除

package Homework; import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Scanner;/** * list集合是否可以包含重复元素? * 如果可以,请写一个算法,用于将list集合内重复元素剔除. * @author 张致远 * */public class Homework2 { public static void main(String[]

用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中

我最近在用java写一个远程视频监控系统,实时监控(类似直播)我想用RPT协议,不知道怎么把RPT协议集成到项目中,第一次写项目,写过这类项目的多多提意见,哪方面的意见都行,有代码或者demo的求赏给我,谢谢