I moved to a new URL! Check it out!

posts tagged with: otter

Dev Log: Quick Lighting Test

Dev Log: Quick Lighting Test
As a quick experiment I wanted to see how Otter would be equipped to handle a simple lighting set up. The basic set up is just a big render texture that is filled with a dark color with a blend mode set to multiply. Then light is rendered to the render texture with a blend mode of additive. The result is a layer of shadow that can have light rendered to it.

Image


The code for this set up right now is pretty straight forward as well. I'm using a black and white image for the light. Just a black rectangle with a white radial gradient in the center.

Here's some sample code to show how this effect is achieved with Otter!
//set up the surface
public Surface SurfaceLighting = new Surface(Game.Instance.Width, Game.Instance.Height, new Color("379")) {
Blend = BlendMode.Multiply
};

//set up the light
public Image ImageLight = new Image(Assets.ImageLight1) {
Blend = BlendMode.Add
};

//add the surface to an entity to render it
//this happens in an object's initialization
AddGraphicGUI(SurfaceLighting);

//render light to the surface
//this happens in a Render() function
Draw.SetTarget(SurfaceLighting);
ImageLight.Color = Color.White;
Draw.Graphic(ImageLight, Input.MouseX, Input.MouseY);
ImageLight.Color = Color.Red;
Draw.Graphic(ImageLight, Input.MouseX + 500, Input.MouseY);
ImageLight.Color = Color.Blue;
Draw.Graphic(ImageLight, Input.MouseX - 500, Input.MouseY);
Draw.ResetTarget();

Dev Log: Coroutine Example

Image


Thanks to knowledge passed down from Chevy Ray I was able to get Coroutines working in Otter recently! Coroutines are magical chunks of code that are able to yield their execution and remember their state. It's bonkers what you can do with them using this power.

I added an example to Otter to hopefully help out any folks that are looking into using them:
using Otter;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CoroutineExample {
class CoroutineScene : Scene {

public Image ImageBox = Image.CreateRectangle(50);

public Color NextColor = Color.White;
public Color CurrentColor = Color.White;

public CoroutineScene() : base() {
// Center that box.
ImageBox.CenterOrigin();

// Gotta draw the box.
AddGraphic(ImageBox);

// Set the box position.
ImageBox.X = 100;
ImageBox.Y = 100;
}

public override void Begin() {
base.Begin();

// Start the coroutine, yo.
Game.Coroutine.Start(MainRoutine());
}

/// <summary>
/// The main coroutine to execute. This will move the box around and change its color.
/// </summary>
/// <returns>Whatever a coroutine thing returns. Sometimes 0 I guess.</returns>
IEnumerator MainRoutine() {
// Wait for 30 frames.
yield return Coroutine.Instance.WaitForFrames(30);
// Set the next color.
NextColor = Color.Red;
// Move the box to the top right.
yield return MoveBoxTo(540, 100);

// Wait for 30 frames.
yield return Coroutine.Instance.WaitForFrames(30);
// Set the next color.
NextColor = Color.Yellow;
// Move the box to the bottom right.
yield return MoveBoxTo(540, 380);

// Wait for 30 frames.
yield return Coroutine.Instance.WaitForFrames(30);
// Set the next color.
NextColor = Color.Green;
// Move the box to the bottom left.
yield return MoveBoxTo(100, 380);

// Wait for 30 frames.
yield return Coroutine.Instance.WaitForFrames(30);
// Set the next color.
NextColor = Color.Cyan;
// Move the box to the top left.
yield return MoveBoxTo(100, 100);

// Start a new coroutine.
Game.Coroutine.Start(MainRoutine());
}

IEnumerator MoveBoxTo(float x, float y) {
// Used to determine the completion.
var initialDistance = Util.Distance(ImageBox.X, ImageBox.Y, x, y);

float currentDistance = float.MaxValue;
while (currentDistance > 1) {
currentDistance = Util.Distance(ImageBox.X, ImageBox.Y, x, y);

// Determine the completion of the movement from 0 to 1.
var completion = Util.ScaleClamp(currentDistance, 0, initialDistance, 1, 0);

// Lerp the color of the box.
ImageBox.Color = Util.LerpColor(CurrentColor, NextColor, completion);

// Spin the box along with its movement.
ImageBox.Angle = Util.ScaleClamp(completion, 0, 1, 0, 360);

// Actually move the box.
ImageBox.X = Util.Approach(ImageBox.X, x, 5);
ImageBox.Y = Util.Approach(ImageBox.Y, y, 5);

// Wait until next frame.
yield return 0;
}

// Done moving. Update the color.
CurrentColor = NextColor;
}
}
}
I'm actually totally not sure if I'm doing it correctly in the example, but it seems to be working out well so far. Going to try using them for various things now in my current projects!

Otter Updates

Otter Updates
Over the past week I've finally pushed some updates to Otter after managing to rip out the Spine animation stuff. It turns out that in order to use the Spine runtime you need a purchased copy of Spine, meaning that if I include the Spine code in Otter everyone that uses Otter would need a copy of Spine... not ideal. (I wish Spine wouldn't license their code like this.)

So now the Spine runtime for Otter lives in a separate repository. It can be used along with Otter if you import it into your solution also using Otter. After you import it you need to give it a reference to Otter (also in your solution) and then give your game project a reference to OtterSpine. Then you should be ready to roll with SpineAnimation.cs.

Other updates to otter include:

* Renamed GetClass to GetEntities on Scene
* Add Vertices graphics type
* Added Color.Mix()
* Corrected issue between game angle and graphics angles
* Fixed issue with BoxCollider constructor
* Fixed some collision bugs
* Added shortcut of Left-Alt in Debugger to hide debugger (useful for screenshots)
* Minor updates to Particle
* Added LerpColor to Util
* Slight changes to Vector2

If there's any bugs or horrific things broken then let me know in the Otter forums!

Dev Log: Workin' Away

Dev Log: Workin' Away
I've been pretty heads down on my game project for the past couple of days. I've managed to fix a few bugs in Otter as well, but I'm putting a hold on any official updates due to issues with the Spine license that I'm pretty sad about.

The Spine license only allows people with a full copy of Spine to download and use the official Spine runtimes. I didn't know this at the time when I created a simple Spine graphic type for Otter. The situation I'm in now is trying to figure out how to easily provide that Spine graphic type for people using Otter, but also separate it from Otter so that I can distribute it only to people that have the Spine license... argh.

In the wild world of my new game, I've been just working on some art related tasks. I've been jumping all over the place and working on totally different things on each day, but that ends up working out because it keeps things fresh and interesting.

That's all for now! Things are going to be pretty hectic for me in the next 2 or 3 weeks, as GDC is fast approaching and I'm also going to be traveling a little bit before then. If you're going to GDC, we should hang out and get sushi!

Dev Log: Otter Spine Animations

Dev Log: Otter Spine Animations
Today is a very awesome day, for I finally got Spine animations running in Otter! I only have the super basic stuff right now, but I'm hoping to expand the support as I tinker around with Otter and my next game.

Image


This is a quick test of the test animation that comes with Spine. Right now a skeleton can be loaded up, and play its animations in the most simple way. The next steps will be getting all of the cool spine functionality in and running, like being able to manipulate bones and mix animations and all that kinda stuff.

This hasn't been pushed to Otter yet, and probably won't be for at least a few more days as I test it out and hopefully work out any show stopping bugs that might appear.

While making the Otter implementation of Spine I made great use of the Spine csharp runtime which I just dragged and dropped into Otter, and I also referenced the XNA runtime, along with C#Punk's implementation of a SpineAnimation graphic type.

Flippy Flop Source

Flippy Flop Source
Yesterday I made a quick game called Flippy Flop using Otter. The whole thing only took me two hours or so, and the end result ended up being a relatively clean coded game.

I decided to add the Flippy Flop source code to the Otter source repository on BitBucket in the Examples folder. So now when you grab Otter you'll also get the source for the Otter Pong Game, and the amazing Flippy Flop.

Flippy Flop makes use of the EventRouter included in Otter. The EventRouter was originally authored by some smart Phoenix locals, and is used a lot in their Unity projects. Since it was just a C# implementation I grabbed and it stuck it in Otter. The EventRouter is all about following the Observer pattern. It can be a little weird to use at first, but I'm beginning to see the appeal of it.

(Disclaimer: There may be some bugs in the source for FlippyFlop. I didn't really check it over for memory leaks, which can easily pop up when using an Event system. If you don't make sure you're unsubscribing from events when objects are removed, or clearing the event router, you might find yourself in memory leak city.)

If you have any questions about Otter, or the source code of the game, check out the Otter forums or leave a comment below.