I'm trying to work with groups of multiple sprites, assemblies of such groups and correctly rotate and transform these.
So in the this code, which is just an example of my problem, I have the following types:
- Block : represents a sprite and holds a sprite ID (should hold other properties, but not in this example)
- BlockShape : represents connected blocks (sprites) which together forms a shape (see f.ex. tetris shapes, L-shape, cross, lines...)
- BlockGroup : represents a group of Block Shapes. In this example the groups are just multiple shapes on one line.
- BlockGroupAssembly : represents an assembly of groups.
What I want is to be able to orient a BlockShape in a certain direction, group multiple BlockShapes in a group, which again is oriented. Multiple BlockGroups should be controled by a BlockGroupAssembly, which should also be rotatable.
Here is a picture of what my example code gives:
Here is the example code:
global ASPECT as float
ASPECT = 1080.0/1920.0
global BLOCK_IMAGE as integer
BLOCK_IMAGE = LoadImage("box.png")
global BLOCK_SIZE as float
BLOCK_SIZE = 2.5
SetWindowSize(1080.0, 1920.0, 0)
SetDisplayAspect(ASPECT)
type BlockGroupAssembly
blockGroups as BlockGroup[]
endtype
type BlockGroup
blockShapes as BlockShape[]
endtype
type BlockShape
blocks as Block[]
endtype
type Block
sprite as integer
endtype
/*
Block - represents a sprite and holds a sprite ID (should hold other properties, but not in this example)
BlockShape - represents connected blocks (sprites) which together forms a shape (see f.ex. tetris shapes)
BlockGroup - represents a group of Block Shapes. In this example the groups are just multiple shapes on one line.
BlockGroupAssembly - represents an assembly of groups.
*/
/***************************************************************************/
function createBlockGroupAssembly()
/***************************************************************************/
assembly as BlockGroupAssembly
assembly.blockGroups.insert(createBlockGroup(4, 10.0, 10.0, 0))
assembly.blockGroups.insert(createBlockGroup(4, 90.0, 10.0, 100))
assembly.blockGroups.insert(createBlockGroup(4, 70.0, 70.0, 180))
assembly.blockGroups.insert(createBlockGroup(4, 20.0, 70.0, 255))
rotateBlockGroup(assembly.blockGroups[1], 100.0)
rotateBlockGroup(assembly.blockGroups[2], 180.0)
rotateBlockGroup(assembly.blockGroups[3], 260.0)
endfunction assembly
/***************************************************************************/
function createBlockGroup(n as integer, xpos as float, ypos as float, colr as integer)
/***************************************************************************/
_blockGroup as BlockGroup
for i = 0 to n - 1
_blockShape as BlockShape
_blockShape = createBlockShapeL(xpos, ypos, colr)
_blockGroup.blockShapes.insert(_blockShape)
xpos = xpos + 25.0
next i
endfunction _blockGroup
/***************************************************************************/
function createBlockShapeL(x as float, y as float, colr as integer)
/***************************************************************************/
_blockShape as BlockShape
_blockShape.blocks.insert(createBlock(x, y, colr))
x = x + BLOCK_SIZE
_blockShape.blocks.insert(createBlock(x, y, colr))
x = x + BLOCK_SIZE
_blockShape.blocks.insert(createBlock(x, y, colr))
y = y + BLOCK_SIZE*ASPECT
_blockShape.blocks.insert(createBlock(x, y, colr))
endfunction _blockShape
/***************************************************************************/
function createBlock(x as float, y as float, colr as integer)
/***************************************************************************/
_block as Block
_block.sprite = CreateSprite(BLOCK_IMAGE)
SetSpriteSize(_block.sprite, BLOCK_SIZE, -1)
SetSpritePosition(_block.sprite, x, y)
SetSpriteColorRed(_block.sprite, colr)
endfunction _block
/*
Rotation functions:
*/
/***************************************************************************/
function rotateBlockGroupAssembly(assembly ref as BlockGroupAssembly, dang as float)
/***************************************************************************/
rotp_x as float = 50.0
rotp_y as float = 50.0
for i = 0 to assembly.blockGroups.length
for j = 0 to assembly.blockGroups[i].blockShapes.length
for k = 0 to assembly.blockGroups[i].blockShapes[j].blocks.length
blockSprite = assembly.blockGroups[i].blockShapes[j].blocks[k].sprite
//SetSpriteOffset(blockSprite, rotp_x - GetSpriteXByOffset(blockSprite), rotp_y - GetSpriteYByOffset(blockSprite))
SetSpriteOffset(blockSprite, rotp_x - GetSpriteX(blockSprite), rotp_y - GetSpriteY(blockSprite))
SetSpriteAngle(blockSprite, GetSpriteAngle(blockSprite) + dang)
next k
next j
next i
endfunction
/***************************************************************************/
function rotateBlockGroup(_blockGroup ref as BlockGroup, angle as float)
/***************************************************************************/
rotp_x as float
rotp_y as float
//Rotating around the first block in the the shape:
sprite_00 = _blockGroup.blockShapes[0].blocks[0].sprite
rotp_x = GetSpriteX(sprite_00)
rotp_y = GetSPriteY(sprite_00)
for i = 0 to _blockGroup.blockShapes.length
for j = 0 to _blockGroup.blockShapes[i].blocks.length
offs_x as float
offs_y as float
sprite_ij = _blockGroup.blockShapes[i].blocks[j].sprite
offs_x = rotp_x - getSpriteX(sprite_ij)
offs_y = rotp_y - getSpriteY(sprite_ij)
SetSpriteOffset(sprite_ij, offs_x, offs_y)
SetSpriteAngle(sprite_ij, angle)
next j
next i
endfunction
/*NOT IMPLEMENTED*/
/***************************************************************************/
function rotateBlockShape(_blockShape ref as BlockShape, angle as float)
/***************************************************************************/
endfunction
/*NOT IMPLEMENTED*/
/***************************************************************************/
function rotateBlock(_blockGroup ref as BlockShape, angle as float)
/***************************************************************************/
endfunction
assembly as BlockGroupAssembly
assembly = createBlockGroupAssembly()
do
//rotateBlockGroupAssembly(assembly, 1.0)
Sync()
loop
So the only function that is being called to create the sprites is createBlockGroupAssembly(), this will create a few BlockGroups and using the rotateBlockGroup() will rotate each group.
What I tried to do in the function rotateBlockGroupAssembly() is to spin the whole assembly of block groups around a specific rotation group, while still keeping the relative orientations and positions between each group.
Eventually I'd like to this at many level, so, rotate the sprite around one point, the shape around another, the group, and then the assembly.
Is there a simple solution for this, or should I implement myself a system that takes care of the transformation calculation and keep track of different coordinate systems?