Sonntag, 27. August 2017

Playing and Pausing CSS Animations

I was recently asked how I would implement a slide show for a website. The requirements were that the slide show should start playing when hovering over it and pause while the mouse is elsewhere. GIF images are out of the question, because we can't control the playback. We could use javascript timers to control the animation and use the CSS transform: translate() property to pick the correct image from a spritesheet. Sounds like a total mess and also it would break if the user has disabled javascript. So maybe we could solve the whole thing using only CSS? I made a small codepen example demonstrationg how the slide show could be implemented. Instead of using images I'm using a colored div and change the background-animation as part of the animation. The container class contains the basic setup. The @keyframes block contains the information about what will happen during the animation. In this case the color will change from blue to purple to red. The animation class contains the setup for the animation. The animation has the name color, is initially paused and will last 4 seconds. When the user is hovering over the object with the animation class it will continue playing.

Samstag, 15. Juli 2017

Tutorial - ASP.NET Core and Selenium Webdriver

Since I'm going to do lots of web development stuff in the near future, I thought that I should take a look at the Selenium testing framework. Selenium comes either as a Firefox plugin (Selenium IDE) or as a framework (Selenium Webdriver) that supports multiple programming languages.

Preparations:

  • Get CoreCompat.Selenium.Webdriver
  • Get a plugin for the browser you want to use for testing, e. g. Selenium.Firefox.WebDriver
  • (optional) If you have issues with running the project you can place the executable for the plugin on your PATH environment variable
The code sample is for a simple console project, that will open the google website and search for racoons. Usually you would combine Selenium with the testing framework of your choice .

using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;

namespace SeleniumTutorial
{
    class Program
    {
        static void Main(string[] args)
        {   
            //Create a driver for a browser
            IWebDriver driver = new FirefoxDriver();
            //navigate to the page
            driver.Navigate().GoToUrl("https://www.google.com/");
        
            //find the search bar
            IWebElement searchInput = driver.FindElement(By.Id("lst-ib"));

            //send date to the seach bar
            searchInput.SendKeys("trash panda" +Keys.Enter);            
        }
    }
}

Sonntag, 2. April 2017

1GAM April - Preparation

I intend to participate in one game a month this april. My plan is to make a game about solving nonograms. The game could have some kind of twist like the pokemon picross game. In pokemon picross you collect pokemon by solving nonograms and you can use the pokemon's abilities to make solving nonograms easier. The game also could be educational. If the nonograms are grouped by starting letters of words there could for example be a nonogram for the letter C followed by words that start with C like cat or car.
    TODOs:
  • figure out how to implement the base mechanic
  • Create a tool to make nonograms. This could be a level editor made with WPF, a custom editor for unity or a script that creates a nonogram from an input image.
  • make a overworld/level selection thing
  • add some juice
  • (optional) add some kind of twist (custom rules)
When the game is done you can find it on itch.io.

Sonntag, 19. März 2017

A Short Introduction to Unit Testing

Why should we unit test

Writing tests before writing the actual algorithms helps in understanding the intended behaviour and potential edge cases. Another advantage is, that bugs might be found earlier, when it is easier (and thus cheaper) to fix them. Also unit tests immediately show if a refactoring or new feature breaks existing code.

Example

As example I implemented a complex number class. The class implements the basic algebraic operations (addition, subtraction, mutiplication and division). The class also implements toString and equals. For the unit tests JUnit will be used. Here is the skeleton for the ComplexNumber class with only equals being implemented:

package com.example.pfogeltech;

public class ComplexNumber {
 
    private double real;
    private double imaginary;
 
    public ComplexNumber(double real, double imaginary){
        this.real = real;
        this.imaginary = imaginary;
    }
 
    public void add(ComplexNumber other){
  
    }

    public void subtract(ComplexNumber other){
  
    }

    public void multiply(ComplexNumber other){
  
    }

    public void divide(ComplexNumber other){
  
    }
 
    @Override
    public String toString(){   
        return "";
    }
 
    @Override
    public boolean equals(Object o){
       boolean equal = false;
  
       if(o instanceof ComplexNumber){
           ComplexNumber other = (ComplexNumber)o;
           if(real == other.real && imaginary == other.imaginary){
               equal = true;
           }
       }
  
       return equal;
    }
 
}
The equals method is already implemented because the unit tests will use assertEquals to compare the results of the computations to what one would expect. JUnit uses annotations to tag tests (@Test), methods for setting up (@Before, @BeforeClass) and methods for cleaning up (@After, @AfterClass). The methods tagged with @Before and @After have a print statement to demonstrate that both methods will be called before/after every test. The test cases for the different algebraic operations compute a single result and compare it against the expected value with assertEquals. The test case for toString tests against multiple values because the formatting changes depending on the value of the complex number. Here is the code for the test cases:

package com.example.pfogeltech;

import static org.junit.Assert.*;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class TestComplexNumber {

 @Before 
 public void setUp(){
  System.out.println("setting up next test");
 }
 
 @After
 public void tearDown(){
  System.out.println("clearing up after test");
 }
 
 @Test
 public void testAdd() {
  ComplexNumber a = new ComplexNumber(1,0);
  ComplexNumber b = new ComplexNumber(0,1);
  a.add(b);
  ComplexNumber expectedResult = new ComplexNumber(1,1);
  assertEquals(expectedResult, a);
 }

 @Test
 public void testSubtract() {
  ComplexNumber a = new ComplexNumber(1,0);
  ComplexNumber b = new ComplexNumber(0,1);
  a.subtract(b);
  ComplexNumber expectedResult = new ComplexNumber(1,-1);
  assertEquals(expectedResult, a);
 }
 
 @Test
 public void testMultiply(){
  ComplexNumber a = new ComplexNumber(0,1);
  ComplexNumber b = new ComplexNumber(0,1);
  a.multiply(b);  
  ComplexNumber expectedResult = new ComplexNumber(-1,0);
  assertEquals(expectedResult, a);
 }
 
 @Test
 public void testDivide(){
  ComplexNumber a = new ComplexNumber(1,1);
  ComplexNumber b = new ComplexNumber(1,1);
  a.divide(b);
  ComplexNumber expectedResult = new ComplexNumber(1,0);
  assertEquals(expectedResult, a);
 }
 
 @Test
 public void testToString(){  
  ComplexNumber real = new ComplexNumber(2,0);  
  ComplexNumber imaginary = new ComplexNumber(0,-2);  
  ComplexNumber mixedPositive = new ComplexNumber(3,14);
  ComplexNumber mixedNegative = new ComplexNumber(3,-14);
  
  assertEquals("2.0", real.toString());  
  assertEquals("-2.0i",imaginary.toString());
  assertEquals("3.0 + 14.0i",mixedPositive.toString());
  assertEquals("3.0 - 14.0i",mixedNegative.toString());
 } 
}

Running the tests will show that all five tests fail. With each successfully implemented method one of the tests will succeed. Here is the code for addition and subtraction:

public void add(ComplexNumber other){
  real += other.real;
  imaginary += other.imaginary; 
 }

 public void subtract(ComplexNumber other){
  real -= other.real;
  imaginary -= other.imaginary;
 }
These methods are pretty straightforward. Here is the code for the multiplication and division:

public void multiply(ComplexNumber other){
  double realResult = real * other.real - imaginary * other.imaginary;  
  imaginary = real*other.imaginary + other.real * imaginary;
  real = realResult;
 }

 public void divide(ComplexNumber other){
  double divisor = other.real*other.real + other.imaginary*other.imaginary;
  double realResult = (real*other.real + imaginary*other.imaginary) / divisor;
  imaginary = (imaginary*other.real - real*other.imaginary)/divisor;
  real = realResult;
 }
Since the new values for the real and imaginary parts depend on each other it is important to save one of the values into a temporary variable. Imagine we wrote the following code instead:

    public void multiply(ComplexNumber other){
        real = real * other.real - imaginary * other.imaginary;  
        imaginary = real*other.imaginary + other.real * imaginary;
    }
If we now compute the result for i * i using the code above we get -1 - i instead of the expected -1. Finally here is the code for the toString method:

@Override
 public String toString(){
  String value = "";
  if(real == 0.0 && imaginary != 0.0){
   value = String.valueOf(imaginary)+"i";
  }
  else if (real != 0.0 && imaginary == 0.0){
   value = String.valueOf(real);
  }
  else{
   if(imaginary > 0.0){
    value = String.valueOf(real) + " + " + String.valueOf(imaginary)+"i";
   }
   else{
    value = String.valueOf(real) + " - " + String.valueOf(Math.abs(imaginary))+"i";
   }
    
  }
  
  return value;
 }
This method checks if we only have a real (e.g. 0.0) or imaginary (e.g. -2i) part and then returns a suitable string representation. The special case where the imaginary part is either 1 or -1 is not handled. Also it may be a good idea to use a formatted string instead of the string concatenations.

Samstag, 22. November 2014

Generating a Battle Space - Procedural Map Generation Using the Dungeon Building Algorithm

For the boarding battles in Infinity Raider I implemented a variation of the Dungeon-Building Algotihm. The basic idea of the Dungeon-Building Algorithm is to place a room in the center of the map (everything else is a wall) and then randomly pick walls connected with floor tiles and place random features (rooms, corridors etc.). In my implementation I placed the start room at the top of the map ("the bridge") and only used half the width of the map, so it can later be mirrored along the vertical axis. The only features used are rooms, larger rooms are created if rooms happen to lie next to each other. This combining of rooms only happens, because the implementation ignores the walls of rooms when checking for overlap. The hardest part to figure out probably is the detection of the floor tile and that a new feature needs to be build into the opposite direction. The methods "MirrorMap", "GenerateUnits" and "ParseMap" are ommited in the code listing. "MirrorMap" mirrors the map along the vertical axis. "GenerateUnits" randomly places units for the player and for the AI. "ParseMap" creates the needed GameObjects from the bool array.

using UnityEngine;
using System.Collections.Generic;

public static class MapGenerator {

private class Room
{
  public int width;
  public int height;
  public Vector2 position;

  public Room(int w, int h, Vector2 pos)
  {
    width = w;
    height = h;
    position = pos;
  }
}

public static GameObject[,] GenerateSpaceShip()
{
  int width = 30;
  int height = 30;

  bool[,] layout = new bool[width,height];

  Room bridge = new Room (5, 5, 
                          new Vector2 (width / 2, height - 3));
  AddRoomToMap (bridge, layout);

  int tries = 10000;
  for (int i = 0; i < tries; i++)
  {
    //pick random wall
    int x = Random.Range(0,width/2);
    int y = Random.Range(0,height);

    if(!layout[x,y])
    {
      bool left = false;
      bool right = false;
      bool top = false;
      bool bottom = false;
      //check for floor in neighbourhood
      if(x -1 >= 0)
      {
        right = layout[x-1,y];
      }
      if(x + 1 < width/2)
      {
        left = layout[x+1,y];
      }
      if(y - 1 >= 0)
      {
        top = layout[x,y-1];
      }
      if(y + 1 < height)
      {
        bottom = layout[x,y+1];
      }

      Vector2 roomPos = Vector2.one;
      int roomWidth = Random.Range(3,6);
      int roomHeight = Random.Range(3,6);

      if(left)
      {
        roomPos = new Vector2(x-1 - roomWidth/2,y);
      }
      else if(right)
      {
        roomPos = new Vector2(x + 1 + roomWidth/2,y);
      }
      else if(bottom)
      {
 roomPos = new Vector2(x, y-1 - roomHeight/2);
      }
      else if(top)
      {
        roomPos = new Vector2(x, y+ 1 + roomHeight/2);
      }

      if(!roomPos.Equals(Vector2.one))
      {
 Room nextRoom = new Room(roomWidth,roomHeight,roomPos);
 if(TestRoomPlacement(nextRoom,layout))
 {
   layout[x,y] = true;
   AddRoomToMap(nextRoom,layout);
 }
      }
    }
  }
  MirrorMap (layout);
  GenerateUnits (layout,10);
  return ParseMap(layout);
}

private static void AddRoomToMap(Room r, bool[,] map)
{
  Vector2 pos = r.position;
  for (int x =  (int)pos.x - r.width / 2;
           x <= (int)pos.x + r.width /2; x++) 
  {
    for(int y = (int)pos.y - r.height / 2;
            y <= (int)pos.y + r.height/2; y++)
    {
      map[x,y] = true;
    }
  }
}

private static bool TestRoomPlacement(Room r, bool[,]map)
{
  Vector2 pos = r.position;
  int width = map.GetLength (0);
  int height = map.GetLength (1);
  for (int x =  (int)pos.x - r.width / 2;
           x <= (int)pos.x + r.width /2; x++) 
  {
    for(int y = (int)pos.y - r.height / 2;
            y <= (int)pos.y + r.height/2; y++)
    {
      if(x < 0 || x >= width/2 || y < 0 || y >= height || map[x,y])
      {
        return false;
      }
    }
  }
  return true;
}

}
Where to go from here? It might be a good idea to replace the bool array with an int array and then post process the map with a cellular automaton (or something else) to place enemies, objects, decorations etc. Also the rooms should be stylized in some way, so that the player knows what kind of environment it is supposed to be. Thanks for reading and happy experimenting with your own space ships (or dungeons or ...)

Procedural Sprites - Space Ships in Infinity Raider

I'm pretty bad at drawing so I tried to let the computer do the drawing of the space ships for Infinity Raider. The basic idea was to split up the space ships into multiple components. Each component would be drawn onto a seperate layer and in the end everything would be combined into a single sprite that could be used by the game. The code in this blogpost is not optimized in any way, use it at your on risk:) In the code shown below the "ship" texture is the texture holding the completed texture, while "cockpit", "weapons", "body" and "engine" hold the different parts. "OutlineTexture", "ClearTexture" and "CopyTexture" are helper functions. "ClearTexture" sets every pixel to transparent black (0f,0f,0f,0f). Unity's default for new created textures is a semitransparent white. "CopyTexture" copies opaque pixels from a source texture to a target texture. This is used to paint the different layers on top of each other. "OutlineTexture" simply draws a black outline around the opaque pixels of a texture.

public static Sprite GenerateShip()
{
  //Create the different ship parts as seperate layers,
  //then bake them into single texture
  Texture2D cockpit = GenerateCockpit ();
  cockpit = OutlineTexture (cockpit);
  Texture2D weapons = GenerateWeapons ();
  weapons = OutlineTexture (weapons);
  Texture2D body = GenerateBody ();
  body = OutlineTexture (body);
  Texture2D engine = GenerateEngine ();
  engine = OutlineTexture (engine);

  Texture2D ship = new Texture2D (width,height);
  ship = ClearTexture (ship);
  ship = CopyTexture (ship, body);
  ship = CopyTexture (ship, engine);
  ship = CopyTexture (ship, cockpit);
  ship = CopyTexture (ship, weapons);
  return Sprite.Create (ship, new Rect (0,0,width,height),
                        new Vector2 (0.5f, 0.5f));  
}
The "body" is maybe the most interesting part, as it can be one of several different shapes. The other parts only vary in color. The following code block shows the code for the body and the diamond as one example for a shape. "MirrorTexture" is another helper function used to mirror textures along the vertical axis.

private static Texture2D GenerateBody()
{
  Texture2D body = new Texture2D (width, height);
  body = ClearTexture (body);

  //generate a random shape
  int shape = Random.Range (1, 4);
  switch (shape)
  {
    case 1:{body = GenerateDiamond(body);break;}
    case 2:{body = GenerateTriangle(body);break;}
    case 3:{body = GenerateCircle(body);break;}
    default:{break;}
  }

  return body;
}

private static Texture2D GenerateDiamond(Texture2D input)
{
  Color bodyColor = new Color (Random.Range (0f, 1f),
                               Random.Range (0f, 1f),
                               Random.Range (0f, 1f), 1f);
  Vector2 seed = new Vector2 (width / 2 - 1, height / 2 - 1);
  int maxDistance = 31;
  for (int x = 0; x < width / 2; x++)
  {
    for(int y = 0; y < height; y++)
    {
      if(Mathf.Abs(x - seed.x)+Mathf.Abs(y-seed.y) <= maxDistance)
      {
        input.SetPixel(x,y,bodyColor);
      }
    }
  }
  input = MirrorTexture (input);
  return input;
}
The space ships created this way look really simple, but are still better than my hand drawings:) If you decide to create your own sprite generator (for space ships or whatever else you need) there's a lot of things that could be improved / played with. It would be more efficient to use a Color array instead of texture objects and to only create a texture when your sprite is complete. Also you could experiment with different sizes and offsets for the different layers. Another thing that could be done is adding fine details and lighting. Thanks fors reading and happy experimenting.

Sonntag, 16. November 2014

Infinity Raider - Post Mortem

I "shipped" my first game today: Infinity Raider. It's a game about space pirates which I created for the procjam 2014. Besides of being the first shipped game it was also my first game jam. There are even a few more "firsts" like working with the new Unity UI, adding sound effects made with Bfxr or procedurally making sprites (and those sprites look even better than sprites I paint by hand).

The optional theme of the jam was "infinity" and one of the first things that came to mind was "space" followed by "space pirates". As to be exspected of a beginner, I overscoped my project. The gameplay is divided into organizing your ship/crew, battling other spaceships and boarding said ships after successful battles.

The part of organizing ship and crew was greatly cut out, the only thing remaining is the option to buy ship parts (which isn't really necessary considering how powerful you are compared to your adversaries).

The space battles were greatly inspired by the G-Castle battles in Mugen Souls (Z) and a certain story about space pirates. Basically you try to disarm the opposing ship either using weapons or electronic warfare. If I had more time I could have experimented with different weapons, maneuvers and a more complex damage model, which for example could allow to target specific ship systems. The sprites for the space ships are procedurally generated. The first version looked similar to aliens from the original NES metroid while the second version (which is part of the release) atleast somewhat resembles spaceships.

The boarding battles are classical turnbased strategy and can be won either by defeating all enemies or by conquering the bridge (the room in the top center). The maps are procedural generated using a variation of the dungeon building algorithm. After fighting with the new Unity UI for a while, I decided to scrap the equipment feature. Originally different kinds of equipment should have been available, to increase tactical options. Also the "Artificial Intelligence" doens't really deserve the "Intelligence", as the AI only reacts when enemies come close enough. In a worst case scenario the map is created in a way, where the bridge can be captured without fighting a single enemy, removing any challange from the game.

All in all I'm happy with my results. During the jam there were moments where I wasn't sure, if I could deliver a game before the end of the deadline. There's still a lot to do, if I should return to working on Infinity Raider, e.g. tying the different gameplay elements together and adding more meaning to the procedural generation parts. If you see a ship you should be able to tell if it's a warship ("Retreat right now!") or if it's a trade ship ("Tonight we gonna party!"). Also the enemies encountered, rooms created and the size of the boarding maps should reflect the kind of ship your boarding.

Thanks for reading and happy plundering!