223 lines
4.8 KiB
V
223 lines
4.8 KiB
V
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
|
|
} |