DEV Community

Abhishek
Abhishek

Posted on • Edited on

2

Game Engine with AI✨ Part 2 - DALL E Sprites

Hey, devs! 🖐🎮
Hope you're all having a nice day! I have some cool updates on helicity.ai

For reference, this was part 1 (nobody saw it🙃)
I'm making an AI JS Browser Game Engine

Inbuilt DALL E Support

I've integrated DALL-E support! 🎨🖌️ Yes, so from now on, you can define your sprite URL as "lookup: some description", and Helicity.ai will generate a unique sprite for you on the fly using DALL-E. Create unique, custom images without having to leave the IDE.

How I made it

  1. So it all happens in the Gameobject.js module. Whenever you make a new instance of the GameObject, this code runs
  2. When you put "lookup:" string in your image source, it takes this as a request and calls a firebase function made in Express
  3. The firebase function calls the DALL E API looking up the string after "lookup:" and asynchronously returns the image-url, this is sent back to the game object.
  4. The game object image is drawn every frame using *render() *(automatically in the game loop) or else, its just a black box
  5. The savedImages makes sure that if 2 game objects are created with the same lookup description, multiple called aren't made to dall e. For example pipes in flappy bird.

Gameobject.js

var savedImages = {};

export class GameObject {
  constructor(x, y, width, height, type, imageSrc) {
    this.x = x;
    this.y = y;
    this.width = width;
    this.height = height;
    this.type = type; // can be Used for collision detection
    this.image = new Image();
    this.image.loaded = false;

    //check if imagesrc contains the string lookup:
    if (imageSrc.includes("lookup:")) {
      //check if the image is already saved
      if (savedImages[imageSrc]) {
        this.image = savedImages[imageSrc];
        this.image.loaded = true;
      } else {
        //make a post request. this is in html to use XMLHttpRequest
        var xhr = new XMLHttpRequest();
        xhr.open(
          "POST",
          "https://us-central1-myaigameengine.cloudfunctions.net/api/Image",
          true
        );
        xhr.setRequestHeader("Content-Type", "application/json");
        xhr.send(
          JSON.stringify({
            userPrompt: imageSrc.split("lookup:")[1],
          })
        );
        xhr.onreadystatechange = () => {
          if (xhr.readyState == 4 && xhr.status == 200) {
            //console.log(xhr.responseText);

            //get the imageURL from the response
            var imageURL = JSON.parse(xhr.responseText).image_url;
            this.image = new Image();
            this.image.src = imageURL;
            this.image.onload = () => {
              this.image.loaded = true;
              //save the image
              savedImages[imageSrc] = this.image;
            };
            this.image.onerror = () => {
              console.error(`Error loading image ${this.imageSrc}`);
            };
          }
        };
      }
    } else {
      this.imageSrc = imageSrc;
      this.image = new Image();
      this.image.src = imageSrc;
      this.image.onerror = () => {
        console.error(`Error loading image ${this.imageSrc}`);
      };
      this.image.onload = () => {
        this.image.loaded = true;
      };
    }

    Game.addGameObject(this);
  }

  update(deltaTime) {
    // Overridden by child classes
  }

  render() {
    //draw a black rectangle if there isnt an image else draw it
    if (this.image.loaded) {
      Renderer.drawImage(this.image, this.x, this.y, this.width, this.height);
    } else {

      Renderer.context.fillStyle = "black";
      Renderer.context.fillRect(this.x, this.y, this.width, this.height);
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Firebase function's Express Image Endpoint

app.post("/Image", async (req, res) => {
  //var uuid = req.body.uuid;
  var userPrompt = req.body.userPrompt;
  //console.log("uuid is " + uuid);
  console.log("user prompt is ");
  openai
    .createImage({
      prompt: userPrompt,
      n: 1,
      size: "256x256",
    })
    .then((result) => {
      image_url = result.data.data[0].url;
      console.log(image_url);
      res.send({
        success: true,
        image_url: image_url,
      });
    });
});
Enter fullscreen mode Exit fullscreen mode

Thats it!

Think about it - need a sprite of a "purple dragon with a top hat?" 🐉🎩 Just type lookup: purple dragon with a top hat and voila, your personalized sprite is ready to be used in your game! It's that simple! 🎲🚀

Multiplayer support is coming soon!

If you'd like to talk about and participate in the development, hit me up on discord!

https://discord.gg/RkH98RgVDr

Stay tuned for more updates! Happy coding 🎮💖

Sentry blog image

How I fixed 20 seconds of lag for every user in just 20 minutes.

Our AI agent was running 10-20 seconds slower than it should, impacting both our own developers and our early adopters. See how I used Sentry Profiling to fix it in record time.

Read more

Top comments (0)

SurveyJS custom survey software

JavaScript UI Libraries for Surveys and Forms

SurveyJS lets you build a JSON-based form management system that integrates with any backend, giving you full control over your data and no user limits. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay