【四圣龙神录的编程教室】第8章、把按键的对应设置一下吧

原文地址:

http://dixq.net/rp/8.html


在STG游戏,键位设置是十分重要的。

如果开始没有设置好,以后程序的代码可能全部都要改动,

这是十分麻烦的,所以我们开始就把它设置好吧。

首先,取得按键的输入状态。(这在前面的章节里已经做好了)

然后,取得手柄摇杆的输入状态。为了要让键盘按键输入和摇杆输入相对应,

把键盘输入状态,和手柄摇杆的输入在Config 设定好,让两方对应起来。

这次,我们要使用叫做  GetJoypadInputState的函数,使用方法如果不清楚的话,去DxLib 的官网去查看一下吧。

那么,手柄设置要用到的构造体,以及 定义为 16的PAD_MAX,就像如下这样定义。

—————————————————————————————————————————————————————————————————————————————

--struct.h 里加上如下代码--


//手柄相关的构造体
typedef struct{
        int key[PAD_MAX];
}pad_t;


//设置相关的构造体
typedef struct{
        int left,up,right,down,shot,bom,slow,start,change;
}configpad_t;

—————————————————————————————————————————————————————————————————————————————

—————————————————————————————————————————————————————————————————————————————

--define.h 的变动--


//活动范围的大小
#define FIELD_MAX_X 384
#define FIELD_MAX_Y 448
//活动范围的左上角坐标
#define FIELD_X 32
#define FIELD_Y 16
//手柄按键的最大数量
#define PAD_MAX 16


#include "struct.h"

—————————————————————————————————————————————————————————————————————————————

手柄使用的键位,在PAD_MAX 里准备了16个最大按键数量,总之,

【上,下,左,右,射击,炸弹,低速,开始,变身】这样9个键先准备好。

这些键,对应到0-15的的哪个数字,按自己的喜好来设定好,就可以使用手柄的键位了。

手柄的键位对应的是哪个数字,请自己去确认一下。

这里已经确认过了,通常是按照如下所示的序号使用的,在初始化函数里代入下面这些值吧。

—————————————————————————————————————————————————————————————————————————————

--ini.cpp的改动--


#include "../include/GV.h"


//最开始的初始化
void first_ini(){
        ch.x=FIELD_MAX_X/2;
        ch.y=FIELD_MAX_Y*3/4;


        configpad.down=0;
        configpad.left=1;
        configpad.right=2;
        configpad.up=3;
        configpad.bom=4;
        configpad.shot=5;
        configpad.slow=11;
        configpad.start=13;
        configpad.change=6;
}

—————————————————————————————————————————————————————————————————————————————

—————————————————————————————————————————————————————————————————————————————

--GV.h 里加上下面的语句--


GLOBAL configpad_t configpad;

—————————————————————————————————————————————————————————————————————————————

GetHitPadStateAll 函数会获得当前的手柄输入状态,然后和键盘输入状态相比较,

采用输入时间更长的存入手柄的输入状态变量里。以上这两个函数没有改动。

到时候,参数1和参数2选择更大的,作为参数1传入下面的函数

void input_pad_or_key(int *p, int k)

这个函数中使用的条件运算符的使用方法如果不清楚的话,去自己查一下吧。

CheckStatePad 是在初始化函数里设定了的,根据传入的序号返回输入状态。

和之前的CheckStateKey函数的机制是一样的。

—————————————————————————————————————————————————————————————————————————————

--key.cpp 的改动--

#include "../include/GV.h"

unsigned int stateKey[256];

int GetHitKeyStateAll_2()
{
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0; i<256; i++)
    {
        if(GetHitKeyStateAll_Key[i]==1)
            stateKey[i]++;
        else
            stateKey[i]=0;
    }
    return 0;
}

int CheckStateKey(unsigned char Handle)
{
    return stateKey[Handle];
}

//存储手柄输入状态的变量
pad_t pad;

//参数1和参数2中,较大者存入参数1
void input_pad_or_key(int *p, int k)
{
    *p = *p>k ? *p : k;
}

//检查键盘和手柄双方的输入状态的函数
void GetHitPadStateAll()
{
    int i,PadInput,mul=1;
    PadInput = GetJoypadInputState( DX_INPUT_PAD1 );//获得手柄的输入状态
    for(i=0; i<16; i++)
    {
        if(PadInput & mul)
            pad.key[i]++;
        else
            pad.key[i]=0;
        mul*=2;
    }
    input_pad_or_key(&pad.key[configpad.left]   ,CheckStateKey(KEY_INPUT_LEFT    ));
    input_pad_or_key(&pad.key[configpad.up]     ,CheckStateKey(KEY_INPUT_UP      ));
    input_pad_or_key(&pad.key[configpad.right]  ,CheckStateKey(KEY_INPUT_RIGHT   ));
    input_pad_or_key(&pad.key[configpad.down]   ,CheckStateKey(KEY_INPUT_DOWN    ));
    input_pad_or_key(&pad.key[configpad.shot]   ,CheckStateKey(KEY_INPUT_Z       ));
    input_pad_or_key(&pad.key[configpad.bom]    ,CheckStateKey(KEY_INPUT_X       ));
    input_pad_or_key(&pad.key[configpad.slow]   ,CheckStateKey(KEY_INPUT_LSHIFT  ));
    input_pad_or_key(&pad.key[configpad.start]  ,CheckStateKey(KEY_INPUT_ESCAPE  ));
    input_pad_or_key(&pad.key[configpad.change] ,CheckStateKey(KEY_INPUT_LCONTROL));
}

//根据传进来的手柄按键的编号,返回其输入状态。返回-1代表出错
int CheckStatePad(unsigned int Handle)
{
    if(0<=Handle && Handle<PAD_MAX)
    {
        return pad.key[Handle];
    }
    else
    {
        printfDx("CheckStatePad传进来的参数不正确\n");
        return -1;
    }
}
—————————————————————————————————————————————————————————————————————————————

input_pad_or_key函数的传入参数写的比较长,如果用数列和指针的话可以省略和跳过一些,

有余力的人可以自己尝试把它变短吧。

—————————————————————————————————————————————————————————————————————————————

--char.cpp 的改动--


#include "../include/GV.h"


void calc_ch(){
        ch.cnt++;
        ch.img=(ch.cnt%24)/6;
        if(CheckStatePad(configpad.left)>0)//左键按下的话
                ch.x-=3;//坐标往左移
        if(CheckStatePad(configpad.right)>0)//右键按下的话
                ch.x+=3;//坐标向右移
}

—————————————————————————————————————————————————————————————————————————————

CheckStatePad函数的用法就像上面这样。根据设定好的键位,比如左键的编号 configpad.left 输入进去,

这个就被传入到CheckStatePad函数里。输入的计数状态就会返回,如果不是0就说明这个键正在被按下。

然后,我们把这次增加的函数,加到头文件里面吧。

—————————————————————————————————————————————————————————————————————————————

--function.h 里加入如下代码--


GLOBAL void GetHitPadStateAll();
GLOBAL int CheckStatePad(unsigned int Handle);

—————————————————————————————————————————————————————————————————————————————

这次main 文件的改动,只有下面GetHitPadStateAll();的这一行。

—————————————————————————————————————————————————————————————————————————————

//--main.cpp改动--

#define GLOBAL_INSTANCE
#include "../include/GV.h"

//主循环里必须做的三大处理
int ProcessLoop()
{
    if(ProcessMessage()!=0)
        return -1   ;       //Process处理出错的话,返回-1
    if(ClearDrawScreen()!=0)
        return -1;          //画面清理出错的话,返回-1
    GetHitKeyStateAll_2();  //当前键盘输入处理
    GetHitPadStateAll();    //当前手柄输入处理  (就加了这一行)
    return 0;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
    ChangeWindowMode(TRUE);     //窗口模式
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1; //初始化和设置双缓冲模式

    while(ProcessLoop()==0)     //主循环
    {
        switch(func_state)
        {
        case 0:
            load();         //载入数据
            first_ini();    //第一次初始化
            func_state=100;
            break;
        case 100:
            calc_ch();      //计算角色的使用图片(这句上一章就加了啊)
            graph_main();   //主绘画函数
            break;
        default:
            printfDx("未知的func_state\n");
            break;
        }

        if(CheckStateKey(KEY_INPUT_ESCAPE)==1)
            break;          //按下ESC的话,break
        ScreenFlip();       //交换双缓冲画面
    }

    DxLib_End();    //DxLib中止
    return 0;
}

—————————————————————————————————————————————————————————————————————————————

运行结果

http://dixq.net/rp/swf/08.swf

—————————————————————————————————————————————————————————————————————————————

连续按手柄的左右键,然后按键盘方向键的左右键,

任务像动画那样左右可以移动的话,就成功了。



本人CSDN博客目录:

http://blog.csdn.net/tidus5


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值