Sign in to follow this  

Isometric Tile Waves

This topic is 400 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi guys!!  

I wanted to make an ocean with Isometric Tiles.

 

I found this JavaScript example here http://codepen.io/arnaudrocca/pen/reNpaP and I tried to port it to XNA/Monogame

 

My wave doesn't look good and I don't know what is wrong.

 

This is my whole code

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.IO;

namespace IsometricWaveDemo
{
    /// <summary>
    /// This is the main type for your game.
    /// </summary>
    public class Game1 : Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;

        Texture2D tileTex;
        float min = 1.25f;
        int mapSize = 12;
	    int width = 50;
	    int height = 25;
	    int speed = 5;
	    int strength = 2;
	    char direction = 'x';

        float timer = 0;
        float deltaTime = 0;
        float lastTime = 0;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            graphics.PreferredBackBufferHeight = 900;
            graphics.PreferredBackBufferWidth = 1600;
        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            spriteBatch = new SpriteBatch(GraphicsDevice);
            FileStream fs = new FileStream("Content\\water4.png", FileMode.Open);
            tileTex = Texture2D.FromStream(GraphicsDevice,fs);
            fs.Close();
        }

        protected override void Update(GameTime gameTime)
        { 

            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.Black);

            spriteBatch.Begin();

            deltaTime = (float)gameTime.TotalGameTime.TotalMilliseconds - lastTime;
            lastTime = (float)gameTime.TotalGameTime.TotalMilliseconds;
            timer += speed * deltaTime / 1000;
            for (int x = 0; x < mapSize; x++)
            {
                for(int y= 0; y < mapSize; y++)
                {

                    float z = 0;
                    if (direction == 'x')
                    {
                        z = (float)(min + Math.Sin(timer + Math.Sin((y - x) * strength / 10)));
                    }
                    else
                    {
                        z = (float)(min + Math.Cos(timer + Math.Cos((x + y) * strength / 10)));
                    }
                    spriteBatch.Draw(tileTex, new Rectangle(400 + (x - y) * width / 2, 200 + (int)((x + y - z) * height  / 2), width, height), Color.White);
                }
            }

            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

I attached the tile which I used. Can someone help me?

 

 

Share this post


Link to post
Share on other sites

Hi!

Checked your code, tried it out actually in a vanilla sample so thx. for the out of the box compiling code sample you posted :wink: !
I've found the issue. It is somewhat "decipherable" based on the resulting visuals.

What you have here is the result of "Integer division", and if I'm not mistaken this is a difference between javascript and C#, that is why the straight port doesn't work.
In javascript you have integers and doubles if I'm not mistaken (integers: 1, 33, 42, doubles: 1.25, 3.14) and the result of the division operator on two numbers (be it integer or double) will be double so 1 / 2 == 0.5, but in C# this is not the case because C# has a language construct called integer division.
This means when the dividend and the divisor are both integers, the result will be an integer too! So in the first case 1 / 2 == 0 is what you will get in C# or another case: 10 / 3 == 3...

I modified your code just a tiny little to make it work:
 

float z = 0;
if (direction == 'x')
{
	z = (float)(min + Math.Sin(timer + Math.Sin((y - x) * strength / 10f))); // Divide by 10f (float) or 10.0 (double)!
}
else
{
	z = (float)(min + Math.Cos(timer + Math.Cos((x + y) * strength / 10f))); // Divide by 10f (float) or 10.0 (double)!
}
spriteBatch.Draw(
	tileTex,
        // The destination rectangle needs integer coordinates for drawing but calculate the position with floats or doubles
	new Rectangle(
		(int)(400f + (x - y) * width / 2f), // Divide by 2f (float) or 2.0 (double)!
		(int)(200f + ((x + y - z) * height / 2f)), // Divide by 2f (float) or 2.0 (double)!
		width, height
	),
	Color.White
);

This code is the modified version of the core of your drawing loop.

Little explanation why/how this works:
C# automatically promotes types to more precise ones when using operations which would result in a more precise data (e.g.: multiplying an integer by a float will result in a float and the first operand integer will be handled as a float), but it is a statically typed "explicit" language and does not do automatic truncating, that is why you have to explicitly write out (int) integer casts, because that can truncate the data (loose precision).
This is usually a good approach regarding programming languages as it promotes explicit control over calculations and results (safty) but it is indeed a bit more complex, requiring more code and more care and it less pleasant to look at.

What is a float/double:
Floating point representations of numbers (e.g.: 33.33333, 3.14, 1.25...) with a specific structure to be able to represent ridiculously big and small numbers alike. In C# (and usually in most static languages) float is a 32 bit floating point number and double is 64 bit hence the name: double precision (float may be called single in many cases).

Hope this helps,
Br.

Edited by Spidi

Share this post


Link to post
Share on other sites

This topic is 400 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this