Artyom Volkov

Ludum Dare 45

HONK, HONK, MOTHERDUCKERS!

LD45.png

honk15.gif

Have you ever thought, why a goose steals humans stuff?

Maybe he is preparing for eternal battle with forces of evil?

Titled Goose Team present a brand new game about goose guy - HONK.

HONK is a true story behind strange behaviour (from humans perspective) of a goose. And without any lootboxes!

PLAY NOW

Unreleased level

When I started working on HONK I wanted to make a real singleplayer experience. However, I realized, I couldn't deliver good results in such short time in such a tiny team (an artist and I). Nonethe less, I had made a level with doors (which enemies can open) and spawn system.

honkLevel.png

Art of reap and tear!

Because the game doesn't clean a surface, all the blood is kept on the level. After several playthroughs, the floor of the arena takes after a piece of abstract art... Art of reap and tear!

screen 0.png

Play the game

Make cool gif preview!

Gif preview is always better than just screenshots, but not many people know what sofware they should use for this.

For my game HONK I use 2 things: 1. Screentogif, as a gif recorder and as an editor; 2. Build in gif recorder in Game Maker Studio 2;

The difference is that GM2 gif recorder doesn't record UI, that's why I also use Screentogif.

Using both methotds or only screentogif can help you make a lot of cool gifs for your game.

honk16.gif

honk17.gif

Small post-jam update

Now you can download a post-jam version of HONK.

There aren't many changes: 1. You can see your time and score on the End screen. 2. Blood now is less vivid. 3. Some sounds are less loud.

Here is my personal record!

2019-10-10_20-16-52.png

Movement is a key

Here is some information about movement system in HONK which I'll use in my another project One Spear, One Kill.

First of all, it based on this tutorial - A Comprehensive Guide To Time Dilation. Even though there is an example project, I've written my own system, which I use everywhere in the game.

Scripts

If I need to move something with acceleration or deceleration I will add in Step Event these scripts: 1. MoveObject; 2. CalculateAcceleratedVelocity; 3. CalculateDeceleratedVelocity; 4. CalculateConstantMovement;

MoveObject

It's a straightforward script, but because of using this system everywhere wherever I want, I keep it so simple. As different things require different calculations. For instance, I use both CalculateAcceleratedVelocity and CalculateDeceleratedVelocity in the player object; on the other hand, in projectiles, I use only one of these things at the same time.

It's very important to call this script before velocity calculations.

```gml //------------// // MoveObject // //------------//

// @param isConstant

var _isConstant = argument0;

if (_isConstant) { x += velocityX * global.TimeFactor; y += velocityY * global.TimeFactor; } else { x += velocityX; y += velocityY; } ```

CalculateAceleratedVelocity

This script calculates velocity while an object is accelerating.

``` //------------------------------// // CalculateAcceleratedVelocity // //------------------------------//

/// @param direction /// @param velocityCurrent /// @param velocityMax /// @param acceleration

var _targetDirection = argument0; var _velocityCurrent = argument1; var _velocityMax = argument2; var _acceleration = argument3;

//Delta X and Y calculations var positionDelta = global.TimeFactor * _velocityCurrent + (0.5 * sqr(global.TimeFactor) * _acceleration); _velocityCurrent = min(velocityCurrent + acceleration * global.TimeFactor, _velocityMax); velocityX = lengthdirx(positionDelta, _targetDirection); velocityY = lengthdiry(_positionDelta, _targetDirection);

return _velocityCurrent; ```

CalculateDeceleratedVelocity

This script calculates velocity while an object is decelerating.

``` //------------------------------// // CalculateDeceleratedVelocity // //------------------------------//

/// @param direction /// @param velocityCurrent /// @param friction

var _targetDirection = argument0; var _velocityCurrent = argument1; var _friction = argument2;

var addX = _friction * sign(velocityCurrent); var positionDelta = global.TimeFactor * _velocityCurrent + (0.5 * sqr(global.TimeFactor) * _addX); _velocityCurrent = max(velocityCurrent - friction * global.TimeFactor, 0); velocityX = lengthdirx(positionDelta, _targetDirection); velocityY = lengthdiry(_positionDelta, _targetDirection);

return _velocityCurrent; ```

CalculateConstantVelocity

In case when I need to move something with a constant velocity I use this script.

``` //---------------------------// // CalculateConstantVelocity // //---------------------------//

/// @param Velocity /// @param direction

var _velocity = argument0; var _direction = argument1;

velocityX = lengthdirx(velocity, direction); velocityY = lengthdiry(_velocity, _direction); ```

Collisions

And what about collisions? I use a classic script for checking collisions, and I place it after all movement calculations.

But be aware, I don't use this script to execute other code, e.g. destroying projectiles, dealing damage etc.

``` //----------------// // CheckCollision // //----------------//

// @param object

var _object = argument0;

// Collision X if (placemeeting(x + velocityX, y, _object)) { while (!placemeeting(x + sign(velocityX), y, _object)) { x += sign(velocityX); } velocityX = 0; }

// Collision Y if (placemeeting(x, y + velocityY, _object)) { while (!placemeeting(x, y + sign(velocityY), _object)) { y += sign(velocityY); } velocityY = 0; } ```

Thank you for reading, feel free to ask questions and give feedback.

Original devlog

Epic death update

I've just made a small post-jam update of HONK with better camera, damage feedback and an epic death sequence!

honk19.gif

HONK reaps Apple

My friend built a post-jam Mac version of HONK! Hope it works well.

He also made a game for the Ludum Dare 45 - HUMAN.

honk19.gif

Heavy post-jam update

Frankly, I didn't think to work on some postjam versions, but I can't stop making HONK a little bit better. And here is a heavy update!

LD45.png

  1. NEW MUSIC! Music by TeknoAXE​​:
  2. New balance. Ammo and medkits now drop less frequently.
  3. Some bug fixes.

Reap and tear without problems

Here is a short tutorial about bloody effect in HONK.

honk05.gif

First of all, this effect is based on this tutorial https://www.youtube.com/watch?v=nz8FUMHEyAU

However, I've made some slight changes to make it better for my game. I think, that my approach is still clunky and needs some upgrade in the future.

Step 0. Make movement system

I use my movement system in this effect, I highly recommend to read about it. Movement.

Step 1. Setup surface object

In my game I use special object which is called obj_drawer, this object does one job - sorting sprites and drawing them in the order I need. It takes a lot of time to explain this, now you should create an empty object which will control surface for these bloody effects.

Create event surfaceFloorEffects= surface_create(room_width, room_height);

Draw event if (surface_exists(surfaceFloorEffects)) { draw_surface_ext(surfaceFloorEffects, 0, 0, 1.0, 1.0, 0, c_white, 1.0); } else { surfaceFloorEffects = surface_create(room_width, room_height); }

Clear event surface_free(surfaceFloorEffects);

Step 2. Setup base object

In the project I use special base objects. They include some logic, which is shared by other objects, e.g. I have obj_sortable, which contain logic for sorting etc.

In this case this you need to create obj_floorEffect and place it on your level.

Destroy event ``` var surface = objdrawer.surfaceFloorEffects;

if (surfaceexists(surface)) { surfacesettarget(_surface);

draw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, direction, c_gray, image_alpha);

surface_reset_target();

} else { surface = surfacecreate(roomwidth, roomheight); } ```

Step 3. Setup splatter object

Create object vfx_splatter without any sprite.

Variable definitions

You need this variables to adjust child objects.

vfxemslplatter/emvd.png

Create event ``` velocityMax = 20;

// Visual paarameters imagespeed = 0; imageindex = irandomrange(0, imagenumber - 1); imagexscale = randomrange(0.05, 1); imageyscale = randomrange(0.05, 1); imagealpha = randomrange(0.25, 1);

// Movement parameters direction = randomrange(0, 359); imageangle = direction; velocityCurrent = randomrange(0.4, velocityMax); groundFriction = randomrange(0.1, 0.2); velocityX = 0; velocityY = 0;

// Smear parameters smearTime = 3; smearTimer = 0; **Step event** // Movement MoveObject();

velocityCurrent = CalculateDeceleratedVelocity(direction, velocityCurrent, groundFriction);

if (velocityCurrent <= 0) { instance_destroy() }

// Smearing smearTimer += global.TimeFactor;

var checkTimer = checktimer(smearTimer, smearTime);

if (_checkTimer) { smearTimer = 0;

instance_create_layer(x, y, layer, smearObject);

} ``` check_timer script

Be aware, I use timefactor, it means you need to arrange global.TimeFactor somewhere at the very start of the game. gml global.TimeFactor = 1;

``` /// @param timer /// @param time

var _timer = argument0; var _time = argument1;

return (floor(timer) >= _time && floor(timer - global.TimeFactor) != floor(_timer)); ```

Step 4. Setup smear object

Create object vfxsmear. It must not have any sprite as well as vfxsplatter.

Create event ``` imagespeed = 0; imageindex = irandomrange(0, imagenumber - 1); imagexscale = randomrange(0.05, 0.5); imageyscale = randomrange(0.05, 0.5); imageangle = irandomrange(0, 359); imagealpha = randomrange(0.25, 1);

instance_destroy(); ```

Step 5. Create sprites and child objects

Here is an example of blood sprite. sprembloodSplatters/emstrip6.png

Yep, it’s small.

After this, you need to create a new object for splatter and smear and make their parents vfxsplatter and vfxsmear relatively.

Do not forget to set up variable definitions.

Step 6. Make a spawn script

This script will definitely make adjustments of the effect easier.

``` /// @param x /// @param y /// @param splatterObject /// @param count /// @param velocityMax

var _x = argument0; var _y = argument1; var _object = argument2; var _count = argument3; var _velocity = argument4;

for (var i = 0; i < count; i++) { var _splatter = instancecreatelayer(x, _y, layer, _object);

with (_splatter)
{
    velocityMax = _velocity;
    velocityCurrent = random_range(0.4, velocityMax);
}

} ```

Step 7. Use script

Now you can place this script wherever you want, but be careful when you will use it in step events.

Step 8. ???

Step 9. PROFIT!

Now you can reap and tear in your game with ease!

Input method manager

I have a strong notion, a game should always have gamepad and keyboard controls and a player shouldn't spend a lot of time on switching between them.

That's why I've made a simple input method manager which I used in HONK. You should place this object in all rooms and it will change your input method on the go.

Create Event

``` // Create a list of gamepad slots connectedGamepads = dslistcreate();

// Set active gamepad global.ActiveGamepad = noone;

// Setup input methods enum InputMethod { Gamepad, KeyboardMouse }

// Set current input global.CurrentInput = InputMethod.KeyboardMouse;

// Set deadzone and threshhold for Xbox gamepad xboxAxisDeadzone = 0.25; xboxButtonThreshhold = 0.1;

// Set deadzone and threshhold for PS4 gamepad ps4AxisDeadzone = 0.2; ps4ButtonThreshhold = 0.1; ```

Clean Up event

ds_list_destroy(connectedGamepads);

Begin step

``` /// @description InputSwitcher

var listSize = dslist_size(connectedGamepads);

if (_listSize != 0) { for (var i = 0; i < _listSize; i++) { var _slot = connectedGamepads[| i];

    var _leftStickV = gamepad_axis_value(_slot, gp_axislv) != 0;
    var _leftStickH = gamepad_axis_value(_slot, gp_axislh) != 0;
    var _rightStickV = gamepad_axis_value(_slot, gp_axisrv) != 0;
    var _rightStickH = gamepad_axis_value(_slot, gp_axisrh) != 0;

    for (var k = gp_face1; k < gp_axisrv; k++) 
    {
        if (gamepad_button_check_pressed(_slot, k)) 
        {
            global.CurrentInput = InputMethod.Gamepad;
            set_active_gamepad(_slot);
        }
    }

    if (_leftStickV && _leftStickH) || (_rightStickV && _rightStickH)
    {
        global.CurrentInput = InputMethod.Gamepad;
        set_active_gamepad(_slot);
    }
}

if (global.CurrentInput != InputMethod.KeyboardMouse)
{
    var _mouseKeyPressed = mouse_check_button_pressed(mb_any);
    var _keyboardKeyPressed = keyboard_check_pressed(vk_anykey);

    if (_mouseKeyPressed || _keyboardKeyPressed)
    {
        global.CurrentInput = InputMethod.KeyboardMouse;
    }
}

} ```

Async - System event

``` /// @description GamepadConnectionHandler

switch(asyncload[? "eventtype"])
{ case "gamepad discovered": var gamepadSlot = asyncload[? "pad_index"];

    if (gamepad_is_supported())
    {
        ds_list_add(connectedGamepads, _gamepadSlot);
        set_active_gamepad(_gamepadSlot);
        global.CurrentInput = InputMethod.Gamepad;
    }
break;

case "gamepad lost":
    var _gamepadSlot = async_load[? "pad_index"];
    var _gamepadListIndex = ds_list_find_index(connectedGamepads, _gamepadSlot);

    ds_list_delete(connectedGamepads, _gamepadListIndex);

    var _listSize = ds_list_size(connectedGamepads);

    if (_listSize == 0)
    {
        global.ActiveGamepad = noone;
        global.CurrentInput = InputMethod.KeyboardMouse;
    }
    else if (_gamepadSlot == global.ActiveGamepad)
    {
        global.ActiveGamepad = connectedGamepads[| 0];
    }
break;

} ```

setactivegamepad script

``` // @param gamepadSlot

var _gamepadSlot = argument0;

global.ActiveGamepad = gamepadSlot; if (gamepadSlot >= 0 && gamepadSlot <= 3) // Set dead zones for Xbox controller { gamepadsetaxisdeadzone(gamepadSlot, xboxAxisDeadzone); gamepadsetbuttonthreshold(gamepadSlot, xboxButtonThreshhold); } else // Set dead zones for Playstation controller { gamepadsetaxisdeadzone(gamepadSlot, ps4AxisDeadzone); gamepadsetbuttonthreshold(_gamepadSlot, ps4ButtonThreshhold); } ```

Flexible camera

I didn't use this code in HONK but it helps me to make this flexible camera for Game Maker 2.

Here is an original devlog.

Hello everybody, I'm carrying on working on the update. Recently I finished developing a new camera system which is very flexible and easy to use.

Display manager

However, before starting working on the camera system, I had made a pixel perfect display manager.

It based on a Game resolution tutorial series by PixelatedPope:

I highly recommend checking this tutorial because it's superb and explains a lot of important moments.

And here is my version of display manager. There aren't significant differences with display manager by PixelatedPope, instead of variables names.

Camera

After implementing a display manager, I started working on a new camera. An old version was pretty simple and not so flexible as I wanted.

I use this tutorial by FriendlyCosmonaut as a start point. This tutorial is fantastic, as it shows how to make a flexible camera controller which can be useful everywhere. Nonetheless, I've made some changes to make this camera system a little bit better for my project.

I wanted to make smooth camera for some camera modes; I needed game pad support; Let's dive in it!

CREATE EVENT

``` /// @description Camera parameters

// Main settings global.Camera = id;

// Macroses

macro mainCamera view_camera[0]

macro cameraPositionX cameragetview_x(mainCamera)

macro cameraPositionY cameragetview_y(mainCamera)

macro cameraWidth cameragetview_width(mainCamera)

macro cameraHeight cameragetview_height(mainCamera)

// User events

macro ExecuteFollowObject event_user(0)

macro ExecuteFollowBorder event_user(1)

macro ExecuteFollowPointPeek event_user(2)

macro ExecuteFollowDrag event_user(3)

macro ExecuteMoveToTarget event_user(4)

macro ExecuteMoveToFollowObject event_user(5)

macro ExecuteMoveWithGamepad event_user(6)

macro ExecuteMoveWithKeyboard event_user(7)

macro ClampCameraPosition event_user(8)

macro ExecuteCameraShake event_user(9)

// Transform cameraX = x; cameraY = y;

cameraOriginX = cameraWidth * 0.5; cameraOriginY = cameraHeight * 0.5;

// Cameramodes enum CameraMode { FollowObject, FollowBorder, FollowPointPeek, FollowDrag, MoveToTarget, MoveToFollowObject }

cameraMode = CameraMode.MoveToTarget; clampToBorders = false;

// Follow parameters cameraFollowTarget = objplayer; targetX = roomwidth / 2; targetY = room_height / 2; isSmooth = true;

mousePreviousX = -1; mousePreviousY = -1;

cameraButtonMoveSpeed = 5; // Only for gamepad and keyboard controls cameraDragSpeed = 0.5; // Only for CameraMode.FollowDrag cameraSpeed = 0.1;

// Camera shake parameters cameraShakeValue = 0; angularShakeEnabled = false; // Enables angular shaking

// Zoom parameters cameraZoom = 0.65; cameraZoomMax = 4; ```

STEP EVENT

This is a state machine of the camera. You can easily modify it without any problems because all logic of each mode contains in separate user events.

``` /// @description Camera logic

cameraOriginX = cameraWidth * 0.5; cameraOriginY = cameraHeight * 0.5;

cameraX = cameraPositionX; cameraY = cameraPositionY;

switch (cameraMode) { case CameraMode.FollowObject: ExecuteFollowObject; break;

case CameraMode.FollowBorder:
    ExecuteFollowBorder;
break;

case CameraMode.FollowPointPeek:
    ExecuteFollowPointPeek;
break;

case CameraMode.FollowDrag:
    ExecuteFollowDrag;
break;

case CameraMode.MoveToTarget:
    ExecuteMoveToTarget;
break;

case CameraMode.MoveToFollowObject:
    ExecuteMoveToFollowObject;
break;

}

ClampCameraPosition;

ExecuteCameraShake;

camerasetview_pos(mainCamera, cameraX, cameraY); ```

USER EVENTS

Why do I use user_events? I don't like creating a lot of exclusive scripts for one object, and user events are a good place to avoid this problem and store exclusive code for objects.

Secondly, it's really easy to make changes in user event than in all sequence, in this case, I'm sure that I won't break something else because of my inattentiveness.

``` ///----------------------------------------------/// /// User Event 0 /// ///----------------------------------------------///

/// @description FollowObject

var targetExists = instanceexists(cameraFollowTarget);

if (_targetExists) { targetX = cameraFollowTarget.x; targetY = cameraFollowTarget.y;

CalculateCameraDelayMovement();

}

///----------------------------------------------/// /// User Event 1 /// ///----------------------------------------------///

/// @description FollowBorder

switch (global.CurrentInput) { case InputMethod.KeyboardMouse: var _borderStartMargin = 0.35; var _borderEndMargin = 1 - _borderStartMargin;

    var _borderStartX = cameraX + (cameraWidth * _borderStartMargin);
    var _borderStartY = cameraY + (cameraHeight * _borderStartMargin);

    var _borderEndX = cameraX + (cameraWidth * _borderEndMargin);
    var _borderEndY = cameraY + (cameraHeight * _borderEndMargin);

    var _isInsideBorder = point_in_rectangle(mouse_x, mouse_y, _borderStartX, _borderStartY, _borderEndX, _borderEndY);

    if (!_isInsideBorder)
    {
        var _lerpAlpha = 0.01;

        cameraX = lerp(cameraX, mouse_x - cameraOriginX, _lerpAlpha);
        cameraY = lerp(cameraY, mouse_y - cameraOriginY, _lerpAlpha);
    }
    else
    {
        ExecuteMoveWithKeyboard;
    }
break;

case InputMethod.Gamepad:
    ExecuteMoveWithGamepad;
break;

}

///----------------------------------------------/// /// User Event 2 /// ///----------------------------------------------///

/// @description FollowPointPeek

var _distanceMax = 190; var _startPointX = cameraFollowTarget.x; var _startPointY = cameraFollowTarget.y - cameraFollowTarget.offsetY - cameraFollowTarget.z;

switch (global.CurrentInput) { case InputMethod.KeyboardMouse: var direction = pointdirection(startPointX, _startPointY, mousex, mousey); var _aimDistance = pointdistance(startPointX, _startPointY, mousex, mousey); var _distanceAlpha = min(aimDistance / _distanceMax, 1); break;

case InputMethod.Gamepad:
    var _axisH = gamepad_axis_value(global.ActiveGamepad, gp_axisrh);
    var _axisV = gamepad_axis_value(global.ActiveGamepad, gp_axisrv);
    var _direction = point_direction(0, 0, _axisH, _axisV);
    var _distanceAlpha = min(point_distance(0, 0, _axisH, _axisV), 1);
break;

}

var distance = lerp(0, _distanceMax, _distanceAlpha); var _endPointX = _startPointX + lengthdirx(distance, _direction) var _endPointY = _startPointY + lengthdiry(_distance, _direction)

targetX = lerp(startPointX, _endPointX, 0.2); targetY = lerp(startPointY, _endPointY, 0.2);

CalculateCameraDelayMovement();

///----------------------------------------------/// /// User Event 3 /// ///----------------------------------------------///

/// @description FollowDrag

switch (global.CurrentInput) { case InputMethod.KeyboardMouse: var mouseClick = mousecheckbutton(mbright);

    var _mouseX = display_mouse_get_x();
    var _mouseY = display_mouse_get_y();

    if (_mouseClick)
    {
        cameraX += (mousePreviousX - _mouseX) * cameraDragSpeed;
        cameraY += (mousePreviousY - _mouseY) * cameraDragSpeed;
    }
    else
    {
        ExecuteMoveWithKeyboard;
    }

    mousePreviousX = _mouseX;
    mousePreviousY = _mouseY;
break;

case InputMethod.Gamepad:
    ExecuteMoveWithGamepad;
break;

}

///----------------------------------------------/// /// User Event 4 /// ///----------------------------------------------///

/// @description MoveToTarget

MoveCameraToPoint(cameraSpeed);

///----------------------------------------------/// /// User Event 5 /// ///----------------------------------------------///

/// @description MoveToFollowObject

var targetExists = instanceexists(cameraFollowTarget);

if (_targetExists) { targetX = cameraFollowTarget.x; targetY = cameraFollowTarget.y;

MoveCameraToPoint(cameraSpeed);

var _distance = point_distance(cameraX, cameraY, targetX - cameraOriginX, targetY - cameraOriginY);

if (_distance < 1)
{
    cameraMode = CameraMode.FollowObject;
}

}

///----------------------------------------------/// /// User Event 6 /// ///----------------------------------------------///

/// @description MoveWithGamepad

var axisH = gamepadaxisvalue(global.ActiveGamepad, gpaxisrh); var axisV = gamepadaxisvalue(global.ActiveGamepad, gpaxisrv);

var direction = pointdirection(0, 0, axisH, _axisV); var _lerpAlpha = min(pointdistance(0, 0, _axisH, _axisV), 1); var _speed = lerp(0, cameraButtonMoveSpeed, _lerpAlpha);

cameraX += lengthdirx(speed, direction); cameraY += lengthdiry(_speed, _direction);

///----------------------------------------------/// /// User Event 7 /// ///----------------------------------------------///

/// @description MoveWithKeyboard

var directionX = objgameManager.keyMoveRight - objgameManager.keyMoveLeft; var _directionY = objgameManager.keyMoveDown - obj_gameManager.keyMoveUp;

if (directionX != 0 || _directionY != 0) { var _direction = pointdirection(0, 0, _directionX, _directionY);

var _speedX = lengthdir_x(cameraButtonMoveSpeed, _direction);
var _speedY = lengthdir_y(cameraButtonMoveSpeed, _direction);

cameraX += _speedX;
cameraY += _speedY;

}

///----------------------------------------------/// /// User Event 8 /// ///----------------------------------------------///

/// @description ClampCameraPosition

if (clampToBorders) { cameraX = clamp(cameraX, 0, roomwidth - cameraWidth); cameraY = clamp(cameraY, 0, roomheight - cameraHeight); }

///----------------------------------------------/// /// User Event 9 /// ///----------------------------------------------///

/// @description CameraShaker

// Private parameters var _cameraShakePower = 5; var _cameraShakeDrop = 0.1; var _cameraAngularShakePower = 0.5;

// Shake range calculations var _shakeRange = power(cameraShakeValue, 2) * _cameraShakePower;

// Add shakeRange to camera position cameraX += randomrange(-shakeRange, _shakeRange); cameraY += randomrange(-_shakeRange, _shakeRange);

// Chanege view angle to shake camera angle if angularShakeEnabled { camerasetviewangle(mainCamera, randomrange(-_shakeRange, _shakeRange) * _cameraAngularShakePower); }

// Decrease shake value if cameraShakeValue > 0 { cameraShakeValue = max(cameraShakeValue - _cameraShakeDrop, 0); } ```

ADDITIONAL SCRIPTS

In order to make my life a little bit easier, I use some scripts too. But be aware CalculateCameraDelayMovement and MoveCameraToPoint are used exclusively in camera code.

You should use SetCameraMode to change camera mode and SetCameraZoom to change camera zoom.

``` ///----------------------------------------------/// /// CalculateCameraDelayMovement /// ///----------------------------------------------///

var _x = targetX - cameraOriginX; var _y = targetY - cameraOriginY;

if (isSmooth) { var _followSpeed = 0.08;

cameraX = lerp(cameraX, _x, _followSpeed);
cameraY = lerp(cameraY, _y, _followSpeed);

} else { cameraX = _x; cameraY = _y; }

///----------------------------------------------/// /// MoveCameraToPoint /// ///----------------------------------------------///

/// @param moveSpeed

var _moveSpeed = argument0;

cameraX = lerp(cameraX, targetX - cameraOriginX, _moveSpeed); cameraY = lerp(cameraY, targetY - cameraOriginY, _moveSpeed);

///----------------------------------------------/// /// SetCameraMode /// ///----------------------------------------------///

/// @description SetCameraMode

/// @param mode /// @param followTarget/targetX /// @param targetY

with (global.Camera) { cameraMode = argument[0];

switch (cameraMode)
{
    case CameraMode.FollowObject:
    case CameraMode.MoveToFollowObject:
        cameraFollowTarget = argument[1];
    break;

    case CameraMode.MoveToTarget:
        targetX = argument[1];
        targetY = argument[2];
    break;
}

}

///----------------------------------------------/// /// SetCameraZoom /// ///----------------------------------------------///

/// @description SetCameraZoom

/// @param newZoom

var _zoom = argument0;

with (global.Camera) { cameraZoom = clamp(zoom, 0.1, cameraZoomMax); camerasetviewsize(mainCamera, global.IdealWidth / cameraZoom, global.IdealHeight / cameraZoom); } ```

Thank you for reading!

HONK, HONK! Motherduckers!

While Doom guy preparing for his eternal battle, goose guy is defending our planet from the hordes of evil beings with his shotgun in HONK.

https://www.youtube.com/watch?v=jC4WCiyWu8Q

You are HONKastic!

Despite hating the theme of this jam, I'm happy to participate in the jam, and play so many magnificent games. Thank you all and wish you luck with your ratings! honk19.gif

See you next time!

Maybe HONK didn't get a high rating, but its rating is better than the rating of Ludum Dare 44 game.

HONK is my second solo programmed game for game jams and my second complete game with GameMaker Studio 2.

There are a lot of things I have to learn, next time I'll try to make a better game. Probaly, HONK II, or HONK Ultimate, HONK Eternal.

2019-10-30_0-45-53.png

Anyway, rihgt now I'm working on a new version of the game which I've made for GMTK 2019 jam and post various staff about this process on my twitter page. I appretiate any feedback and discussions!

Ludum Dare 46

Titled Goose Team is back

I had planned to be a solo jammer, but suddenly I've found a team mate! And it means that Titled Goose Team assembles again!! team.png