Discord
Login
Community
DARK THEME

Importing images on Android

Hi all,

I dont have access to a PC as I only use android devices, which is why microStudio is such an awesome tool. I can work on things while i'm out.

I see it says you can drag and drop files into the sprites list to add them, but on android drag and drop just doesnt seem to be an option. I havent been able to find a button to load in sprites, only to add new ones and new folders.

Am I missing something? Or is this something that doesnt exist yet?

The other option would be to write a plugin to handle loading in external sprites but I don't know exactly how the plugins work.

Any help would be appreciated thanks!

This is the code I have for a plugin, I am sure it is close to working, but I dont know why it isnt writing the new sprite to the sprites folder

init = function() {
  
}

update = function() {
  if(touch.press) {
    let input = document.createElement('input');
    input.type = 'file';
    input.accept = 'image/*';
    input.onChange = function(event) {
      let file = event.target.files[0];
      let reader = new FileReader();
      reader.onLoad = function(e) {
        var img = new Image();
        img.src = e.target.result;
        document.body.appendChild(img);
        
        system.project.writeFile( "sprites/generated/sprite1", img, 0, function(result, error){ console.log(result) });
      };
      
      reader.readAsDataURL(file);
    };
    input.click();
  }
}

draw = function() {
  screen.clear("rgb(150, 150, 120)");
  screen.drawText("Touch here to import a sprite", 0, 0, 16, "rgb(200, 200, 202)");
}

I have narrowed it down to

init = function() {
  catchConsole();
}

update = function() {
  if(touch.press) {
    system.file.load(["png","jpg"]);
    
    
  }
  if(system.file.dropped) {
      let file = system.file.dropped[0];
      
      system.file.save(file.content, 'image');
      console.log(file.content.type);
      //if(file.content.class == Image) {
      //system.project.writeFile( "sprites/generated/sprite1", file.content, 0, function(result, error) { console.log(result); });
      //}
    }
  if(system.file.loaded) {
      let file = system.file.loaded[0];

      
      console.log(file.content.type);
      //if(file.content.class == Image) {
      system.project.writeFile( "sprites/generated/sprite1", file.content, 0, function(result, error) { console.log(result); });
      //}
    }
}

draw = function() {
  screen.clear("rgb(150, 150, 120)");
  screen.drawText("Touch here to import a sprite", 0, 0, 16, "rgb(200, 200, 202)");
}

But its still not working

update = function() {
  if(touch.press||mouse.press) {
    let input = document.createElement('input');
    input.type = 'file';
    input.accept = 'image/*';
    input.addEventListener('change', function(event) {
      let file = event.target.files[0];
      let reader = new FileReader();

      console.log("input call change")
      reader.onload = function(e) {
        var img = new Image;
        
        img.src = e.target.result;
        console.log("reader call onload");
        img.onload = function(){
          let canvas = document.createElement('canvas');
          let context = canvas.getContext('2d');
          canvas.width = img.width;
          canvas.height = img.height;
          context.drawImage(img, 0, 0);
          let imgData = context.getImageData(0, 0, img.width, img.height);
          let msImg = new msImage( img.width, img.height )
          msImg.initContext();
          msImg.context.putImageData(imgData, 0, 0);
          console.log('img onload:'+ img.width +" "+ img.height);
          system.project.writeFile( "sprites/generated/sprite1", msImg, { ext : "jpg" }, function(result, error){ console.log(result) });
        };
          
      };
      
      reader.readAsDataURL(file);
    });
    input.click();
  }
}

I modified your code a bit - now it works for me (windows).

I also fell into this trap where DOM and javascript meet - adding the code element.on"Some name" (onChange, onEnter) did not result in calling this method.

In other languages, adding code causes it to be called immediately.

And half a day wasted on Googling because you don't even know what to look for.


Edit : I corrected the code.

Tell me if it works for you!

Maybe it can be done in a simpler way, but I don't know how.

Yet again you have saved me! This seems to work perfectly. I cant thank you enough. I went and altered the code of the Pixelfy plugin to just import and save the image loaded avoiding the resolution changes etc, but that didnt handle transparency. I will add credits to you in the code and make the plugin publically available for anyone running into the issue of importing sprites on mobile.

Heres the plugin for anyone wanting to utilize it https://microstudio.io/i/SynKrown/spriteimport2/

Don't forget to make your library public.

It seemed to me that it could be done in fewer and simpler steps.

And we managed to simplify the code - now it is only a few lines, and there is no transfer of data between different objects.

update = function() {
  if(touch.press||mouse.press) {
    let input = document.createElement('input');
    input.type = 'file';
    input.accept = 'image/*';
    input.addEventListener('change', function(event) {
      let file = event.target.files[0];
      let reader = new FileReader();

      console.log("input call change")
      reader.onload = function(e) {
        var img = new Image;
        img.src = e.target.result;
        console.log("reader call onload");
        img.onload = function(){
          let msImg = new msImage( img.width, img.height )
          msImg.setPixelated(true);
          msImg.context.drawImage( img, 0, 0 );
          console.log('img onload:'+ img.width +" "+ img.height);
          system.project.writeFile( "sprites/generated/sprite1", msImg, { ext : "jpg" }, function(result, error){ console.log(result) });
        };
      };
      reader.readAsDataURL(file);
    });
    input.click();
  }
}

Hey man, are you working on any game projects? I mean with your understanding of programming logic, I am willing to bet that you could program pretty much anything you get stumped with.

As you know, I have been working on a game manager to handle back end game logic and I have been working on a GTA 2 type example with it to get top down physics etc working. I have functional polygon collisions that can rotate with the direction of the game objects, I have very simple yet effective physics working(but not perfect).

https://microstudio.io/i/SynKrown/ruler/

If you check the ruler/gtaexample file and have a look at the Car class, you'll see some basic collisions between cars etc. If you've ever played GTA 2, you'll know what I'm aiming for.

The gta example was originally just to test my physics etc but the more I add to it the more I want to make a gta 2 style game for cross platform and I just know that will be a hit.

Not to mention how powerful the engine behind it will be to make other 2D games(planning on doing a metroidvania example to get platforming mint too).

Let me know what you think and if you'd be interested in working on this with me, or even if you understand how the car physics I have there works, if you could figure out a way to make the cars collisions a bit more like gta 2 with the car being hits direction changes based on where its been hit from what angle

To make car collisions more realistic, you need to take into account

  • their mass
  • the shape of the object, hitting a long object at a point away from its center of gravity will cause the object to tend to rotate rather than move away.
  • friction against the ground and against colliding objects.
  • the location of the object's center of gravity.

Matter.js - has it all. I know because I am currently combining the PIXI graphics engine and the Matter.js graphics engine into one.

You can add this library to your project and compare the behavior of Matter.js and your code.

Here is an example of physics for the collision of circle objects, taking into account that the collision may not occur at a normal angle.

https://microstudio.dev/i/this_name_is_taken/poolballphysics/

https://www.youtube.com/watch?v=9IULfQH7E90 - 1:18 - here it is explained how the physics engine works.

Generally, the smaller the step, the better.

Search for videos on YouTube with titles - 2d physics engine

I will check your code.

I see that the graphics are nicer now than when I first looked at the project.

It looks nice.


Edit Code analysis :

  • you don't use deltaTime, in the future it will take its revenge when, for example, chilow frames drop by half. Physics calculations should take into account how much time has passed since the last update.

  • Objects behave strangely because, from what I have analyzed, collisions are counted twice for the same pair of cars in one frame.

"collisionSolid(other)" function

  • I don't really understand the code of the collisionSolid(other) function, I would do it like this
    calculateCollisionVelocity(m1, v1, m2, v2) {
    // Calculating the final velocity of objects after a collision
      let velocity = ((m1 - m2) * v1 + 2 * m2 * v2) / (m1 + m2);
      return velocity;
    }   
    collisionSolid(other) {
      let vx1 = this.vx;
      let vy1 = this.vy;
      let vx2 = other.vx;
      let vy2 = other.vy;
      this.vx = this.calculateCollisionVelocity( this.mass, vx1, other.mass, vx2);
      this.vy = this.calculateCollisionVelocity( this.mass, vy1, other.mass, vy2);

      other.vx = this.calculateCollisionVelocity( other.mass, vx2, this.mass, vx1);
      other.vy = this.calculateCollisionVelocity( other.mass, vy2, this.mass, vy1);
    }

It's not perfect because

  • collision is triggered twice.
  • does not take into account the place of collision
  • does not take into account angles

Ok I have heard of deltaTime and used it in construct as it has access to the deltaTime by calling 'dt', but I've never actually researched what exactly it does. Thank you for pointing that out, I will jump on YouTube. How do we call deltaTime in microStudio? Like 'x += 10 * dt'?

Also, that youtube link you sent about understanding the physics and spatial partitioning is brilliant! I'm about to go down a rabbit hole of this guys videos lol.

I had a play around with matter.js but found the collisions weren't feeling very solid. Like they would overlap and push outside of each other. Maybe I was missing something.

I will have a look at that new collisionSolid code and see how it performs. I get what you mean by it calling the collision twice too, I didn't think of that. I will try to work out a way to fix that. Or if I can find a way to make matter.js feel more like solid objects hitting each other I might go down that route(is that what you meant by the smaller the step the better?). As 50 vehicles checking collisions with eachother works fine, but the moment I put it up to 100 vehicles the lag is extreme(maybe thats where spacial partitioning and deltaTime comes in to play).

I'm learning a lot while building this game manager and have a lot more features to add. For example, I've added an Environment class to handle day/night system, date and time tracking, will also handle weather effects etc.

Currently my object handling is just iterating through a list of GameObjects and I am looking at the spacial partitioning mentioned in that physics video you sent to maybe allow for a lot of game objects to be in the playing field.

MicroStudio - no deltaTime . You have to write it yourself. There is an example in the Explore section.

https://microstudio.dev/i/Skaruts/delta_time/

in the file "isothermal" method "updateGameTime()" you create the dt variable - but you never use it.

  • to calculate deltaTime, you remember the current time (e.g. when starting physics).

  • In the physics update function you check the time again.

  • You calculate the delta and remember the current time - it will be needed in the next iteration of the physics update.

You can eliminate double collisions by appropriately iterating through the list.

gameObj = Array
for (let i = 0; i < game.Obj.length-1; i+= 1){
   for( let j = i+1; j < gameObj.length; j += 1){
      testColl( gameObj[i], gameObj[j] );
   }
}

You may have noticed overlapping objects in Matter.js - to prevent this, the number of intermediate steps increases.

engine.solver.iterations = 10;

https://www.youtube.com/watch?v=sKHf_o_UCzI

Here is a comparison of physics engines.

Each engine has some simplifications in physics that result in different simulation results. Sometimes absurd behaviors appear - such as objects jumping or moving through walls.

Matter.js is no exception and you need to know about it, tune the engine to the program's requirements, and avoid situations in which the engine cannot cope.

Yeah I did try making my own delta time but the results were very fast lol. I dont know if I have the calculation correct or not.

So I keep getting messed up with the translations. So like, I am used to top left being '0, 0', top right being 'w, 0', bottom right being 'w, h' etc, but even when I setTranslation(-1, 1) or even (-1, -1) I still get centered and the Y axis is '+' for top and '-' for bottom. I have been working around it but I would rather look at it from top left being the anchor point and down the Y axis being positive rather than negative

Also thanks again. Maybe I should do more research on game physics if I want to start that from scratch

https://microstudio.dev/i/JimB007/screencoords/

https://microstudio.dev/i/osterberg/screentools/

Image/screen.setScae - to change the scale and axis reversal.

Image/screen.screen.setTranslation - to change the reference point

  screen.setTranslation( -screen.width/2, scren.height/2 )

Tests are the most important thing - the correctness of the tests.

Eliminate double collision calculations for the same objects. This alone will improve the effect.

Change the code so that there is a separate object/class responsible for physics.

And this object is supposed to perform collisions.

And signals about the start and end of the collision are sent to objects that participate in the collision.

Brilliant thank you. I used Bings AI to convert the screen coords one to javascript and added it to my IsoMath library. Mighty useful addition(credits to the original creator are commented in).

Once I fix up Isothernal Game Manager with the new screen coordinates, I will get on to fixing the physics. A separate physics class using vectors is a great idea

When I checked how physics works, I noticed that when I change the mass of an object from 1 to, for example, 100, the object accelerates very strongly.

In my opinion, mass should not have such an effect on acceleration.

Try to change it in this new version.

Post a reply

Progress

Status

Preview
Cancel
Post
Validate your e-mail address to participate in the community