Gamemaker studio2经验(1)——右键人物移动逻辑

分类栏目:gamemaker教程

236

问题概述

红警、帝国时代、星际争霸……想必很多玩家都对这类即时战略游戏保有极深的感情。其中有一个较为常见的逻辑便是——左键划动选中人物,然后右键标记目标地点,使得人物向目标地点移动。这个逻辑最常见的问题在于——可能会有不同的部队被选中,使得他们在同一时间向不同的地区进发。为了解决这个难点,博主想了一套相对简单的逻辑来实现。

 

解决方案

基本思路非常简单。首先我们先定义一个叫旗帜的物体,旗帜的本质意义就是玩家点击右键后留下的目标点,其他的按照逻辑编写代码即可。基本流程如下:

 

创建旗帜物体obj_mubiao.(建议给这个物体挂一个sprite,方便debug)

编写选中角色的逻辑代码。

编写在空白区域点击左键以取消选中的逻辑代码。

编写在空白区域点击右键以放置旗帜的逻辑代码。

编写旗帜的逻辑代码。

代码实现

按照上述思路,我们开始对各个物体分别编写代码。

 

obj_zhujue

一、创建

对于主角,先创建一个属于自己的旗帜。

具体方法是创建一个旗帜并把这个旗帜的id赋给一个变量mubiao中,然后再把自己(id)赋成旗帜(mubiao)的“主人”,这样把人物和自己旗子的关系确定下来

 

mubiao=instance_create(0,0,obj_mubiao);   //创造一个以自己为对象的旗子

mubiao.zhuren=id;                         //将旗子的对象设置为自己

 

二、鼠标左键放开

里面就一句话,shubiao=1表示选中了主角(当时不习惯使用布尔值,表打我~)

shubiao=1;     //表示鼠标选中了这号角色

三、全局左键按下

里面也只有一句话,表示空白区域点一下左键就取消所有选中

if (shubiao==1) shubiao=0;    //判定:如果此时处于选中状态,则取消选中

四、全局右键按下

首先判断是否有人物被选中,如果有便进入创作

 

if (shubiao==1 )                                    //判定右键时是否是该物体被选中

{

    move=1;                                          //开启移动模式

    zhan=0;

    move_x=mouse_x;                                  //移动目标:鼠标x值

    move_y=mouse_y;                                  //移动目标:鼠标y值

    dertax=move_x-x;                                 //横坐标远近

    dertay=move_y-y;                                 //纵坐标远近

    if (dertax!=0) k=dertay/dertax;                    //斜率

    if (dertax==0) k=dertay/(dertax+0.001);             //补救当x=0时导致的运算错误

    if (k<-1 || k>1 && dertay>0) fangxiang=1;

    if (k>=-1 && k<=1 && dertax>=0) fangxiang=2;

    if (k<-1 || k>1 && dertay<0) fangxiang=3;

    if (k>=-1 && k<=1 && dertax<0) fangxiang=4;

}

五、步事件

这个是人物移动指令,不难理解

 

/*     向下移动     */

if (move==1 && fangxiang==1 && (image_index>=2)) image_index=0;

if (move==1 && fangxiang==1)

    {

    if (distance_to_point(move_x,move_y)>0.5)mp_potential_step_object(move_x,move_y,move_speed,obj_no);

    if (distance_to_point(move_x,move_y)<=0.5) 

        {

        speed=0;

        move=0;

        zhan=1;

        }

    }

        

/*     向右移动     */

if (move==1 && fangxiang==2 && (image_index<=10 or image_index>=13)) image_index=11

if (move==1 && fangxiang==2)

    {

    if (distance_to_point(move_x,move_y)>0.5) mp_potential_step_object(move_x,move_y,move_speed,obj_no);

    if (distance_to_point(move_x,move_y)<=0.5) 

        {

        speed=0;

        move=0;

        zhan=1;

        }

    }

        

/*     向上移动     */

if (move==1 && fangxiang==3 && (image_index<=1 or image_index>=4)) image_index=2

if (move==1 && fangxiang==3)

    {

    if (distance_to_point(move_x,move_y)>0.5) mp_potential_step_object(move_x,move_y,move_speed,obj_no);

    if (distance_to_point(move_x,move_y)<=0.5) 

        {

        speed=0;

        move=0;

        zhan=1;

        }

    }

        

/*     向左移动     */

if (move==1 && fangxiang==4 && (image_index<=3 or image_index>=6)) image_index=4

if (move==1 && fangxiang==4)

    {

    if (distance_to_point(move_x,move_y)>0.5) mp_potential_step_object(move_x,move_y,move_speed,obj_no);

    if (distance_to_point(move_x,move_y)<=0.5) 

        {

        speed=0;

        move=0;

        zhan=1;

        }

    }

 

obj_mubiao

步事件

表示如果对应主角处于被选中状态,那么就显示旗帜,否则会隐藏

一旦主角到达指定位置,旗帜消失

 

if (zhuren.shubiao=1) image_alpha=100;

if (zhuren.shubiao=0) image_alpha=0;

if collision_point(x,y,zhuren,0,0)

{

    x=0;

    y=0;

}

 

全局右键

这里面是设定终点位置

 

if (zhuren.shubiao==1)

{

x=zhuren.move_x;

y=zhuren.move_y;

}

if (collision_circle(x,y,1,obj_difang,1,0) && zhuren.duixiang=collision_circle(x,y,1,obj_difang,1,0))

{

    zhuren.move=0;

    zhuren.da=1;

}

else

{

    zhuren.chetui=1;

}

if collision_point(x,y,1,obj_no,1)

{

x=0;

y=0;

}