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

Topics - bulka_tarta

#1
Hi!

This comes from a Discord chat, but I'm putting it here for future reference and hopefully someone will find it useful!
I was asking on Discord if there's a way to scroll a label in a GUI. eri0o suggested the approach which to take, and crimson wizard developed the code.

The idea here is to use a large label on a much smaller GUI. The GUI should be the size of area that you want the text to be visible on. Any part of the label that goes beyond the GUI will not be drawn to the screen. You can then add a slider which will move the label's position, and so revealing more text as you scroll.

crimson wizard was kind enough to work on the code to make the scrolling as nice as possible. You can see it in the snippet below.

Code: ags
int DEFAULT_LABEL_Y = 10;
int DEFAULT_PAGE_HEIGHT = 178;
int LABEL_LINE_SPACING = 1;

void DisplayQuest(String text)
{
    gQuestGui.Visible = true;
 
    lblQuestDetails.Text = text;
    int text_height = GetTextHeight(text, lblQuestDetails.Font, lblQuestDetails.Width + 1);
    int line_height = GetTextHeight("AAA", lblQuestDetails.Font, 100);
    int num_lines = text_height / line_height;
    lblQuestDetails.Height = text_height + (num_lines - 1) * LABEL_LINE_SPACING;
    
    lblQuestDetails.Y = DEFAULT_LABEL_Y;
    if (text_height <= DEFAULT_PAGE_HEIGHT)
    {
        sldQuestDetails.Visible = false;
    }
    else
    {
        sldQuestDetails.Visible = true;
        sldQuestDetails.Min = 0;
        sldQuestDetails.Max = lblQuestDetails.Height - DEFAULT_PAGE_HEIGHT;
        sldQuestDetails.Value = sldQuestDetails.Max;
    }
}

function sldQuestDetails_OnChange(GUIControl *control)
{
    lblQuestDetails.Y = DEFAULT_LABEL_Y -(sldQuestDetails.Max - sldQuestDetails.Value);
}


Again, big thanks to eri0o and crimson wizard for the help!
#2
Hi,

I have multiple buttons in my GUI, and all of them do fairly similar stuff. To avoid re-writing same code over and over in GlobalScript, I wanted to create a function which will be used by multiple buttons. The function detects which button you're clicking on, and based on that you can do various stuff.

The problem I'm having is that the game keeps crashing with "Null pointer referenced", and I have no idea how to fix this. I even simplified the code to just couple of lines to see if I made mistake elsewhere.

I tried running the following code in one function that is hooked to multiple buttons:
Code: ags

  GUIControl* button = GUIControl.GetAtScreenXY(mouse.x, mouse.y);
  if ((button.AsButton.NormalGraphic != 0) && (button != null)) //The game keeps crashing on this line
  {
    Display("It works");
  }


The most frustrating thing is that this code works half of the time! Once you can click on bunch of buttons and everything works, and sometimes the game just crashes.

Any ideas how to make this work? I don't really want to re-write lots of code over and over, but it seems like the only solution at the moment.
#3
Hey,

I've been recently playing around with a map screen for my game.
The main issue is that the desired map is much bigger then original game size (Game Resolution: 384x216, Map: 975x618) and because of that I struggle to decide on the best approach to set the whole thing up.

Brief idea behind the map's functionality is that you should be able to pan it around. The character does not directly move around the map, but rather it has various locations on top, which you can click to access info about it. A label of some sort would be in place to show the location's name.


I looked around on forums, and it seems that there are three possible approaches, but all with some disadvantages. I wonder if I'm missing anything, or if I just need to stick to one of them and accept certain quirks.

Map as a GUI - seems like the ideal approach for my needs. I can add locations as buttons. I can add lists for location names. Clicking on button can trigger related the stuff. The issue? As you may already figured it out, a GUI cannot be bigger than the game's size. Using this approach gives me a warning when playing the game, but other than that everything works as intended. I guess just ignoring the warning is not acceptable?

Map as a separate Room - at glance, this could be a good alternative for the GUI map. I can pan around with SetViewport(), locations could be in a form of hotspots/objects - I'm not entirely sure about the labels though. The main issue here seems to be more of a visual one - having the map in a separate room means that I will need to have the fade in/out effect when accessing the map. The way all of the GUI in the game is meant to work is that it has this "flow". When you switch between various menus, they slide from one to another, and having this one menu to have to fade in/out is just very out of place.

DynamicSprite Approach - from what I found on the forums, it seems to be a good idea to create a DynamicSprite for the map. From what I can understand you create a DynamicSprite, then create a copy and crop it. I imagine that you can later pan it around achieving the desired effect. However, it seems to me that adding locations or UI info (e.g. label with name) to the map would be a huge hassle. I guess you could create another DynamicSprites for each location on top of the map one, but to declare x,y positions for each location seems like a nightmare, where I can't easily see how the location presents itself on the map.



As already mentioned above, GUI approach would be my favourite, where I can easily move the buildings (buttons) on the map to make sure they look just fine. I can easily add labels, and trigger anything I may need when the building is clicked. I was wondering if there would be some kind of way to perhaps crop the GUI so it does't give me the warning message? So basically the GUI is larger than screen in the editor, but when you start the game the GUI size is cropped down and you can pan around when dragging.

Are there any other ways to deal with the maps in AGS that I missed? Perhaps there's something I missed about the any of the above approaches?
Any suggestions or pointers in the right directions are welcome!
#4
Advanced Technical Forum / Queue System
Wed 05/07/2017 22:43:45
Hi, I thought this question will be more complex and it felt like advanced section of the forum would be suitable - sorry if that's not the case!

I was playing around with AGS for a little while now, constantly trying to do some more complex bits of code.
I'm currently planning out on how to do a queue system in my project. Imagine a restaurant-type game, where you need to prepare burgers etc. You have various customers that come from left side, stop, the queue gets bigger and you can call each customer to talk to him. He walks up to the counter, orders stuff (through dialogue) and then goes away. There's a bunch of tricks though. I would like the customers to be different every time, and they order different stuff each time, so each customer needs to "hold" some (also random) information.

I'm trying to plan things ahead (I heard that's what real programmers do ;) ), and see what would be the best method to do all of this. I'm not sure if this questions isn't too broad at the moment, so I can always come back here later.

I'm thinking of creating a struct for the characters, so for example:
Code: ags

struct Client {
  String name;
  String foodType;
  int sprite;
  int gender;
};
import Client clients[MAX_CLIENTS];


And then set things up:
Code: ags

clients.name = "Bob";
clients.foodType = "burger";
clients.sprite = Random(10); //select random sprite from 10
clients.gender = Random(2); //1 = male   2 = female


I was thinking of creating two characters in the game: cMale and cFemale. Based on "gender" I decide (TBC how) if we are using cMale or cFemale, and based on the "sprite" I was thinking to use the number to attach the view to the character. I was thinking of using something like: vMale1, vMale2 etc and same for female. That way I could attach a random view to the character. My worry is that I won't be able to have cMale multiple times on the screen, right? In that case I would need cMale1, cMale2 etc? I'm planning to have up to 10 people in the queue at once.

Would a queue system like the one I described (or something similar) be possible in AGS?
I would really appreciate any pointers in the right direction.
#5
Hi,

I'm not sure if this is not going to be too advanced for "Beginners Forum", but I'm a beginner (in AGS and programming!) so it felt appropriate to post it here.

I'm trying to get a custom dialogue to look like a chat box, like you could expect in Skype, Facebook Chat or similar.

Key points that I want it (eventually) to include:
- text stays on screen and it's scrollable
- possibility to divide messages into individual boxes (boxes/labels anything)
- possibility for (at least) two variations of the boxes to determine characters
- non-blocking - so perhaps some kind of a backgroundSay?

I tested out at least 3 different dialogue modules to try and get them to do what I wanted. I also spent all day browsing through various topics. Considering that I'm a total programming noob, it is highly possible that I have seen the answers somewhere on the forums, but have totally misunderstood it or I just didn't notice that it could be of use to me.

I have however, managed to put ttogether a very simple hack

Code: ags

//setting up the function
void MySay(this Character*, String text ,String text2, String text3) {
   
  lblSay2.Visible = false;
  lblSay2.SetPosition(7, 123);
  lblSay3.Visible = false;
  lblSay3.SetPosition(7, 123);
  
  lblSay1.Text = text;
  lblSay2.Text = text2;
  lblSay3.Text = text3;

  gDialog.Visible = true;  
  Wait(40);
  lblSay1.TweenPosition(0.2, 7, 100);
  
  lblSay2.Visible = true;
  Wait(40);
  lblSay1.TweenPosition(0.2, 7, 77, eEaseLinearTween , eNoBlockTween);
  lblSay2.TweenPosition(0.2, 7, 100);
  
  lblSay3.Visible = true;
  Wait(40);
  lblSay2.TweenPosition(0.2, 7, 100);
  
  Wait(40);
  gDialog.Visible = false;

// using MySay();
function cClient1_Talk()
{
  cClient1.MySay("Hi", "What's up", "Blah");
}


All of the above does pretty much what I wanted, but as you can imagine it is extremely limiting and very primitive. I wanted to be able to determine what each individual label (chat box) has to say, where the function would keep creating new labels for each phrase. I was thinking of using some sort of "[" in the text to determine where a new box would be created.


I understand that this may require extensive amount of work, but any kind of pointers would be much appreciated.


EDIT: I just remembered a good example of how it could work like:https://youtu.be/Kek4zO0OF_8?t=121
It's the chat-thing on the left. Player doesn't give any input, it's just triggered at certain points in the game.
I believe the game was made in Gamemaker, but would something similar be achievable in AGS at all?
(BTW the game is pretty damn cool, if you haven't played it already give it a go!)
#6
Hi,

I have a ListBox that I wanted to be in alphabetical order - and I have manged to find piece of code on these forums to help me achieve this. It works great! Well... almost - there's a little catch to it thought.

I have bunch of arrays that I want to display on GUI labels when a certain item in the ListBox is clicked on. The problem is that these arrays are meant to be connected with each other - so "0" goes with all other "0" variables, "1" with other "1" and so on. When I sort the items in ListBox, it only sorts the "clientName[]", but all the other labels use the same Index as they are written in.

Code: ags

// Creates list of clients in the lstDatabase
function ClientList() 
{
 ClientInfo(); // this function includes bunch of Arrays with required info
 
 int index = 0;
   while (index < maxClients) { // maxClients = total number of clients in database
     lstDatabase.AddItem(clientName[index]);
     index ++;
   }   
  lstDatabase.Sort(eOrderAscending, false); //Sorting function
}

// Replaces all GUI labels and buttons with client info
function ClientLabels()
{
  lblName.Text = clientName[lstDatabase.SelectedIndex];
  lblAddress.Text = clientAddress[lstDatabase.SelectedIndex];
  lblName2.Text = clientName[lstDatabase.SelectedIndex];
  lblAddress2.Text = clientAddress[lstDatabase.SelectedIndex];
  bPhoto.NormalGraphic = clientPhoto[lstDatabase.SelectedIndex];
  bPhoto2.NormalGraphic = clientPhoto[lstDatabase.SelectedIndex];
}


Sort ListBox Code:
Code: ags

void Sort(this ListBox*, eOrder order, bool caseSensitive) {
  
  int ic = this.ItemCount;
  if (ic < 2) return;
 
  int i, j, c;
  String temp;
  while (i < ic - 1) {
    j = i + 1;
    while (j < ic) {
      c = this.Items[i].CompareTo(this.Items[j], caseSensitive);
      if ((c < 0 && order == eOrderDescending) || (c > 0 && order == eOrderAscending)) {
        temp = this.Items[i];
        this.Items[i] = this.Items[j];
        this.Items[j] = temp;
      }
      j++;
    }
    i++;
  }
}


What all the code above does is that it leaves me with "clientName[]" sorted alphabetically in the ListBox, but the labels just follow the order in which they are written in. I'm not sure how to get the labels to "stay" with their associated variables. Any help would be greatly appreciated.
#7
Hi,

This is a bit tricky to explain so hopefully you can bare with me... I wanted to set up a computer screen, where the player can look through the "database of characters" to find required information.

What I was hoping of getting:
Character Name - Name of the character
Photo - Image of the character
Balance - How much money they have
Bunch of other stats (but I want to keep it short for now)

I wanted to display this info in a ListBox. You see a list of Names on the left, and the right side of the screen shows all the other information. Ideally, player would be then able to click on "More Info" to show a page with additional information. This means, that more than one Label would need to get the same data - for example, in the original List you see "name" and "photo". When you click on "More Info" you get another screen showing "name" and "photo" but also other bits.

I currently show this info with simply changing the string in each listbox.

Code: ags

if (lDatabase.SelectedIndex == 0){ 
    ClientID = 00;
lblName.Text = ClientName; // Here I just list all the labels that need to be changed
}


and in a another script I determine

Code: ags

if (ClientID == 00){
ClientName = "John Smith;
ClientPhoto = 29;
}


This saves me having to repeat the same info for each of the Labels, however I realized that all this does, is just change the text on each label, while I need each of this things to be a variable, that can be later modified.

Ideally, I wanted to be able to give an ID to each item in the Listbox. If you click on that item (name), it gets the information of that ID's variables and shows it on the right - Name, Photo, Balance.
The only way I can think of to achieve this, was to store all the info in separate functions. For example,

Code: ags

function ID00(){
ClientName = John Smith
ClientPhoto = 29
Balance = 200
}

function ID01(){
ClientName = Jonny Smithy
ClientPhoto = 30
Balance = 2
}

//etc


I'm still unsure of how I would be able to assign this info in the ListBox items thought, so a (bad?) alternative would be to create a separate button for each name in the list (custom list with lots of buttons?). You click on the button and it changes all the Labels on the right.
In other words, I guess it's like making an "inventory item" (which is not an actual inventory item) that has various stats - dmg, durability, lvl etc all of which can be changed in-game.

I've read in the manual about the Arrays, but I don't see how I can make them work - If I have an Array e.g. String Name[]; how can I determine what this Array "holds" (name, photo, balance)? Do I just make an Array for each info bit separate, and just make sure to keep the track of each number "on paper"?

I have searched the forums, but I can't find anything that I could successfully apply to my scenario. Any kind of help or a pointer in right direction would be greatly appreciated!



EDIT:
I just remembered why I wanted to use the different functions.
I was planning on creating a different function for each of the Items in the ListBox and later call these functions with
Code: ags
 if (lDatabase.SelectedIndex == 0){ 
function ID01();
}

That way I could store different variables for each of the Characters, but having so many functions seems like an overkill (I'm thinking of increasing the characters in the ListBox to 100 :P).
#8
I changed the resolution from 320x180 to 480x270 and... Strange things started to happen.

I changed the Game Resolution in General Settings, and later I updated my background to be 480x270.
I would expect everything to work as normal, except that I would need to set up all the hotspots etc. all over again.

The problem is that somehow, the "brush" that you use to draw the hotspots has increased it's size to 2 pixels.
Usually, you can paint "pixel by pixel" but now the lines are thicker and I can't force it to draw over certain areas.

Is it some sort of bug? Or can you actually change the size of the brush? I'm not sure why it would change anyway.
#9
Hi,

This is probably super easy to do, but I am no programming guru :(

I'm trying to create a login screen for a computer interface.
Basically I have a GUI with two TextBoxes, and when player types in correct username and password it will pop up a new GUI (computer screen).
The problem is that whenever you get to the login screen, both textboxes work at the same time.

This topic was the closest thing I found to get this to work (link).

That's the code I use:
Code: ags

function on_event (EventType event, int data) {

   // when a mouse button is pressed down over a GUI
   if (event == eEventGUIMouseDown)
   {
      if (gui[data] == gLoginScreen) // <-- remove it to effect an arbitrary GUI
      {
         GUI *theGui = gui[data];
         TextBox *theTextbox = null;
         GUIControl *control = GUIControl.GetAtScreenXY( mouse.x, mouse.y );
         if (control) 
          theTextbox = control.AsTextBox;
         if (theTextbox)
         {
            // disable GUI textboxes
            int i = 0;
            while (i < theGui.ControlCount)
            {
               if (theGui.Controls.AsTextBox)
               {
                  theGui.Controls.AsTextBox.Enabled = false;
               }
               i++;
            }
            // but enable the selected one:
            theTextbox.Enabled = true;
         }
      }
   }
}


However, I get error message saying: "Error (line19):'[' expected".

Using a different code, I have managed to get the text parser to work, in a sense that when you type in "username" it takes you to the next screen. The problem is that when you type "username" it appears in both textboxes, and I would like to make it work so that you need to have correct phrases in both textboxes (different ones) in order to get you to the next screen.
#10
Hi,

Sorry for the second thread, but I wasn't sure if it would be best to continue under the first one, or to create a second one.
I'm also sorry for putting multiple questions/problems in the same thread but splitting them up into couple various ones seemed unappropriated.

I'm trying to set up a bunch of features before I start creating all the rooms, items and puzzles for the game.
The way I usually work is that if I get stuck way too long on one thing, I move onto something else, so I can come back to the first problem later with a fresh approach (hence I "generated" so many questions).

Here's what I have been struggling with:

1) [SOLVED] Cursor Modes - I'm planning on using two clicks instead of Coin Verb etc.
I already found all the scripts and help on the forum and I got everything working. However, I'm also using the Parallax and Smooth Camera module, which complicates things a little bit. The problem is that the cursor changes depending if it's on hotspot or object. To have some Parallax layers on top, I'm using objects on the background that I don't want the player to interact with (e.g. trees in the front, mountains in the back). I couldn't find another way for the Parallax effect to work, so I'm trying to get the object's PxPos in order to determine if the cursor should change.

Code: ags

void UpdateMouseGraphic() {
  if (player.ActiveInventory != null) return; // do nothing
  int newGraphic = 30;  // no location / walking
  int lt = GetLocationType(mouse.x, mouse.y);
  //  ORIGINAL: if (lt == eLocationHotspot || lt == eLocationObject) newGraphic = 27;
  if (lt == eLocationHotspot) newGraphic = 27;  // interact                            
  if (lt == eLocationObject && (object[0].GetProperty("PxPos") == 0)) newGraphic = 27;   // if it's an object AND it's PxPos property is 0 (no parallax)
  else if (lt == eLocationCharacter) newGraphic = 27;  // talk
  // change?
  if (newGraphic != mouse.GetModeGraphic(mouse.Mode)) mouse.ChangeModeGraphic(mouse.Mode, newGraphic);
}


Problem with the above is that I'm only limiting myself with object[0], whereas I want to check "all the objects".
I have tried multiple different variants, but I can't get it to work.

----------
2) A general question with Parallax objects. Do they have to be "objects"? Is there a different way to set it up? Any best practice?

----------
3) Camera - My backgrounds currently are quite tall, and the camera always centers on the main character. In some places, I want the camera to be higher up, to show the background a little bit better. I have currently created a cDummy character which is attached to main hero. I placed the Dummy slightly higher than the main character, so I kind of have the camera a little higher up. However, it's not perfect, and depending on different positions of the character I get different results with the camera - I can't control it that well.

Is there a way to keep the main character within the lower 1/3 of the screen?

----------
4) [SOLVED] Book GUI - I wanted to have a book in the game, where player can read-through (well, look at some images), which later helps solve some of the puzzles. My current approach was based on Densming's tutorial on List Boxes. I have a GUI background, two buttons at each side of the book (for flipping through the pages) and a large button that overlays the background. The idea was that when you press the left/right button, the image on the large one would change, imitating flipping through the pages.

I thought I could have a function that keeps track of the variable, and depending on it, it would change the picture. I was thinking that the buttons (left and right) could add or subtract the variable, thus changing pages.

Something like this:

Code: ags
function BookPage(int bp){
 
 if (bp == 0){
   bBookPage.NormalGraphic = 33;
 }
 else if (bp == 1){
   bBookPage.NormalGraphic = 34;
 }
 else if (bp == 2){
   bBookPage.NormalGraphic = 35;
 }


}


And later the buttons:
Code: ags

function bTurnRight_OnClick(GUIControl *control, MouseButton button)
{
  BookPage(+= 1);
}


Although the above doesn't give me any errors, it also doesn't do anything in the game at all. I went through all of the tutorials, and it all makes sense when shown with examples, but when I try to apply anything to my own script I just keep asking myself questions "what if, why is that etc." and I can't get anything to work.

From what I understand, each of this tasks is relatively simple, but I am new to programming, hence I thought that the best way to start learning would be with AGS. Any kind of help would be appreciated, even pointing in the right direction (e.g. link to a similar problem) would be great!
#11
Hey there,

I'm new around here so please bare with me (I'm mostly do game art / design, so my programming knowledge basically equals zero).
I started playing around with AGS a couple days ago and today I got really stuck at making custom Speech/Say dialogues.

What I'm after is something similar to Superbrothers style of narration.
Whenever the player interacts with an object, the text instead of showing above characters head, would slide in from the top with a custom background.
The background that is used for Serria Speech Style would seem like best starting point, but the GUI for that doesn't have the "layout" options, and I can't seem to have it being displayed on top.

This Topic was the closest thing I have managed to find, that could somehow do what I was after.
I tried going with the Akril 15's last post and have used the bits of code found on the last post. Of course, I got some errors, but I have managed to get through them - I used the transparent font, I made a GUI with Label, named everything correctly until I had no errors.

The things is... nothing has changed. I'm using LucasArts speech mode, and the only difference is that it has transparent font and the GUI appears on top of the screen.
What did I miss?

EDIT:
I did some digging and I have something like this:

Code: ags

void MySay(this Character*, String text) {

  TextButtonOK.Visible = false;
  TextLabel.Visible = false;
  gTextTop.Visible = true;  
  TextLabel.Text = text;
  gTextTop.TweenPosition(0.5, 0, -1);
  TextLabel.Visible = true;
  Wait(40);
  TextButtonOK.Visible = true;

}


Would this be a correct way of setting this up? I placed the code at the top of Global Script. The visibility stuff is just some fluff to make it a tad nicer.
I set up the original position of the GUI to be off screen, so that way I can tween it onto the screen.

A little extra: I tried to get the button and the text to tween their transparency, but Tween Transparency options don't seem to work with buttons and labels?
I also tried tweening text color from 225, 0, 255 (magenta transparency) to the color of the text I'm planning on using, but that way the Tween function just goes through all of the colors in between magenta and my color :P
I imagine it's fairly simple thing to do, so I will do some more digging on this.

Also, I realized that calling "MySay" in dialogues doesn't quite work (e.g. cHero.MySay("blah");) and I imagine it would need some further work when setting up custom Say function for dialogues?

And the last thing... currently that Say function is set up to wait 1sec before player can click on "ok" button to close the option. Would there be a way to set up a timer that waits long enough depending on the text length? Like it does in the original MI style speech?
SMF spam blocked by CleanTalk