<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: ntop</title>
    <description>The latest articles on DEV Community by ntop (@ntoooop).</description>
    <link>https://dev.to/ntoooop</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F61220%2Fe1a85a4d-a65b-49fd-bfd2-1025c448a2bb.jpg</url>
      <title>DEV Community: ntop</title>
      <link>https://dev.to/ntoooop</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ntoooop"/>
    <language>en</language>
    <item>
      <title>How I create a Web3 project in 7 days.</title>
      <dc:creator>ntop</dc:creator>
      <pubDate>Sun, 14 Nov 2021 07:04:05 +0000</pubDate>
      <link>https://dev.to/ntoooop/how-i-create-a-web3-project-in-7-days-1b58</link>
      <guid>https://dev.to/ntoooop/how-i-create-a-web3-project-in-7-days-1b58</guid>
      <description>&lt;p&gt;I'm a totally newbie to the crypto world. I think most people in dev.to is same as me. As a web2 developer(they called us), this is the first time I know the term - Web3. What's web3? It confused me for a long time. If you ask me, I'll tell you that web3 is some tech stack from Ethereum, Which you can used to create DApp. (That's may not be right, I'm sure! And what is DApp?...)&lt;/p&gt;

&lt;p&gt;Let's just throw away these confusing concept, I just tell what I did, What I learn. &lt;/p&gt;

&lt;h2&gt;
  
  
  What I did?
&lt;/h2&gt;

&lt;p&gt;The project I created is a tool, which can be used to store money(crypto money) in NFT(What is NFT? 😂). You can play it at: &lt;a href="https://redpacket.app/"&gt;https://redpacket.app/&lt;/a&gt; .&lt;/p&gt;

&lt;p&gt;I use react to create the frontend ui, and use web3js to interact with the Ethereum.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I learn?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Ethereum&lt;/li&gt;
&lt;li&gt;Solidity
&lt;/li&gt;
&lt;li&gt;Web3js&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Ethereum is a blockchain, as you known blockchain is just an unchanged database. What Ethereum different from normal database is that Ethereum can run code, the code running on Ethereum called Smart Contract. So if you want to write something like a small program, in Ethereum world, you should write smart contract(like android's apk, or iOS's ipa).&lt;/p&gt;

&lt;p&gt;Smart contract use Solidity as it native language. Solidity is a little like javascript, here is some code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/**
 * @title Storage
 * @dev Store &amp;amp; retrieve value in a variable
 */
contract Storage {

    uint256 number;

    /**
     * @dev Store value in variable
     * @param num value to store
     */
    function store(uint256 num) public {
        number = num;
    }

    /**
     * @dev Return value 
     * @return value of 'number'
     */
    function retrieve() public view returns (uint256){
        return number;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These code above store a number in the Ethereum blockchain. When you deployed the Solidity program(or smart contract) to Ethereum, how to use it? When we create an android application, we can install it in our smart phone, and open it/play it. But ethereum has no mobile application, if we want to play the program, we should use some library, one of these libraries is web3js. So you can also see web3js as a library to interact with ethereum. &lt;/p&gt;

&lt;p&gt;Web3js provide api to call method of the smart contract. The last thing is to write some ui, then people can use it more friendly. I use react to create the website, at dev.to everyone know react, so I wont talk it more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8TdNcE0O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ta5bcjwoa8gwjd9m98cl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8TdNcE0O--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ta5bcjwoa8gwjd9m98cl.png" alt="Here is the architecture" width="880" height="428"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, you known the architecture of a mini DApp.&lt;/p&gt;

&lt;h1&gt;
  
  
  End
&lt;/h1&gt;

&lt;p&gt;I always want to try some new tech, and blockchain is my new favor! There are so many concept in the crypto world, I'm sinking and enjoying. &lt;/p&gt;

&lt;p&gt;One more thing: If someone know what I'm doing and have a MetaMask wallet, you can play the small project at develop mode: &lt;a href="https://redpacket.app/send#dev"&gt;https://redpacket.app/send#dev&lt;/a&gt; at dev mode, you can switch to Ropsten testnet. &lt;/p&gt;

&lt;p&gt;Sourecode：&lt;a href="https://github.com/NFTRedpacket/redpacketv1"&gt;https://github.com/NFTRedpacket/redpacketv1&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Use obj-c method swizzling in GoMobile iOS games</title>
      <dc:creator>ntop</dc:creator>
      <pubDate>Tue, 02 Oct 2018 07:34:45 +0000</pubDate>
      <link>https://dev.to/ntoooop/use-obj-c-method-swizzling-in-gomobile-ios-games-335l</link>
      <guid>https://dev.to/ntoooop/use-obj-c-method-swizzling-in-gomobile-ios-games-335l</guid>
      <description>&lt;p&gt;We have used gomobile to develop games for Android and iOS. But it's not easy to add new features like integrating Ads/Analytics. On Android, we can just unpack the Apk built with gomobile and use the &lt;code&gt;.so&lt;/code&gt; directly in a new android project. But on iOS, it's impossible.  I have written a post about how to integrate ads SDK weeks ago, you can found it &lt;a href="https://dev.to/ntoooop/port-a-golang-game-to-ios-p2c"&gt;here&lt;/a&gt;. In the post, I changed the gomobile's source code and patched with two hook method. These days, I found a new way, need no change of the source code, it's the magic of Object-C, called &lt;em&gt;Method Swizzling&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Method swizzling provide a way to exchange the implementation a method, so, you can use it to add new feature to an existing class. Here is what we do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@implementation GoAppAppController(AD)

+ (void)load {
    static dispatch_once_t onceToken;
    dispatch_once(&amp;amp;onceToken, ^{
        Class class = [self class];

        SEL originalSelector = @selector(viewDidLoad);
        SEL swizzledSelector = @selector(kkViewDidLoad);

        Method originalMethod = class_getInstanceMethod(class, originalSelector);
        Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

        BOOL success = class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod));
        if (!success) {
            method_exchangeImplementations(originalMethod, swizzledMethod);
        }
    });
}


- (void)kkViewDidLoad {
    [self kkViewDidLoad];

    // Initialize Google Mobile Ads SDK
    [GADMobileAds configureWithApplicationID:@"..."];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;+ (void)load&lt;/code&gt; method, I use method swizzling to exchange the implementation of &lt;code&gt;GoAppAppController&lt;/code&gt;'s viewDidLoad method and my &lt;code&gt;kkViewDidLoad&lt;/code&gt; method. &lt;code&gt;GoAppAppController&lt;/code&gt; is gomobile's implementation of UIViewController, you can found the source code in &lt;code&gt;x/mobile/app/darwin_ios.m&lt;/code&gt;. In &lt;code&gt;kkViewDidLoad&lt;/code&gt; method, I call &lt;code&gt;[self kkViewDidLoad]&lt;/code&gt; to invoke the original &lt;code&gt;viewDidLoad&lt;/code&gt; , than, call &lt;code&gt;GADMobileAds&lt;/code&gt; to initialize my Admob Ads SDK. &lt;/p&gt;

&lt;p&gt;That's all, it's very concise and easy! I also used it in my second game &lt;em&gt;Unstable Tower&lt;/em&gt;, but, unfortunately, Apple say it's alike existing game in AppStore, so it did not pass the review. There is also an Android version, if you like it, you can download it in &lt;a href="https://play.google.com/store/apps/details?id=io.korok.unstabletower"&gt;GooglePlay&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>gomobile</category>
      <category>ios</category>
      <category>gamdev</category>
    </item>
    <item>
      <title>Port a Golang game to iOS</title>
      <dc:creator>ntop</dc:creator>
      <pubDate>Thu, 06 Sep 2018 13:03:53 +0000</pubDate>
      <link>https://dev.to/ntoooop/port-a-golang-game-to-ios-p2c</link>
      <guid>https://dev.to/ntoooop/port-a-golang-game-to-ios-p2c</guid>
      <description>&lt;p&gt;These days, I'm porting our Android game &lt;a href="https://play.google.com/store/apps/details?id=io.korok.shootingblock" rel="noopener noreferrer"&gt;Shoot Stack&lt;/a&gt; to iOS. It's a game written in Golang with our own &lt;a href="https://korok.io" rel="noopener noreferrer"&gt;game engine&lt;/a&gt;. This article will give some tips and our experiences in poring Golang game to iOS. If you have ever used the GoMobile you know that &lt;code&gt;gomobile build&lt;/code&gt; can build &lt;code&gt;.app&lt;/code&gt; and install directly to an iOS device. But if you want to integrate third-party SDK, like ads, analytics, it's impossible with &lt;code&gt;gomobile build&lt;/code&gt;. We need a way to build library, then we can use it in xcode and &lt;code&gt;gomobile bind&lt;/code&gt; just do this.&lt;/p&gt;

&lt;p&gt;Here is our project structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✗ tree .
.
├── arena.go
├── audio.go
├── build.md
├── color.go
├── file.go
├── flash_message.go
├── gameover.go
├── input_glfw.go
├── input_mob.go
├── main.go
├── particle.go
├── ready.go
└── welcome.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;yeah, it's all in a main package. Using &lt;code&gt;gomobile bind&lt;/code&gt; command, we can build &lt;code&gt;.framework&lt;/code&gt; file for xcode. But we still need a way to invoke the &lt;code&gt;main&lt;/code&gt; method of our lib. All xcode project has a &lt;code&gt;main.h&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;int main(int argc, char * argv[]) {
@autoreleasepool {
    return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we can invoke our lib's main method here. As I said above, all my code stay in a &lt;code&gt;main&lt;/code&gt; package, but GoMobile cann't bind file in &lt;code&gt;main&lt;/code&gt;(it's just not supported). So I do have to change a little to my project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;✗ tree .
.
├── ios
│   └── ios.go
└── main
    ├── game
    │   ├── arena.go
    │   ├── audio.go
    │   ├── build.md
    │   ├── color.go
    │   ├── file.go
    │   ├── flash_message.go
    │   ├── gameover.go
    │   ├── input_glfw.go
    │   ├── input_mob.go
    │   ├── main.go
    │   ├── particle.go
    │   ├── ready.go
    │   └── welcome.go
    └── main.go
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I put the source code in &lt;code&gt;main/game&lt;/code&gt; package, then I can still use &lt;code&gt;gomobile build&lt;/code&gt; to build Desktop and Android. Then I created &lt;code&gt;ios/ios.go&lt;/code&gt; file, it's not a main file, so I can build it with &lt;code&gt;gomobile bind&lt;/code&gt;, the content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package ios

import (
   "korok.io/korok/gfx/dbg"
   "korok.io/korok"
   "korok.io/korok/math/f32"
   "main/game"
)

func Run() {
   dbg.DEBUG = dbg.None
   option := korok.Options{
      Width:360,
      Height:640,
      Clear:f32.Vec4{0,0,0,1},
   }
   korok.Run(&amp;amp;option, &amp;amp;game.StartScene{})
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The method &lt;code&gt;Run&lt;/code&gt; is same as the &lt;code&gt;main.main()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;func main() {
    dbg.DEBUG = dbg.None
    option := korok.Options{
        Width:360,
        Height:640,
        Clear:f32.Vec4{0,0,0,1},
    }
    korok.Run(&amp;amp;option, &amp;amp;StartScene{})
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's just created to easy the bind process. Now, we can use &lt;code&gt;gomobile bind -target=ios ios&lt;/code&gt; to build a &lt;code&gt;.framework&lt;/code&gt;. If all is OK, next, we can integrate the &lt;code&gt;.framework&lt;/code&gt; to our xcode project(just drag it to xcode). Modify the &lt;code&gt;main.h&lt;/code&gt; file as following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#import "Ios/Ios.h"

int main(int argc, char * argv[]) {
    IosRun();
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Build &amp;amp; Run, now the project (with Go inside) works. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to add ads SDK?
&lt;/h2&gt;

&lt;p&gt;Now, we have successfully created a library and used it in xcode project. If we want to integrate Ad SDK, we still need add some lifecycle hook in the original &lt;code&gt;.m&lt;/code&gt; file used by  GoMobile. In the package &lt;code&gt;x/mobile/app&lt;/code&gt;, we can find a file &lt;code&gt;darwin_ios.m&lt;/code&gt;, this is the file GoMobile used to build iOS application, there are two &lt;code&gt;@interface&lt;/code&gt; defined here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@interface GoAppAppController : GLKViewController&amp;lt;UIContentContainer, GLKViewDelegate&amp;gt;
@end

@interface GoAppAppDelegate : UIResponder&amp;lt;UIApplicationDelegate&amp;gt;
@end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I will hook the lifecycle method, so that I can use it in the xcode project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@implementation GoAppAppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...
    [self kkDidFinishLaunching];
    return YES;
}
- (void)viewDidLoad {
    ...
    [self kkViewDidLoad];
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then create a file (&lt;code&gt;ad.m&lt;/code&gt;) in the xcode project, add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@implementation GoAppAppDelegate(AD)
-(void)kkDidFinishLaunching {
    NSLog(@"hi, implemenmt method");
}
@end

@interface GoAppAppController(AD)
@end

@implementation GoAppAppController(AD)

- (void)kkViewDidLoad {
    NSLog(@"view did load2..");
@end
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we used the Category in Obj-C language. It'll implement the method we used in 'darwin_ios.h'.&lt;/p&gt;

&lt;p&gt;Build &amp;amp; Run, you should see the log info printed in Console.&lt;/p&gt;

&lt;p&gt;Here is a snapshot of our game (with ad, but I'll remove it when release):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flqawva7u914o7wudfo2v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flqawva7u914o7wudfo2v.jpg" alt="Golang game with admob" width="750" height="1334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Other problem
&lt;/h2&gt;

&lt;p&gt;Life is not easy, in fact, it takes days to build a actual game and run it on my iPhone6. There is a problem I just don't know how to solve it, the problem is when the Application suspended and reactive to the foreground the App will freeze. I have tested the basic example provide by GoMobile, it also have the problem, it's bug. In the basic example, it uses &lt;code&gt;switch e.Crosses(lifecycle. StageVisible)&lt;/code&gt; to manage app lifecycle, if you change the &lt;code&gt;lifecycle. StageVisible&lt;/code&gt; to &lt;code&gt;lifecycle. StageAlive&lt;/code&gt;, it'll freeze.&lt;/p&gt;

&lt;p&gt;I have digged into the problem for serval days. It seems that GoMobile use a custom loop to draw GL command, and call:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[EAGLContext setCurrentContext:ctx];
[ctx presentRenderbuffer:GL_RENDERBUFFER];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to swap buffer, but this code will fail if the app suspended and activated again. I tried serval ways to solve the problem, but it's not that easy as I thought, at last, I given up and created an issue in Github: &lt;a href="https://github.com/golang/go/issues/27483" rel="noopener noreferrer"&gt;application freeze after resumed from suspend state on iOS &lt;/a&gt;. But I still need a way to work around the bug, after some research in the git commit, I found that the old implementation --- just use the system loop instead of Go loop. So I rollback to the old implementation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;self.glview.enableSetNeedsDisplay = NO;
CADisplayLink* displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(render:)];
[displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

- (void)render:(CADisplayLink*)displayLink {
    [self.glview display];
}

- (void)glkView:(GLKView *)view drawInRect:(CGRect)rect {
    drawloop();
}
//export drawloop
func drawloop() {
    runtime.LockOSThread()
    defer runtime.UnlockOSThread()

    for workAvailable := theApp.worker.WorkAvailable();;{
        select {
        case &amp;lt;-workAvailable:
            theApp.worker.DoWork()
        case &amp;lt;-theApp.publish:
            theApp.publishResult &amp;lt;- PublishResult{}
            return
        case &amp;lt;-time.After(50 * time.Millisecond): // incase the method blocked!!
            return
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also found the same(mostly) implementation in Cocos2DX and &lt;a href="https://github.com/hajimehoshi/ebiten" rel="noopener noreferrer"&gt;Ebiten&lt;/a&gt;. Finally, all the problem solved!! I'm uploading the Game to Apple Store Connect, you can download it in several days or weeks(you know AppStore review is not easy, too).&lt;/p&gt;

</description>
      <category>go</category>
      <category>ios</category>
      <category>game</category>
    </item>
    <item>
      <title>Integrate Ad SDK in Golang games</title>
      <dc:creator>ntop</dc:creator>
      <pubDate>Fri, 31 Aug 2018 06:39:35 +0000</pubDate>
      <link>https://dev.to/ntoooop/integrate-ad-sdk-in-golang-games-198f</link>
      <guid>https://dev.to/ntoooop/integrate-ad-sdk-in-golang-games-198f</guid>
      <description>&lt;p&gt;Days ago, I wrote an article about porting Golang project to Android with &lt;code&gt;gomobile build&lt;/code&gt; command. These days, Our team has developed a new game, and we are going to integrate AD SDK to make money.  &lt;/p&gt;

&lt;p&gt;It's not easy to add java code to a Golang project, but if you think in the other way, we can simply copy the go binary to an Android project, that we can take this project as a normal Android project.&lt;/p&gt;

&lt;p&gt;So here is the main step:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a new Android project&lt;/li&gt;
&lt;li&gt;Copy the &lt;code&gt;GoNativeActivity.java&lt;/code&gt; file to project (you can find the file in gomobile package)&lt;/li&gt;
&lt;li&gt;Copy the &lt;code&gt;.so&lt;/code&gt; to project&lt;/li&gt;
&lt;li&gt;Configure the &lt;code&gt;AndroidManifest.xml&lt;/code&gt; file to use your new Acitivity&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's all, Build and Run, you can see that the Android project has been running our Golang code. But where can I get these &lt;code&gt;.so&lt;/code&gt; files?  I just unzip the &lt;code&gt;.apk&lt;/code&gt; built from &lt;code&gt;gomobile build -target=android ./&lt;/code&gt; command. &lt;/p&gt;

&lt;p&gt;The next step is to add ads. Adding ads to this special project is no different from any Android project. Here, we add the Ad code in &lt;code&gt;GoNativeActivity&lt;/code&gt;. Note that, GoNativeActivity has no view tree, we can't just add AdView as a subview. A way to solve this problem is to use a &lt;code&gt;PopupWindow&lt;/code&gt; to contain the adview.&lt;/p&gt;

&lt;p&gt;In fact, it's very simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// load adview
popup = new PopupWindow(this);
popup.setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
// banner
AdView adView = new AdView(this);
popup.setContentView(adView);

// show ad at bottom of screen
popup.showAtLocation(getWindow().getDecorView(), Gravity.BOTTOM, 0, 0);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In my project, I integrated AdMob's Banner SDK. It works very well with test ad-uint-id. Here are screenshots of my game:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffdxs3gr7uivx4polaox7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Ffdxs3gr7uivx4polaox7.png" alt="Shoot Stack"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have released the MAC version and Android version. You can get MAC version from itch.io: &lt;a href="https://ntop.itch.io/shootingblock" rel="noopener noreferrer"&gt;https://ntop.itch.io/shootingblock&lt;/a&gt; or download from GooglePlay: &lt;a href="https://play.google.com/store/apps/details?id=io.korok.shootingblock" rel="noopener noreferrer"&gt;https://play.google.com/store/apps/details?id=io.korok.shootingblock&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It's casual game, I really like the art style. (PS: Is there a way to close the ad remotely, it shows always. It seems AdMob doesn't provide a way to control frequency)&lt;/p&gt;

</description>
      <category>go</category>
      <category>game</category>
    </item>
    <item>
      <title>Just port a Golang game to Android</title>
      <dc:creator>ntop</dc:creator>
      <pubDate>Sat, 18 Aug 2018 07:11:21 +0000</pubDate>
      <link>https://dev.to/ntoooop/just-port-a-golang-game-to-android--3a9f</link>
      <guid>https://dev.to/ntoooop/just-port-a-golang-game-to-android--3a9f</guid>
      <description>&lt;p&gt;Months ago, &lt;a class="mentioned-user" href="https://dev.to/hajimehoshi"&gt;@hajimehoshi&lt;/a&gt; wrote a post &lt;a href="https://dev.to/hajimehoshi/go-packages-we-developed-for-our-games--4cl9"&gt;Go Packages we developed for our games&lt;/a&gt;, he use &lt;code&gt;gomobile bind&lt;/code&gt; to port Go games to Android in his engine - ebiten. But here, I'll use &lt;code&gt;gomobile build&lt;/code&gt;, &lt;code&gt;gomobile build&lt;/code&gt; can pack &lt;code&gt;.apk&lt;/code&gt; directly and need no other dependencies.&lt;/p&gt;

&lt;p&gt;I have written a game engine to implement some basic game logic. But I won't talk about it (for anyone interested: &lt;a href="https://korok.io" rel="noopener noreferrer"&gt;https://korok.io&lt;/a&gt;) today, I'll talk about the problems we meet when using 'gomobile build' command.&lt;/p&gt;

&lt;p&gt;Here is 2048 game I made: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1wb01bo4mi3dymoft1u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz1wb01bo4mi3dymoft1u.png" alt="2048" width="720" height="1280"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can get it on itch.io: &lt;a href="https://ntop.itch.io/the-2048-game" rel="noopener noreferrer"&gt;The 2048 Game&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  How to make a fullscreen/NoTitleBar screen?
&lt;/h2&gt;

&lt;p&gt;The first problem is to make a full screen, &lt;code&gt;gomobile&lt;/code&gt; does't provide any configuration to do this.  After reading the &lt;a href="https://github.com/golang/go/wiki/Mobile" rel="noopener noreferrer"&gt;gomobile wiki&lt;/a&gt;, I know that I can create an &lt;code&gt;AndroidManifest.xml&lt;/code&gt; file at the root directory in my project. &lt;code&gt;gomobile&lt;/code&gt; will include it in android APK file.&lt;/p&gt;

&lt;p&gt;This is the manifest file I used in my project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;?xml version="1.0" encoding="utf-8"?&amp;gt;
&amp;lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
          android:versionCode="1" android:versionName="1.0" package="io.korok.ad2048"&amp;gt;
    &amp;lt;application android:label="2048 Game"&amp;gt;
        &amp;lt;activity android:label="2048 Game"
                  android:name="org.golang.app.GoNativeActivity"
                  android:configChanges="keyboardHidden|orientation"
                  android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
                  android:screenOrientation="portrait"&amp;gt;
            &amp;lt;meta-data android:name="android.app.lib_name" android:value="2048" /&amp;gt;
            &amp;lt;intent-filter&amp;gt;
                &amp;lt;action android:name="android.intent.action.MAIN" /&amp;gt;
                &amp;lt;category android:name="android.intent.category.LAUNCHER" /&amp;gt;
            &amp;lt;/intent-filter&amp;gt;
        &amp;lt;/activity&amp;gt;
    &amp;lt;/application&amp;gt;
&amp;lt;/manifest&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the file, &lt;code&gt;android:theme="@android:style/Theme.NoTitleBar.Fullscreen"&lt;/code&gt; will make a full screen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where to store my game data ?
&lt;/h2&gt;

&lt;p&gt;In my 2048 game, I need to store the score value in local storage. As an Android developer once, I known there are three ways to store data in Android:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;File &lt;/li&gt;
&lt;li&gt;SharedPreferences&lt;/li&gt;
&lt;li&gt;SQLite&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There is no wrapper method in Go. But, if I can find a writable file directory, I can use File system. After reading the source code of &lt;code&gt;android.go&lt;/code&gt;, I see that &lt;code&gt;gomobile&lt;/code&gt; has a environment value -- 'TMPDIR', which represent a temporary file directory(only works on Android):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var filepath = os.Getenv("TMPDIR")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, I can create file and store data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to get the system language?
&lt;/h2&gt;

&lt;p&gt;If you installed my 2048 games, You'll find that it supports multi-language(Chinese and English), I implemented this by getting the system language. Getting system language is harder than getting a writable file path, it needs writing glue method: Go -&amp;gt; Cgo -&amp;gt; Java. I'll also lean JNI to call java method from C, fortunately, JNI is like java reflection, very easy！&lt;/p&gt;

&lt;p&gt;Here is the code to get system language:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
#cgo LDFLAGS: -landroid

#include &amp;lt;jni.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

// Equivalent to:
// String lan = Locale.getDefault().getLanguage();
char* kk_getLanguage(uintptr_t java_vm, uintptr_t jni_env, jobject ctx) {
    JavaVM* vm = (JavaVM*)java_vm;
    JNIEnv* env = (JNIEnv*)jni_env;

    jclass locale_clazz = (*env)-&amp;gt;FindClass(env, "java/util/Locale");
    jmethodID getdft_id = (*env)-&amp;gt;GetStaticMethodID(env, locale_clazz, "getDefault", "()Ljava/util/Locale;");
    jobject locale = (*env)-&amp;gt;CallStaticObjectMethod(env, locale_clazz, getdft_id);

    jmethodID getlang_id = (*env)-&amp;gt;GetMethodID(env, locale_clazz, "getLanguage", "()Ljava/lang/String;");
    jobject lang = (*env)-&amp;gt;CallObjectMethod(env, locale, getlang_id);
    const char* str = (*env)-&amp;gt;GetStringUTFChars(env, (jstring) lang, NULL);
    char * retString = strdup(str);
    (*env)-&amp;gt;ReleaseStringUTFChars(env, (jstring)lang, str);
    return retString;
}
 */
import "C"
import (
    "golang.org/x/mobile/app"
    "unsafe"

)

func Language() string {
    return deviceAttr.Lang(func() string {
        var ret string
        app.RunOnJVM(func(vm, jniEnv, ctx uintptr) error {
            cstring := C.kk_getLanguage(C.uintptr_t(vm), C.uintptr_t(jniEnv), C.jobject(ctx))
            ret = C.GoString(cstring)
            C.free(unsafe.Pointer(cstring))
            return nil
        })
        return ret
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: &lt;code&gt;app.RunOnJVM&lt;/code&gt; method is a useful method to access JNI, the latest version of gomobile has this method.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Back Key!
&lt;/h2&gt;

&lt;p&gt;When I installed my game on an Android device, I found that it'll just exit if I press the Back key. It's not a normal behavior when I'm playing and touch the Back accidently. Most Android games will have a 'Double Click to Exit' mechanism to ensure you really want to exit the game.&lt;/p&gt;

&lt;p&gt;The Good news is you can gets the key event from gomobile, the Bad news is gomobile just ignores the Back key. There is a function called &lt;code&gt;convAndroidKeyCode&lt;/code&gt; in &lt;code&gt;android.go&lt;/code&gt; which maps the Back key as Unknown. To solve the problem, I have to changes the code in gomobile, I did this in a new branch(thanks git!!).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// event/key/key.go
// generate different Codes (but the same Rune).
    Code Code

+   // Origin is the original value of the key code.
+   Origin int
+
    // Modifiers is a bitmask representing a set of modifier keys: ModShift,
    // ModAlt, etc.
    Modifiers Modifiers

// app/android.go
k := key.Event{
        Rune: rune(C.getKeyRune(env, e)),
        Code: convAndroidKeyCode(int32(C.AKeyEvent_getKeyCode(e))),
+       Origin: int(C.AKeyEvent_getKeyCode(e)),
    }
    switch C.AKeyEvent_getAction(e) {
    case C.AKEY_STATE_DOWN:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adding a new filed 'Origin', I can use it to get the original key code value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case key.Event:
    if e.Origin == 4 {
           // do something
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: The Back key's value is 4 on Android. You need also rebuild the &lt;code&gt;gomobile&lt;/code&gt; tools to make it works.&lt;/p&gt;

&lt;p&gt;I can get the Back key event, but the game still exit. To change the default Back key behavior on Android, need to override the &lt;code&gt;OnBackPressed&lt;/code&gt; method in &lt;code&gt;Acitivty&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;There is a &lt;code&gt;java&lt;/code&gt; file in gomobile package called &lt;code&gt;GoNativeActivity.java&lt;/code&gt;, this is where the Activity declared. Add the following method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    @Override
    public void onBackPressed() {
        Log.e("Go", "Override Back key");
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note: You need also regenerate the &lt;code&gt;dex.go&lt;/code&gt; file with &lt;code&gt;go run gendex.go&lt;/code&gt;, then rebuild the &lt;code&gt;gomobile&lt;/code&gt; again. &lt;/p&gt;

&lt;h2&gt;
  
  
  How to Exit the app, manually?
&lt;/h2&gt;

&lt;p&gt;Now, we override the default Back key event, and can get Back key event, what should we do next? A simple way to do this is call &lt;code&gt;panic&lt;/code&gt; method, just kill the process with an exception. Or we can call the &lt;code&gt;Activity.finish()&lt;/code&gt; method with glue method, I have written some JNI method, it not that hard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
#cgo LDFLAGS: -landroid

#include &amp;lt;jni.h&amp;gt;
#include &amp;lt;stdlib.h&amp;gt;
#include &amp;lt;string.h&amp;gt;

// Equivalent to:
// Activity.Finish()
void kk_finish(uintptr_t java_vm, uintptr_t jni_env, jobject ctx) {
    JavaVM* vm = (JavaVM*)java_vm;
    JNIEnv* env = (JNIEnv*)jni_env;
    jclass clazz = (*env)-&amp;gt;GetObjectClass(env, ctx);
    jmethodID finish_id = (*env)-&amp;gt;GetMethodID(env, clazz, "finish", "()V");
    (*env)-&amp;gt;CallVoidMethod(env, ctx, finish_id);
}
 */
import "C"
import (
    "golang.org/x/mobile/app"
    "unsafe"

)


func Quit() {
    app.RunOnJVM(func(vm, jniEnv, ctx uintptr) error {
        C.kk_finish(C.uintptr_t(vm), C.uintptr_t(jniEnv), C.jobject(ctx))
        return nil
    })
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also make a 'Double Click Exit':&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqla9v1h35oiut0nfs8y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjqla9v1h35oiut0nfs8y.png" alt="Click Back Again to Quit!" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Preserve eglContext!!
&lt;/h2&gt;

&lt;p&gt;If I pressed the Home button on an Android device, the system'll bring my game to back. Then click the game icon again, the system'll bring my game to front, but, it's a white screen!!! Nothing is showing!!! I have searched a lot about this bugly behavior, it seems that Android apps will lost eglContext when paused. Ebiten has some code to restore the eglContext, reload all shaders/texutres... But I think it's too complicated to implement this, SDL2 use setPreserveEGLContextOnPause method, I can implement the same logic on gomobile, too.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;android.c&lt;/code&gt; file, add a new global variable &lt;code&gt;EGLContext context = NULL;&lt;/code&gt;, then reuses it if it's valid or creates it if it's invalid.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/android.c
 EGLDisplay display = NULL;
 EGLSurface surface = NULL;
+EGLContext context = NULL;

-   const EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
-   context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
+    if (context == NULL) {
+        const EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+        context = eglCreateContext(display, config, EGL_NO_CONTEXT, contextAttribs);
+    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These changes works very well. Now, my game can correctly paused and resumed.&lt;/p&gt;

&lt;p&gt;Note: You need to rebuild the &lt;code&gt;gomobile&lt;/code&gt; tools again!&lt;/p&gt;

&lt;h2&gt;
  
  
  How to set 'targetSdkVersion '?
&lt;/h2&gt;

&lt;p&gt;I thought I have fixed all the bug and successfully build an APK file. But when I upload the APK file to GooglePlay, it always fails with an error message -"you need to target Android version 26"!!&lt;/p&gt;

&lt;p&gt;As an experienced Android developer, I know how to fix it, just add 'targetSdkVersion=26' in 'AndroidManifest.xml' will works. But, unfortunately, it failed, gomoile complains that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;manual declaration of uses-sdk in AndroidManifest.xml not supported
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gomobile must did some weird logic when building APK file. After digging into the &lt;code&gt;build_androidapp.go&lt;/code&gt; and &lt;code&gt;binres.go&lt;/code&gt; file, I found that gombile checks the 'uses-sdk' element and fails the build process:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case "uses-sdk":
    return nil, fmt.Errorf("manual declaration of uses-sdk in AndroidManifest.xml not supported")
case "manifest":
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also found where 'gomobile' set the 'minSdkVersion', but, it never set the &lt;code&gt;targetSdkVersion&lt;/code&gt;, so I add some code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if !skipSynthesize {
    s := xml.StartElement{
        Name: xml.Name{
            Space: "",
            Local: "uses-sdk",
        },
        Attr: []xml.Attr{
            xml.Attr{
                Name: xml.Name{
                    Space: androidSchema,
                    Local: "minSdkVersion",
                },
                Value: fmt.Sprintf("%v", MinSDK),
            },
            xml.Attr{
                Name: xml.Name{
                    Space: androidSchema,
                    Local: "targetSdkVersion",
                },
                Value: fmt.Sprintf("%v", 26),
            },
        },
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, I have to say, it's a long way, I fixed all the problem, and upload it to GooglePlay. It's welcomed to download my 2048 games, it's 99% Golang、no ads、clean design、smooth animation... Yeah, just install, I'm really happy to hear that. &lt;/p&gt;

&lt;p&gt;Here is the link to itch.io: &lt;a href="https://ntop.itch.io/the-2048-game" rel="noopener noreferrer"&gt;The 2048 Game&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I also create serval issues in Github, but with no respond now:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/golang/go/issues/27023" rel="noopener noreferrer"&gt;x/mobile: manual declaration of uses-sdk in AndroidManifest.xml not supported&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/golang/go/issues/26985" rel="noopener noreferrer"&gt;x/mobile: Can't get the Back key event on Android &lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/golang/go/issues/26962" rel="noopener noreferrer"&gt;x/mobile: preserve eglContext when activity paused on Android&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/golang/go/issues/26959" rel="noopener noreferrer"&gt;x/mobile: lifecycle.StageDead never reach on Android &lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>gomobile</category>
      <category>game</category>
      <category>korok</category>
      <category>go</category>
    </item>
    <item>
      <title>Write a GIF player with Golang</title>
      <dc:creator>ntop</dc:creator>
      <pubDate>Sat, 31 Mar 2018 15:24:38 +0000</pubDate>
      <link>https://dev.to/ntoooop/write-a-gif-player-with-golang-1350</link>
      <guid>https://dev.to/ntoooop/write-a-gif-player-with-golang-1350</guid>
      <description>&lt;p&gt;I just wrote a gif player with golang (less then 200 lines code). I use MAC a lot, but it can't play gif like windows, so this project come out.&lt;/p&gt;

&lt;p&gt;It's a Golang project, also a &lt;a href="https://korok.io"&gt;korok&lt;/a&gt; project. The core code is little:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;gfile&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;flag&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Arg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// decode !&lt;/span&gt;
    &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;Load&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;gfile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Fatal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;err&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Size&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;korok&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Options&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"Gif Player"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Width&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;w&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;Height&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;korok&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;MainScene&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;gp&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gif decoding use Golong's gif module, the ui is setup with korok engine's GUI system. In fact, just one method is used:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;gui&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Image&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;img&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This API will draw a Texture at (0,0) of screen. &lt;/p&gt;

&lt;p&gt;I have uploaded the project to Github: &lt;a href="https://github.com/ntop001/xgif"&gt;https://github.com/ntop001/xgif&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;About korok: it's component based 2d game engine in Golang, include a concise gui system. I use it to write some small tools. See: &lt;a href="https://korok.io/"&gt;https://korok.io/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>gif</category>
      <category>korok</category>
    </item>
  </channel>
</rss>
