IE盒子

搜索
查看: 128|回复: 0

c++ c语言 游戏 飞机大战

[复制链接]

3

主题

6

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2023-1-8 11:52:42 | 显示全部楼层 |阅读模式
首先,感谢:林耿亮老师,可搜公众号:你好编程。C语言学习最好的兴趣教材。
其次,本文是我学完并手动输入完成飞机大战的复盘内容。比较零散,仅作为我的复习笔记。

一、基本知识与技能。
1、作为游戏,肯定离不开图形和声音。建议使用easyx图形库。网址:http://www.easyx.cn。
涉及基本图形的绘制,形状的样式、颜色的设置,形状的剪贴。
涉及基本图形及图片的运动,碰撞处理。
涉及游戏中键盘、鼠标的控制及交互处理。
涉及图片的加载,前景与背景图片的融合。
涉及批量绘图及图片显示的精确帧率控制。
涉及游戏中文字内容的显示,设置。
涉及游戏音频的调用,控制。多个音频实例的复用。
2、掌握C语言基础知识,程序结构、熟练循环、判断语句的使用。
面向对象的程序涉及,通过结构体构建面向对象风格。
指针的使用,参数的含义。
数组的使用,及动态数组的构建。
3、掌握常见头文件的内容,库文件的使用,相关编译器的设置及程序调试。
二、主要使用的头文件,库文件;编译器设置。
1、头文件
easyx.h
stdio.h
stdlib.h
stdint.h
math.h
time.h
windows.h
2、库文件,winmm.lib。工程-属性-链接器-输入-附加依赖项,添加。库winmm.lib。
3、编译报警设置,(C4996错误)。
工程,预处理器,屏蔽错误_CRT_SECURE_NO_WARNINGS;
使用安全函数;
工程,配置属性,c/c++,高级,禁用特定警告;
4、字符集设置,多字节字符。需要修改:项目名称-属性-配置属性-高级-字符集=未设置。
三、飞机大战程序结构


四、程序实现
1、图像融合文件,包括image.h文件:
#pragma once
#include <easyx.h>//引用图形库
void putTransparentImage(int x, int y, const IMAGE* mask, const IMAGE* img);//对应cpp文件函数
image.app文件:
#include "image.h"
//函数为图片背景透明化,easyx功能。采用位运算。
void putTransparentImage(int x, int y, const IMAGE* mask, const IMAGE* img)
{
        putimage(x, y, mask, SRCAND);
        putimage(x, y, img, SRCPAINT);
}
2、通用动态数组,包括两个文件,vector.h和vector.cpp文件。
vector.h头文件:
#pragma once
#define VECTOR_INIT_CAPACITY 10//定义常量,vector_init_capacity,表示初始数组大小,10;
struct vector {
    bool (*append)(struct vector* pVec, void* data);//追加数据方法
    void* (*get)(struct vector* pVec, int index);//获取数据方法
    void (*clear)(struct vector *pVec);//清除全部数据方法
    void (*remove)(struct vector* pVec, int index);//删除一条数据方法
    void **pData;//二级指针,关于游戏元素结构体的首地址,为啥是二级指针,理解中。
    int size;//结构体数组存储数据数量;
    int capacity;//动态数组空间大小;
};
void vectorInit(struct vector*);//动态数组初始化函数;
void vectorDestroy(struct vector* pVec);//动态数组销毁函数;
vector.cpp文件:
#include "vector.h"//引用
#include <stdlib.h>//malloc,realloc,动态数组
//追加数据函数
bool vectorAppend(struct vector* pVec, void *data)//结构体指针传入
{
        if (pVec == NULL || data == NULL)//判空
                return false;

        //  数据超过数组长度
        if (pVec->size >= pVec->capacity)
        {
                //  加长到两倍,二级指针newdata,二级指针pvec->pdata。理解中。
                void ** newData = (void **)realloc(pVec->pData, pVec->capacity * sizeof(void *) * 2);//2倍增加
                if (newData == NULL)//判空
                {
                        return false;
                }
                pVec->pData = newData;//赋值新指针
                pVec->capacity = 2 * pVec->capacity;
        }
        pVec->pData[pVec->size] = data;//将传入的结构体内容,赋值pData[]数组,pData是指针。
        pVec->size++;
        return true;
}
void* vectorGet(struct vector* pVec, int index)//读取一条记录内容
{
        if (index >= pVec->size)//记录号大于记录条数。
                return NULL;
        return pVec->pData[index];//返回一条记录内容
}
void vectorRemove(struct vector* pVec, int index)//删除一条记录内容
{
        for (int i = index; i < pVec->size - 1; i++)//数据依次移动覆盖前一数据。
                pVec->pData = pVec->pData[i + 1];
        pVec->size -= 1;//记录数量减一。
}
void vectorClear(struct vector* pVec)//清查全部记录
{
        if (pVec->pData != NULL)//数据不为空,释放数据空间。
                free(pVec->pData);
//以下重新初始化。
        pVec->pData = (void**)malloc(sizeof(void*) * VECTOR_INIT_CAPACITY);
        pVec->capacity = VECTOR_INIT_CAPACITY;
        pVec->size = 0;
}
void vectorInit(struct vector* pVec)//动态数组初始化
{
        pVec->get = vectorGet;
        pVec->append = vectorAppend;
        pVec->remove = vectorRemove;
        pVec->clear = vectorClear;//以上是四个方法的声明
        //  初始情况下申请VECTOR_INIT_CAPACITY个element
        pVec->pData = (void**)malloc(sizeof(void*) * VECTOR_INIT_CAPACITY);
        pVec->capacity = VECTOR_INIT_CAPACITY;
        pVec->size = 0;
}
void vectorDestroy(struct vector* pVec)//销毁数组
{
         if (pVec->pData == NULL)
                 return;
         free(pVec->pData);//释放空间
         pVec->pData = NULL;
         pVec->size = 0;
         pVec->capacity = 0;
3、声音播放处理,soundmanager.h文件
#pragma once
#include "vector.h"//动态数组头文件
struct soundManager {//定义结构体,声音播放,关闭,两个函数,
        void (*play)(struct soundManager*);
        void (*close)(struct soundManager* e, int interval);
        vector vecSoundAlias;//声音别名
        char soundPath[100];//声音路径
};
void soundManagerInit(struct soundManager*, const char *);//初始化
void soundManagerDestroy(struct soundManager*);//销毁
soundmanager.cpp文件:
#include "soundmanager.h"
#include <stdlib.h>
#include <stdio.h>
#include <easyx.h>
#include <time.h>
#include <stdint.h>
#include <Windows.h>

void soundPlay(struct soundManager *e)
{
        int currentTime = GetTickCount();
        int* pAlias = (int*)malloc(sizeof(int));
        if (pAlias == NULL)
                return;
        *pAlias = currentTime;
        e->vecSoundAlias.append(&e->vecSoundAlias, pAlias);

        char command[100];
        sprintf(command, "open %s alias %d", e->soundPath, currentTime);
        mciSendString(command, NULL, 0, NULL);
        sprintf(command, "play %d", currentTime);
        mciSendString(command, NULL, 0, NULL);
}

void soundClose(struct soundManager *e, int interval)
{
        int currentTime = GetTickCount();
        char command[100];
        for (int i = 0; i < e->vecSoundAlias.size; i++)
        {
                int* pAlias = (int*)e->vecSoundAlias.get(&e->vecSoundAlias, i);
                if (currentTime - *pAlias < interval)
                        continue;
                sprintf(command, "close %d", *pAlias);
                mciSendString(command, NULL, 0, NULL);
                free(pAlias);
                e->vecSoundAlias.remove(&e->vecSoundAlias, i);
                i--;
        }
}

void soundManagerInit(struct soundManager*e, const char *soundPath)
{
        e->play = soundPlay;
        e->close = soundClose;

        vectorInit(&e->vecSoundAlias);
        strcpy(e->soundPath, soundPath);
}

void soundManagerDestroy(struct soundManager* e)
{
        char command[100];
        for (int i = 0; i < e->vecSoundAlias.size; i++)
        {
                int*pAlias = (int*)e->vecSoundAlias.get(&e->vecSoundAlias, i);
                sprintf(command, "close %d", *pAlias);
                mciSendString(command, NULL, 0, NULL);
                free(pAlias);
        }
        vectorDestroy(&e->vecSoundAlias);
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表