Godot 3.1a1.

Jedno, no dobra – dwa słowa – niesamowity projekt. Nie byłem nigdy chętny do zabawy silnikami growymi, ale Godot jest wyjątkowy. W zasadzie wszystko mnie w nim zachwyca – począwszy od formy dystrybuowania – jeden plik wykonywalny, przez możliwości i ogólnie sposób pracy z programem. No i jeszcze możliwości. I zapomniałem dodać jeden ficzer: możliwości.

Język skryptowy GDScript, dla Pythonisty – miodzio. Oprócz tego pełna swoboda, może być C#, GDNative i C++, jest i edytor wizualny. Szok. Wersja alpha (niestety wersja stabilna działa tylko na sprzęcie z OpenGL ES 3.0, ale w 3.1 będzie tylko GL ES 2.0) ani razu mi się nie wysypała, nawet jednego komunikatu o błędzie!

Powyższy screen to tutorial „Tiles and Animated Sprites” HartBeast-a (super się go słucha).

Obsługa ruchu i animacji sprajta to 27 linijek w GDScript.

extends KinematicBody2D

var motion = Vector2()
const UP = Vector2(0, -1)
const GRAVITY = 20
const SPEED = 200
const JUMP_HEIGHT = -550

func _physics_process(delta):
	motion.y += GRAVITY
	if Input.is_action_pressed("ui_right"):
		motion.x = SPEED
		$Sprite.flip_h = false
		$Sprite.play("Run")
	elif Input.is_action_pressed("ui_left"):
		$Sprite.flip_h = true
		$Sprite.play("Run")
		motion.x = -SPEED
	else:
		motion.x = 0
		$Sprite.set_animation("Idle")

	if is_on_floor():
		if Input.is_action_just_pressed("ui_up"):
			motion.y = JUMP_HEIGHT

	motion = move_and_slide(motion, UP)

 

Reklamy

ESP32 i klon Dual shock przez BT.

Przez nieuwagę kupiłem Pada BigBen RFLX BB5152 (PS3) myśląc, że podłączę go do interfejsu TOM2 (liczyłem na to, że będzie działał lepiej od Logitecha F710). Niestety w obecnie dostępnej wersji ten pad jest tylko na bluetooth, więc nie będzie działał wcale.

A gdyby tak przez bluetooth z ESP32 podłączyć pada z PS3 do Atari? 🙂

https://github.com/greblus/esp32_ps3_bt_pad

Może się uda. W projekcie Usb Host Shield dla Arduino autor obsługuje nawet czujniki ruchu, więc jest się od kogo uczyć.

f() – swoboda argumentów.

Na początku nie wiedziałem co o tym myśleć, ale po namyśle – fajowy ten JS 😉 mimo, że użycie „arguments” w ES6 jest niezalecane ze względu na lepsiejsze . Trochę nieprzekonany jestem niestety do:

666

Ale pewnie środowisko z którego wywodzi się JS nie jest tu bez znaczenia 😉

Szeregowanie kooperacyjne w Micropythonie na ESP8266.

Ku mojemu zdziwieniu Micropython na esp8266 nie obsługuje wątków, a potrzebna mi była funkcja „sleep()”, która będzie się wykonywać równolegle do głównego wątku. Dziwne to, bo z FreeRTOS SDK wątki ponoć działają, choć całkiem możliwe, że kosztują zbyt wiele cennych zasobów potrzebnych Micropythonowi do życia. Znalazłem też info, że wynika to z ograniczeń zestawu instrukcji procesora. Cóż, FreeRTOS działa super na esp32 i niech tak zostanie. Niestety bez wątków funkcja zawłaszcza procesor licząc czas w pętli i jak chciałoby się wcześniej zasterować podłączonymi do esp8266 ustrojstwami, to trzeba by to zrobić manualnie ;). Na szczęście dostępna ilość pamięci pozwala na użycie modułu uasyncio i nieblokujących się socketów, bo to też istotne jeśli chcemy obsługiwać sprzęt przez requesty http typu <adres_ip>/onoff czy <adres_ip>/sleep=czas. Jedyny minus, to upip, którym nie zainstalujemy uasyncio ze względu na zbyt małą ilość pamięci. Trzeba to zrobić ręcznie.

import network
import usocket as socket
import errno

sta_if = network.WLAN(network.STA_IF)
addr = socket.getaddrinfo(sta_if.ifconfig()[0], 8000)[0][-1]
s = socket.socket()
s.setblocking(False)
s.bind(addr)
s.listen(1)
print('listening on', addr)

import machine
pin = machine.Pin(5, machine.Pin.OUT)
status = True; timeout = None
pin.value(status)

import uasyncio as asyncio
loop = asyncio.get_event_loop()

async def sleep(newtm):
    global status, timeout
    if timeout == newtm:
        return
    if timeout != None:
        timeout = newtm
        return
    else:
        timeout = newtm
    while timeout > 0:
        await asyncio.sleep(60)
        timeout = timeout - 60
    status = False; timeout = None
    pin.value(status)

async def worker():
    global status
    while True:
        line = None
        try:
            cl, addr = s.accept()
            print('client connected from', addr)
            cl_file = cl.makefile('rwb', 0)
            while not line:
                line = cl_file.readline()
        except OSError as exc:
            if exc.args[0] in [errno.ETIMEDOUT, errno.EAGAIN]:
                await asyncio.sleep(0)
                continue
        print(line, status)
        if 'onoff' in line:
            status = not status
            pin.value(status)
        if 'sleep' in line:
            s1 = line.find(b'sleep')+6
            s2 = line.find(b'H')-1
            try:
                timeout = int(line[s1:s2])
                loop.create_task(sleep(timeout*60))
            except ValueError:
                print('/sleep needs a numeric timeout')
        cl.close()

loop.create_task(worker())
loop.run_forever()

# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4

Ten sam skrypt na esp32 z użyciem _thread. Esp32 to już jednak potężna bestia, z ogromną ilością pamięci, zwłaszcza z PSRAM na pokładzie, oraz sporym zapasem mocy procesora dual-core ;).

JS / Ecmascript w QtQuick.

Od lat krążę wokół tematu ale trafiłem ostatnio na fajną książkę o ES6 (Learning JS z O’Reilly’ego) i sporo rzeczy w tej wersji standardu mi się podoba. Na tyle to fajne, że postanowiłem trochę poeksperymentować. Nieprzypadkowo akurat z ES6, bo Qt5.12 ma obsługiwać Ecmascript w wersji 6-tej. Fajne toto i szybkie, a z Qt nie musi być przywiązane do backendu, czy przeglądarki:

import QtQuick 2.11
import QtQuick.Window 2.11

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("JS fun 2")

    Rectangle {
        id: rect
        width: parent.width-100; height: parent.height-100
        border.color: 'red'
        border.width: 10
        anchors.centerIn: parent

        function get_fibo(n) {
            function fibo(n) {
                if (n < 1)
                    return 0;
                if (n <= 2)
                    return 1;
               return fibo(n-1) + fibo(n-2);
            }
            var ret = '';
            for (var i=0; i<n; i++)
                ret += fibo(i) + ' ';
            return ret;
        }

        Text {
            text: parent.get_fibo(15)
            anchors.centerIn: parent
        }
    }
}
fib_js
JS w QML nie wymaga magicznych sztuczek. Można go sobie ot tak używać, jak widać w powyższym przykładzie.
Nieco dziwny jest scoping w QML, bo jeśli obiekt który wywołujemy znajduje się w obiekcie nadrzędnym, trzeba się do niego dostać np. przez parent albo id. Jeśli nie, trzeba obiekt, np. funkcję wrzucić do obiektu najgłówniejszego ;). Może ma to jakieś głębsze uzasadnienie, a może to się zmieni w implementacji ES6.