Enemies at the edge of the screen

Crimsondeath

Active member
This most commonly happens in 2 player games,
There are areas where the enemy (or boss) leaves the screen due to attacks where they are thrown by the players (or dodge their attacks backwards):

lzAwPpm.gif
omeQxvp.gif
GEbyhEx.gif


I don't know if it's possible to make enemies "not leave the screen" (or leave just a little), I don't want to use the "subject_to_screen" property because if the player moves away the enemy is dragged by the "camera" that follows the player.

Thanks in advance :)
 
Last edited:
Solution
Here is an example I use on animationscript, but you can use it as onmovexscript too:

C-like:
void isOffScreen2(int Ani){
// Check if an entity is offscreen
// Douglas Baldan / O Ilusionista - 07.05.2021
void self = getlocalvar("self"); // Get caller
int  XPos  = openborvariant("xpos"); // Get camera X position
int selfx = getentityproperty(self, "x"); // Get caller X position
int Screenwidth = openborvariant("hResolution"); // Get screen width
int offset = 15; // How much the entity will be shifted on screen

    if (selfx > XPos + Screenwidth - offset){ // beyond camera pos
    changeentityproperty(self, "position", (XPos + Screenwidth) - offset, NULL(), 0);
    performattack(self, openborconstant(Ani));
    }
    if (selfx - offset <...
Yes, you can use an onmovexscript that detects an offset that is "allowed" for the enemy to move off-screen (for example, 50px).

You determine its position on the screen, and if it's larger on the right edge or smaller on the left edge, you cut its X speed or simply make it change animation.
 
Here is an example I use on animationscript, but you can use it as onmovexscript too:

C-like:
void isOffScreen2(int Ani){
// Check if an entity is offscreen
// Douglas Baldan / O Ilusionista - 07.05.2021
void self = getlocalvar("self"); // Get caller
int  XPos  = openborvariant("xpos"); // Get camera X position
int selfx = getentityproperty(self, "x"); // Get caller X position
int Screenwidth = openborvariant("hResolution"); // Get screen width
int offset = 15; // How much the entity will be shifted on screen

    if (selfx > XPos + Screenwidth - offset){ // beyond camera pos
    changeentityproperty(self, "position", (XPos + Screenwidth) - offset, NULL(), 0);
    performattack(self, openborconstant(Ani));
    }
    if (selfx - offset < XPos ){ // before camera pos
        changeentityproperty(self, "position", XPos + offset, NULL(), 0);
        performattack(self, openborconstant(Ani));
    }
}

This is a second function that I use, which will return 1 or 2 to be used on other functions which won't use animation change:


C-like:
void isOffScreen(){
// Check if an entity is offscreen
// Douglas Baldan / O Ilusionista - 07.05.2021
void self = getlocalvar("self");
int  XPos  = openborvariant("xpos");
int selfx = getentityproperty(self, "x");
int Screenwidth = openborvariant("hResolution"); // Get screen width

if (selfx > XPos + Screenwidth){ return 1; } // beyond camera pos
if (selfx < XPos){ return 2; } // before camera pos
}
 
Solution
I don't know if it's possible to make enemies "not leave the screen" (or leave just a little)

There are two solutions I have in mind :
1. Put two large invisible blockers just offscreen fighting area. One to the left and the other to the right. This will prevent enemies from getting knocked too far offscreen from both sides.
If fighting area were a wait or limited scrolling area and has ended its purpose, those blockers could be removed to allow players to move to the next fighting area.
You could make these blockers using blank sprite and set platform with large size.
2. Use entity to pull offscreen enemies slowly toward the screen. Just like those blockers above, it could be removed if not needed.

Each has pros and cons. Which one do you prefer to use?
 
Here is an example I use on animationscript, but you can use it as onmovexscript too:

C-like:
void isOffScreen2(int Ani){
// Check if an entity is offscreen
// Douglas Baldan / O Ilusionista - 07.05.2021
void self = getlocalvar("self"); // Get caller
int  XPos  = openborvariant("xpos"); // Get camera X position
int selfx = getentityproperty(self, "x"); // Get caller X position
int Screenwidth = openborvariant("hResolution"); // Get screen width
int offset = 15; // How much the entity will be shifted on screen

    if (selfx > XPos + Screenwidth - offset){ // beyond camera pos
    changeentityproperty(self, "position", (XPos + Screenwidth) - offset, NULL(), 0);
    performattack(self, openborconstant(Ani));
    }
    if (selfx - offset < XPos ){ // before camera pos
        changeentityproperty(self, "position", XPos + offset, NULL(), 0);
        performattack(self, openborconstant(Ani));
    }
}

This is a second function that I use, which will return 1 or 2 to be used on other functions which won't use animation change:


C-like:
void isOffScreen(){
// Check if an entity is offscreen
// Douglas Baldan / O Ilusionista - 07.05.2021
void self = getlocalvar("self");
int  XPos  = openborvariant("xpos");
int selfx = getentityproperty(self, "x");
int Screenwidth = openborvariant("hResolution"); // Get screen width

if (selfx > XPos + Screenwidth){ return 1; } // beyond camera pos
if (selfx < XPos){ return 2; } // before camera pos
}

I modified the second script, so now fits perfect for my game:

C++:
void isOffScreen(){
    // Check if an entity is offscreen
    // Douglas Baldan / O Ilusionista - 07.05.2021
    void self = getlocalvar("self");
    float health = getentityproperty(self, "health");
    int XPosBefore = getentityvar(self, "OffScreenBefore");
    int XPosAfter = getentityvar(self, "OffScreenAfter");
    int selfx = getentityproperty(self, "x");

    if(health >= 0 && !getentityproperty(self,"dead")){
        if (selfx > XPosAfter){
            if(!getentityproperty(self, "aiflag", "drop")){
                if(getentityproperty(self, "a") == getentityproperty(self, "base")){
                    executeanimation(self, openborconstant("ANI_FOLLOW32"), 0);
                }
            }
        }
        if (selfx < XPosBefore){
            if(!getentityproperty(self, "aiflag", "drop")){
                if(getentityproperty(self, "a") == getentityproperty(self, "base")){
                    executeanimation(self, openborconstant("ANI_FOLLOW32"), 0);
                }
            }
        }
    }
}

I just have to set up the boss entity like this :D :

Code:
spawn    Crazy_Mat_
@script void main() {
    executeanimation(getlocalvar("self"), openborconstant("ANI_FOLLOW11"), 1);
    setindexedvar(2, 1);
    setindexedvar(3, getlocalvar("self"));
    setindexedvar("Crazy_mat_st1c_1", getlocalvar("self"));
    setentityvar(getlocalvar("self"), 77, "Champion");
    changeopenborvariant("game_time", 80000);
    setentityvar(getlocalvar("self"), "OffScreenBefore", 370);
    setentityvar(getlocalvar("self"), "OffScreenAfter", 920);
} @end_script
coords    80 212 240
boss    1
flip    1
at      420

I have no problems with enemies. Thanks :D
 
Back
Top Bottom