So sorry but I'm so so lost

Started by Salamdandersad, Wed 23/10/2024 22:51:07

Previous topic - Next topic

Salamdandersad

I'm really sorry. But I'm very lost, and there aren't any tutorials for AGS in my language, and the ones that exist are too technical or directly advanced.

I'm trying to create a puzzle, a wall with the Einstein game (the typical puzzle where, based on some clues: John lives in the yellow house, the American is John, the Spaniard doesn't live next to the American, the one who buys the newspaper is two houses to the left of the one who buys the magazines... and based on those clues, you have to locate each person, house, nationality...)

The idea is that each element appears on a digital screen, and when you press a button, it changes until it's correct (it's verified to be correct by clicking a hotspot).

I tried doing it roughly, checking that each sprite is in a specific location, and it doesn't work. But from what I read in the guide, there are "arrays," but I'm not quite understanding how they work. Can someone help me with that?

eri0o

#1
Spoiler
OK, let's start with the basics and see if you are talking about something like Logic Grid Puzzles. Example below

QuotePuzzle Description:
Lucy is a sought-after cake maker in the friendly small town of Plumpton. There aren't enough residents in the town to run her business full-time, so she bakes and decorates the cakes in the evenings after her main job. Tomorrow night, Lucy will be busy with three cakes to prepare - all different flavors and occasions!

From the clues given, can you determine which client (identified by first name) ordered which type of cake, what the occasion is, and the price each customer will pay?

Clues
  • Emma ordered carrot cake for an event she is hosting at her home, but it did not cost $37.00.
  • Attendees of the farewell party will each be enjoying a big slice of vanilla cake.
  • The cake Michael ordered cost $2.00 less than the cake that is for a birthday.
  • The chocolate cake is Lucy's specialty, which she currently has discounted to $35.00.





It looks like it depends a lot on the size of the grid you wish to make if it's something like this. Essentially you would need to support three states per "cell" in the grid. I guess it also depends on the resolution of what you are doing - like, if it's anything above 320x200 I would suggest to avoid using dynamic sprites. Can you give at least a drawing of the scale of what you want to make?
[close]

Actually I don't think I understand what is Einstein game. I really wish people used more images here... Googling for Einstein game it appears its something like Simon says. I am a bit confused, there appears there is also a weird board game. I put in spoiler because I skipped the Einstein game on the first read of your question and read the description that happens later.

Khris

#2
I'm 99% sure OP is talking about the thing from the spoiler, however there's a slightly easier version of this where you don't need the triangle diagram, just a basic table.

        |  Color  |  Name  |  Country  |  buys
----------------------------------------------------
House 1  | yellow  |  John  |  USA      |
----------------------------------------------------
House 2  |        |        |  Spain    | newspaper
----------------------------------------------------
House 3  |        |        |          |



So we're talking about a bunch of interactive areas where a click loops through a bunch of possible String values.

To display text on screen, we can use
a) a label or a button on a transparent GUI
b) a textual Overlay
c) the DrawString function to directly draw to the room background or a dynamic sprite

Since we also need to be able to click the text, a button is a straightforward solution. The downside is we need to create 16 or 20 buttons manually.

I'd use a single hotspot covering the clickable area to detect the click and option c) to display the text.

We also need a way to store the table's state. This can be done using an array of ints the size of which is the number of interactive cells.

Let's start with a bunch of variables:

Code: ags
#define ROWS 4 // four houses
#define COLS 4 // color, name, country, article
#define CELLCOUNT 16 // ROWS * COLS

int cellValue[CELLCOUNT]; // one integer for each cell: -1 is empty, 0 = first option, 1 = second option, etc.
String options[CELLCOUNT]; // # of total options == # of cells

// table's room coordinates
int offsetX = 40, offsetY = 60; // coordinates of the top left corner of the first clickable cell
int cellWidth = 70, cellHeight = 20; // cell size

// sprite to store room background
DynamicSprite* backup;

Next, we need to set the possible options and all cells to empty (don't forget to create this function via the room's event table!):

Code: ags
function room_Load() {
  options[0] = "yellow";
  options[1] = "red";
  options[2] = "green";
  options[3] = "blue";
  options[4] = "John";
  // ...
  options[8] = "USA";
  options[9] = "Spain";
  // ...
  options[12] = "magazines";
  options[13] = "newspapers";

  for (int i = 0; i < CELLCOUNT; i++) cellValue[i] = -1;
  backup = DynamicSprite.CreateFromBackground();
}

Handling a hotspot click works like this:
Code: ags
function hTable_AnyClick(Hotspot* theHotspot, MouseButton button) {
  // calculate clicked row and column from mouse coordinates
  int col = (mouse.x + Screen.Viewport.X - offsetX) / cellWidth;
  int row = (mouse.y + Screen.Viewport.Y - offsetY) / cellHeight;
  // change cell value
  int i = row * COLS + col; // array index
  cellValue[i]++; // move to next option
  if (cellValue[i] == ROWS) cellValue[i] = -1; // if cell contained last option, set to empty
  UpdateCells();
}

This requires a function further up in the script:
Code: ags
void UpdateCells() {
  DrawingSurface* ds = Room.GetDrawingSurfaceForBackground();
  ds.DrawImage(0, 0, backup.Graphic); // restore room bg (i.e. empty table)

  // cell contents
  ds.DrawingColor = Game.GetColorFromRGB(123, 45, 74); // font color
  for (int row = 0; row < ROWS; row++) {
    for (int col = 0; col < COLS; col++) {
      int i = row * COLS + col; // array index
      if (cellValue[i] > -1) {
        String text = options[col * ROWS + cellValue[i]];
        int x = col * cellWidth + offsetX + 2; // some padding
        int y = row * cellHeight + offsetY + (cellHeight - GetFontHeight(eFontFont0)) / 2;
        ds.DrawStringWrapped(x, y, cellWidth, eFontFont1, eAlignCenter, text);
      }
    }
  }
  ds.Release();
}

NOT TESTED!

Edit:
Solution check to follow, if this works.
@Salamdandersad please edit your first post and change the title to something descriptive like "Creating a table with clickable cells"

Edit 2: fixed a few small errors

Salamdandersad

Quote from: eri0o on Thu 24/10/2024 00:59:59
Spoiler
OK, let's start with the basics and see if you are talking about something like Logic Grid Puzzles. Example below

QuotePuzzle Description:
Lucy is a sought-after cake maker in the friendly small town of Plumpton. There aren't enough residents in the town to run her business full-time, so she bakes and decorates the cakes in the evenings after her main job. Tomorrow night, Lucy will be busy with three cakes to prepare - all different flavors and occasions!

From the clues given, can you determine which client (identified by first name) ordered which type of cake, what the occasion is, and the price each customer will pay?

Clues
  • Emma ordered carrot cake for an event she is hosting at her home, but it did not cost $37.00.
  • Attendees of the farewell party will each be enjoying a big slice of vanilla cake.
  • The cake Michael ordered cost $2.00 less than the cake that is for a birthday.
  • The chocolate cake is Lucy's specialty, which she currently has discounted to $35.00.





It looks like it depends a lot on the size of the grid you wish to make if it's something like this. Essentially you would need to support three states per "cell" in the grid. I guess it also depends on the resolution of what you are doing - like, if it's anything above 320x200 I would suggest to avoid using dynamic sprites. Can you give at least a drawing of the scale of what you want to make?
[close]

Actually I don't think I understand what is Einstein game. I really wish people used more images here... Googling for Einstein game it appears its something like Simon says. I am a bit confused, there appears there is also a weird board game. I put in spoiler because I skipped the Einstein game on the first read of your question and read the description that happens later.

More or less, and simpler. But yes, the idea is that there are clues that help you locate each person (or anything) indirectly from direct statements

Crimson Wizard

#4
Quote from: Khris on Thu 24/10/2024 09:10:51@Salamdandersad please edit your first post and change the title to something descriptive like "Creating a table with clickable cells"

I wanted to post the same, please do not create topics called like "I need help", give them names which tell what you need help with instead. This will let other people identify questions and to search for similar topics.


Khris have already posted one possible solution above.
But I would like to post a general advise on how to approach such problems (I posted similar thing in many topics around the forum, but it's worth to repeat):


When you have a complex problem, you may easily get lost in all the details.
It's essential to divide it in smaller subtasks, and decide how do you want to design each of them. Then go over them step by step, see which parts you already know how to do, and which not.

1. Explain the puzzle logic "on paper" in human language (real paper, or text file), step by step. The point here is to make it clear to yourself, and to others (if you ask others for help), how the puzzle works.

2. Try to distinguish puzzle elements: what does it consist of, how the player is supposed to interact with it, how do you tell when the puzzle is solved?

3. Now, going into the game engine (AGS) find out how you may describe the puzzle's current state in script. Which variables to use, do you need simple variables or arrays, or structs, and so forth. The more you learn about the scripting language, the easier it will be for you to find better solution.

4. Find out how to present the puzzle's state on screen. Which game objects do you use for that? Do they have to be interactable, or only there for display? that matters.

5. Handle player's input: how the puzzle is controlled, what happens when player clicks here or there.

6. Handle success detection: how do you test that the puzzle have reached the correct state.


I advise practicing this general approach, starting with simpler puzzles, and then taking on more complex ones as you learnt.

Salamdandersad

Hello everyone, thank you for the help. I tried using the method that user Khris suggested, but I wasn't able to make it work. In the end, I did it in a more brute-force way: I created several objects, each object could change its sprite with a hotspot, and once each object matched the correct sprite, another hotspot would check that variable. If object1 = sprite2, it would give a correct message; if it didn't match the expected sprite, it would give a negative response.

Code: ags
int currentSprite = 6;  // Inicialmente empieza con el sprite 12
int spriteStart = 6;    // Primer sprite de la secuencia
int spriteEnd = 25;      // Último sprite de la secuencia

function hHotspot1_Interact() {
    // Cambia el sprite al siguiente
    currentSprite++;

    // Si hemos llegado al último sprite, volvemos al primero
    if (currentSprite > spriteEnd) {
        currentSprite = spriteStart;
    }

    // Actualiza el sprite del objeto
    oObject0.Graphic = currentSprite;
}



function hHotspot2_Interact(Hotspot *theHotspot, CursorMode mode)
{
// Cambia el sprite al siguiente
    currentSprite++;

    // Si hemos llegado al último sprite, volvemos al primero
    if (currentSprite > spriteEnd) {
        currentSprite = spriteStart;
    }

    // Actualiza el sprite del objeto
    oObject1.Graphic = currentSprite;
}

function hHotspot3_Interact(Hotspot *theHotspot, CursorMode mode)
{
// Cambia el sprite al siguiente
    currentSprite++;

    // Si hemos llegado al último sprite, volvemos al primero
    if (currentSprite > spriteEnd) {
        currentSprite = spriteStart;
    }

    // Actualiza el sprite del objeto
    oObject4.Graphic = currentSprite;
}

function hHotspot4_Interact(Hotspot *theHotspot, CursorMode mode)
{
// Cambia el sprite al siguiente
    currentSprite++;

    // Si hemos llegado al último sprite, volvemos al primero
    if (currentSprite > spriteEnd) {
        currentSprite = spriteStart;
    }

    // Actualiza el sprite del objeto
    oObject5.Graphic = currentSprite;
}



function BotonVerificador_Interact(Hotspot *theHotspot, CursorMode mode)
{
// Verificamos si los sprites de los objetos coinciden con los valores deseados
    if (oObject0.Graphic == 15 &&    // 
        oObject1.Graphic == 10 &&    //
        oObject4.Graphic == 19 &&
        oObject5.Graphic == 25) {    // Aquí poner todos los objetos y sprites vinculados
           
        // Si todos los objetos tienen los sprites correctos, ejecuta la acción
        Display("¡Has desbloqueado la puerta!");  // Muestra un mensaje en pantalla
         //(configurar) Cambia el sprite de la puerta para que parezca abierta (ejemplo)
        // También podrías reproducir un sonido o activar un cambio de habitación:
        // PlaySound(1);  // Reproduce un sonido de puerta abriéndose (si has importado el sonido)
    } else {
        // Si los sprites no coinciden, puedes dar un mensaje de error o hacer otra cosa
        Display("La puerta está cerrada, intenta de nuevo.");
    }
}


SMF spam blocked by CleanTalk