Skip navigation

Monthly Archives: December 2013

GameCube_Analog_Stick[1]Here are a couple functions I wrote recently to improve my player movement. These are applicable to most 2d games.

The first is a wrapper around Polycode’s getJoystickAxisValue() function, which implements a gradient deadzone for analog sticks. This scales the speed of player movement by how far the analog stick is being tilted. It allows for more precise control and a better feeling for movement overall. The important bits are lines 11-13. This method is adapted from a Gamasutra post by Josh Sutphin.

function getScaledJoystickAxis(controllerIndex, stick)
        if Services.Core:getInput():getNumJoysticks() > controllerIndex then
                local retVal = Vector2(0, 0)
                if stick == JOY_LEFTSTICK then
                        retVal.x = Services.Core:getInput():getJoystickAxisValue(controllerIndex, JOY_LEFTSTICK_X)
                        retVal.y = Services.Core:getInput():getJoystickAxisValue(controllerIndex, JOY_LEFTSTICK_Y)
                elseif stick == JOY_RIGHTSTICK then
                        retVal.x = Services.Core:getInput():getJoystickAxisValue(controllerIndex, JOY_RIGHTSTICK_X)
                        retVal.y = Services.Core:getInput():getJoystickAxisValue(controllerIndex, JOY_RIGHTSTICK_Y)
                end
                if vMagnitude(retVal) > 0.23 then
                        return vNormalize(retVal, (vMagnitude(retVal) - 0.23) / 0.77)
                end
        end
        return Vector2(0, 0)
end

The second function modifies the player’s movement vector so that they cannot leave the boundaries of the arena, and is performed individually to each axis of movement. If their current velocity would move them past a boundary, they are instead moved the remaining distance to the boundary. This improves on the method most beginners use, in which movement is prevented altogether if it would result in a player being out of bounds.

function Player:clampMovementToArena(moveVect, pos, radius)
        local newMoveVect = Vector2(0,0)
 
        local leftWallDisp = arenaLeft - (pos.x - radius)
        local rightWallDisp = arenaRight - (pos.x + radius)
        local topWallDisp = arenaTop - (pos.y - radius)
        local bottomWallDisp = arenaBottom - (pos.y + radius)
 
        newMoveVect.x = math.max(moveVect.x, leftWallDisp)
        newMoveVect.x = math.min(newMoveVect.x, rightWallDisp)
        newMoveVect.y = math.max(moveVect.y, topWallDisp)
        newMoveVect.y = math.min(newMoveVect.y, bottomWallDisp)
 
        return newMoveVect
end

This is simple stuff, but it’s not always obvious to programmers new to game development. Feel free to adapt this for your own use, or, if you are using Polycode, copy it directly. I am trying to keep all code that is non-specific to Eucloid separate, and I’ll probably post it later on for other Polycode users to enjoy.

Design a site like this with WordPress.com
Get started