2 Person fighter (kind of)- and how would YOU do it?

Started by TheManInBoots, Sat 08/02/2020 18:12:24

Previous topic - Next topic

TheManInBoots

Hey.

In my adventure game I want to include some kind of 2 person fighter.
With a slight difference.
The main character, who flies, has to fly away from the constant attacks of the enemy character.
And after avoiding the attack quickly counter attack by clicking on the enemy.

So before creating this part I wanted to see if I can create the script more efficiently.
I have illustrations on how the game works, and a sample script how I would have scripted it.
I am open for any critic of the script or suggestions to do it completely differently or get a shorter and more efficient script.
You could even only suggest your idea on how to do it and completely ignore my script.

One can learn a lot from how other people do things.
Thanks for any ideas in advance.

(It says beginner's technical forum is for help with starting off scripts so I reckoned this is the right place to post this)

The game plan (illustrations):
Spoiler

In the first? level the screen is split into two fields.
The enemy is going to attack randomly one of the fields (announced with a title or a gui):


If you-re on the attacked field then you need to quickly move to the field that is not attacked to save yourself.


When the enemy reaches the middle of the attacked field, he changes the view to an "attack" frame, and now you have to click on him to counterattack.


If the enemy looses three lifes before you do, you move on to the next level.
If you loose all three lifes you die and have to restart the fight.

The further levels will evolve but I leave it with level 1 for simplicity's sake.
[close]

How I would have scripted it
Spoiler

Note: Apparently some space bar entries have been replaced with question marks when posting.


In Global variables I declare the following variables:



int life=3;
int enemylife=3;
int position;
int field;
int playerfield;
int currentlevel=1;
int n;
bool attackable=false;

life defines how much life the character has (starts with 3)
enemylife defines enemy's life.
position defines if the dog attacks from the left or right in level 1.
field defines which field the dog attacks (field 0 or 1 in level 1).
playerfield defines in which field the player cureently find himself in (field 0 or 1).
currentlevel defines what Level you are currently on.
n is used to run a loop later on.
attackable defines wether the monster has already reached the point where you can counterattack or not.

The game begins in a different room than the rest of the game.

before the room is loaded I put the enemy character and the attack sign gui outside the room borders so you see only the character flying.

Then in after the room fades in:
Code: ags

function room_AfterFadeIn()
{

field=Random(1); //decide which field will be attacked.
position=Random(1); //decide from which position/direction the enemy attacks
if(position==0)
? {gattack.x=...; //place the attackgui in the corresponding field.
? cEnemy.LockView(...);//Lock enemy into the right frame to attack from that position
? cEnemy.x=...;
? cEnemy.y=...;}//place the Enemy to attack from the right direction
else
? {gattack.x=...;
? cEnemy.LockView(...);
? cEnemy.x=...;
? cEnemy.y=...;}

Level[1]=Timer.Start(120);//Set Timer "Level" array 1 (stands for Level 1) to three seconds before the enemy attacks.

}


And In the Global Script:

Code: ags

// main global script file
Timer*Level[10];//Timer called "Level" to define time before enemy attacks for each level, created with Crimson Wizard's module. Level timer is exported to Global Header script
Timer*Hit;// Timer used define how long enemy stays in hitting/attack view
Timer*Waittimer[10];//Timer used when I want non-blocking Waiting time
bool avoidwrongtrigger[100];//this bool will help me differentiate different functions that are set off when the enemy finds himself on specific coordinates (see below)

function? repeatedly_execute_always() 
{

if(Timer.IsExpired(Level[1]))
? {gattack.x=-1000;//put gui out of screen
? if(field==0) 
? ? {cEnemy.move(x0,y0,eNoBlock...);//move enemy to attackpoint of field 0. The main character still has to be able to move around, so I need to do it non-blocking.
? ? avoidwrongtrigger[0]=true;}
? else 
? ? {cEnemy.move(x1,y1,eNoBlock...);//move enemy to attackpoint of field 1.
? ? avoidwrongtrigger[1]=true;}
? }

if((cEnemy.x==x0&&cEnemy.y==y0&&avoidwrongtrigger[0]==true)||(cEnemy.x==x1&&cEnemy.y==y1&&avoidwrongtrigger[1]==true))//if the enemy crosses x[sub]0[/sub],y[sub]0[/sub] or x[sub]1[/sub],y[sub]1[/sub] at any other point in the game accidentally I don't want this function to be triggered, that's why I use the avoidoverlap bool
? {
? for(n=0;n!=2;n? )
? {avoidwrongtrigger[n]=false;} //set all avoid bool arrays to false (important for later levels with more fields)
? if(field==playerfield)life=life-1;//if the character finds himself in the same field as the the attacked field he looses a life
? attackable=true;
? cEnemy.LockView(...);//Lock enemy into hitting/attacking view
? Bite=Timer.Start(40);//Start timer to unlock hit/attack view after 1 second
? cEnemy.Move(x2,y2,eNoBlock);//move enemy out of screen again
? }
//defining in which field the player finds himself in:
//level on is very easy. The screen resolution is 1600x900,so:

if(currentlevel==1)//the fields change for the upcoming levels
?? {if(cm.x<801) playerfield=0;
?? else playerfield=1;}

//how to proceed after the attack

//If both still have lifes:
if(life!=0&&enemylife!=0) Waittimer[1]=Timer.Start(40);

if(Timer.IsExpired(Waittimer[1]))
{//same script as above
field=Random(1); //decide which field will be attacked.
position=Random(1); //decide from which position/direction the enemy attacks
if(position==0)
? {gattack.x=...; //place the attackgui in the corresponding field.
? cEnemy.LockView(...);//Lock enemy into the right frame to attack from that position
? cEnemy.x=...;
? cEnemy.y=...;}
else
? {gattack.x=...;
? cEnemy.LockView(...);
? cEnemy.x=...;
? cEnemy.y=...;}
attackable=false;//make it so that you cannot attack the enemy again, until he reaches the attack point.
Level[1]=Timer.Start(120);//Set Timer "Level" array 1 (stands for Level 1) to three seconds before the enemy attacks.
}

//if player looses

if(life==0)gLoose.Visible=true;//Shows a full screen gui that pauses the game when visible. You have a funny YOU LOST image and two buttons: Quit or Retry. When you quit you change to the menu room. And when you click retry:

function Retrybutton_OnClick(GUIControl *control, MouseButton button)
{
life=3;
enemylife=3;
Waittimer=Timer.Start(1);
}

//if enemy looses

gWin.Visible=true; //Full screen gui that is as well a button. Any click on the gui will start Level two. (resetting lifes and everyting, and now starting Level[currentlevel 1]-timer)


THE COUNTERATTACK

For the counterattack I have a function that is triggered when clicking on the enemey.
In Global script I made it so that whenever you left click, the Usermode1 (mousemode8) Mouseclick is triggered at the mouse-coordinates.

So when clicking on the enemy this is what happens:
Code: ags

function cEnemy_Mode8()
{
if(attackable==true)
{
cplayer.Lockview(attackviewID);
cplayer.SetWalkspeed(50,50);
cplayer.Walk(cEnemy.x,cEnemy.y,eBlock);
aEnemyscream.Play(...);
enemylife=enemylife-1;
cplayer.Lockview(normalflyviewID);
cplayer.Walk(cEnemy.x,cEnemy.y,eBlock);
cplayer.Animte(cplayer.Loop...,eRepeat);//keep flapping the wings while in the air
}
else{}


[close]

The life bar
Spoiler


The life bar I want to create with a gui.
Every heart will be one button with a heart graphic.

Another function I will run in repeatedly execute in global script then will be:

Code: ags

function repeatedly_execute_always() 
{
if(life==0)
? {Button1.Visible=false;}
else
? {Button1.Visible=true;
? if(life==1)
? ? {Button2.Visible=false;}
? else
? ? {Button2.Visible=true;
? ? if(life==2)
? ? ? ? {Button3.Visible=false;}
? ? else
? ? ? ? {Button3.Visible=true;}
? ? }
? }
}

And then I repeat that with int monsterlife.
[close]

SMF spam blocked by CleanTalk