原文地址:
在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;
}
—————————————————————————————————————————————————————————————————————————————
运行结果
—————————————————————————————————————————————————————————————————————————————
连续按手柄的左右键,然后按键盘方向键的左右键,
任务像动画那样左右可以移动的话,就成功了。
本人CSDN博客目录: