module main import math // TODO: add world_to_cell_pos, cell_to_world_pos (as an extra to screen versions) // World pos to screen pos fn world_to_screen_pos(x, y int) (int, int) { sx := x + -game.viewport.shx sy := y + -game.viewport.shy return sx, sy } fn screen_to_world_pos(sx, sy int) (int, int) { wx := sx + game.viewport.shx wy := sy + game.viewport.shy return wx, wy } // XXX returned value is top-left corner of cell // use center version for cell's center fn cell_to_world_pos(cx, cy int) (int, int) { //wx := cx * c_cell_w //wy := cy * c_cell_h cell_size_z := 0 cz := 0 wx := (c_cell_w * cx) + ((cy&1) * (c_cell_w / 2)) wy := (c_cell_h * cy / 2) - cell_size_z * cz return wx, wy } // XXX get center position of cell at cx, cy in world-space fn cell_to_world_pos_center(cx, cy int) (int, int) { wx, wy := cell_to_world_pos(cx, cy) center_wx := wx + c_cell_w / 2 center_wy := wy + c_cell_h / 2 return center_wx, center_wy } fn cell_to_screen_pos(cx, cy int) (int, int) { pan_x := 0 pan_y := 0 cell_size_z := 0 cz := 0 sx := pan_x + (c_cell_w * cx) + ((cy&1) * (c_cell_w / 2)) sy := pan_y + (c_cell_h * cy / 2) - cell_size_z * cz return sx, sy } // XXX bad fn cell_to_screen_pos2(cx, cy int) (int, int) { scale_ := f32(1.0) width_ := f32(c_cell_w) height_ := f32(c_cell_h) //width_ := f32(game.field.w * c_cell_w) //height_ := f32(game.field.h * c_cell_h) sw := scale_ * width_/2.0 sh := scale_ * height_/2.0 rx, ry := (cx - cy + f32(int(cy)&1)/2.0) * sw, (cx + cy + f32(int(cy)&1)/2.0) * sh rxi, ryi := int(rx), int(ry) return rxi, ryi } /* fn screen_to_cell_pos(sx, sy int) (int, int) { pan_x := 0 pan_y := 0 cell_size_z := 0 mut cy := (2 * (sy - pan_y)) / c_cell_h mut cx := (sx - pan_x - ((cy&1) * (c_cell_w / 2))) / c_cell_w mut cz := 0 // Correction? //mut xx, mut yy := cell_to_screen_pos(cx, cy, cz) mut xx, mut yy := cell_to_screen_pos(cx, cy) xx = sx - xx mx0 := cx yy = sy - yy my0 := cy if xx <= (c_cell_w / 2) { if yy > xx * c_cell_h/c_cell_w { cy++ if int(cy&1) != 0 { cx-- } } } else { if yy > (c_cell_w - xx) * c_cell_h/c_cell_w { cy++ if int(cy&1) == 0 { cx++ } } } return cx, cy } */ // XXX bad fn screen_to_cell_pos2(sx, sy int) (int, int) { px := f32(sx) py := f32(sy) //width := game.field.w * c_cell_w //height := game.field.h * c_cell_h //width := game.field.w //height := game.field.h width := c_cell_w height := c_cell_h mx := int(math.floor(px / width)) my := int(math.floor(py / height) * 2) return mx, my } fn screen_to_cell_pos3(sx, sy int) (int, int) { wx, wy := screen_to_world_pos(sx, sy) return world_to_cell_pos3(wx, wy) } // XXX // x is accurate +/- // y is not very //fn screen_to_cell_pos3(sx, sy int) (int, int) { fn world_to_cell_pos3(wx, wy int) (int, int) { // XXX name alias for world version sx := wx sy := wy //y := f32(game.field.h) - 1.0 - f32(sy) * 2.0 / f32(c_cell_h) //sy_ := ctx.vars.res_y - sy //sy_ := game.field.height_px() - (f32(c_cell_h) * 1.5) - sy //sy_ := sy //sy_ := 1.0 //sy_ := f32(0.0) //println("sy_: $sy_") //y := f32(game.field.h) - f32(sy_) * 2.0 / f32(c_cell_h) //y := f32(game.field.h) - 1.0 - f32(sy_) * 2.0 / f32(c_cell_h) //mut y := f32(sy) / f32(c_cell_h) //mut y := 0.0 - 1.0 - f32(sy_) * 2.0 / f32(c_cell_h) mut y := f32(sy) * 2.0 / f32(c_cell_h) + 1.0 //mut y := f32(sy) * 2.0 / f32(c_cell_h) mut x := f32(0.0) y = (2 * (sy)) / c_cell_h if int(y) % 2 == 0 { x = f32(sx) / f32(c_cell_w) } else { //x = f32(sx) / f32(c_cell_w) //x = (f32(sx) / f32(c_cell_w)) / 2.0 //x = (f32(sx) + f32(c_cell_w / 2)) / f32(c_cell_w) x = ((f32(sx) / f32(c_cell_w))) - f32(0.5) // 0.5 is float rounding correction to the lower number } yi, xi := int(y), int(x) return xi, yi } // XXX inaccurate fn mouse_to_cell_pos(mx, my int) (int, int) { // https://gamedev.stackexchange.com/questions/45103/staggered-isometric-map-calculate-map-coordinates-for-point-on-screen px := f32(mx) - (c_cell_w / 2.0) py := f32(my) - (c_cell_h / 2.0) x := math.floor((px + (py - (c_cell_h / 2.0)) * 2.0) / c_cell_w) y := math.floor((py - (px - (c_cell_w / 2.0)) * 0.5) / c_cell_h) tx := math.floor((x - y) / 2.0) + 1.0 //+ this.camera.x; ty := y + x + 2.0 //+ this.camera.y; /* tx := math.floor((x - y) / 2) + 1 + -(game.viewport.shx / c_tile_w) ty := y + x + 2 + -(game.viewport.shy / c_tile_h) */ // XXX rounding errors? mut txi := int(tx) mut tyi := int(ty) // XXX correct y by shift, fixme? tyi = tyi - 1 /* vp_shx_tiles := game.viewport.shx / c_tile_w vp_shy_tiles := game.viewport.shy / c_tile_h txi = txi + vp_shx_tiles tyi = tyi + (vp_shy_tiles * 2) */ return txi, tyi }