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 - Khris

#301
You mean like you're pressing F5 in the editor, and after the message, the editor crashes?
Have you tried pressing F7 instead? Then running the game from the Compiled folder?
#302
It sounds like you want a button for each item. This is possible but not necessary, all you need is the sprite slot for each item, then put the associated image on a single, static button.

Let's say you've created the description image for iTickets and imported it into AGS. It ends up being sprite #73.
To show the correct image when the player is hovering over iTickets, you want to display sprite 73.
The easiest way to display an image in a GUI is to add a button to the GUI, make it "dead" (i.e. not react to clicks / hovering) and set the sprite as the button's .NormalGraphic.

Let's assume the button is called "btnItemDesc".
What we now want is code that essentially does btnItemDesc.NormalGraphic = 73; if the currentItem is iTickets.
That code is also supposed to use a different image / sprite slot number, when currentItem is iBlender, and so on.

The long way to do this is:
Code: ags
  if (currentItem == iTickets) btnItemDesc.NormalGraphic = 73;
  else if (currentItem == iBlender) btnItemDesc.NormalGraphic = 74;
  // ... lots more of the same duplicate mess here

This is incredibly ineffective obviously, given that we can use a single line instead. This requires to somehow get from currentItem == iTickets to 73, but also from currentItem == iBlender to 74, same for the rest of the items. The ideal system is always one that requires as few changes to existing code as possible when you add or change something elsewhere, ideally zero changes.

There are multiple ways to do this. Using a table where AGS can look up the number is one way, this is implemented using an array of integers.

Another way is to use specific numbers for the sprites and basic addition (this is a new solution I somehow didn't mention yet). After importing a sprite, you can change its slot number by right-clicking it. You can now pick any unused slot. Assuming iTickets is the first inv item and thus its ID is 1, you can change the slot number of the description sprite to for instance 101. Or 501. Doesn't really matter, as long as the difference between an item's ID and the associated sprite slot is always the same. (I'll use 100 for the example code below)

Now in the code we can do this:
Code: ags
    if (prevItem != null) {
      // Mouse OFF the PREVIOUS item
      // cleanup here, possibly only if currentItem == null
      btnItemDesc.Visible = false; // we actually want to hide the button here
    }
    if (currentItem != null) {
      // mouse OVER CURRENT item
      // display info GUI, etc.
      btnItemDesc.NormalGraphic = currentItem.ID + 100; // we no longer need an array
      btnItemDesc.Visible = true; // show button
    }

(To clarify the meaning of "current" and "previous" item, this is in the context of a single frame, i.e. 1/40th of a second by default; "currentItem" is the item under the mouse in the current frame, "previousItem" is the item under the mouse 1/40 seconds ago)
#303
Average.

Wordle 567 4/6

⬜⬜⬜⬜🟨
⬜🟨🟨⬜⬜
🟩🟨⬜🟨⬜
🟩🟩🟩🟩🟩

Spoiler
STARE
CLOUT
LOVED
LEMON
[close]
#304
I'm sorry, but can you clarify what you're asking for exactly?
The solution to this issue is to either
a) create an array of dynamic sprites so each overlay has its own
b) use the clone option so each overlay has its own

The github post seems to just restate the original problem, which in my book is thoroughly analyzed and solved already?
#305
My original code assumed that hovering an item would
a) display a sprite on a GUI button
and
b) display text via a GUI label

a) requires storing a sprite slot for each inv item
b) requires storing a string for each inv item

Hence two arrays, an int one for the sprite slots, and a string one for the texts.

There's three issues with
Code: ags
bWindowTickets.NormalGraphic = image[34]
1. no semi-colon at the end of the line
2. a hard-coded 34, which makes no sense, since the code/line is supposed to work for each item dynamically
3. unembedded, which will not work at all; assignments can only happen inside functions

The statement should go in line 12 of my original reply, and it should use currentItem
#306
Yeah, fixed.

The idea is to store a sprite slot (integer) for each item. You can do this via custom properties, or via an array. If you use an array, you can use the inv item's ID as array index.

The array code doesn't need anything else, the right side is just a single element of the image array, i.e. the sprite slot.

int image[20]; creates 20 integers, image[0] to image[19].
If the keycard has an ID of 3, line 5 becomes image[3] = 123;
Later, when the player is hovering over the keycard and thus currentItem == iKeycard, this number is now read back and assigned as NormalGraphic to the button.
#307
What's happening here is you tried to use a single DynamicSprite to create multiple persistent overlays all showing different sprites.
I get VERY sad when somebody blames the tools.
#308
You can read the value by accessing game.previous_game_data but you can simply not do that. Which means the number you put in the call doesn't matter at all. This isn't a big deal.
#309
You shouldn't have to use multiple GUIs for this. Say you have a single GUI with a button (btnImage) and a label (lblDescription).

You can now do this:
Code: ags
  btnImage.NormalGraphic = image[currentItem.ID];
  lblDescription.Text = text[currentItem.ID];

This requires two arrays populated by you in game_start, like:
Code: ags
int image[20];
String text[20];

function game_start() {
  image[iKeycard.ID] = 123; // keycard sprite
  text[iKeycard.ID] = "It's the keycard you found in the dining room.";
  // etc.
}

You can also use custom properties for this; add two properties that apply to inventory items only, an integer ("image_slot") and a text one ("description"). Then just enter the info in there for each item. Finally, use these lines instead:

Code: ags
  btnImage.NormalGraphic = currentItem.GetProperty("image_slot");
  lblDescription.Text = currentItem.GetTextProperty("description");
#310
I'm pretty sure I just missed something; I looked at the code again and it branches inside the loop, also creating overlays from static sprites. Just a few of them are flipped and they basically all end up being blue cups as far as I can tell.
#311
Here's how to detect the two relevant events ("cursor moves on top of item X", "cursor leaves item X"):

Code: ags
// add this above the repeatedly_execute_always function, if it exists
InventoryItem* prevItem;
function handle_inv_images() {
  InventoryItem* currentItem = InventoryItem.GetAtScreenXY(mouse.x, mouse.y);
  if (currentItem != prevItem) {
    if (prevItem != null) {
      // mouse was moved away from prevItem
      // cleanup here, possibly only if currentItem == null
    }
    if (currentItem != null) {
      // mouse was moved over currentItem
      // display info GUI, etc.
    }
  }
  prevItem = currentItem;
}

Code: ags
// this function might already exist, otherwise simply add it
function repeatedly_execute_always() {
  handle_inv_images();
}
#312
The extremely crucial part that is missing from this thread is the fact that the code runs in a loop.

Combine this with the fact that an Overlay does not by default create a copy of the sprite and the reason for the bug is obvious: reusing the same single sprite pointer for several overlays like this means there will only exist two dynamic sprites, in this case #65 and #66.

The first free slot is 65, so running CreateFromExistingSprite() for the first time creates a new dynamic sprite in slot 65.
In the next loop iteration the command runs again, the first free slot is now 66. At the same time though slot 65 is freed because the only pointer to it has just been overwritten. So when the line runs for the third time, it re-uses slot 65.

The resulting overlays will eventually contain arbitrary sprites, arbitrarily flipped or not, since all overlays with the exception of the last two are still using a sprite slot that contains a completely unrelated sprite.*

Debugging this was not hard, I simply added a line that displays flipped.Graphic and moved the code to room_AfterFadeIn.

What I don't get is why all these overlays do not change their sprite as soon as the slot is repopulated with a new sprite, so it looks like the graphical overlay does somehow buffer the sprite even without the clone parameter?*

*I'm still not sure what exactly is happening tbh. But it's pretty safe to say that this is caused by user error, not an engine bug.

Edit:
I created a test game and created three overlays in a loop, using a single DynamicSprite pointer. Without cloning, the result is as expected: only the third overlay uses the sprite correctly, the other two appear as blue cups.
Flipping the 1st and 3rd sprite first also gives the expected result: it works fine if the overlay clones the sprite, without cloning I again get two non-flipped blue cups (because being flipped is a property of the Dynamic Sprite, not the overlay).
#313
If you want a complicated title / intro, make it a separate exe. You have my blessing :)
However what Cassie brought up is a very good counterpoint: if this is actually a menu screen that is supposed to appear when you pause the game, putting it in a separate exe is, you guessed it: bollocks ;-D

Also, the 51 is an integer. Like the manual entry explicitly states. An integer is a whole number, and you can use it to send some information to the 2nd game, like for instance the player's score, or their health, or how many toenail clippings they have in their inventory from the previous game.
#314
Phew.

Wordle 564 6/6

⬜⬜🟨🟨🟨
⬜🟨🟨🟨🟩
🟩🟩⬜🟩🟩
🟩🟩⬜🟩🟩
🟩🟩⬜🟩🟩
🟩🟩🟩🟩🟩

Spoiler
STARE
CLEAR
LASER
LAGER
LAMER
LAYER
[close]
:P
#315
The pathfinding algorithm shouldn't move the character outside a walkable area, ever.
How are you moving the character exactly? Standard WalkTo clicks / keyboard movement only?
#316
A player.ChangeRoom() call gets queued and only runs after the current function finishes. You need to change the entire approach.

You need to
1. move any loop variables outside the function so they retain their value
2. use a function that gets called each time the player enters a room

Like this:
Code: ags
int i = 0;

function on_event(EventType event, int data) {
  if (event == eEventEnterRoomBeforeFadein) {
    // do stuff inside the current room
    // ...
    // finally, schedule room change
    if (i < ARRAY_SIZE && liste_room[i] > 0) {
      player.ChangeRoom(liste_room[i]);
      i++;
    }
  }
}
#317
That's what I was afraid of: you want to do this because you don't know that there's a much easier way.
Maintaining two games and publishing two exes just because you want to add a title screen to a 70% finished game is also bollocks :)

Also, the data parameter is explained right inside the manual entry you mention:
QuoteDATA allows you to pass an integer through to the next game. The value you pass here will be accessible to the loaded game by it reading the game.previous_game_data variable.

The 51 is just an example value.

Anyway, this is known as the xy problem.
Instead simply ask "I have a game that is 70% done, how do I add a title screen to it?"
#318
You upload it elsewhere, then post the link.
OneDrive, Google Drive, Dropbox, Mediafire, etc.
#319
That link doesn't work for me; go here instead: https://jumpjack.github.io/oricutronJS/
Then click the link at the top (space1999-en.dsk).
#320
Very weird.

Are you positive what you're seeing is the overlay? What happens when you comment out all other drawing commands? None of this makes sense to me.
AGS shouldn't be able to draw the overlay after the function ends, but instead of no longer drawing the flipped one it draws the original one...?

I means as far as I can tell, if your original code had worked as intended you'd have created the overlay exactly on top of the sprite you're drawing on the background, which already raises one or two questions for me.

To clarify: what you describe is the sprite's non-flipped version (overlay) appearing right on top of the flipped version (part of background), correct?

Can you post a screenshot? Or better, upload a demo that replicates this?
SMF spam blocked by CleanTalk