Home > Software engineering >  Newbie cant generate a chessboard in Godot 3
Newbie cant generate a chessboard in Godot 3

Time:07-30

I'm new to godot 3.4! My first project is a orthographic chess make. I cant generate the chess board. I've wrote the following script trying to generate the chessboard:

using Godot;
using System;

public class TileSpawner : Spatial {
    [Export] private readonly Material lightSquare;
    [Export] private readonly Material darkSquare;
    private bool isLight = false;

    public override void _Ready() {
        Vector2 coordinates = new Vector2(0, 0);

        for (int y = 0; y < 8; y  )
            for (int x = 0; x < 8; x  ) {
                coordinates.x = x; coordinates.y = y;
                AddChild(MakeTile(coordinates));
            }
    }

    private MeshInstance MakeTile(Vector2 coordinates) {
        MeshInstance mesh = new MeshInstance() {
            Mesh = new CubeMesh() {
                Material = isLight ? lightSquare : darkSquare
            }
        };
        mesh.Translate(new Vector3(-coordinates.x, 0, coordinates.y)   new Vector3(coordinates.x/2, 0, -coordinates.y/2));
        mesh.Scale = new Vector3(1.0f, 0.2f, 1.0f);
        isLight = !isLight;
        return mesh;
    }
}

and the result its flickery... one object overlapping other

so I added this line on the MakeTile function to see the problem clearly:

        mesh.Translate(isLight ? Vector3.Up : Vector3.Down);

and got something like this.there's two big block in place small 64 tiles

not sure what's going on. I've been trying to solve this for 4 hours.

CodePudding user response:

We are going to make a Transform:

var t = new Transform(
    x_axis,
    y_axis,
    z_axis,
    origin
);

So, let us define the components we used there. First for origin I'm going to guess that leaving it zero is fine. You will be able to change it to move the board.

var origin = Vector3.Zero;

And I'm also assuming the axis can be in the usual directions, just scaled:

var x_axis = Vector3.Right;
var y_axis = Vector3.Up * 2.0f;
var z_axis = Vector3.Back;

Alternatively, do you want them rotated? You could do something like this:

var x_axis = (Vector3.Right   Vector3.Back).Normalized();
var y_axis = Vector3.Up * 2.0f;
var z_axis = (Vector3.Back   Vector3.Left).Normalized();

Addendum: The scale is too big. The tiles are taking up the area of four cells. So shrink on the x and z axis by half:

var x_axis = Vector3.Right * 0.5f;
var y_axis = Vector3.Up * 2.0f;
var z_axis = Vector3.Back * 0.5f;

Or for the other case:

var x_axis = (Vector3.Right   Vector3.Back).Normalized() * 0.5f;
var y_axis = Vector3.Up * 2.0f;
var z_axis = (Vector3.Back   Vector3.Left).Normalized() * 0.5f;

Now, do you remember I said this is the Transform?

var t = new Transform(
    x_axis,
    y_axis,
    z_axis,
    origin
);

Well, not quite. We are going to displace it according to the coordinates we got, like this:

var t = new Transform(
    x_axis,
    y_axis,
    z_axis,
    origin   x_axis * coordinates.x   z_axis * coordinates.y
);

Addendum: I think you need to compensate for halving the scale by doubling the offset here: origin x_axis * coordinates.x * 2.0f z_axis * coordinates.y * 2.0f

And set it to the mesh:

mesh.Transform = t;

Addendum: the decision of light vs dark si wrong. It goes by rows and switching, like this:

10101010
10101010
… 

Here is an alternative algorithm:

isLight = (((int)coordinates.x) % 2 == 0) != (((int)coordinates.y) % 2 == 0)

CodePudding user response:

@Theraot answer was promising but didn't changed any thing. My Solution: Step 1: Create a scene containing the dark and light square mesh. Step 2: Go Scene(On the top left corner of the screen) > Convert To... > MeshLibrary. Step 3: Tick the "Merge With Existing" Checkbox and save the file as name.meshlib Step 4: Create a GridMap on the scene you want your chessboard to be in. Step 5: Load the name.meshlib on the GridMap Node and attach the following script:

using Godot;
using System;

public class FillWithTile : GridMap {
    public override void _Ready() {

        Vector2 coordinates = new Vector2(0, 0);

        for (int y = -4; y < 4; y  )
            for (int x = -4; x < 4; x  ) {
                coordinates.x = x; coordinates.y = y;
                MakeTile(coordinates);
            }
    }

    private void MakeTile(Vector2 coordinates) {
        SetCellItem((int)coordinates.x, 0, (int)coordinates.y, (coordinates.x % 2 == 0) != (coordinates.y % 2 == 0)?1:0);
    }
}
  • Related