Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - johanvepa

#1
Thank you both very much.

crimson: I am aware of the array starting at 0. It's just easier on my eye to work with code beginning at 1, so I don't assign anything to 0.

Khris:
I noticed it only pops up if I assign values to trash[1] (and so on) in game_start. Crash occurs right after room_load in room 1. Any ideas what might be causing it?

Other than, of course, that elsewhere the script sets it to null.
#2
I just can't seem to get arrays right.

I am trying something that should be real simple and works if I just name all the characters one after the other, but I want to do it using arrays.

Whats wrong with this simple piece of code?? I am told there's a null pointer reference. But I assigned a value to the pointers. I don't understand.

In globalscript:
Code: ags
Character *trash[12];
int trashcounter;

function removetrash()
{
  trashcounter = 1;
  while (trashcounter < 3)
  {
    if (trash[trashcounter].Frame == 4)
    {
      trash[trashcounter].x = 1;
      trash[trashcounter].y = 1;
      trash[trashcounter].Frame = 0;
    }
    trashcounter ++;
  }    
}

function repeatedly_execute() 
{
  removetrash();
}

function game_start() 
{
  trashcounter = 1;
  trash[1] = cAffald1;
  trash[2] = cAffald11;
  trash[3] = cAffald12;
}


#3
Last one for the evening (roll)

At a certain point in my game, I'd like a certain character to animate while moving towards another character. Not the walk command, since the animation is to be done only once (if it repeats it'll look silly). The animation is that of disappearing into the other character.

trash is a Character variable. itemcarried determines if the relevant other character is currently in position. This all works.

Code: ags
function catchtrash()
{
  if ((trash != null) && (trash.Frame == 0) && (itemcarried != cTrashbin))
  {
    trash.ChangeView(2);
    trash.Animate(1, 4, eOnce, eNoBlock, eForwards); //nÃ¥r animation er bagved move, vil den ikke move
    trash.Move(cTrashbin.x, cTrashbin.y, eNoBlock, eAnywhere); //nÃ¥r move er bagved animation, sker der noget med animation
    cTrashbintimer = 0;
    GiveScore(1);
    bScore.Text = String.Format("%d", game.score);
  }
}


If trash.animate is set to operate after trash.move, then it animates but doesn't move. This is explained in the manual that the move command is stopped by the animate command. So that makes sense. I try to get around it by putting trash.animate before trash.move.

The strange things:
If trash.animate is set to operate before trash.move, then the trash moves and animates, but it animates twice. First it animates while moving, then it animates again.

There are several characters that can be the variable trash. If the function operates first on one of these characters, then another, then the first character to be 'trash' will operate as described, moving but animating twice. If another character is then subject to being 'trash', then the animation first plays without moving, then it moves while animating again, and finally it animates a third time.

Any thoughts?
#4
I was already at a solution with checking the frame property of the character in rep_exec. The question was if it was possible to avoid this. But no matter, I got a working solution now. Thank you both.
#5
That was the idea. I just wondered if it was possible to avoid this.
#6
Thank you for the suggestion. I opted for a clumsy solution of having two more characters present, one flat and one tall, invisible, then check for collission with all three. This mimics collission with the visible parts of the character in question.

The mod is no longer there, by the way.
#7
Somewhere in my script I wisd to use an animation that does not block the whole script from continuing, but I would like some things to wait for the animation to end. Like, in my tower game I have this for whenever the character cAffald1 is hit and should first do its little death animation, then be placed somewhere else "out of the game".

Code: ags
function cAffald11_Look()
{
cAffald11.StopMoving();
cAffald11.ChangeView(2);
cAffald11.Animate(0, 4, eOnce, eNoBlock, eForwards);
a4.Play();
GiveScore(1);
bScore.Text = String.Format("%d", game.score);
cAffald11.x = 1;
cAffald11.y = 1;
}


What happens here is that cAffald1 moves to x=1, y=1 immediately and I cannot see its death animation. But if I use eBlock, then everything else stops, which is not good.

I could put something in rep_exec_always, but that seems and unsatisfactory solution to some other way to make the execution of function cAffald11_Look() simply wait its turn.

How to?
#8
Is there an easy way to determine if the visuals of two characters are overlapping? Like AreThingsOverlapping, but without being triggered by transparent parts of the characters?
#9
So I should write cTrashbin.ID? Because that is an integer, a numeric constant created by AGS. Allright, got that. It's damn hard to remember all these things, but it' still fun.
However, a nother problem just popped up. I try to determine if two characters are overlapping and I would expect that condition to be true when the graphics are actually touching each other, visually. These characters are just big circles, so its plain to see that they're 'overlapping' the moment the outer borders of their respective square 'boxes' touch, even though these parts of the characters are transparent. Do parts of characters that are transparent also set off 'AreThingsOverlapping'?



EDIT: I just read the manual. Of course they do. Sorry. And thank you for your help, wizard
#10
I read that.
In the example it shows us that it is suitable to write EGO.
What, then, is the CHARID of "cTrashbin" if not "cTrashbin"?

#11
I am doing a check to see if things are overlapping. I have two character, one stationary called ctrashbin, and one moving, called cAffald1. Every game cycle, I wish to see if they overlap, then something happens.

Code: ags
  if (AreThingsOverlapping(cTrashbin, cAffald1))


When trying to compile, I am told there is an error at the line: Cannot convert 'Character*' to 'int'.

Me no unnerstand?
#12
Wait, this time I got it (roll)

cTrashbin must be turned unclackable when it is picked up.

Two places must it be made clickable again: When it is 'placed' at cBrikker2, and when it is released and tgherefore returns to its place of origin.

This works.


Edit: I forgot to say thank you. Thank you Crimson    ;)
#13
Wait, the problem was something else. I'm trying to ProcessClick at the character cBrikker2, but when the character being dragged (cTrashbin) is dragged by the mouse and is therefore at the same place as the mouse, naturally AGS is attempting to ProcessClick at the charcter cTrashbin instead of the character cBrikker2, since cTrashbin is above cBrikker2! cTrashbin is overshadowing cBrikker2.

How to solve this?

I could change the mouse cursor image to that of cTrashbin and make the real cTrashbin invisible. But that is somewhat impractical to code.

I could try to switch off cTrashbin. This was unsuccesful (same as line 31-34 of localscript in the code described earlier)=:
Code: ags
      if (IsInteractionAvailable(mouse.x, mouse.y, eModeInteract)) //if mouse coordinate (not item coordinate) is above a place where interaction is possible (in the script, a character that may be interacted with)
      {
        cTrashbin.Clickable = false;
        ProcessClick(mouse.x,mouse.y, eModeInteract);//then run the eModeInteract script with that character
        cTrashbin.Clickable = true;
      }


#14
In my little tower defense game, I want a feature where one can pickup items (made as Characters in AGS, not objects or inventory items) and drag them (mouse button held down) to another part of the screen, then drop them there (release mouse button). If the intended place for drop is not suitable, the item returns to its place of origin.

This is simple enough. I couldn't find a feature already in AGS that does this, so I did the following:

In globalscript:
Code: ags
Character *itemcarried;
export itemcarried;

function cTrashbin_PickUp()
{
itemcarried = cTrashbin;
}

function cBrikker2_Interact()
{
  if (itemcarried == cTrashbin)
  {
    cTrashbin.x = cBrikker2.x;
    cTrashbin.y = cBrikker2.y;
    itemcarried = null;
  }
}


In local script:
Code: ags

import Character *itemcarried;

function room_RepExec()
{

    //to pick stuff up and let it follow the mouse cursor
  if (mouse.IsButtonDown(eMouseLeft)) //if button is down, something is supposedly being carried
  {
    if (itemcarried == null) //in the instance nothing yet is assigned as the item carried :
    {
      if (IsInteractionAvailable(mouse.x, mouse.y, eModePickup))//if something is there to be picked up (in the globalscript this is possible for the cTrashbin):
      {
        ProcessClick(mouse.x,mouse.y, eModePickup); //in the event script for cTrashbin, this assigns cTrashbin as 'itemcarried', item will no longer be == null:
      }
      else //else if nothing is there to pick up, do no more about the mouse cursor pressed down:
      {
        return(0);
      }
    }
    else //if button is down and something is assigned as the item to be carried
    {
      //then each game cycle, the itemcarried's coordinates should be the mouse coordinates
      itemcarried.x = mouse.x;
      itemcarried.y = mouse.y; //The issue: when assigning the mouse y-coordinate as the itemcarried's room y-coordinate, the two does not match. I need to adjust value for the item's room y-coordinate
    }
  }
  else //if noone is holding the mouse button down
  {
    if (itemcarried != null) //in the instance a character is assigned as the itemcarried but the mousebutton is not down. This will happen if someone is releasing the mouse button after carrying stuff
    {
      if (IsInteractionAvailable(mouse.x, mouse.y, eModeInteract)) //if mouse coordinate (not item coordinate) is above a place where interaction is possible (in the script, a character that may be interacted with, i.e. the character cBrikker2)
      {
        ProcessClick(mouse.x,mouse.y, eModeInteract);//then run the eModeInteract script with that character
      }
      else //in the instance there is an item assigned to Character *item but there is nothing to interact with at the place the mouse button is released
      {
        itemcarried.Move(cBrikker1.x, cBrikker1.y, eNoBlock, eAnywhere); //move the item back to starting point
        itemcarried = null; //no 'item carried' any more
      }
    }
  }

//any other business
}


This works fine.


Issue
The background is larger than the screen to allow for characters walking in from outside the screen boundaries. So I have to add 95 to the y axis and lock viewport.

In order for 'Character *item' (in the example cTrashcan) to appear alongside the mouse cursor, and not 95 pixels away from it, I have to add to the y axis assigned to the coordinates of itemcarried in the above script.

And so, this part of the code
Code: ags
    else //if button is down and something is assigned as the item to be carried
    {
      //then each game cycle, the items ccordinates should be the mouse coordinates
      itemcarried.x = mouse.x;
      itemcarried.y = mouse.y; //Problem: when assigning the mouse y-coordinate to the item's room y-coordinate, the two does not really match. I need to add some value to the item's room y-coordinate
    }

could look like this to adjust the itemcarried's room coordinates:
Code: ags

    else //if button is down and something is assigned as the item to be carried
    {
      //then each game cycle, the items ccordinates should be the mouse coordinates
      itemcarried.x = mouse.x;
      itemcarried.y = mouse.y+110; //Problem: when assigning the mouse y-coordinate to the item's room y-coordinate, the two does not really match. I need to add some value to the item's room y-coordinate
    }


This should be simple. It works, meaning that itemcarried now appears alongside the mouse cursor. Problem: For some reason, the interaction with the character cTrashbin that in globalscript should trigger this:
Code: ags
function cTrashbin_PickUp()
{
itemcarried = cTrashbin;
}

just doesn't happen. Instead, the itemcarried returns to its poont of origin, as if there was nothing to interact with at the mouse coordinates.

If I take away "+110" from the itemcarried's room coordinates again, then it works fine.

Seemingly, the change in the room coordinates of 'itemcarried' changes how the mouse cursor interacts, but th emouse cursor's coordinates are not changed, only cTrashbins room coordinates are changes. I don't understand.

#15
Thanks for the pointer Khris ;)
#16
Quote from: Khris on Thu 22/09/2016 12:04:39
Also note that this code will break as soon as you add a scrolling room.

Use this:
Code: ags
  if (Region.GetAtRoomXY(mouse.x + GetViewportX(), mouse.y + GetViewportY()) == Region[1])


That was exactly the issue in this thread.
#17
I might want to use animated cursors, that is why I check mouse.Mode
#18
The issue here was the mouse coordinates. I added Space on each side of the room's borders and locked ViewPort, in order to allow for the little monsters to walk in from outside the boundaries of the screen. Didn't think about this changing what coordinates the mouse had.

Also, the room is very simple indeed (game is made on the blank template, too) so I doubt there are any actual performance issues once I apply the necessary changes to mouse coordinates. But good idea with the Region variable, less code to handle.

Thank you both.

#19
I am making a simple tower defense game, and a feature is that the mouse cursor changes with whatever region it is hovering over. The code is this:
Code: ags

function room_RepExec()
{
  if (Region.GetAtRoomXY(mouse.x, mouse.y) == region[1])
  {
    if (mouse.Mode != eModePickup)
    {
      mouse.Mode = eModePickup;
    }    
  }
  if (Region.GetAtRoomXY(mouse.x, mouse.y) == region[3])
  {
    if (mouse.Mode != eModeLookat)
    {
      mouse.Mode = eModeLookat;
    }
  }


This works, but with huge performance issues. The mouse cursor does not always change, it stays in eModePickUp even when hovering over region [3]. After a while it changes, so the code is recognized, but it takes long time for the game to realize. The issue is varying, sometimes it changes more quickly than other times.
Any ideas?
#20
Checked case settings. Thanks (laugh)
SMF spam blocked by CleanTalk