From b58c1afa420340233877ef513ca7a921072901ef Mon Sep 17 00:00:00 2001 From: Ratstail91 Date: Wed, 8 Mar 2023 07:58:02 +1100 Subject: [PATCH] Added lejana's kick animation --- assets/scripts/gameplay/lejana.toy | 78 +++++++++++----- assets/scripts/init.toy | 1 + assets/sprites/lejana-mask.png | Bin 0 -> 1619 bytes assets/sprites/lejana.png | Bin 1889 -> 4021 bytes box/lib_node.c | 137 ++++++++++++++++++++++++++++- 5 files changed, 191 insertions(+), 25 deletions(-) create mode 100644 assets/sprites/lejana-mask.png diff --git a/assets/scripts/gameplay/lejana.toy b/assets/scripts/gameplay/lejana.toy index 091b93c..b364696 100644 --- a/assets/scripts/gameplay/lejana.toy +++ b/assets/scripts/gameplay/lejana.toy @@ -28,7 +28,7 @@ var inputY: int = 0; var direction: int = null; //BUGFIX: animation not looping properly var enableMovementCounter: int = 30 * 3; //BUGFIX: freeze while drones reach their starting spot - +var attackCounter: int = 0; //polyfills - animating different cycles on one image var stepCount: int = 0; @@ -106,26 +106,9 @@ fn onStep(node: opaque) { enableMovementCounter--; return; } - + //process input when aligned to a grid if (realX / TILE_WIDTH == gridX && realY / TILE_HEIGHT == gridY && motionX == 0 && motionY == 0) { - //disallow wall phasing - if (inputX != 0 && parent.callNodeFn("getCollisionAt", gridX + inputX, gridY) != true) { - inputX = 0; - } - - if (inputY != 0 && parent.callNodeFn("getCollisionAt", gridX, gridY + inputY) != true) { - inputY = 0; - } - - //disallow diagonal movement - if (abs(inputX) != 0) { - gridX += inputX; - } - else { - gridY += inputY; - } - //facing if (inputY > 0) { node.faceDown(); @@ -143,21 +126,58 @@ fn onStep(node: opaque) { node.faceLeft(); } + //disallow wall phasing + if (inputX != 0 && parent.callNodeFn("getCollisionAt", gridX + inputX, gridY) != true) { + inputX = 0; + } + + if (inputY != 0 && parent.callNodeFn("getCollisionAt", gridX, gridY + inputY) != true) { + inputY = 0; + } + + //disallow diagonal movement + if (abs(inputX) != 0) { + gridX += inputX; + } + else { + gridY += inputY; + } + //trigger the world if (inputX != 0 || inputY != 0) { parent.callNodeFn("runAI"); } } - //animation - if (motionX == 0 && motionY == 0 && inputX == 0 && inputY == 0) { - stepCount = 0; - node.setCurrentNodeFrame(0); + //animation - standing still + if (attackCounter == 0 && stepCount == 0) { + //move to standing state + if (node.getNodeRectY() != 0) { + node.setNodeRect(direction * 32 * 4, 0, 32, 32); + node.setNodeFrames(4); + } } + //animation - attacking + if (attackCounter > 0 && stepCount == 0) { + //move to attacking state + if (node.getNodeRectY() != 32) { + node.setNodeRect(direction * 32 * 4, 32, 32, 32); + node.setNodeFrames(3); + } + } + + //actually animate if (++stepCount >= 5) { + if (motionX == 0 && motionY == 0 && inputX == 0 && inputY == 0) { + stepCount = 0; + } + + if (attackCounter > 0) { + attackCounter--; + } + node.incrementCurrentNodeFrame(); - stepCount = 0; } //calc movement @@ -183,6 +203,16 @@ fn customOnDraw(node: opaque, parentX: int, parentY: int) { //event functions fn onKeyDown(node: opaque, event: string) { + //initial freeze + if (enableMovementCounter > 0) { + return; + } + + if (event == "character_attack" && inputX == 0 && inputY == 0) { + attackCounter = 2; + return; + } + if (event == "character_up") { inputY -= 1; return; diff --git a/assets/scripts/init.toy b/assets/scripts/init.toy index e7377a2..76db406 100644 --- a/assets/scripts/init.toy +++ b/assets/scripts/init.toy @@ -26,6 +26,7 @@ mapInputEventToKeyUp("character_down", "down"); //event, keysym mapInputEventToKeyUp("character_right", "right"); //event, keysym + mapInputEventToKeyDown("character_attack", "space"); //event, keysym //TODO: escape to kill the game diff --git a/assets/sprites/lejana-mask.png b/assets/sprites/lejana-mask.png new file mode 100644 index 0000000000000000000000000000000000000000..1d5e7a41885c659472d9b4891b8b8bf9a9928d70 GIT binary patch literal 1619 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%0DtdUZN^hF>8}IJ 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 diff --git a/box/lib_node.c b/box/lib_node.c index 6f2b980..3293468 100644 --- a/box/lib_node.c +++ b/box/lib_node.c @@ -488,6 +488,138 @@ static int nativeSetNodeRect(Toy_Interpreter* interpreter, Toy_LiteralArray* arg return 0; } +static int nativeGetNodeRectX(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { + if (arguments->count != 1) { + interpreter->errorOutput("Incorrect number of arguments passed to getNodeRectX\n"); + return -1; + } + + //extract the arguments + Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments); + + Toy_Literal nodeIdn = nodeLiteral; + if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) { + Toy_freeLiteral(nodeIdn); + } + + //check argument types + if (!TOY_IS_OPAQUE(nodeLiteral)) { + interpreter->errorOutput("Incorrect argument type passed to getNodeRectX\n"); + Toy_freeLiteral(nodeLiteral); + return -1; + } + + //actually get + Box_EngineNode* node = (Box_EngineNode*)TOY_AS_OPAQUE(nodeLiteral); + Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(node->rect.x); + Toy_pushLiteralArray(&interpreter->stack, resultLiteral); + + //cleanup + Toy_freeLiteral(nodeLiteral); + Toy_freeLiteral(resultLiteral); + + return 1; +} + +static int nativeGetNodeRectY(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { + if (arguments->count != 1) { + interpreter->errorOutput("Incorrect number of arguments passed to getNodeRectY\n"); + return -1; + } + + //extract the arguments + Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments); + + Toy_Literal nodeIdn = nodeLiteral; + if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) { + Toy_freeLiteral(nodeIdn); + } + + //check argument types + if (!TOY_IS_OPAQUE(nodeLiteral)) { + interpreter->errorOutput("Incorrect argument type passed to getNodeRectY\n"); + Toy_freeLiteral(nodeLiteral); + return -1; + } + + //actually get + Box_EngineNode* node = (Box_EngineNode*)TOY_AS_OPAQUE(nodeLiteral); + Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(node->rect.y); + Toy_pushLiteralArray(&interpreter->stack, resultLiteral); + + //cleanup + Toy_freeLiteral(nodeLiteral); + Toy_freeLiteral(resultLiteral); + + return 1; +} + +static int nativeGetNodeRectW(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { + if (arguments->count != 1) { + interpreter->errorOutput("Incorrect number of arguments passed to getNodeRectW\n"); + return -1; + } + + //extract the arguments + Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments); + + Toy_Literal nodeIdn = nodeLiteral; + if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) { + Toy_freeLiteral(nodeIdn); + } + + //check argument types + if (!TOY_IS_OPAQUE(nodeLiteral)) { + interpreter->errorOutput("Incorrect argument type passed to getNodeRectW\n"); + Toy_freeLiteral(nodeLiteral); + return -1; + } + + //actually get + Box_EngineNode* node = (Box_EngineNode*)TOY_AS_OPAQUE(nodeLiteral); + Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(node->rect.w); + Toy_pushLiteralArray(&interpreter->stack, resultLiteral); + + //cleanup + Toy_freeLiteral(nodeLiteral); + Toy_freeLiteral(resultLiteral); + + return 1; +} + +static int nativeGetNodeRectH(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { + if (arguments->count != 1) { + interpreter->errorOutput("Incorrect number of arguments passed to getNodeRectH\n"); + return -1; + } + + //extract the arguments + Toy_Literal nodeLiteral = Toy_popLiteralArray(arguments); + + Toy_Literal nodeIdn = nodeLiteral; + if (TOY_IS_IDENTIFIER(nodeLiteral) && Toy_parseIdentifierToValue(interpreter, &nodeLiteral)) { + Toy_freeLiteral(nodeIdn); + } + + //check argument types + if (!TOY_IS_OPAQUE(nodeLiteral)) { + interpreter->errorOutput("Incorrect argument type passed to getNodeRectH\n"); + Toy_freeLiteral(nodeLiteral); + return -1; + } + + //actually get + Box_EngineNode* node = (Box_EngineNode*)TOY_AS_OPAQUE(nodeLiteral); + Toy_Literal resultLiteral = TOY_TO_INTEGER_LITERAL(node->rect.h); + Toy_pushLiteralArray(&interpreter->stack, resultLiteral); + + //cleanup + Toy_freeLiteral(nodeLiteral); + Toy_freeLiteral(resultLiteral); + + return 1; +} + static int nativeSetNodeFrames(Toy_Interpreter* interpreter, Toy_LiteralArray* arguments) { if (arguments->count != 2) { interpreter->errorOutput("Incorrect number of arguments passed to setNodeFrames\n"); @@ -973,7 +1105,10 @@ int Box_hookNode(Toy_Interpreter* interpreter, Toy_Literal identifier, Toy_Liter {"loadNodeTexture", nativeLoadNodeTexture}, {"freeNodeTexture", nativeFreeNodeTexture}, {"setNodeRect", nativeSetNodeRect}, - //get rect + {"getNodeRectX", nativeGetNodeRectX}, + {"getNodeRectY", nativeGetNodeRectY}, + {"getNodeRectW", nativeGetNodeRectW}, + {"getNodeRectH", nativeGetNodeRectH}, {"setNodeFrames", nativeSetNodeFrames}, {"getNodeFrames", nativeGetNodeFrames}, {"setCurrentNodeFrame", nativeSetCurrentNodeFrame},