Legacy GM [SOLVED] Trying to convert image from link to a sprite.

Edwin

Member
Hello.

I'm trying to get the image from my avatar using Image Loaded async event.

Code:
Code:
/// Image Loaded:
avatar_sprite = sprite_add("https://forum.yoyogames.com/data/avatars/l/31/31538.jpg?1547144011", 1, false, false, 0, 0);

if (ds_map_find_value(async_load, "id") == avatar_sprite) {
   if (ds_map_find_value(async_load, "status") >= 0) {
      sprite_index = avatar_sprite;
   }
}
Nothing.

Can anyone explain me how it works?
 

Homunculus

Member
Async function calls need to be processed in Async events. The idea is that your game continues to run normally while waiting for the async call to complete.
In short, you just have to move the "if" code in the correct async event.

Edit: didn't see you had this whole code in the async event. You have to take the sprite_add call outside of that
 
Last edited:

FrostyCat

Member
The sprite_add() line belongs outside the Image Loaded event. The Manual clearly says that.
Well you would have something like this in a create event or an alarm event (for example):

Code:
spr = sprite_add("http://www.angusgames.com/game/background1.png", 0, false, false, 0, 0);
This will now start to load the image into the device or the browser, but it will not block GameMaker Studio 2 while it waits for the file to be loaded.
The Image Loaded event handles what happens AFTER an image is loaded, it is NOT responsible for starting the load.
 

Edwin

Member
Async function calls need to be processed in Async events. The idea is that your game continues to run normally while waiting for the async call to complete.
In short, you just have to move the "if" code in the correct async event.

Edit: didn't see you had this whole code in the async event. You have to take the sprite_add call outside of that
The sprite_add() line belongs outside the Image Loaded event. The Manual clearly says that.

The Image Loaded event handles what happens AFTER an image is loaded, it is NOT responsible for starting the load.
Oh, that's what! Thanks a lot, guys!

Anyway, I changed my code for the future.
Code:
avatar_link = http_get_file(link to avatar, string(working_directory)+"\avatar.jpg");
avatar_sprite = sprite_add("avatar.jpg", 0, false, false, 0, 0);
sprite_index = avatar_sprite;
 

Edwin

Member
http_get_file is asynchronous as well, there's no way this can work properly
If you guys know how to fix it, then...

I have similar problem with HTTP asynchronous using http_get() to get SteamID's JSON, convert it into DS map and find the avatar link.

Create Event:
Code:
steam_request = http_get("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=A689432685442875EBB8B6E4039D73AE&steamids=76561198074393173");

result_map = json_decode(steam_request);

avatar_link = ds_map_find_value(result_map, "avatarfull"); // avatar, avatarmedium, avatarfull
When I check string of avatar_link variable using Draw Event, it shows undefined but it need to show me the link to the image that I need to use.

I will appreciate any help =)
 

Homunculus

Member
Me and frosty literally told you what to do in the previous answers. Run your http_get / sprite_add functions in the create / whatever event you prefer and store their async id.
Then, in the appropriate async event decode the response / apply the sprite. That's it. You can even find a full example for those in the manual.

The only thing you CAN'T do is run the request and the response sequentially, which is what you are doing now.
 

FrostyCat

Member
If you've read the extended example that came with the Manual entries for http_get() or http_get_file(), you wouldn't have put everything in the same piece of code. Split your code and put the post-downloading code into Async events.

Create:
Code:
avatar_sprite = sprite_add("https://forum.yoyogames.com/data/avatars/l/31/31538.jpg?1547144011", 1, false, false, 0, 0);
sprite_index = spr_loading_avatar;
Async - Image Loaded:
Code:
if (async_load[? "id"] == avatar_sprite) {
  switch (async_load[? "status"]) {
    case 1:
      sprite_index = spr_loading_avatar;
      break;
    case 0:
      sprite_index = avatar_sprite;
      break;
    default:
      sprite_index = spr_no_avatar;
  }
}
Same deal with http_get_file().

Create:
Code:
xhr_avatar_link = http_get_file("https://forum.yoyogames.com/data/avatars/l/31/31538.jpg?1547144011", working_directory+"avatar.jpg");
sprite_index = spr_loading_avatar;
avatar_sprite = -1;
Async - HTTP:
Code:
if (async_load[? "id"] == xhr_avatar_link) {
  switch (async_load[? "status"]) {
    case 1:
      sprite_index = spr_loading_avatar;
      break;
    case 0:
      avatar_sprite = sprite_add(working_directory+"avatar.jpg", 0, false, false, 0, 0);
      sprite_index = avatar_sprite;
      break;
    default:
      sprite_index = spr_no_avatar;
  }
}
More of the same with http_get().

Create:
Code:
xhr_steam = http_get("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=A689432685442875EBB8B6E4039D73AE&steamids=76561198074393173");
avatar_type = "";
Async - HTTP:
Code:
if (async_load[? "id"] == xhr_steam) {
  switch (async_load[? "status"]) {
    case 1:
      avatar_type = "loading";
    case 0:
      var result_map = json_decode(async_load[? "result"]);
      avatar_type = result_map[? "avatarfull"];
      ds_map_destroy(result_map);
      break;
    default:
      avatar_type = "error";
  }
}
 

Edwin

Member
If you've read the extended example that came with the Manual entries for http_get() or http_get_file(), you wouldn't have put everything in the same piece of code. Split your code and put the post-downloading code into Async events.

Create:
Code:
avatar_sprite = sprite_add("https://forum.yoyogames.com/data/avatars/l/31/31538.jpg?1547144011", 1, false, false, 0, 0);
sprite_index = spr_loading_avatar;
Async - Image Loaded:
Code:
if (async_load[? "id"] == avatar_sprite) {
  switch (async_load[? "status"]) {
    case 1:
      sprite_index = spr_loading_avatar;
      break;
    case 0:
      sprite_index = avatar_sprite;
      break;
    default:
      sprite_index = spr_no_avatar;
  }
}
Same deal with http_get_file().

Create:
Code:
xhr_avatar_link = http_get_file("https://forum.yoyogames.com/data/avatars/l/31/31538.jpg?1547144011", working_directory+"avatar.jpg");
sprite_index = spr_loading_avatar;
avatar_sprite = -1;
Async - HTTP:
Code:
if (async_load[? "id"] == xhr_avatar_link) {
  switch (async_load[? "status"]) {
    case 1:
      sprite_index = spr_loading_avatar;
      break;
    case 0:
      avatar_sprite = sprite_add(working_directory+"avatar.jpg", 0, false, false, 0, 0);
      sprite_index = avatar_sprite;
      break;
    default:
      sprite_index = spr_no_avatar;
  }
}
More of the same with http_get().

Create:
Code:
xhr_steam = http_get("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=A689432685442875EBB8B6E4039D73AE&steamids=76561198074393173");
avatar_type = "";
Async - HTTP:
Code:
if (async_load[? "id"] == xhr_steam) {
  switch (async_load[? "status"]) {
    case 1:
      avatar_type = "loading";
    case 0:
      var result_map = json_decode(async_load[? "result"]);
      avatar_type = result_map[? "avatarfull"];
      ds_map_destroy(result_map);
      break;
    default:
      avatar_type = "error";
  }
}
I stuck at the last example. I want to get "avatarfull" key's value that equals to Steam avatar link, but I keep getting undefined variable.
 

FrostyCat

Member
I stuck at the last example. I want to get "avatarfull" key's value that equals to Steam avatar link, but I keep getting undefined variable.
I assumed that your issue was just with HTTP, but upon looking at the real URL, I noticed that you have a problem in the JSON parsing as well. You missed the 3 nesting layers that came before the "avatarfull" key you're looking for. This one you have to know how to dig down.

First get this helper script to simplify the syntax for digging down (since accessor chaining isn't available yet), then do this:

Create:
Code:
xhr_steam = http_get("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=A689432685442875EBB8B6E4039D73AE&steamids=76561198074393173");
avatar_link = "";
Async - HTTP
Code:
if (async_load[? "id"] == xhr_steam) {
  switch (async_load[? "status"]) {
   case 1:
     avatar_link = "loading";
   case 0:
     var result_map = json_decode(async_load[? "result"]);
     avatar_link = json_get(result_map, "response", "players", 0, "avatarfull");
     break;
   default:
     avatar_link = "error";
  }
}
Next time, get a JSON viewer such as this Chrome plugin that shows you the nesting structure. Don't just look at a piece of JSON in plain form, see a key and automatically assume it is available off the top.
 

Edwin

Member
I assumed that your issue was just with HTTP, but upon looking at the real URL, I noticed that you have a problem in the JSON parsing as well. You missed the 3 nesting layers that came before the "avatarfull" key you're looking for. This one you have to know how to dig down.

First get this helper script to simplify the syntax for digging down (since accessor chaining isn't available yet), then do this:

Create:
Code:
xhr_steam = http_get("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=A689432685442875EBB8B6E4039D73AE&steamids=76561198074393173");
avatar_link = "";
Async - HTTP
Code:
if (async_load[? "id"] == xhr_steam) {
  switch (async_load[? "status"]) {
   case 1:
     avatar_link = "loading";
   case 0:
     var result_map = json_decode(async_load[? "result"]);
     avatar_link = json_get(result_map, "response", "players", 0, "avatarfull");
     break;
   default:
     avatar_link = "error";
  }
}
Next time, get a JSON viewer such as this Chrome plugin that shows you the nesting structure. Don't just look at a piece of JSON in plain form, see a key and automatically assume it is available off the top.
Thank you very much!
 
Top