carlini / js13k2019-yet-another-doom-clone

Yet another doom clone (in 13kb of JavaScript)
GNU General Public License v3.0
288 stars 62 forks source link

Changing game textures. #6

Open Boomstronk0 opened 4 months ago

Boomstronk0 commented 4 months ago

I am using your javascript code as a base for a school project (sorry for using it ;) ) but I was wonderdering how I could change the textures and change the looks of the caracters but since you used javascript cilinders without texture and compressed the map code that a bit dificult. ( I'm 14 please go easy on the spelling English is not my native language). If somebody could help in any way that would be fantastic!

carlini commented 4 months ago

I used to write javascript games when I was 14 too! I hope you have fun with this. Please do let me know if you have other questions about the code.

First: this code is some of the hardest code to understand I have written. I wrote it in a month, and my main objective was making the code as short as possible. It was for a project where the entire code had to be under 13,000 bytes. This means it is very hard to understand, so don't feel bad if things are confusing here. I had to avoid a lot of good programming style because it would have made the program larger.

One thing you didn't ask, but if you're going to work on is good to know: this code is very slow to start. You look at a loading screen for a long time, and that makes it hard to test your code. The reason it is slow to load is because the music takes a long time to generate.

To fix this and make it faster to work on, you should make these changes:

  1. Remove load() and replace it with a call to main_go() on this line: https://github.com/carlini/js13k2019-yet-another-doom-clone/blob/8911f70af4de93d76f55fdc9a9264fd9b9222cb4/src/audio.js#L112
  2. Delete the body of the doplay() function so it just looks like function doplay() {} here https://github.com/carlini/js13k2019-yet-another-doom-clone/blob/8911f70af4de93d76f55fdc9a9264fd9b9222cb4/src/audio.js#L36

This will make it load almost immediately. If you want the music back you can add it at the end.

The textures are defined in the graphics.js file. Here, for example, is the definition of wall graphics: https://github.com/carlini/js13k2019-yet-another-doom-clone/blob/8911f70af4de93d76f55fdc9a9264fd9b9222cb4/src/graphics.js#L498-L506

Let me explain this one piece in a bit more detail. Here's a rewritten version

// Initialize an empty array to hold the pixel colors
const texture = [];
const width = 256;
const height = 256;

let y = 0;
while (y < height) {
    let x = 0;
    while (x < width) {
        // This is where the magic happens to make the bricks. I want to add horizontal and vertical lines.
        // The horizontal lines appear every 64 pixels vertically, and are 2 pixels of black: (y%64) < 2
        // To make the bricks look stacked, I offset the bricks every other one. 
        // If I just wrote (x%128) < 2 you would get rectangles but perfectly stacked.
        if ((y % 64) <= 2 || Math.abs(x - ((Math.floor(y / 64) % 2) * 128)) <= 2) {
            texture.push([0, 0, 0, 1]); 
        } else {
            // I don't want the bricks to have a completely "flat" texture. This adds some nice noise to make them look more real.
            let noiseValue = perlin_noise[x * 256 + y]; 
            let r = 0.9 - noiseValue / 20;
            texture.push([r, r, r, 1]); // Set the pixel color to the calculated grayscale value with full opacity
        }
        x++; // Move to the next column
    }
    y++; // Move to the next row
}

// Flatten the 2D array of pixel colors into a 1D array
const flatTexture = texture.flat();
// Create the texture using the specified colors
make_texture(flatTexture);

Changing the character is a little bit harder. Here is where the walking person enemy is defined

https://github.com/carlini/js13k2019-yet-another-doom-clone/blob/8911f70af4de93d76f55fdc9a9264fd9b9222cb4/src/game.js#L363-L371

The structure of this code is [dimensions of the rectangle], [offset relative to the person], [color].

So if you wanted the enemies to glow purple you could change the last entry to [5,0,5]. Or if you wanted to make them have a huge head you could change the size from [4,5,4] to [8, 8, 8].

You can also add new pieces to the person by adding more entires to this list, but because I animate the person moving around, this will be a little bit hard to get right. You might want to remove the animations first and then change how the person looks.

Also, because a lot of this code uses 3d graphics, you will need to know matrix math to understand how many things work. If you don't yet, that's okay, just try to work on the pieces that don't use it. And then you can come back later after you have taken some matrix math and better understand what is going on.

Boomstronk0 commented 4 months ago

Wow thank you very much. I am not shure if I will be able to do it with this but atleast now I am not stuck anymore.

Boomstronk0 commented 4 months ago

Something that havent been able to figur out was how to instead of giving the game texture with javascript objects and coloring a percent of pixels I was wondering how to get an jpg ore png on one perticulaire side of a javascript object so for exemple now the enemies are just gray with a red head but i wanted to ad a png to al sides of the object that the enemies are made of. But I have no clue on how to do this since I dont understand how the bodyparts work. ( I am sorry for potentially interrupting you with something) ( if you dont want anything to do with this you just need to say it but i would appreciate the help) (moving the cursor doesn't work anymore when i changed the code for it to load faster) Have a nice day!

Boomstronk0 commented 4 months ago

Sorry, this helped me way more then I intentionelly thought. But I still want to now how I can a png to the heads of the enemies.

Boomstronk0 commented 4 months ago

Something else... where are the eyes defined? (I wanna make them crazy glowing white)

carlini commented 4 months ago

Fixing the texture to the face of the object is actually hard. The code is not set up in a way to make this possible.

The problem is here: the code looks up the texture for the object based on its position in 3d space. This means, if the object moves throughout space, the texture will move too.

Here's the line of code that looks up how to put the texture on to the objects

https://github.com/carlini/js13k2019-yet-another-doom-clone/blob/8911f70af4de93d76f55fdc9a9264fd9b9222cb4/src/shaders/program1.js#L69

Notice that what I do is call get_shader with world_position.xy / 32. This means that it looks up the shader color based on the world position, so if the object moves, the texture will change.

It should be possible to make adjustments to make this possible. But it will take work. You will need to create a new shader that tracks the local object position, and then looks up the texture from there.

The eyes are defined here:

https://github.com/carlini/js13k2019-yet-another-doom-clone/blob/8911f70af4de93d76f55fdc9a9264fd9b9222cb4/src/game.js#L369-L370

Boomstronk0 commented 4 months ago

Thx again for all the help!