我是Gamemaker的新手,正在制作一个简单的平台游戏。昨天我在编写敌人在站立和移动之间切换的程序,过程中我开始处理他的碰撞。不知为何,水平碰撞工作得很好,但垂直碰撞却不起作用。我尝试了各种方法,但垂直碰撞似乎根本不存在。
下面是敌人在创建事件中的“AI”代码,用于使其在站立和行走之间切换。
//BIGGER SPRITEimage_xscale = 3image_yscale = 3//VARIABLEShsp=0vsp=0grav=2state=noone state_time = room_speed * 10;state_timer=0;destination_x = x;vel=2//STANDING STATE//WALKING STATE//METHOD OF CHANGE OF STATEchange_state = function(_state){ state_time--; state_timer = irandom(state_time); if (state_timer == state_time or state_time <= 0) { //I'LL CHECK WHICH STATE SHOULD I GO state = _state[irandom(array_length(_state)-1)]; time_state = room_speed * 10; }}//METHOD OF IT STANDINGstanding_state = function(){ //image_blend = c_white; sprite_index = spr_enemy change_state([walking_state, standing_state]);}walking_state = function(){ //MAKE HIM WALK //HE WILL CHOOSE ANY POINT WITHIN THE ROOM //CHECKING MY DISTANCE FROM THE DESTINATION var _dist = point_distance(x, y, destination_x, y); //I WILL ONLY SET A DESTINATION IF I AM CLOSE TO MY DESTINATION if (_dist < 100) { destination_x = random(room_width); } //FINDING THE DIRECTION TO MY DESTINATION var _dir = point_direction(x, y, destination_x, y) //MOVING TO MY DESTINATION x += lengthdir_x(vel, _dir); //image_blend = c_red; //SETTING THE SPRITE sprite_index = spr_enemy_run if (destination_x < x) { image_xscale = -3 } else { image_xscale = 3 } change_state([standing_state, walking_state]);}//SETTING ITS INITIAL STATEstate = standing_state;`
下面是步骤事件中碰撞和重力的代码
//HORIZONTAL COLLISIONif place_meeting(x + hsp, y, obj_block){ var _hsp = sign(hsp); //AS LONG AS I'M NOT COLLIDING 1 PIXEL IN THE DIRECTION I'M while (!place_meeting(x + _hsp, y, obj_block)) { //I MOVE 1 PIXEL IN THAT DIRECTION x+=_hsp; } //I'VE MOVED WHAT I HAD TO MOVE, AND NOW I'M COLLIDING. //I END MY SPEED hsp = 0; show_debug_message("colliding with the floor")}//I MOVEx += hsp;//VERTICAL COLLISIONif place_meeting(x, y + vsp, obj_block){ var _vsp = sign(vsp); while (!place_meeting(x, y + _vsp, obj_block)) { y+=_vsp; } vsp = 0; show_debug_message("colliding with the wall")}y += vsp;//GRAVITYif !place_meeting(x,y,obj_block){ vsp += grav;}//RUNNING THE CURRENT STATEstate();
还有一件事我不明白,消息“colliding with the wall”和“colliding with the floor”显示反了,也就是说,当敌人碰到墙壁时,会显示“colliding with the floor”的消息,而当它碰到地面时,会显示“colliding with the wall”的消息。
我需要帮助,我快要疯了,哈哈(作为一个新手,完全依赖教程也没什么帮助)
如果我的英语有问题,请原谅,我不得不将所有代码翻译成英语以便更好地理解,因为之前是葡萄牙语
我希望敌人能像任何碰撞一样与墙壁碰撞,敌人在触碰到墙壁时会停止,但相反,敌人就像幽灵一样直接穿过了墙壁。
我尝试了一切,测试了碰撞掩码,检查了变量,代码的顺序,检查了对象的名称,但什么都不起作用
回答:
在碰撞之前调用state()和重力代码。这样做不是必须的,但如果不这样做,玩家的移动会延迟一帧,感觉不够灵敏。
你的碰撞代码实际上是在移动玩家,所以除非你想让玩家传送,否则永远不要直接更改x和y。相反,应该使用变量hsp和vsp。
在walking_state中,你调用了”x += lengthdir_x(vel, _dir);”,这会直接移动玩家。由于碰撞代码依赖于hsp,所以通过直接更改x位置来移动玩家时,碰撞不会被检查。
你应该改为说:“hsp = lengthdir_x(vel, _dir);”,然后碰撞代码会负责移动玩家并处理碰撞
编辑:另外,消息显示反转的原因是X轴是水平的,Y轴是垂直的。所以X是墙壁,Y是地面和天花板。