2017-10-16

Template DIY Nintendo 64 and GameBoy Inlay

Over the years, since I've been a child, my N64 cartrige inlays have gone astray. I lost a couple of them, but still got 2. So I measured the original one to create a template for printing and folding new ones.

The following template is DIN A4, standard paper layout in Germany. Print the template on thick paper or thin cardboard. Set printer settings to no scaling / 100%. Cut along black lines, fold along dashed lines. Print on the backside, so your front stays clean.

I know the middle part is bigger than a catrige, but so it is in an original inlay.

Have fun :)


Download the template as PDF: Template N64 Inlay
SVG Source File: SVG Template 




GameBoy Inlay Template: PDF SVG







GameBoy Pokemon Pinball Inlay Template: PDF SVG





GameBoy Advance Inlay Template: PDF SVG

 

2017-08-29

Generic Service Locator in Java for Game Development

ServiceLocator is a very useful decoupling pattern to avoid too many Singletons. It's structure is always the same, so I thought it should be possible to create a generic one, to decrease code duplication. Well, here is what I've come up with,  guess someone with more knowledge about generics could create something better, but it is better than nothing.

PS: I thought it must be possible to have a static method generating NulServices / Stub Services in the Classes implementing IService, but I couldn't find out how to demand a static method createNullService in an interface. Tell me if you have an idea.

Here ist the abstract ServiceLocator


import java.util.HashMap;
import java.util.Map;

/**
 * IServiceLocator
 *
 * @author Georg Eckert 2017
 */

public abstract class ServiceLocator
{
    private final Map<Class<? extends IService>, IService> services, nullServices;


    public ServiceLocator()
    {
        services = new HashMap<>();
        nullServices = new HashMap<>();
        provideNullServices();
    }

    public abstract void provideNullServices();

    public <T extends IService> T get(Class<T> serviceInterface)
    {
        if(!services.containsKey(serviceInterface) && !nullServices.containsKey(serviceInterface))
        {
            throw new IllegalArgumentException("No such Service in this Module.");
        }

        if(services.containsKey(serviceInterface))
            return (T) services.get(serviceInterface);
        else {
            System.err.println("SERVICES: No " + serviceInterface.getSimpleName() + " service injected, returning NullService.");
            return (T) nullServices.get(serviceInterface);
        }
    }

    public <T extends IService> void provide(T service , Class<? extends IService> serviceInterface)
    {
        services.put(serviceInterface, service);
    }

    public <T extends IService> void provideNull(T service , Class<? extends IService> serviceInterface)
    {
        nullServices.put(serviceInterface, service);
    }
}

and a concrete one, overriding the abstract provideNullServices method


import de.limbusdev.utils.ServiceLocator;

/**
 * GuardiansServiceLocator
 *
 * @author Georg Eckert 2017
 */

public class ConcreteServiceLocator extends ServiceLocator
{
    private ServiceLocator instance;

    public ServiceLocator getInstance()
    {
        if(instance == null) instance = new ConcreteServiceLocator();
        return instance;
    }

    @Override
    public void provideNullServices()
    {
        provideNull(new AbstractFactory()
            {
                @Override
                public AbstractProduct createProduct(int ID)
                {
                    return null;
                }
            },
            AbstractFactory.class
        );
    }
}

all real services must be provided somewhere in your initialization code

// Providing a concrete Service
ConcreteServiceLocator.provide(new ConcreteFactory());

// Retrieving the concrete service without knowing its exact implementation
AbstractFactory factory = ConcreteServiceLocator.getService(AbstractFactory.class);

2017-05-27

[Tutorial] Play Pokemon GO and Mario RUN on Lineage OS or CyanogenMod

Hi there,

I finally managed to run Mario Run and some other Nintendo Games (Mario RUN, Magikarp Jump, Pokemon Shuffle; including Pokemon GO, which is made by Niantic and not Nintendo) on my Samsung Galaxy Note II with Lineage OS 14.1 / Android 7.1.

Look no further, here is what you have to do :) Unfortunately you might have to reinstall your custom ROM, so backup all your data or enable Google App Data Saving.

  1. remove all other SU tools and SU-hiding apps
  2. (optional) if in the Developer Settings Root Access only shows ADB / Deactivate, you have to re-flash your Custom ROM and GApps
  3. Enable Developer Settings and set Root Access to "Apps and ADB"
  4. Download iSU and install it
  5. Give Root Access to iSU, when you run it the first time
  6. in iSU: change to tab "Controls" and set "Change SU state" to "Deactivated"
  7. in iSU: change to tab "Props" > "Force set all Known props" > "Safe Value"
  8. in iSU: (optional) tab "Checks" > "Safety Net test"
  9. launch Mario RUN, Pokemon GO or whatever needs positive SafetyNet Check
Everything fine with SafetyNet

Time to show bowser, who's the boss.



Have fun :)

2017-05-18

JavaScript ES6 Game Loop Design Pattern

Get Started

This is just a short overview how to setup a very simple game loop with ES6 (JavaScript) using classes.

The following code sections are pretty easy to understand

Note that in many cases you need to use ES6's arrow operator => to make sure, you are accessing the correct this. Otherwise you will often get the error "this.method is not a function". That happens because when accessing this from anonymous methods, this points to the object of the anonymous method, not the object your calling it from.

In the HTML snippet, we set up a simple X3D scene with a ground and a small bar.

In the JavaScript main.js we create a game object. In Game.js the constructor sets up the game object and initializes the game loop to be triggered every 10 ms. We keep track of the pressed buttons (WASD) with booleans and move the bar accordingly.

This is what you will see, you can move the bar around with the WASD keys.



Have fun :)

PS: To develop this into a real game, have a look at the tutorial at MDN Developers, which is for 2D games with canvas, but much of it can be applied to our system as well: Tutorial

HTML Base Project


Here is the HTML frame:


<!doctype html>
<html>
  <!-- ......................................................................... HEAD -->
  <head>
    <title>LinuVerse Simple Game Loop Example</title>
    <meta charset="utf-8" />
    <script
      type='text/javascript'
      src='http://www.x3dom.org/download/x3dom.js'></script>
    <link
      rel='stylesheet'
      type='text/css'
      href='http://www.x3dom.org/download/x3dom.css'></link>
  </head>
  <!-- ......................................................................... BODY -->
  <body>
    <h1>LinuVerse Simple Game Loop Example</h1>
    <!-- ....................................................................... x3d -->
    <x3d width="800px" height="600px">
      <scene>
        <Viewpoint position="0,5,20" orientation="1,0,0,-.2"></Viewpoint>
        
        <!-- Scene ......................................................... -->
        <!-- Bar -->
        <transform id="bar" translation="0 -3 0">
          <shape>
            <appearance>
              <material diffuseColor=".9 .9 .9" />
            </appearance>
            <box size="5 1 1" />
          </shape>
        </transform>

        <!-- Scene ground -->
        <transform translation="0 -4 0">
          <shape>
            <appearance>
              <material diffuseColor=".8 .8 .8" />
            </appearance>
            <box size="20 1 20" />
          </shape>
        </transform>
      </scene>
    </x3d>

    <!-- ....................................................................... SCRIPTS -->
    <script type='text/javascript' src='Game.js'></script>
    <script type='text/javascript' src='main.js'></script>
    <script>
      main();
    </script>
  </body>
</html>

JavaScript Code


The Main JavaScript-File:
var game;

function main(args) {
  game = new Game();
}
And the Game Class:
'use strict'

class Game {

  constructor() {
    this.bar = document.getElementById('bar');
    this.barPos = [0,-3,0];

    this.upKeyPressed = false;
    this.downKeyPressed = false;
    this.leftKeyPressed = false;
    this.rightKeyPressed = false;

    document.addEventListener('keydown', event => this.onKeyDown(event));
    document.addEventListener('keyup', event => this.onKeyUp(event));

    setInterval(() => this.render(), 10);
  }

  /**
   * Main Render Cycle
   */
  render() {
    this.moveBar();
  }

  moveBar() {
    if(this.upKeyPressed){
      this.barPos[2] -= .1;
    }
    if(this.downKeyPressed){
      this.barPos[2] += .1;
    }
    if(this.leftKeyPressed){
      this.barPos[0] -= .1;
    }
    if(this.rightKeyPressed){
      this.barPos[0] += .1;
    }
    this.bar.setAttribute('translation', this.barPos);
  }

  onKeyDown(event) {
    switch(event.keyCode) {
      case 87: this.upKeyPressed = true; break;
      case 83: this.downKeyPressed = true; break;
      case 65: this.leftKeyPressed = true; break;
      default: this.rightKeyPressed = true; break;
    }
  }

  onKeyUp(event) {
    switch(event.keyCode) {
      case 87: this.upKeyPressed = false; break;
      case 83: this.downKeyPressed = false; break;
      case 65: this.leftKeyPressed = false; break;
      default: this.rightKeyPressed = false; break;
    }
  }
}

2017-03-05

Game Development: Construction Method (Java Design Pattern)

If you want to extend a Class and do some stuff, before the super constructor gets called, you can do the following:

Create static methods, which return everything your super constructor needs.
Here is a simple example from LibGDX. I wanted to extend ScrollPane and provide some additional predefined values.

What I wanted to do is:
  • children of my ScrollableWidget should always sit in the middle
  • both scrollbars should always be active
  • children should always sit in the middle of a bigger container (overscrolling)


public class ScrollableWidget extends ScrollPane {

    public ScrollableWidget( 

        int scrollWidth, int scrollHeight, 

        int childWidth, int childHeight, Actor child, Skin skin) {

 

        super(construct(childWidth, childHeight, child), skin);
        setSize(scrollWidth, scrollHeight);
        setScrollBarPositions(true, true);
        layout();
        setScrollPercentX(.5f);
        setScrollPercentY(.5f);

    }

    private static Actor construct( 

        int width, int height, Actor child) {

 

        Group container = new Group();
        container.setSize(width,height);
        child.setPosition(width/2-child.getWidth()/2,height/2-child.getHeight()/2, Align.bottomLeft);
        container.addActor(child);

        return container;
    }
}

2017-01-06

Nintendo new 3DS Bildschirm Flackern / Flimmern beheben

Wenn bei eurem Nintendo new 3DS der Bildschirm flimmert, solltet ihr Automatische Helligkeit und Energiesparmodus abschalten, dann hört das flackern wieder auf.

Frohes Spielen :)

2016-12-22

Ubuntu 16.04 USB-Stick - "Das Ziel ist schreibgeschützt" lösen

Es gibt Dinge, die dürfen in einem nutzerfreundlichen Betriebssystem einfach nicht passieren. Vor allem dürfen Sie aber nicht monatelang bestehen bleiben.

Mit Ubuntu 16.04 kann ich Freunden und Bekannten Ubuntu einfach nicht mehr empfehlen, wenn selbst ich an einfachsten Aufgaben scheitere.

Gemeint ist hier das Kopieren von Dateien auf USB-Sticks. Trotz jahrelanger Ubuntu/Linux-Erfahrung gelang es mir erst nach gründlicher Recherche das Problem zu beheben. Ein Laie hat hier keine Chance. Damit ihr nicht lange suchen müsst, hier das Problem samt Lösung:

Problem

Datei oder Ordner auf Fat32-USB-Stick kopieren oder anlegen schlägt fehl mit der Meldung "Das Ziel ist schreibgeschützt".

Lösung

das Paket fuse-posixovl installieren und Ubuntu neu starten



sudo apt-get install fuse-posixovl

Viel Erfolg