This script implements a Diablo 2 style movement system. You click on a location and the player will attempt to move there. Included is acceleration and friction, which are configurable from onCreated().
This script used to have stamina and walking/running, but I removed it since most people would probably want to implement their own such system anyway (And to avoid bloating the script with features no one will use which only make it harder to read.).
Here's some documentation to help you expand it if necessary.
onCreated():
onTimeout():
- Acceleration, friction and movement.
SetTarget(x, y):
- Properly sets this.target.[x/y] which is where the player will accelerate towards.
Accelerate(xspeed, yspeed, maxspeed):
- Properly increases this.speed.[x/y] to avoid accelerating further than maxspeed.
Move(x, y):
- Moves the player with block detection.
Distance(x, y):
- Helper function; returns distance between (0, 0) and (x, y).
Installation: Used as a weapon.
PHP Code:
//#CLIENTSIDE
//**************************************************
function onCreated()
{
this.baseSpeed = 8;
this.acceleration = 4;
this.baseFriction = 0.5;
this.target.x = player.x + 1.5;
this.target.y = player.y + 2;
onTimeout();
}
//**************************************************
function onTimeout()
{
// *****Set target position so we know where to move
if (leftmousebutton) {
SetTarget(mousex, mousey);
}
// *****Friction (We aren't walking on ice)
this.speed.x *= this.baseFriction;
this.speed.y *= this.baseFriction;
// *****Accelerate so we'll eventually reach that target position.
if (Distance(this.target.x - player.x - 1.5, this.target.y - player.y - 2) > 1 && !this.stopped) {
temp.angle = getangle(this.target.x - player.x - 1.5, this.target.y - player.y - 2);
temp.speed.x = cos(temp.angle) * this.acceleration;
temp.speed.y = -sin(temp.angle) * this.acceleration;
Accelerate(temp.speed.x, temp.speed.y, this.baseSpeed);
setani("walk", "");
}
else
{
if (this.speed.x < 0.5 && this.speed.x > -0.5) this.speed.x = 0;
if (this.speed.y < 0.5 && this.speed.y > -0.5) this.speed.y = 0;
this.stopped = true;
setani("idle", "");
}
// *****Actually move the player according to current speed.
Move(this.speed.x, this.speed.y);
if (this.speed.x != 0 && this.speed.y != 0) player.dir = getdir(this.speed.x, this.speed.y);
setTimer(0.05);
}
//**************************************************
function onMouseDown(button)
{
// Set target position so we know where to move.
if (button == "left") {
SetTarget(mousex, mousey);
}
}
//**************************************************
// Set the position the system will try to reach.
function SetTarget(targetx, targety)
{
if (Distance(targetx - player.x - 1.5, targety - player.y - 2) > 1) {
this.target.x = targetx;
this.target.y = targety;
this.stopped = false;
}
}
//**************************************************
// Increase the speed in pixels per frame.
function Accelerate(xSpeed, ySpeed, maxSpeed)
{
if (Distance(this.speed.x, this.speed.y) < maxSpeed || (Distance(this.speed.x + xSpeed, this.speed.y + ySpeed) - Distance(this.speed.x, this.speed.y)) <= 0) {
this.speed.x += xSpeed;
this.speed.y += ySpeed;
if (Distance(this.speed.x, this.speed.y) > maxSpeed) {
temp.angle = getangle(this.speed.x, this.speed.y);
this.speed.x = cos(temp.angle) * maxSpeed;
this.speed.y = -sin(temp.angle) * maxSpeed;
}
}
}
//**************************************************
// Move the player by specified amount of pixels.
function Move(xSpeed, ySpeed)
{
if (!isapplicationactive) return;
xSpeed = xSpeed<0?int(xSpeed)+1:int(xSpeed);
ySpeed = ySpeed<0?int(ySpeed)+1:int(ySpeed);
// --- 'x' movement of the player --- \\
if (xSpeed != 0) {
temp.x = int(player.x * 16);
temp.xDir = (abs(xSpeed) / xSpeed);
for (i=0; i<abs(xSpeed); i++) {
if (!onwall2(temp.x / 16 + 1 + temp.xDir * (1/16), player.y + 2, 1, 1)) temp.x += temp.xDir;
else break;
}
player.x = temp.x / 16;
}
// --- 'y' movement of the player --- \\
if (ySpeed != 0) {
temp.y = int(player.y * 16);
temp.yDir = (abs(ySpeed) / ySpeed);
for (i=0; i<abs(ySpeed); i++) {
if (!onwall2(player.x + 1, temp.y / 16 + 2 + temp.yDir * (1/16), 1, 1)) temp.y += temp.yDir;
else break;
}
player.y = temp.y / 16;
}
//Hack
if (tiletype(player.x + 1.5, player.y + 2) == 3) {
setani("sit", "");
}
}
//**************************************************
//Calculate the distance between (0, 0) and (dx, dy).
function Distance(dx, dy)
{
return ((dx)^2 + (dy)^2)^0.5
}