keyboard movements - code mode

currently does not include the collision issues. Will be updated later. 

Games that use this feature (Does not have to be made with Stencyl and not limited to:)
Mindustry (the core unit that harvests and builds)
Shrouded in Sanity 
Stardew Valley (the main character that inherit a farm in Pelican Town)

How it works: the player moves when the some key is pressed. 
Pre-requisite: settings > controls. 

The video above shows how the direct position settings works. 
Instead of directly setting the player position, there is an internal variable that determines the position via update. because the traditional direct setting position will not work if change position is less than 0.5.  

Indirect position method: 
Advantage: contols the precise positions. 
Disadvantage: bypass collisions and solid objects. However, it can be triggered away by using when this actor collides with something. then moving = false, . In design mode: Add event > collisions. 

This code uses alternative-to com.stencyl.graphics.G. that is a free-from code. 
http://stencyl-nator.blogspot.com/p/text-drawing-arbitrary-code-for-stencyl.html. However, in this case, the import is not required because the code has been moved to scripts where all behaviors go. 

code: 
// imports. Removed the unuseful imports. 
package scripts;
import com.stencyl.Engine;
import com.stencyl.behavior.ActorScript; // this behavior extends
import com.stencyl.behavior.Script; 
import com.stencyl.behavior.TimedTask; //used for delays. eg frame change. 
import com.stencyl.models.Actor; //this is actor behavior 
import com.stencyl.utils.motion.Easing;

class Player_leg_behav extends ActorScript
{
public var h:Float; public var w:Float; public var x:Float; public var y:Float;
        public var diagt:F = new F(); //for diagnosis drawing. 
        public var camx:Float; public var camy:Float; 
public var offsx:Float; public var offsy:Float; 
public var move_north:Bool= false; public var move_south:Bool = false; 
        public var move_east:Bool = false; public var move_west:Bool = false;  
public var move_x_mult:Float = 0; public var move_y_mult:Float = 0;  
        public var move_dir: Int = 0; public var moving:Bool = false; public var move_rev:Bool = false           public var move_perframe:Float=1.6; 
public var coll:Bool = false
public var chg_frame:Bool = true; public var chg_delay:Int;  
public var chg_tt:TimedTask = new TimedTask(null,50,false,null); public var frame_id:Int; 
public var coll:Bool= false; 
public function new (u0:Int,a:Actor,u1:Engine){super(a);}
override public function init() //when created
{
actor.tweenProps.realScaleXY.tween(actor.realScaleX, 0.25, actor.realScaleY, 0.25, Easing.linear,0); // optional if your actor sprite is in 1x
this.x=actor.getX(); this.y = actor.getY(); 
Engine.engine.cameraFollow(actor);
this.camx = Engine.cameraX; this.camy = Engine.cameraY; 
this.diagt.f_cu = Script.getFont(19); 
addKeyStateListener("d",press_east); addKeyStateListener("w",press_north); addKeyStateListener("s",press_south); addKeyStateListener("a",press_west);
this.add_def(def); this.add_dra(diagd); this.chg_tt.actor = actor; 
this.calc_frame_time();
this.x=actor.getX(); this.y = actor.getY();
}
public function add_def(a:Dynamic):Void{actor.whenUpdatedListeners.push(a);} //add always
public function add_dra(a:Dynamic):Void{actor.whenDrawingListeners.push(a);} //add drawing
public function calc_frame_time():Void
{
this.chg_delay = Std.int(40/this.move_perframe); 
}
public function def():Void //Always but without frame or time parameters, 
{
if(this.moving)
{
if(this.chg_frame) // changes frame with back-and-forth pattern. 
{
this.chg_frame = false;
if(this.move_rev){
                                    if(this.frame_id > 0){this.frame_id -= 1;}
                                    else{this.move_rev = false;}
                                }
else {
if(this.frame_id < 19){this.frame_id += 1;}
else{this.move_rev = true;}
                                        }
actor.setAnimation("a"+this.frame_id);
Script.runLater(this.chg_delay, enable_change_frame,actor);
}
// use this actor movement method for players work with position change less than 0.5 per frame. otherwise it would not work.   
this.x += this.move_x_mult * this.move_perframe; 
                        this.y += this.move_y_mult * this.move_perframe;  
actor.setX(this.x); actor.setY(this.y);
}
                else if(this.coll)
                {
this.x = actor.getX(); this.y = actor.getY(); this.coll = false
                }
}
public function diagd():Void{} //diagnosis drawing. used to check away the bugs during development. Not to used in real game. 

//adjustible frame time according to movement speeds. 
public function enable_change_frame(t:TimedTask):Void{this.chg_frame = true;} 

//pressing movements. in this case, W,A,S,D. 
public function press_east(p:Bool, r:Bool,u0:Array<Dynamic>):Void
{
if(p)
{ this.moving = true; 
this.move_east = true;
if(this.move_north && !(this.move_south)){actor.spinTo(315,0,Easing.linear); this.move_x_mult = 0.707; this.move_y_mult = -0.707;}
else if(!(this.move_north) && this.move_south){actor.spinTo(45,0,Easing.linear); this.move_x_mult = 0.707; this.move_y_mult = 0.707;}
else if(!(this.move_north) && !(this.move_south)){actor.spinTo(0,0,Easing.linear); this.move_x_mult = 1; this.move_y_mult = 0;}
}
else if(r)
{
this.move_east = false;
if(this.move_north && !(this.move_south)){actor.spinTo(270,0,Easing.linear); this.move_x_mult = 0;this.move_y_mult = -1;}
else if(!(this.move_north) && this.move_south){actor.spinTo(90,0,Easing.linear); this.move_x_mult = 0;this.move_y_mult = 1;}
else if(this.move_west) {actor.spinTo(180,0,Easing.linear); this.move_x_mult = -1; this.move_y_mult = 0;};
else {this.move_x_mult = 0;this.move_y_mult = 0; this.moving = false;}
}
}

public function press_north(p:Bool, r:Bool,u0:Array<Dynamic>):Void
{
if(p)
{ this.moving = true
this.move_north = true;
if(this.move_east && !(this.move_west)){actor.spinTo(315,0,Easing.linear); this.move_x_mult = 0.707;this.move_y_mult = -0.707;}
else if(!(this.move_east) && this.move_west){actor.spinTo(225,0,Easing.linear); this.move_x_mult = -0.707;this.move_y_mult = -0.707;}
else if(!(this.move_east) && !(this.move_west)){actor.spinTo(270,0,Easing.linear); this.move_x_mult = 0;this.move_y_mult = -1;}
}
else if(r)
{
this.move_north = false;
if(this.move_east && !(this.move_west)){actor.spinTo(0,0,Easing.linear); this.move_x_mult = 1;this.move_y_mult = 0;}
else if(!(this.move_east) && this.move_west){actor.spinTo(180,0,Easing.linear); this.move_x_mult = -1;this.move_y_mult = 0;}
else if(this.move_south) {actor.spinTo(90,0,Easing.linear); this.move_x_mult = 0; this.move_y_mult = 1;};
else {this.move_x_mult = 0;this.move_y_mult = 0; this.moving = false;}
}
}
public function press_south(p:Bool, r:Bool,u0:Array<Dynamic>):Void //move to bottom
{
if(p)
{ this.moving = true; 
this.move_south = true;
if(this.move_east && !(this.move_west)){actor.spinTo(45,0,Easing.linear); this.move_x_mult = 0.707;this.move_y_mult = 0.707;}
else if(!(this.move_east) && this.move_west){actor.spinTo(135,0,Easing.linear); this.move_x_mult = -0.707;this.move_y_mult = 0.707;}
else if(!(this.move_east) && !(this.move_west)){actor.spinTo(90,0,Easing.linear); this.move_x_mult = 0;this.move_y_mult = 1;}
}
else if(r)
{
this.move_south = false;
if(this.move_east && !(this.move_west)){actor.spinTo(0,0,Easing.linear); this.move_x_mult = 1;this.move_y_mult = 0;}
else if(!(this.move_east) && this.move_west){actor.spinTo(180,0,Easing.linear); this.move_x_mult = -1;this.move_y_mult = 0;}
else if(this.move_north) {actor.spinTo(270,0,Easing.linear); this.move_x_mult = 0; this.move_y_mult = -1;};
else {this.move_x_mult = 0;this.move_y_mult=0; this.moving = false;}
}
}
public function press_west(p:Bool, r:Bool,u0:Array<Dynamic>):Void //move to the left. 
{
if(p)
{ this.moving = true; 
this.move_west = true;
if(this.move_north && !(this.move_south)){actor.spinTo(225,0,Easing.linear); this.move_x_mult = -0.707;this.move_y_mult = -0.707;}
else if(!(this.move_north) && this.move_south){actor.spinTo(135,0,Easing.linear); this.move_x_mult = -0.707;this.move_y_mult = 0.707;}
else if(!(this.move_north) && !(this.move_south)){actor.spinTo(180,0,Easing.linear); this.move_x_mult = -1;this.move_y_mult = 0;}
}
else if(r) // when left key or a is released, 
{ this.moving = true; 
this.move_west = false;
if(this.move_north && !(this.move_south)){actor.spinTo(270,0,Easing.linear); this.move_x_mult = 0;this.move_y_mult = -1;}
else if(!(this.move_north) && this.move_south){actor.spinTo(90,0,Easing.linear); this.move_x_mult = 0;this.move_y_mult = 1;}
else if(this.move_east) {actor.spinTo(0,0,Easing.linear); this.move_x_mult = 1; this.move_y_mult = 0;}
else {this.move_x_mult = 0;this.move_y_mult = 0; this.moving = false;}
}
}

public function col(a:Collision, u0:Array<Dynamic>):Void // for collisions
{
if(Conte.get_AG("object") == a.otherActor.getGroup())
{
this.moving = false; this.coll = true;
if(a.otherFromBottom){actor.setY(actor.getY() +2); }
if(a.otherFromLeft){actor.setX(actor.getX() - 2); }
if(a.otherFromRight){actor.setX(actor.getX() +2); }
if(a.otherFromTop){actor.setY(actor.getY() -2); }
// the collided actor must be solid and normal physical mode for it to work properly. 
}
}
}

No comments:

Post a Comment