• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

MoveEvent [1.3] Snek šŸ

Noice Thats Nice GIF
 
Cute game! there are little problem is you use keys so fast the game kick you, only that, but all is nice! thanks for share Snavy!
 
There is a small problem. If I have not seal a single apple, the game is complete and I stay in place. In the rest, everything is fine.
So far I am waiting for an answer, in the pop contact your other scripts))
 
Game work exelent on TFS 1.4. Thank you!
Post automatically merged:

šŸ Snek For TFS 1.3 šŸ
How to play:
(CTRL + Arrows) to move snake.

map setup

data/scripts/snake.lua
Lua:
local config = {
    -- Don't change ( unless you know what you're doing )
    TILE_CUSTOMATTR_KEY = "snakeScore",

    -- Where players will be kicked after finishing the game.
    KICKPLAYER_POS  = Position(201, 390, 7),

    -- Where players will steer the snake.
    CONTROL_POS     = Position(213, 391, 6),

    -- Snake room corner positions
    TOP_LEFT        = Position(205, 385, 7),
    BOTTOM_RIGHT    = Position(219, 395, 7),
    SNAKE_SPAWN_POS = Position(212, 390, 7),

    FOOD_ID  = 2674,
    SNAKE_ID = 463,

    -- How long the snake will be at start
    SNAKE_START_SCORE = 3,
    SPEED_START = 600, -- 0.6s

    -- How much faster the snake will get..
    -- ..after consuming 'food' object. ( milliseconds )
    SPEED_INCREMENT = 100, -- 0.1s

    -- ActionId to be used on enter tile
    TILE_ACTION_ID = 12345,

    -- How long a player should wait before they can play again
    PLAYER_PLAY_STORAGE = 191214,
    PLAYER_PLAY_DELAY = 10 -- 10 seconds
}
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function handleSnakeTile(position, score)
    local tile = Tile(position)
    if not tile:getGround() then
        return print("[Warning - snake::handleSnakeTile] Ground not found.")
    end
    local tailScore = tile:getGround():getCustomAttribute(config.TILE_CUSTOMATTR_KEY)
    local snakeObject = tile:getItemById(config.SNAKE_ID)
    if not tailScore or tailScore == 0 then
        if snakeObject then
            snakeObject:remove()
        end
        return
    end
    tile:getGround():setCustomAttribute(config.TILE_CUSTOMATTR_KEY, tailScore - 1)
    if (tailScore - 1) == 0 and snakeObject then
        snakeObject:remove()
    end
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function moveSnake(nextHeadPosition, score)
    if not Game.createItem(config.SNAKE_ID, 1, nextHeadPosition) then
        print('[Error - snake::moveSnake] Could not create item snake.')
        return
    end
    local tile = Tile(nextHeadPosition)
    tile:getGround():setCustomAttribute(config.TILE_CUSTOMATTR_KEY, score + 1)
    local z = config.TOP_LEFT.z
    for y = config.TOP_LEFT.y, config.BOTTOM_RIGHT.y do
        for x = config.TOP_LEFT.x, config.BOTTOM_RIGHT.x do
            handleSnakeTile(Position(x, y, z), score)
        end
    end
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function showScore(player, score)
    local text = "Snake Score: " .. score
    player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, text)
    player:setStorageValue(config.PLAYER_PLAY_STORAGE, config.PLAYER_PLAY_DELAY + os.time())
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function placeFood()
    Game.createItem(config.FOOD_ID, 1, Position(
        math.random(config.TOP_LEFT.x, config.BOTTOM_RIGHT.x),
        math.random(config.TOP_LEFT.y, config.BOTTOM_RIGHT.y),
        config.TOP_LEFT.z
    ))
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function isFood(position)
    local tile = Tile(position)
    if not tile then return true end
    local foodObject = tile:getItemById(config.FOOD_ID)
    if foodObject then
        foodObject:remove()
        placeFood()
        return true
    end
    return false
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function isSnakeTail(position)
    local tile = Tile(position)
    if not tile then return true end
    local snakeObject = tile:getItemById(config.SNAKE_ID)
    if snakeObject then
        return true
    end
    return false
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function isWall(position)
    if (position.x < config.TOP_LEFT.x)
    or (position.x > config.BOTTOM_RIGHT.x)
    or (position.y < config.TOP_LEFT.y)
    or (position.y > config.BOTTOM_RIGHT.y) then
        return true
    end
    return false
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function createSnake()
    local tile = Tile(config.SNAKE_SPAWN_POS)
    if not tile then
        return print("[Error - snake::createSnake] Tile not found")
    end
    local ground = tile:getGround()
    if not ground then
        return print("[Error - snake::createSnake] Ground not found.")
    end
    ground:setCustomAttribute(config.TILE_CUSTOMATTR_KEY, config.SNAKE_START_SCORE)
    Game.createItem(config.SNAKE_ID, 1, config.SNAKE_SPAWN_POS)
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function positionToReadable(position)
    return "(".. position.x .." / ".. position.y .." / ".. position.z ..")"
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function clearTile(position)
    local tile = Tile(position)
    if not tile then
        return print("[Warning - snake::clearSnakeArea] Tile not found " .. positionToReadable(position))
    end
    local tileItems = tile:getItems()
    if tileItems then
        for _, item in pairs(tileItems) do
            item:remove()
        end
    end
    -- Maybe there's a sneaky GM? xD
    local creature = tile:getTopCreature(position)
    if creature then
        creature:teleportTo(config.KICKPLAYER_POS)
    end
    tile:getGround():removeCustomAttribute(config.TILE_CUSTOMATTR_KEY)
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function clearSnakeArea()
    local z = config.TOP_LEFT.z
    for y = config.TOP_LEFT.y, config.BOTTOM_RIGHT.y do
        for x = config.TOP_LEFT.x, config.BOTTOM_RIGHT.x do
            clearTile(Position(x, y, z))
        end
    end
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function gameLoop(player, score, speed, headPosition)
    player = Player(player)
    if (not player) or (not Tile(config.CONTROL_POS):getTopCreature()) then
        return print('[Error - snake::gameLoop] Player not found.')
    end
    local direction  = player:getDirection()
    headPosition:getNextPosition(direction)
    if isWall(headPosition) or isSnakeTail(headPosition) then
        showScore(player, score)
        player:teleportTo(config.KICKPLAYER_POS)
        clearSnakeArea()
        return
    end
    local foundFood = false
    if isFood(headPosition) then
        foundFood = true
        score = score + 1
        player:sendTextMessage(MESSAGE_STATUS_CONSOLE_BLUE, 'score: ' .. score)
    end
    moveSnake(headPosition, score)
    if foundFood then
        speed = speed - config.SPEED_INCREMENT
        if speed <= 100 then
            speed = 100
        end
    end
    addEvent(gameLoop, speed, player:getId(), score, speed, headPosition)
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local function init(player)
    clearSnakeArea()
    placeFood()
    createSnake()
    player:teleportTo(config.CONTROL_POS)
    local headPosition = Position(
        config.SNAKE_SPAWN_POS.x,
        config.SNAKE_SPAWN_POS.y,
        config.SNAKE_SPAWN_POS.z
    )
    gameLoop(player:getId(), config.SNAKE_START_SCORE, config.SPEED_START, headPosition)
end
-- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ## -- ##
local snakeEnter = MoveEvent("snakeEnter")
snakeEnter:type('stepin')
function snakeEnter.onStepIn(player, item, position, fromPosition)
    local controlTile = Tile(config.CONTROL_POS)
    if controlTile and controlTile:getTopCreature() then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, 'The game is currently occupied. Try again later.')
        player:teleportTo(fromPosition)
        fromPosition:sendMagicEffect(CONST_ME_POFF)
        return true
    end

    local lastPlayed = player:getStorageValue(config.PLAYER_PLAY_STORAGE)
    if lastPlayed > os.time() then
        player:sendTextMessage(MESSAGE_STATUS_SMALL, 'You need to wait ' .. (lastPlayed - os.time()) .. ' seconds.')
        player:teleportTo(fromPosition)
        fromPosition:sendMagicEffect(CONST_ME_POFF)
        return true
    end

    init(player)
    return true
end

snakeEnter:aid(config.TILE_ACTION_ID)
snakeEnter:register()


Preview
View attachment 57427
One question, how to change this SNAKE_START_SCORE = 3,?
Replace this with something else that will allow you to start with 0 points initially but with a snake length of 3.
 
Last edited:
Back
Top