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

问题概述

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

解决方案

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

  1. 创建旗帜物体obj_mubiao.(建议给这个物体挂一个sprite,方便debug)
  2. 编写选中角色的逻辑代码。
  3. 编写在空白区域点击左键以取消选中的逻辑代码。
  4. 编写在空白区域点击右键以放置旗帜的逻辑代码。
  5. 编写旗帜的逻辑代码。

代码实现

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

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;
}
发布了8 篇原创文章 · 获赞 1 · 访问量 331

猜你喜欢

转载自blog.csdn.net/weixin_42921101/article/details/100087409