C语言课程设计【热血传奇】

前言

传奇游戏,作为游戏历史上的一个里程碑,自诞生以来一直以其独特的魅力吸引着数百万玩家的关注和热情。这款游戏不仅仅是一种娱乐方式,更是一个世界,一个充满冒险、挑战和合作的虚拟领域。C语言,作为一门强大的编程语言,可以用来创造各种各样的软件和游戏,而传奇游戏正是其中之一。

本课程设计旨在帮助你深入了解C语言的基本概念和编程技巧,同时将这些知识应用到传奇游戏的开发中。通过学习本课程,你将有机会创建自己的传奇游戏版本,了解游戏开发的核心原理,并培养解决问题和团队协作的能力。

游戏头文件引入与定义宏变量

#include<stdio.h>
#include<graphics.h>
#include <Windows.h>
#include"tools.h"
//包含多媒体接口源文件
#include<conio.h>//使用_getch();
#pragma comment(lib,"winmm.lib")//加载静态库

#include <mmsystem.h>//播放音乐
#define WIN_WIDTH 1600
#define WIN_HEIGHT 900

播放游戏音乐函数

void BGM() {
    mciSendString("open 我落泪情绪飘碎.mp3", NULL, NULL, NULL);
    mciSendString("play 我落泪情绪飘碎.mp3 repeat", NULL, NULL, NULL);
}

定义方向枚举类型,上下左右等八个方向

typedef enum {
    RIGHT_UP,//行走时方向
    LEFT_UP,
    DOWN,
    RIGHT_DOWN,
    LEFT_DOWN,
    LEFT,
    UP,
    RIGHT,
    PRIGHT_UP,//加速时方向
    PLEFT_UP,
    PDOWN,
    PRIGHT_DOWN,
    PLEFT_DOWN,
    PLEFT,
    PUP,
    PRIGHT,
    DIRECT_COUNT,
    DIRECT_NONE
}direct_t;//方向类型

封装游戏角色的结构体

struct Hero {
    double x=0, y=0;
    //当前方向
    direct_t curDirect=RIGHT;
    IMAGE* imgs[DIRECT_COUNT][9] = {0};
    int curImgIndex=0;
    bool walking=false;//当前是否在行走
    double speed=5;
};

初始化函数

void init() {
    //创建游戏窗口
    
    initgraph(WIN_WIDTH, WIN_HEIGHT,SHOWCONSOLE);
    loadimage(&imgMap, "thzb.png");
    mapX = (double)WIN_WIDTH / 2 - (double)imgMap.getwidth() / 2;
    mapY = (double)WIN_HEIGHT / 2 -(double) imgMap.getheight() / 2;
    putimage((int)mapX,(int)mapY, &imgMap);

    //初始化hero
    hero.x = WIN_WIDTH / 2;
    hero.y = WIN_HEIGHT / 2;
    hero.curDirect = RIGHT;
    hero.curImgIndex = 0;
    char name[32];
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            sprintf_s(name, sizeof(name), "shga/%d%d.png", i + 1, j);
            //为每个图片分配内存
            hero.imgs[i][j] = new IMAGE;
            loadimage(hero.imgs[i][j], name);
        }
    }
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            sprintf_s(name, sizeof(name), "paobu/%d%d.png", i + 1, j);
            //为每个图片分配内存
            hero.imgs[i+8][j] = new IMAGE;
            loadimage(hero.imgs[i+8][j], name);
        }
    }
}

实时更新游戏视图

void updateWindow() {
    BeginBatchDraw();
    putimage((int)mapX, (int)mapY, &imgMap);
    putimagePNG2((int)hero.x, (int)hero.y, hero.imgs[hero.curDirect][hero.curImgIndex]);
    EndBatchDraw();
}

判断角色行走方向

direct_t calDirection(double x, double y) {
    double top = hero.y;
    double bottom = top + (hero.imgs[hero.curDirect][hero.curImgIndex]->getheight());
    double left = hero.x;
    double right = left + hero.imgs[hero.curDirect][hero.curImgIndex]->getwidth();
    direct_t ret = DIRECT_NONE;
    if (y < top) {
        if (x < left) ret = LEFT_UP;
        else if (x > right) ret = RIGHT_UP;
        else ret = UP;
    }
    else if (y > bottom) {
        if (x < left) ret = LEFT_DOWN;
        else if (x > right) ret = RIGHT_DOWN;
        else  DOWN;
    }
    else {
        if (x < left) ret = LEFT;
        else if (x > right) ret = RIGHT;
        else ret = DIRECT_NONE;
    }
    return ret;
}

定义鼠标点击监听事件

void mouseEvent() {
    MOUSEMSG msg;
   
    PeekMouseMsg(&msg);
    direct_t direct;
    if (MouseHit) {
        switch (msg.uMsg) {
        case WM_RBUTTONDOWN:
            direct = PcalDirection(msg.x, msg.y);
            hero.walking = false;
            heroGo(direct);
            break;
        case WM_LBUTTONDOWN:
            direct = calDirection(msg.x, msg.y);
            hero.walking = false;
            heroGo(direct);
        default:
            break;
        }
    }
    
}

更新游戏数据

void updateData() {
    if (hero.walking) {
        switch (hero.curDirect)
        {
        case UP:
            mapY += hero.speed;
            break;
        case DOWN:
            mapY -= hero.speed;
            break;
        case LEFT:
            mapX += hero.speed;
            break;
        case RIGHT:
            mapX -= hero.speed;
            break;
        case RIGHT_UP:
            mapX -= hero.speed*0.707;//
            mapY += hero.speed* 0.707;
            break;
        case RIGHT_DOWN:
            mapX -= hero.speed*0.707 ;
            mapY -= hero.speed * 0.707;
            break;
        case LEFT_UP:
            mapX += hero.speed*0.707;
            mapY += hero.speed * 0.707;
            break;
        case LEFT_DOWN:
            mapX += hero.speed* 0.707;
            mapY -= hero.speed*0.707;//
            break;
        case PUP:
            mapY += hero.speed*2;
            break;
        case PDOWN:
            mapY -= hero.speed*2;
            break;
        case PLEFT:
            mapX += hero.speed*2;
            break;
        case PRIGHT:
            mapX -= hero.speed*2;
            break;
        case PRIGHT_UP:
            mapX -= hero.speed * 0.707*2;
            mapY += hero.speed * 0.707*2;
            break;
        case PRIGHT_DOWN:
            mapX -= hero.speed * 0.707*2;
            mapY -= hero.speed * 0.707*2;
            break;
        case PLEFT_UP:
            mapX += hero.speed * 0.707*2;
            mapY += hero.speed * 0.707*2;
            break;
        case PLEFT_DOWN:
            mapX += hero.speed * 0.707*2;
            mapY -= hero.speed * 0.707*2;//
            break;
        default:
            break;
        }	
            hero.curImgIndex++;
            if (hero.curImgIndex >= 7) {	             
                hero.curImgIndex = 0;            
            }
    }
}

主体main函数

int main() {
    init();
    BGM();
    int timer = 0;
    bool updateFlag = true;  
        while (1) {
            //mouseEvent();//处理鼠标点击
            //updateWindow();
            //updateData();//更新游戏数据
            //Sleep(50);
               mouseEvent();//处理鼠标点击              
               timer += getDelay();//距离上一次调用间隔了多少ms
               if(timer > 30) {
                    timer = 0;
                    updateFlag = true;
               }           
               if (updateFlag) {            
                    updateFlag = false;
                    updateWindow();
                updateData();//更新游戏数据
            

               }
        
        }		
        return 0;
}

游戏画面

结尾

一款简易的C语言传奇游戏就完成了,需要游戏资源的C友可以后台私信我哦 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值