使用GameMaker中用于碰撞检测的脚本小记

来源:互联网 发布:nb仿真实验室软件 编辑:程序博客网 时间:2024/06/07 14:28

使用GameMaker中用于碰撞检测的脚本小记

    在GameMaker的中文论坛精华例子里面下了一个关于跳跃的gmk,说是关于跳跃,但是里面实现了所有动作游戏角色的移动/跳跃(还有二段跳)/爬墙的逻辑。界面如下:


其中游戏核心是角色object的step_event中的200多行脚本。

原代码如下:

switch (state){case 0:{//地面    if(keyboard_check_pressed(vk_left)){//向左移动        sprite_index=sp_l;    }    else if(keyboard_check_pressed(vk_right)){//向右移动        sprite_index=sp_r;    }    else if(keyboard_check_released(vk_left) || keyboard_check_released(vk_right)){//停止移动        sprite_index=sp0;    }    if(keyboard_check_pressed(ord('Z'))){//按下跳        state=1;        sprite_index=sp_u;        gravity_direction=270;        gravity=1;        vspeed=-16;    }    else if(instance_position(x-15,y+1,ob_land)<0 && instance_position(x+15,y+1,ob_land)<0){//落下        state=2;        gravity_direction=270;        gravity=1;        sprite_index=sp_d;    }    break;}case 1:{//跳起    test=collision_rectangle(x-15,y-37+vspeed,x+15,y-20,ob_bottom,false,false);//撞到顶    if(test!=noone ){        y=test.y+27;        vspeed=0;        state=2;        sprite_index=sp_d;    }    else if(keyboard_check_released(ord('Z')) || vspeed>=0 ){//松开或速度为0        vspeed=0;        state=2;        sprite_index=sp_d;    }    break;}case 2:{//落下    test=collision_rectangle(x-15,y,x+15,y+vspeed,ob_land,false,false);    if(keyboard_check_pressed(ord('Z'))){//按下跳        state=3;        sprite_index=sp_u;        vspeed=-12;    }    else if(test!=noone){//撞到地面        image_speed=7;        y=test.y-1;        vspeed=0;        gravity=0;        state=0;        sprite_index=sp0;    }    break;}case 3:{//二段跳起    test=collision_rectangle(x-15,y-37+vspeed,x+15,y-20,ob_bottom,false,false);    if(test!=noone ){//撞到顶        y=test.y+27;        vspeed=0;        state=4;        sprite_index=sp_d;    }    else if(keyboard_check_released(ord('Z')) || vspeed>=0 ){//松开或速度为0        vspeed=0;        state=4;        sprite_index=sp_d;    }    break;}case 4:{//二段落下    test=collision_rectangle(x-15,y,x+15,y+vspeed,ob_land,false,false);//撞到地面    if(test!=noone){        image_speed=7;        y=test.y-1;        vspeed=0;        gravity=0;        state=0;        sprite_index=sp0;    }    break;}case 5:{//沿墙左滑下    if(keyboard_check_pressed(ord('Z'))){//按下跳沿墙边跳起        state=1;        vspeed=-16;        gravity=1;        sprite_index=sp_u;        x+=40;    }    if(keyboard_check_released(vk_left)){//松开左,落下        state=2;        gravity=1;        sprite_index=sp_d;        x+=20;    }    else{        test=collision_rectangle(x,y-10,x+29,y+20+vspeed,ob_land,false,false);//撞到地面        if(test!=noone){            sprite_index=sp0;            image_speed=7;            y=test.y-1;            x=x+20;            vspeed=0;            gravity=0;            state=0;        }    }    break;}case 6:{//沿墙右滑下    if(keyboard_check_pressed(ord('Z'))){//按下跳沿墙边跳起        state=1;        vspeed=-16;        gravity=1;        sprite_index=sp_u;        x-=40;    }    else if(keyboard_check_released(vk_right)){//松开右,落下        state=2;        gravity=1;        sprite_index=sp_d;        x-=20;    }    else{        test=collision_rectangle(x,y-10,x+29,y+20+vspeed,ob_land,false,false);//撞到地面        if(test!=noone){            sprite_index=sp0;            image_speed=7;            y=test.y-1;            x=x-20;            vspeed=0;            gravity=0;            state=0;        }    }    break;}}switch (state){case 0:{//地面    if(keyboard_check(vk_left)){        test=collision_rectangle(x-28,y-30,x-8,y,ob_side,false,false);//撞到墙壁        if(test!=noone){            x=test.x+20;        }        else{            x-=8;        }    }    else if(keyboard_check(vk_right)){        test=collision_rectangle(x+8,y-30,x+28,y,ob_side,false,false);//撞到墙壁        if(test!=noone){            x=test.x-20;        }        else{            x+=8;        }    }    break;}case 1://跳起case 2://落下case 3://二段跳起case 4:{//二段落下    if(keyboard_check(vk_left)){        test=collision_rectangle(x-24,y-30,x-8,y,ob_side,false,false);//撞到墙壁        if(test!=noone){            state=5;            gravity=0;            x=test.x+1;            vspeed=5;            sprite_index=sp_sl;        }        else{            x-=8;        }    }    else if(keyboard_check(vk_right)){        test=collision_rectangle(x+8,y-30,x+24,y,ob_side,false,false);//撞到墙壁        if(test!=noone){            state=6;            gravity=0;            x=test.x-1;            vspeed=5;            sprite_index=sp_sr;        }        else{            x+=8;        }    }    break;}case 5:{//沿墙左滑下    test=collision_rectangle(x-8,y-30,x,y,ob_side,false,false);//离开墙壁    if(test==noone){        state=2;        gravity=1;        sprite_index=sp_d;        x+=20;    }    break;}case 6:{    test=collision_rectangle(x,y-30,x+8,y,ob_side,false,false);//离开墙壁    if(test==noone){        state=2;        gravity=1;        sprite_index=sp_d;        x-=20;    }    break;}}

       摘录一下其中的碰撞参数,加以图形化,有以下几种模型(有些模型说明忘了加,有些重复或互为镜像的模型也没有加)。最头疼是模型参数的设置,原代码中的参数让我觉得这份代码可能是个半成品。

修改后的代码如下(根据初步猜想的参数修改,这份代码与原代码运行一致):

switch (state){case 0:{//地面    if(keyboard_check_pressed(vk_left)){//向左移动        sprite_index=sp_l;    }    else if(keyboard_check_pressed(vk_right)){//向右移动        sprite_index=sp_r;    }    else if(keyboard_check_released(vk_left) || keyboard_check_released(vk_right)){//停止移动        sprite_index=sp0;    }    if(keyboard_check_pressed(ord('Z'))){//按下跳        state=1;        sprite_index=sp_u;        gravity_direction=270;        gravity=1;        vspeed=-16;    }    else if(instance_position(x-15,y+1,ob_land)<0 && instance_position(x+15,y+1,ob_land)<0){//落下        state=2;        gravity_direction=270;        gravity=1;        sprite_index=sp_d;    }    break;}case 1:{//跳起    test=collision_rectangle(x-15,y-37+vspeed,x+15,y-20,ob_bottom,false,false);//撞到顶    if(test!=noone ){        y=test.y+37;        vspeed=0;        state=2;        sprite_index=sp_d;    }    else if(keyboard_check_released(ord('Z')) || vspeed>=0 ){//松开或速度为0        vspeed=0;        state=2;        sprite_index=sp_d;    }    break;}case 2:{//落下    test=collision_rectangle(x-15,y,x+15,y+vspeed,ob_land,false,false);    if(keyboard_check_pressed(ord('Z'))){//按下跳        state=3;        sprite_index=sp_u;        vspeed=-12;    }    else if(test!=noone){//撞到地面        image_speed=7;        y=test.y-1;        vspeed=0;        gravity=0;        state=0;        sprite_index=sp0;    }    break;}case 3:{//二段跳起    test=collision_rectangle(x-15,y-37+vspeed,x+15,y-20,ob_bottom,false,false);    if(test!=noone ){//撞到顶        y=test.y+37;        vspeed=0;        state=4;        sprite_index=sp_d;    }    else if(keyboard_check_released(ord('Z')) || vspeed>=0 ){//松开或速度为0        vspeed=0;        state=4;        sprite_index=sp_d;    }    break;}case 4:{//二段落下    test=collision_rectangle(x-15,y,x+15,y+vspeed,ob_land,false,false);//撞到地面    if(test!=noone){        image_speed=7;        y=test.y-1;        vspeed=0;        gravity=0;        state=0;        sprite_index=sp0;    }    break;}case 5:{//沿墙左滑下    if(keyboard_check_pressed(ord('Z'))){//按下跳沿墙边跳起        state=1;        vspeed=-16;        gravity=1;        sprite_index=sp_u;        x+=40;    }    if(keyboard_check_released(vk_left)){//松开左,落下        state=2;        gravity=1;        sprite_index=sp_d;        x+=20;    }    else{        test=collision_rectangle(x,y,x+29,y-40,ob_land,false,false);//撞到地面        if(test!=noone){            sprite_index=sp0;            image_speed=7;            y=test.y-1;            x=x+20;            vspeed=0;            gravity=0;            state=0;        }    }    break;}case 6:{//沿墙右滑下    if(keyboard_check_pressed(ord('Z'))){//按下跳沿墙边跳起        state=1;        vspeed=-16;        gravity=1;        sprite_index=sp_u;        x-=40;    }    else if(keyboard_check_released(vk_right)){//松开右,落下        state=2;        gravity=1;        sprite_index=sp_d;        x-=20;    }    else{        test=collision_rectangle(x,y,x-29,y-40,ob_land,false,false);//撞到地面        if(test!=noone){            sprite_index=sp0;            image_speed=7;            y=test.y-1;            x=x-20;            vspeed=0;            gravity=0;            state=0;        }    }    break;}}switch (state){case 0:{//地面    if(keyboard_check(vk_left)){        test=collision_rectangle(x-28,y-30,x-8,y,ob_side,false,false);//撞到墙壁        if(test!=noone){            x=test.x+20;        }        else{            x-=8;        }    }    else if(keyboard_check(vk_right)){        test=collision_rectangle(x+8,y-30,x+28,y,ob_side,false,false);//撞到墙壁        if(test!=noone){            x=test.x-20;        }        else{            x+=8;        }    }    break;}case 1://跳起case 2://落下case 3://二段跳起case 4:{//二段落下    if(keyboard_check(vk_left)){        test=collision_rectangle(x-28,y-30,x-8,y,ob_side,false,false);//撞到墙壁        if(test!=noone){            state=5;            gravity=0;            x=test.x+1;            vspeed=5;            sprite_index=sp_sl;        }        else{            x-=8;        }    }    else if(keyboard_check(vk_right)){        test=collision_rectangle(x+8,y-30,x+28,y,ob_side,false,false);//撞到墙壁        if(test!=noone){            state=6;            gravity=0;            x=test.x-1;            vspeed=5;            sprite_index=sp_sr;        }        else{            x+=8;        }    }    break;}case 5:{//沿墙左滑下    test=collision_rectangle(x-8,y-30,x,y,ob_side,false,false);//离开墙壁    if(test==noone){        state=2;        gravity=1;        sprite_index=sp_d;        x+=20;    }    break;}case 6:{    test=collision_rectangle(x,y-30,x+8,y,ob_side,false,false);//离开墙壁    if(test==noone){        state=2;        gravity=1;        sprite_index=sp_d;        x-=20;    }    break;}}
源代码及修改后的代码均有一个在Flash游戏中常见的BUG,就是角色obj可以依靠爬墙逻辑从上端bottom跟下端land“逃出墙壁”,这个缺陷是爬墙的逻辑不够完善所致。


0 0
原创粉丝点击