diff options
Diffstat (limited to 'samples/99_genre_tactical_rpg/isometric_grid/app/main.rb')
| -rw-r--r-- | samples/99_genre_tactical_rpg/isometric_grid/app/main.rb | 262 |
1 files changed, 262 insertions, 0 deletions
diff --git a/samples/99_genre_tactical_rpg/isometric_grid/app/main.rb b/samples/99_genre_tactical_rpg/isometric_grid/app/main.rb new file mode 100644 index 0000000..28bea32 --- /dev/null +++ b/samples/99_genre_tactical_rpg/isometric_grid/app/main.rb @@ -0,0 +1,262 @@ +class Isometric + attr_accessor :grid, :inputs, :state, :outputs + + def tick + defaults + render + calc + process_inputs + end + + def defaults + state.quantity ||= 6 #Size of grid + state.tileSize ||= [262 / 2, 194 / 2] #width and heigth of orange tiles + state.tileGrid ||= [] #Holds ordering of tiles + state.currentSpriteLocation ||= -1 #Current Sprite hovering location + state.tileCords ||= [] #Physical, rendering cordinates + state.initCords ||= [640 - (state.quantity / 2 * state.tileSize[0]), 330] #Location of tile (0, 0) + state.sideSize ||= [state.tileSize[0] / 2, 242 / 2] #Purple & green cube face size + state.mode ||= :delete #Switches between :delete and :insert + state.spriteSelection ||= [['river', 0, 0, 262 / 2, 194 / 2], + ['mountain', 0, 0, 262 / 2, 245 / 2], + ['ocean', 0, 0, 262 / 2, 194 / 2]] #Storage for sprite information + #['name', deltaX, deltaY, sizeW, sizeH] + #^delta refers to distance from tile cords + + #Orders tiles based on tile placement and fancy math. Very left: 0,0. Very bottom: quantity-1, 0, etc + if state.tileGrid == [] + tempX = 0 + tempY = 0 + tempLeft = false + tempRight = false + count = 0 + (state.quantity * state.quantity).times do + if tempY == 0 + tempLeft = true + end + if tempX == (state.quantity - 1) + tempRight = true + end + state.tileGrid.push([tempX, tempY, true, tempLeft, tempRight, count]) + #orderX, orderY, exists?, leftSide, rightSide, order + tempX += 1 + if tempX == state.quantity + tempX = 0 + tempY += 1 + end + tempLeft = false + tempRight = false + count += 1 + end + end + + #Calculates physical cordinates for tiles + if state.tileCords == [] + state.tileCords = state.tileGrid.map do + |val| + x = (state.initCords[0]) + ((val[0] + val[1]) * state.tileSize[0] / 2) + y = (state.initCords[1]) + (-1 * val[0] * state.tileSize[1] / 2) + (val[1] * state.tileSize[1] / 2) + [x, y, val[2], val[3], val[4], val[5], -1] #-1 represents sprite on top of tile. -1 for now + end + end + + end + + def render + renderBackground + renderLeft + renderRight + renderTiles + renderObjects + renderLabels + end + + def renderBackground + outputs.solids << [0, 0, 1280, 720, 0, 0, 0] #Background color + end + + def renderLeft + #Shows the pink left cube face + outputs.sprites << state.tileCords.map do + |val| + if val[2] == true && val[3] == true #Checks if the tile exists and right face needs to be rendered + [val[0], val[1] + (state.tileSize[1] / 2) - state.sideSize[1], state.sideSize[0], + state.sideSize[1], 'sprites/leftSide.png'] + end + end + end + + def renderRight + #Shows the green right cube face + outputs.sprites << state.tileCords.map do + |val| + if val[2] == true && val[4] == true #Checks if it exists & checks if right face needs to be rendered + [val[0] + state.tileSize[0] / 2, val[1] + (state.tileSize[1] / 2) - state.sideSize[1], state.sideSize[0], + state.sideSize[1], 'sprites/rightSide.png'] + end + end + end + + def renderTiles + #Shows the tile itself. Important that it's rendered after the two above! + outputs.sprites << state.tileCords.map do + |val| + if val[2] == true #Chcekcs if tile needs to be rendered + if val[5] == state.currentSpriteLocation + [val[0], val[1], state.tileSize[0], state.tileSize[1], 'sprites/selectedTile.png'] + else + [val[0], val[1], state.tileSize[0], state.tileSize[1], 'sprites/tile.png'] + end + end + end + end + + def renderObjects + #Renders the sprites on top of the tiles. Order of rendering: top corner to right corner and cascade down until left corner + #to bottom corner. + a = (state.quantity * state.quantity) - state.quantity + iter = 0 + loop do + if state.tileCords[a][2] == true && state.tileCords[a][6] != -1 + outputs.sprites << [state.tileCords[a][0] + state.spriteSelection[state.tileCords[a][6]][1], + state.tileCords[a][1] + state.spriteSelection[state.tileCords[a][6]][2], + state.spriteSelection[state.tileCords[a][6]][3], state.spriteSelection[state.tileCords[a][6]][4], + 'sprites/' + state.spriteSelection[state.tileCords[a][6]][0] + '.png'] + end + iter += 1 + a += 1 + a -= state.quantity * 2 if iter == state.quantity + iter = 0 if iter == state.quantity + break if a < 0 + end + end + + def renderLabels + #Labels + outputs.labels << [50, 680, 'Click to delete!', 5, 0, 255, 255, 255, 255] if state.mode == :delete + outputs.labels << [50, 640, 'Press \'i\' for insert mode!', 5, 0, 255, 255, 255, 255] if state.mode == :delete + outputs.labels << [50, 680, 'Click to insert!', 5, 0, 255, 255, 255, 255] if state.mode == :insert + outputs.labels << [50, 640, 'Press \'d\' for delete mode!', 5, 0, 255, 255, 255, 255] if state.mode == :insert + end + + def calc + calcCurrentHover + end + + def calcCurrentHover + #This determines what tile the mouse is hovering (or last hovering) over + x = inputs.mouse.position.x + y = inputs.mouse.position.y + m = (state.tileSize[1] / state.tileSize[0]) #slope + state.tileCords.map do + |val| + #Conditions that makes runtime faster. Checks if the mouse click was between tile dimensions (rectangle collision) + next unless val[0] < x && x < val[0] + state.tileSize[0] + next unless val[1] < y && y < val[1] + state.tileSize[1] + next unless val[2] == true + tempBool = false + if x == val[0] + (state.tileSize[0] / 2) + #The height of a diamond is the height of the diamond, so if x equals that exact point, it must be inside the diamond + tempBool = true + elsif x < state.tileSize[0] / 2 + val[0] + #Uses y = (m) * (x - x1) + y1 to determine the y values for the two diamond lines on the left half of diamond + tempY1 = (m * (x - val[0])) + val[1] + (state.tileSize[1] / 2) + tempY2 = (-1 * m * (x - val[0])) + val[1] + (state.tileSize[1] / 2) + #Checks to see if the mouse click y value is between those temp y values + tempBool = true if y < tempY1 && y > tempY2 + elsif x > state.tileSize[0] / 2 + val[0] + #Uses y = (m) * (x - x1) + y1 to determine the y values for the two diamond lines on the right half of diamond + tempY1 = (m * (x - val[0] - (state.tileSize[0] / 2))) + val[1] + tempY2 = (-1 * m * (x - val[0] - (state.tileSize[0] / 2))) + val[1] + state.tileSize[1] + #Checks to see if the mouse click y value is between those temp y values + tempBool = true if y > tempY1 && y < tempY2 + end + + if tempBool == true + state.currentSpriteLocation = val[5] #Current sprite location set to the order value + end + end + end + + def process_inputs + #Makes development much faster and easier + if inputs.keyboard.key_up.r + $dragon.reset + end + checkTileSelected + switchModes + end + + def checkTileSelected + if inputs.mouse.down + x = inputs.mouse.down.point.x + y = inputs.mouse.down.point.y + m = (state.tileSize[1] / state.tileSize[0]) #slope + state.tileCords.map do + |val| + #Conditions that makes runtime faster. Checks if the mouse click was between tile dimensions (rectangle collision) + next unless val[0] < x && x < val[0] + state.tileSize[0] + next unless val[1] < y && y < val[1] + state.tileSize[1] + next unless val[2] == true + tempBool = false + if x == val[0] + (state.tileSize[0] / 2) + #The height of a diamond is the height of the diamond, so if x equals that exact point, it must be inside the diamond + tempBool = true + elsif x < state.tileSize[0] / 2 + val[0] + #Uses y = (m) * (x - x1) + y1 to determine the y values for the two diamond lines on the left half of diamond + tempY1 = (m * (x - val[0])) + val[1] + (state.tileSize[1] / 2) + tempY2 = (-1 * m * (x - val[0])) + val[1] + (state.tileSize[1] / 2) + #Checks to see if the mouse click y value is between those temp y values + tempBool = true if y < tempY1 && y > tempY2 + elsif x > state.tileSize[0] / 2 + val[0] + #Uses y = (m) * (x - x1) + y1 to determine the y values for the two diamond lines on the right half of diamond + tempY1 = (m * (x - val[0] - (state.tileSize[0] / 2))) + val[1] + tempY2 = (-1 * m * (x - val[0] - (state.tileSize[0] / 2))) + val[1] + state.tileSize[1] + #Checks to see if the mouse click y value is between those temp y values + tempBool = true if y > tempY1 && y < tempY2 + end + + if tempBool == true + if state.mode == :delete + val[2] = false + state.tileGrid[val[5]][2] = false #Unnecessary because never used again but eh, I like consistency + state.tileCords[val[5]][2] = false #Ensures that the tile isn't rendered + unless state.tileGrid[val[5]][0] == 0 #If tile is the left most tile in the row, right doesn't get rendered + state.tileGrid[val[5] - 1][4] = true #Why the order value is amazing + state.tileCords[val[5] - 1][4] = true + end + unless state.tileGrid[val[5]][1] == state.quantity - 1 #Same but left side + state.tileGrid[val[5] + state.quantity][3] = true + state.tileCords[val[5] + state.quantity][3] = true + end + elsif state.mode == :insert + #adds the current sprite value selected to tileCords. (changes from the -1 earlier) + val[6] = rand(state.spriteSelection.length) + end + end + end + end + end + + def switchModes + #Switches between insert and delete modes + if inputs.keyboard.key_up.i && state.mode == :delete + state.mode = :insert + inputs.keyboard.clear + elsif inputs.keyboard.key_up.d && state.mode == :insert + state.mode = :delete + inputs.keyboard.clear + end + end + +end + +$isometric = Isometric.new + +def tick args + $isometric.grid = args.grid + $isometric.inputs = args.inputs + $isometric.state = args.state + $isometric.outputs = args.outputs + $isometric.tick +end |
