como dice el titulo cual es la manera correcta de executar one way slopes y ceiling slopes, yo uso una mezcla de codigo sacados del tutorial de plataformas de monthy Drake y algunas cosas de una engine de un chico italiano big mama era su nombre creo , bueno lo que me tiene intrigado, es si lo estoy haciendo de la forma correcta o existe alguna manera mejor de hacerlo aqui les dejo el codigo y el projecto por si quieren echarle un viztaso y ayudarme a aclarar mis dudas, por lo poco que e probado el juego tiene poco bugs como quedarse atascado dentro de una plataforma solida y una plataforma oneway
EDITABLE NO DUDE EN MODIFICARLO MEJORARLO O HACER ALGUNA SUGERENCIA:
https://drive.google.com/file/d/1zF4Se-PHWXp8nTsLLBUh6S3TYtZhxEFq/view?usp=sharing
EVENTO CREATE JUGADOR:
[spoiler]
[gml]
onGround = 0;
onOneway = 0;
konckback = 0;
vspd = 0;
hspd = 0;
grvzero = 1;
accspd = 0.5;
fricspd = 0.25;
gfric = 0.5;
mainspd = movespd;
//ATTACK VAR
hitsCount = 0;
maxHits = 4;
slashHit = 0;
//JUMP VAR
jumped = 0;
minijump = 0;
buffCount = 0;
coyCount = 0;
//KEYS VAR
moveX = 0;
moveY = 0;
keyLeft = 0;
keyRight = 0;
keyUp = 0;
keyDown = 0;
keyJumpC = 0;
keyJumpP = 0;
keyAttackC = 0;
keyAttackP = 0;
[/gml]
[/spoiler]
SCRIPT MOTION SIMPLIFICADO:
[spoiler]
[gml]
///scrMotion();
/*******************************************************
/* HORIZONTAL COLLISION CHECK **
/******************************************************/
repeat(abs(hspd)){
var block = place_meeting(x+sign(hspd),y,parSolid);
//SOLID SLOPE UPWARD
if(block){
for(var i=1; i<=maxslp; i++;){
if(!place_meeting(x+sign(hspd),y-i,parSolid)){
y -= i;
break;
}
}
}else{//SOLID SLOPE UPWARD
for(var i=maxslp; i>=1; i--;){
if(!place_meeting(x+sign(hspd),y+i,parSolid)){
if(place_meeting(x+sign(hspd),y+i+1,parSolid)){
y += i;
break;
}
}
}
}
//ONEWAY SLOPE CONDITIONS
with(parPlayers){
//condiciones para poder subir oneway slopes
if(!place_meeting(x,y+1,parSolid) && !place_meeting(x,y+1,overOneway))
||(!place_meeting(x,y+1,overOneway) && place_meeting(x,y+1,parSolid) && keyUp)
||(!place_meeting(x,y+1,parSolid) && place_meeting(x,y+1,overOneway) && keyUp){
var oneway = place_meeting(x+sign(hspd),y,parOneway);
//ONEWAY SLOPE UPWARD
if(oneway){
for(var i=1; i<=maxslp; i++;){
if(!place_meeting(x+sign(hspd),y-i,parOneway)){
y -= i;
break;
}
}
}else{//ONEWAY SLOPE DOWNWARD
for(var i=maxslp; i>=1; i--;){
if(!place_meeting(x+sign(hspd),y+i,parOneway)){
if(place_meeting(x+sign(hspd),y+i+1,parOneway)){
y += i;
break;
}
}
}
}
}
//limitar jugador a la view tambien puede clampear su jugador a la view
if(x+sign(hspd)<=view_xview+16) || (x+sign(hspd)>=view_xview+view_wview-16){
hspd = 0;
}
}
//LEFT-RIGHT SOLID COLISION CHECK
if(!place_meeting(x+sign(hspd),y,parSolid)){
x += sign(hspd);
}else{
hspd = 0;
break;
}
}
/*******************************************************
/* VERTICAL COLLISION CHECK **
/******************************************************/
repeat(abs(vspd)){
if(place_meeting(x,y+sign(vspd),parSolid)){
vspd = 0;
break;
}
if(vspd>0 && !place_meeting(x,y,parOneway) && place_meeting(x,y+sign(vspd),parOneway)){
vspd = 0;
break;
}
if(vspd>0 && !place_meeting(x,y,overOneway)&& place_meeting(x,y+sign(vspd),overOneway)){
vspd = 0;
break;
}else{
y += sign(vspd);
}
}
[/gml]
[spoiler]
SCRIPT PLAYER STEP:
en este script van todas las entradas que realizara el jugador y la inicializacion de los estados
puede modificarlo a su gusto es solo un ejemplo
[spoiler]
[gml]
///scrPlayerStep{player,movLeft,movRight,movUp,movDown,button1,button2,view}
var playerID = argument[0];
var moveLeft = argument[1];
var moveRight = argument[2];
var moveUp = argument[3];
var moveDown = argument[4];
var action1 = argument[5];
var action2 = argument[6];
var viewIndex = argument[7];
with(playerID){
var getName = object_get_name(object_index);
sprite_index = asset_get_index("spr"+getName+setAction);
scrAction();
var onWallL = vspd>0 && !place_meeting(x,y+1,parSolid) && place_meeting(x-1,y,sWall);
var onWallR = vspd>0 && !place_meeting(x,y+1,parSolid) && place_meeting(x+1,y,sWall);
onGround = scrGroundCheck();
onOneway =!place_meeting(x,y,parOneway) && place_meeting(x,y+1,parOneway) && moveX==0 && moveY==-1;
//SET.CONTROL PLAYER
switch(canMove){
case 0:
keyJumpP = 0;
keyAttackP = 0;
if(onGround){
hspd = scrApproach(hspd,0,1);
}
break;
case 1: keyLeft = keyboard_check(moveLeft);
keyRight = keyboard_check(moveRight);
keyUp = keyboard_check(moveUp);
keyDown = keyboard_check(moveDown);
keyJumpC = keyboard_check(action1);
keyJumpP = keyboard_check_pressed(action1);
keyAttackC = keyboard_check(action2);
keyAttackP = keyboard_check_pressed(action2);
moveX = keyRight-keyLeft;
moveY = keyUp-keyDown;
if(moveX<>0){
image_xscale = sign(moveX);
hspd = scrApproach(hspd,moveX*mainspd,accspd);
}
}
//INIT.JUMP BUFFER
if(keyJumpP && !keyAttackP && !keyAttackC && buffCount<=0 && !onOneway){
buffCount = buffMaxJump;
}
//COUNTDOWN.JUMP BUFFER
if(buffCount>0){
buffCount--;
}
//MINI.JUMP
if(vspd<0 && minijump && !keyJumpC && !onOneway){
minijump = 0;
vspd = 0;
}
//WALL.JUMP LEFT
if(onWallL){
setAction = "JumpMove2";
grvzero = 2;
if(buffCount>0){
vspd =-jumpspd;
hspd = 4;
setAction = "JumpMove1";
airState = stateWallJump;
image_xscale = 1;
}
}else{
if(!onWallL && !onWallR){
grvzero = 1;
}
}
//WALL.JUMP RIGHT
if(onWallR){
setAction = "JumpMove2";
grvzero = 2;
if(buffCount>0){
vspd =-jumpspd;
hspd =-4;
setAction = "JumpMove1"
airState = stateWallJump;
image_xscale =-1;
}
}else{
if(!onWallL && !onWallR){
grvzero = 1;
}
}
//ON.GROUND
if(onGround){
airState = noone;
minijump = 1;
//HITS.BUFFER
var hitBuffer = keyboard_check_pressed(action2);
if(hitBuffer && hitsCount<maxHits){
hitsCount = (hitsCount+1) mod(maxHits);
}
//GROUNDED.STATES
if(groundState==noone){
groundState = stateIdle;
}else{
scrGroundStates();
}
//DESCENDER DE PLATAFORMA ONEWAY
if(keyJumpP && onOneway){
y++;
}
}
//ON.AIR
if(!onGround){
vspd += grvspd/grvzero;
countHits = 0;
groundState = noone;
//AIR.STATES
if(airState==noone && jumped==0){
setAction = "JumpMove2";
airState = "JumpMoving2";
image_index = 0;
vspd = 0;
}else{
scrAirStates();
}
//COYOTE.TIME
if(coyCount>0){
coyCount -= 1;
if(!jumped && minijump){
if(keyJumpP){
jumped = 1;
buffCount = 0;
vspd =-jumpspd;
}
}
}
}else{
jumped = 0;
coyCount = coyMax;
}
}
/******************************************************************************
/* SIMPLE CAMERA 1 **
/*****************************************************************************/
//TWO PLAYERS FREE CAMERA
if(instance_exists(P1) && instance_exists(P2)){
view_xview = ((mean(P1.x,P2.x)-view_wview/2)+view_xview*5)/6;
view_yview = ((mean(P1.y,P2.y)-view_hview/2)+view_yview*5)/6;
}else{
view_xview = ((x-view_wview/2)+view_xview*5)/6;
view_yview = ((y-view_hview/2)+view_yview*5)/6;
}
/*
//TWO PLAYERS ONE-SIDE CAMERA
var camH = ((mean(P1.x,P2.x)-view_wview/2)+view_xview*5)/6 && P1.moveX>0 && P2.moveX>0;
if(camH){
view_xview += 1*dTime;
}
view_yview = ((mean(P1.y,P2.y)-view_hview/2)+view_yview*5)/6;
*/
if(view_xview[viewIndex]<=0){view_xview[viewIndex] = 0;}
if(view_xview[viewIndex]>=room_width-view_wview[viewIndex]){view_xview[viewIndex] = room_width-view_wview[viewIndex];}
if(view_yview[viewIndex]>=room_height-view_hview[viewIndex]){view_yview[viewIndex] = room_height-view_hview[viewIndex];}
[/gml]
[/spoiler]
y por ultimo
SCRIPT ON GROUND:
regresa 1 si estamos pisando tierra firme
[spoiler]
[gml]
///scrGroundCheck();
var colGround = ((place_meeting(x,y+1,parSolid)) || (vspd>=0 && !place_meeting(x,y,parOneway) && place_meeting(x,y+1,parOneway)) || (vspd>=0 && !place_meeting(x,y,overOneway) && place_meeting(x,y+1,overOneway)));
return colGround;
[/gml]
[/spoiler]