Compare commits
No commits in common. "master" and "refactor" have entirely different histories.
505
.ackrc
@ -1,505 +0,0 @@
|
||||
--ignore-ack-defaults
|
||||
# This is the default ackrc for ack version v3.7.0.
|
||||
|
||||
# There are four different ways to match
|
||||
#
|
||||
# is: Match the filename exactly
|
||||
#
|
||||
# ext: Match the extension of the filename exactly
|
||||
#
|
||||
# match: Match the filename against a Perl regular expression
|
||||
#
|
||||
# firstlinematch: Match the first 250 characters of the first line
|
||||
# of text against a Perl regular expression. This is only for
|
||||
# the --type-add option.
|
||||
|
||||
### Directories to ignore
|
||||
|
||||
# Bazaar
|
||||
# https://bazaar.canonical.com/
|
||||
--ignore-directory=is:.bzr
|
||||
|
||||
# Codeville
|
||||
# http://freshmeat.sourceforge.net/projects/codeville
|
||||
--ignore-directory=is:.cdv
|
||||
|
||||
# Interface Builder (Xcode)
|
||||
# https://en.wikipedia.org/wiki/Interface_Builder
|
||||
--ignore-directory=is:~.dep
|
||||
--ignore-directory=is:~.dot
|
||||
--ignore-directory=is:~.nib
|
||||
--ignore-directory=is:~.plst
|
||||
|
||||
# Git
|
||||
# https://git-scm.com/
|
||||
--ignore-directory=is:.git
|
||||
# When submodules are used, .git is a file.
|
||||
--ignore-file=is:.git
|
||||
|
||||
# Mercurial
|
||||
# https://www.mercurial-scm.org/
|
||||
--ignore-directory=is:.hg
|
||||
|
||||
# Quilt
|
||||
# https://directory.fsf.org/wiki/Quilt
|
||||
--ignore-directory=is:.pc
|
||||
|
||||
# Subversion
|
||||
# https://subversion.apache.org/
|
||||
--ignore-directory=is:.svn
|
||||
|
||||
# Monotone
|
||||
# https://www.monotone.ca/
|
||||
--ignore-directory=is:_MTN
|
||||
|
||||
# CVS
|
||||
# https://savannah.nongnu.org/projects/cvs
|
||||
--ignore-directory=is:CVS
|
||||
|
||||
# RCS
|
||||
# https://www.gnu.org/software/rcs/
|
||||
--ignore-directory=is:RCS
|
||||
|
||||
# SCCS
|
||||
# https://en.wikipedia.org/wiki/Source_Code_Control_System
|
||||
--ignore-directory=is:SCCS
|
||||
|
||||
# darcs
|
||||
# http://darcs.net/
|
||||
--ignore-directory=is:_darcs
|
||||
|
||||
# Vault/Fortress
|
||||
--ignore-directory=is:_sgbak
|
||||
|
||||
# autoconf
|
||||
# https://www.gnu.org/software/autoconf/
|
||||
--ignore-directory=is:autom4te.cache
|
||||
|
||||
# Perl module building
|
||||
--ignore-directory=is:blib
|
||||
--ignore-directory=is:_build
|
||||
|
||||
# Perl Devel::Cover module's output directory
|
||||
# https://metacpan.org/release/Devel-Cover
|
||||
--ignore-directory=is:cover_db
|
||||
|
||||
# Node modules created by npm
|
||||
--ignore-directory=is:node_modules
|
||||
|
||||
# CMake cache
|
||||
# https://www.cmake.org/
|
||||
--ignore-directory=is:CMakeFiles
|
||||
|
||||
# Eclipse workspace folder
|
||||
# https://eclipse.org/
|
||||
--ignore-directory=is:.metadata
|
||||
|
||||
# Cabal (Haskell) sandboxes
|
||||
# https://www.haskell.org/cabal/users-guide/installing-packages.html
|
||||
--ignore-directory=is:.cabal-sandbox
|
||||
|
||||
# Python caches
|
||||
# https://docs.python.org/3/tutorial/modules.html
|
||||
--ignore-directory=is:__pycache__
|
||||
--ignore-directory=is:.pytest_cache
|
||||
|
||||
# macOS Finder remnants
|
||||
--ignore-directory=is:__MACOSX
|
||||
--ignore-file=is:.DS_Store
|
||||
|
||||
### Files to ignore
|
||||
|
||||
# Backup files
|
||||
--ignore-file=ext:bak
|
||||
--ignore-file=match:/~$/
|
||||
|
||||
# Emacs swap files
|
||||
--ignore-file=match:/^#.+#$/
|
||||
|
||||
# vi/vim swap files https://www.vim.org/
|
||||
--ignore-file=match:/[._].*[.]swp$/
|
||||
|
||||
# core dumps
|
||||
--ignore-file=match:/core[.]\d+$/
|
||||
|
||||
# minified JavaScript
|
||||
--ignore-file=match:/[.-]min[.]js$/
|
||||
--ignore-file=match:/[.]js[.]min$/
|
||||
|
||||
# minified CSS
|
||||
--ignore-file=match:/[.]min[.]css$/
|
||||
--ignore-file=match:/[.]css[.]min$/
|
||||
|
||||
# JS and CSS source maps
|
||||
--ignore-file=match:/[.]js[.]map$/
|
||||
--ignore-file=match:/[.]css[.]map$/
|
||||
|
||||
# PDFs, because they pass Perl's -T detection
|
||||
--ignore-file=ext:pdf
|
||||
|
||||
# Common graphics, just as an optimization
|
||||
--ignore-file=ext:gif,jpg,jpeg,png
|
||||
|
||||
# Common archives, as an optimization
|
||||
--ignore-file=ext:gz,tar,tgz,zip
|
||||
|
||||
# Python compiled modules
|
||||
--ignore-file=ext:pyc,pyd,pyo
|
||||
|
||||
# Python's pickle serialization format
|
||||
# https://docs.python.org/2/library/pickle.html#example
|
||||
# https://docs.python.org/3.7/library/pickle.html#examples
|
||||
--ignore-file=ext:pkl,pickle
|
||||
|
||||
# C extensions
|
||||
--ignore-file=ext:so
|
||||
|
||||
# Compiled gettext files
|
||||
--ignore-file=ext:mo
|
||||
|
||||
# Visual Studio user and workspace settings
|
||||
# https://code.visualstudio.com/docs/getstarted/settings
|
||||
--ignore-dir=is:.vscode
|
||||
|
||||
### Filetypes defined
|
||||
|
||||
# Makefiles
|
||||
# https://www.gnu.org/s/make/
|
||||
--type-add=make:ext:mk
|
||||
--type-add=make:ext:mak
|
||||
--type-add=make:is:makefile
|
||||
--type-add=make:is:Makefile
|
||||
--type-add=make:is:Makefile.Debug
|
||||
--type-add=make:is:Makefile.Release
|
||||
--type-add=make:is:GNUmakefile
|
||||
|
||||
# Rakefiles
|
||||
# https://rake.rubyforge.org/
|
||||
--type-add=rake:is:Rakefile
|
||||
|
||||
# CMake
|
||||
# https://cmake.org/
|
||||
--type-add=cmake:is:CMakeLists.txt
|
||||
--type-add=cmake:ext:cmake
|
||||
|
||||
# Bazel build tool
|
||||
# https://docs.bazel.build/versions/master/skylark/bzl-style.html
|
||||
--type-add=bazel:ext:bzl
|
||||
# https://docs.bazel.build/versions/master/guide.html#bazelrc-the-bazel-configuration-file
|
||||
--type-add=bazel:ext:bazelrc
|
||||
# https://docs.bazel.build/versions/master/build-ref.html#BUILD_files
|
||||
--type-add=bazel:is:BUILD
|
||||
# https://docs.bazel.build/versions/master/build-ref.html#workspace
|
||||
--type-add=bazel:is:WORKSPACE
|
||||
|
||||
|
||||
# Actionscript
|
||||
--type-add=actionscript:ext:as,mxml
|
||||
|
||||
# Ada
|
||||
# https://www.adaic.org/
|
||||
--type-add=ada:ext:ada,adb,ads
|
||||
|
||||
# ASP
|
||||
# https://docs.microsoft.com/en-us/previous-versions/office/developer/server-technologies/aa286483(v=msdn.10)
|
||||
--type-add=asp:ext:asp
|
||||
|
||||
# ASP.Net
|
||||
# https://dotnet.microsoft.com/apps/aspnet
|
||||
--type-add=aspx:ext:master,ascx,asmx,aspx,svc
|
||||
|
||||
# Assembly
|
||||
--type-add=asm:ext:asm,s
|
||||
|
||||
# DOS/Windows batch
|
||||
--type-add=batch:ext:bat,cmd
|
||||
|
||||
# ColdFusion
|
||||
# https://en.wikipedia.org/wiki/ColdFusion
|
||||
--type-add=cfmx:ext:cfc,cfm,cfml
|
||||
|
||||
# Clojure
|
||||
# https://clojure.org/
|
||||
--type-add=clojure:ext:clj,cljs,edn,cljc
|
||||
|
||||
# C
|
||||
# .xs are Perl C files
|
||||
--type-add=cc:ext:c,h,xs
|
||||
|
||||
# C header files
|
||||
--type-add=hh:ext:h
|
||||
|
||||
# CoffeeScript
|
||||
# https://coffeescript.org/
|
||||
--type-add=coffeescript:ext:coffee
|
||||
|
||||
# C++
|
||||
--type-add=cpp:ext:cpp,cc,cxx,m,hpp,hh,h,hxx
|
||||
|
||||
# C++ header files
|
||||
--type-add=hpp:ext:hpp,hh,h,hxx
|
||||
|
||||
# C#
|
||||
--type-add=csharp:ext:cs
|
||||
|
||||
# Crystal-lang
|
||||
# https://crystal-lang.org/
|
||||
--type-add=crystal:ext:cr,ecr
|
||||
|
||||
# CSS
|
||||
# https://www.w3.org/Style/CSS/
|
||||
--type-add=css:ext:css
|
||||
|
||||
# Dart
|
||||
# https://dart.dev/
|
||||
--type-add=dart:ext:dart
|
||||
|
||||
# Delphi
|
||||
# https://en.wikipedia.org/wiki/Embarcadero_Delphi
|
||||
--type-add=delphi:ext:pas,int,dfm,nfm,dof,dpk,dproj,groupproj,bdsgroup,bdsproj
|
||||
|
||||
# Elixir
|
||||
# https://elixir-lang.org/
|
||||
--type-add=elixir:ext:ex,exs
|
||||
|
||||
# Elm
|
||||
# https://elm-lang.org
|
||||
--type-add=elm:ext:elm
|
||||
|
||||
# Emacs Lisp
|
||||
# https://www.gnu.org/software/emacs
|
||||
--type-add=elisp:ext:el
|
||||
|
||||
# Erlang
|
||||
# https://www.erlang.org/
|
||||
--type-add=erlang:ext:erl,hrl
|
||||
|
||||
# Fortran
|
||||
# https://en.wikipedia.org/wiki/Fortran
|
||||
--type-add=fortran:ext:f,f77,f90,f95,f03,for,ftn,fpp
|
||||
|
||||
# Go
|
||||
# https://golang.org/
|
||||
--type-add=go:ext:go
|
||||
|
||||
# Groovy
|
||||
# https://www.groovy-lang.org/
|
||||
--type-add=groovy:ext:groovy,gtmpl,gpp,grunit,gradle
|
||||
|
||||
# GSP
|
||||
# https://gsp.grails.org/
|
||||
--type-add=gsp:ext:gsp
|
||||
|
||||
# Haskell
|
||||
# https://www.haskell.org/
|
||||
--type-add=haskell:ext:hs,lhs
|
||||
|
||||
# HTML
|
||||
--type-add=html:ext:htm,html,xhtml
|
||||
|
||||
# Jade
|
||||
# http://jade-lang.com/
|
||||
--type-add=jade:ext:jade
|
||||
|
||||
# Java
|
||||
# https://www.oracle.com/technetwork/java/index.html
|
||||
--type-add=java:ext:java,properties
|
||||
|
||||
# JavaScript
|
||||
--type-add=js:ext:js
|
||||
|
||||
# JSP
|
||||
# https://www.oracle.com/technetwork/java/javaee/jsp/index.html
|
||||
--type-add=jsp:ext:jsp,jspx,jspf,jhtm,jhtml
|
||||
|
||||
# JSON
|
||||
# https://json.org/
|
||||
--type-add=json:ext:json
|
||||
|
||||
# Kotlin
|
||||
# https://kotlinlang.org/
|
||||
--type-add=kotlin:ext:kt,kts
|
||||
|
||||
# Less
|
||||
# http://www.lesscss.org/
|
||||
--type-add=less:ext:less
|
||||
|
||||
# Common Lisp
|
||||
# https://common-lisp.net/
|
||||
--type-add=lisp:ext:lisp,lsp
|
||||
|
||||
# Lua
|
||||
# https://www.lua.org/
|
||||
--type-add=lua:ext:lua
|
||||
--type-add=lua:firstlinematch:/^#!.*\blua(jit)?/
|
||||
|
||||
# Markdown
|
||||
# https://en.wikipedia.org/wiki/Markdown
|
||||
--type-add=markdown:ext:md,markdown
|
||||
# We understand that there are many ad hoc extensions for markdown
|
||||
# that people use. .md and .markdown are the two that ack recognizes.
|
||||
# You are free to add your own in your ackrc file.
|
||||
|
||||
# Matlab
|
||||
# https://en.wikipedia.org/wiki/MATLAB
|
||||
--type-add=matlab:ext:m
|
||||
|
||||
# Objective-C
|
||||
--type-add=objc:ext:m,h
|
||||
|
||||
# Objective-C++
|
||||
--type-add=objcpp:ext:mm,h
|
||||
|
||||
# OCaml
|
||||
# https://ocaml.org/
|
||||
--type-add=ocaml:ext:ml,mli,mll,mly
|
||||
|
||||
# Perl
|
||||
# https://perl.org/
|
||||
--type-add=perl:ext:pl,pm,pod,t,psgi
|
||||
--type-add=perl:firstlinematch:/^#!.*\bperl/
|
||||
|
||||
# Perl tests
|
||||
--type-add=perltest:ext:t
|
||||
|
||||
# Perl's Plain Old Documentation format, POD
|
||||
--type-add=pod:ext:pod
|
||||
|
||||
# PHP
|
||||
# https://www.php.net/
|
||||
--type-add=php:ext:php,phpt,php3,php4,php5,phtml
|
||||
--type-add=php:firstlinematch:/^#!.*\bphp/
|
||||
|
||||
# Plone
|
||||
# https://plone.org/
|
||||
--type-add=plone:ext:pt,cpt,metadata,cpy,py
|
||||
|
||||
# PowerShell
|
||||
# https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_scripts
|
||||
# https://learn.microsoft.com/en-us/powershell/scripting/developer/module/understanding-a-windows-powershell-module
|
||||
--type-add=powershell:ext:ps1,psm1
|
||||
|
||||
# PureScript
|
||||
# https://www.purescript.org
|
||||
--type-add=purescript:ext:purs
|
||||
|
||||
# Python
|
||||
# https://www.python.org/
|
||||
--type-add=python:ext:py
|
||||
--type-add=python:firstlinematch:/^#!.*\bpython/
|
||||
|
||||
# R
|
||||
# https://www.r-project.org/
|
||||
# https://r4ds.had.co.nz/r-markdown.html
|
||||
--type-add=rr:ext:R,Rmd
|
||||
|
||||
# reStructured Text
|
||||
# https://docutils.sourceforge.io/rst.html
|
||||
--type-add=rst:ext:rst
|
||||
|
||||
# Ruby
|
||||
# https://www.ruby-lang.org/
|
||||
--type-add=ruby:ext:rb,rhtml,rjs,rxml,erb,rake,spec
|
||||
--type-add=ruby:is:Rakefile
|
||||
--type-add=ruby:firstlinematch:/^#!.*\bruby/
|
||||
|
||||
# Rust
|
||||
# https://www.rust-lang.org/
|
||||
--type-add=rust:ext:rs
|
||||
|
||||
# Sass
|
||||
# https://sass-lang.com
|
||||
--type-add=sass:ext:sass,scss
|
||||
|
||||
# Scala
|
||||
# https://www.scala-lang.org/
|
||||
--type-add=scala:ext:scala,sbt
|
||||
|
||||
# Scheme
|
||||
# https://groups.csail.mit.edu/mac/projects/scheme/
|
||||
--type-add=scheme:ext:scm,ss
|
||||
|
||||
# Shell
|
||||
--type-add=shell:ext:sh,bash,csh,tcsh,ksh,zsh,fish
|
||||
--type-add=shell:firstlinematch:/^#!.*\b(?:ba|t?c|k|z|fi)?sh\b/
|
||||
|
||||
# Smalltalk
|
||||
# http://www.smalltalk.org/
|
||||
--type-add=smalltalk:ext:st
|
||||
|
||||
# Smarty
|
||||
# https://www.smarty.net/
|
||||
--type-add=smarty:ext:tpl
|
||||
|
||||
# SQL
|
||||
# https://www.iso.org/standard/45498.html
|
||||
--type-add=sql:ext:sql,ctl
|
||||
|
||||
# Stylus
|
||||
# http://stylus-lang.com/
|
||||
--type-add=stylus:ext:styl
|
||||
|
||||
# SVG
|
||||
# https://en.wikipedia.org/wiki/Scalable_Vector_Graphics
|
||||
--type-add=svg:ext:svg
|
||||
|
||||
# Swift
|
||||
# https://developer.apple.com/swift/
|
||||
--type-add=swift:ext:swift
|
||||
--type-add=swift:firstlinematch:/^#!.*\bswift/
|
||||
|
||||
# Tcl
|
||||
# https://www.tcl.tk/
|
||||
--type-add=tcl:ext:tcl,itcl,itk
|
||||
|
||||
# TeX & LaTeX
|
||||
# https://www.latex-project.org/
|
||||
--type-add=tex:ext:tex,cls,sty
|
||||
|
||||
# Template Toolkit (Perl)
|
||||
# http//template-toolkit.org/
|
||||
--type-add=ttml:ext:tt,tt2,ttml
|
||||
|
||||
# TOML
|
||||
# https://toml.io/
|
||||
--type-add=toml:ext:toml
|
||||
|
||||
# TypeScript
|
||||
# https://www.typescriptlang.org/
|
||||
--type-add=ts:ext:ts,tsx
|
||||
|
||||
# Visual Basic
|
||||
--type-add=vb:ext:bas,cls,frm,ctl,vb,resx
|
||||
|
||||
# Verilog
|
||||
--type-add=verilog:ext:v,vh,sv
|
||||
|
||||
# VHDL
|
||||
# http://www.eda.org/twiki/bin/view.cgi/P1076/WebHome
|
||||
--type-add=vhdl:ext:vhd,vhdl
|
||||
|
||||
# Vim
|
||||
# https://www.vim.org/
|
||||
--type-add=vim:ext:vim
|
||||
|
||||
# XML
|
||||
# https://www.w3.org/TR/REC-xml/
|
||||
--type-add=xml:ext:xml,dtd,xsd,xsl,xslt,ent,wsdl
|
||||
--type-add=xml:firstlinematch:/<[?]xml/
|
||||
|
||||
# YAML
|
||||
# https://yaml.org/
|
||||
--type-add=yaml:ext:yaml,yml
|
||||
|
||||
|
||||
|
||||
# TOM
|
||||
--ignore-directory=is:src
|
||||
--ignore-directory=is:tmp
|
||||
--ignore-directory=is:fonts
|
||||
--ignore-file=ext:ldtk
|
||||
--ignore-file=ext:png
|
||||
--ignore-file=ext:ase
|
||||
--ignore-file=ext:json
|
||||
--ignore-file=ext:svg
|
||||
|
||||
3
.gitignore
vendored
@ -1,2 +1 @@
|
||||
openquell*
|
||||
tmp
|
||||
openquell
|
||||
|
||||
27
Makefile
@ -1,12 +1,3 @@
|
||||
version = $(shell egrep "version string = " config/static.go | cut -d'"' -f 2)
|
||||
BRANCH = $(shell git branch --show-current)
|
||||
COMMIT = $(shell git rev-parse --short=8 HEAD)
|
||||
BUILD = $(shell date +%Y.%m.%d.%H%M%S)
|
||||
#VERSION := $(if $(filter $(BRANCH), development),$(version)-$(BRANCH)-$(COMMIT)-$(BUILD),$(version))
|
||||
VERSION := $(version)-$(BRANCH)-$(COMMIT)-$(BUILD)
|
||||
SHORTVERSION := $(version)-$(BRANCH)-$(COMMIT)
|
||||
LDFLAGS := -ldflags "-X 'openquell/config.VERSION=$(VERSION)'"
|
||||
|
||||
all: clean build
|
||||
@echo ok
|
||||
|
||||
@ -14,22 +5,8 @@ clean:
|
||||
rm -f openquell
|
||||
|
||||
build:
|
||||
go build -ldflags "-X 'openquell/config.VERSION=$(VERSION)'"
|
||||
go build
|
||||
|
||||
buildwasm:
|
||||
env GOOS=js GOARCH=wasm go build -o openquell.wasm $(LDFLAGS) .
|
||||
|
||||
buildwindows:
|
||||
GOOS=windows GOARCH=amd64 go build $(LDFLAGS) -o openquell.exe
|
||||
|
||||
zipwasm:
|
||||
zip -r openquell-$(SHORTVERSION).zip index.html openquell.wasm wasm_exec.js
|
||||
|
||||
wasm: buildwasm zipwasm
|
||||
@ls -l openquell-$(SHORTVERSION).zip
|
||||
|
||||
test:
|
||||
@echo $(VERSION)
|
||||
|
||||
nixshell:
|
||||
nix-shell -p xorg.libX11 xorg.libXrandr libGL xorg.libXcursor xorg.libXinerama xorg.libXi xorg.libXxf86vm xorg_sys_opengl
|
||||
@echo 1
|
||||
|
||||
97
TODO.md
@ -1,74 +1,35 @@
|
||||
## Levels:
|
||||
|
||||
- Start New game starts with last played level, better add a Resume
|
||||
Game menu item for this and use Start New always for level 1.
|
||||
- use first line as background image name
|
||||
- ignore comments in lvl files
|
||||
- check when sphere bounces from one end to the other endlessly w/o
|
||||
any solids in between. this is a game lock and equals game over
|
||||
- Start the game end timer and add a score FIXME: put the actual max
|
||||
reachable score into the level definition along with the minimum
|
||||
steps required to reach it, also add a step counter
|
||||
|
||||
- Turn menu button in hud_system (events in level_scene!) into ebitenui button
|
||||
- Grid Observer:
|
||||
https://github.com/mlange-42/arche/issues/374
|
||||
|
||||
- Obstacle don't stop at collectibles
|
||||
|
||||
- Player can collect collectible hidden under obstacle (should be
|
||||
fixed when above is fixed)
|
||||
Screenshot:
|
||||
|
||||
Yes, since *ebiten.Image implements the standard image.Image interface
|
||||
I just made a screenshot example (in Draw() function):
|
||||
if inpututil.IsKeyJustPressed(ebiten.KeyS) {
|
||||
f, err := os.Create("screenshot.png")
|
||||
if err != nil {
|
||||
log.Fatal("can't create file: ", err)
|
||||
}
|
||||
png.Encode(f, screen)
|
||||
}
|
||||
|
||||
|
||||
- Add some final message when the player reaches the last level, start
|
||||
from scratch or a message to buy me some beer, whatever
|
||||
|
||||
- Calculate obstacle collision the same as solid collision with future
|
||||
velocity and included snap in so that the player ends up right on
|
||||
the edge of the obstacle and not inside as it is now
|
||||
|
||||
- Add player idle animation
|
||||
|
||||
- Add player collision animation
|
||||
|
||||
- Create pixel art ui elements (button, list things) and ui borders/backgrounds
|
||||
Replace HUD with pixel art variant
|
||||
|
||||
- Modify font and font color matching the palette
|
||||
|
||||
- On game start respond to any key (ebitengine-input has an anykey func)
|
||||
|
||||
- Switch to use https://github.com/quasilyte/ebitengine-input
|
||||
|
||||
- Add drag support: point and hold on the player, move cursor in some
|
||||
direction and let the player start moving on release. Respond to
|
||||
mouse and touch pad. See ~/tmp/ebiten/examples/drag/.
|
||||
|
||||
- Add options scene (mouse, player speed, sound options etc)
|
||||
|
||||
- Add save to disk feature including settings and player
|
||||
accomplishements (FIXME: find the lib, asked in Discord)
|
||||
|
||||
- Rework sprites (again!) to match stellar background: maybe more
|
||||
technical tiles and items? Like some robotic setup?
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## Collider Rework [abandoned: see branch collider-system, fails]
|
||||
|
||||
- do not use the map anymore for collision detection
|
||||
- central collision_system
|
||||
- add Collider component with callback funcs to call on certain events
|
||||
- callback types:
|
||||
- rect intersect (== future collision)
|
||||
- collision resolve (set new position)
|
||||
- pass over foreign rect (to e.g. change sprite while flying over sprite)
|
||||
- pass over done (switch sprite)
|
||||
- check for all moving objects against non-moving ones like moving
|
||||
obstacle, player, bullet, laser
|
||||
- check if executing callbacks within query loop is allowed
|
||||
- callback function needs to be able to modify other components, so
|
||||
possibly use observers for them, e.g.:
|
||||
Collider.IntersectResolve => func(newpos) {player.pos = newpos; player.vel = stop}
|
||||
- in the end it must be possible to add new entities without the need
|
||||
to write a collision check for them, but have collision detection anyway!
|
||||
|
||||
## Just in case stuff
|
||||
|
||||
- for finding caller:
|
||||
pc := make([]uintptr, 10)
|
||||
n := runtime.Callers(0, pc)
|
||||
pc = pc[:n]
|
||||
fs := runtime.CallersFrames(pc)
|
||||
source, _ := fs.Next()
|
||||
source, _ = fs.Next()
|
||||
source, _ = fs.Next()
|
||||
|
||||
slog.Debug("get observer", "minmoves", observer.LevelScore,
|
||||
"file", source.File, "line", source.Line)
|
||||
- Check player-player collisions!
|
||||
|
||||
17
assets/levels/00-deadly-obstacles.lvl
Normal file
@ -0,0 +1,17 @@
|
||||
Description: test obstacles
|
||||
Background: background-lila
|
||||
|
||||
|
||||
|
||||
#######
|
||||
# #
|
||||
# t #
|
||||
#> S <#
|
||||
# #
|
||||
# ^ #
|
||||
#######
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
17
assets/levels/01-friendly-obstacles.lvl
Normal file
@ -0,0 +1,17 @@
|
||||
Description: test obstacles
|
||||
Background: background-lila
|
||||
|
||||
|
||||
|
||||
#############
|
||||
# #
|
||||
#> S # #
|
||||
# ># >#
|
||||
#< # #
|
||||
# v# <#
|
||||
#############
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
17
assets/levels/02-start.lvl
Normal file
@ -0,0 +1,17 @@
|
||||
Description: find the fruit
|
||||
Background: background-lila
|
||||
|
||||
|
||||
# ############
|
||||
# #
|
||||
############ #
|
||||
# o S #
|
||||
# ######## ###
|
||||
+ #
|
||||
############ #
|
||||
# o # #
|
||||
# # ######## #
|
||||
# # o
|
||||
# ############
|
||||
|
||||
|
||||
17
assets/levels/03-own.lvl
Normal file
@ -0,0 +1,17 @@
|
||||
Description: win
|
||||
Background: background-lila
|
||||
|
||||
|
||||
|
||||
|
||||
########
|
||||
#v o #
|
||||
# S<# #
|
||||
# #### #
|
||||
|
||||
|
||||
# #### #
|
||||
# #
|
||||
#> ^#
|
||||
########
|
||||
|
||||
17
assets/levels/04-mayhem.lvl
Normal file
@ -0,0 +1,17 @@
|
||||
Description: use multiple players
|
||||
Background: background-lila
|
||||
|
||||
|
||||
|
||||
|
||||
##########
|
||||
# v#
|
||||
# #
|
||||
#S s#
|
||||
# #
|
||||
#^ #
|
||||
##########
|
||||
|
||||
|
||||
|
||||
|
||||
30
assets/levels/gen.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
width=$(grep "width " ../../main.go | awk '{print $4}')
|
||||
height=$(grep "height " ../../main.go | awk '{print $4}')
|
||||
|
||||
read -p " Enter level name: " name
|
||||
read -p " Enter background: " background
|
||||
read -p "Enter description: " des
|
||||
|
||||
if test -z "$name"; then
|
||||
name="newlevel"
|
||||
fi
|
||||
|
||||
if test -z "$bbackground"; then
|
||||
background="background-lila"
|
||||
fi
|
||||
|
||||
w=$(($width/32))
|
||||
h=$(($height/32))
|
||||
|
||||
(
|
||||
echo "Description: $des"
|
||||
echo "Background: $background"
|
||||
|
||||
for x in $(seq 1 $h); do
|
||||
for y in $(seq 1 $w); do
|
||||
echo -n " "
|
||||
done
|
||||
echo
|
||||
done
|
||||
)
|
||||
@ -1,83 +1,42 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
_ "image/png"
|
||||
"io/fs"
|
||||
"log"
|
||||
"log/slog"
|
||||
"openquell/config"
|
||||
"openquell/util"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/solarlune/ldtkgo"
|
||||
)
|
||||
|
||||
var Project = LoadLDTK("levels")
|
||||
var Levels = LoadLevels("levels")
|
||||
var Tiles = InitTiles()
|
||||
|
||||
type TileAnimation struct {
|
||||
OnCollision bool // wether to animate a collision
|
||||
OnDestruction bool // wether to animate destruction
|
||||
OnIdle bool // wether to animate during idling
|
||||
OnMoving bool // wether to animate during moving
|
||||
|
||||
CollisionSheet AnimationSet // an entry in assets.Animations[name]
|
||||
DestructionSheet AnimationSet
|
||||
IdleSheet AnimationSet
|
||||
}
|
||||
|
||||
// Tile: contains image, identifier (as used in level data) and
|
||||
// additional properties
|
||||
type Tile struct {
|
||||
Id, Ref string
|
||||
Sprite *ebiten.Image
|
||||
ToggleSprite *ebiten.Image
|
||||
Solid bool // wall brick
|
||||
Player bool // player sphere
|
||||
IsPrimary bool // primary player sphere
|
||||
Renderable bool // visible, has sprite
|
||||
Velocity bool // movable
|
||||
Collectible bool // collectible, vanishes once collected
|
||||
Transient bool // turns into brick wall when traversed
|
||||
Destroyable bool // turns into empty floor when bumped into twice
|
||||
Tiles []*ebiten.Image // has N sprites
|
||||
TileNames []string // same thing, only the names
|
||||
Obstacle bool // is an obstacle/enemy
|
||||
Direction int // obstacle business end shows into this direction
|
||||
Shader *ebiten.Shader
|
||||
Alpha *ebiten.Image
|
||||
Bond bool // denotes an entity which can have a relation to another
|
||||
Door bool // a door, can be manipulated by a switch
|
||||
Switch bool // opens|closes a door
|
||||
Animation TileAnimation
|
||||
}
|
||||
|
||||
func (tile *Tile) Clone() *Tile {
|
||||
newtile := &Tile{
|
||||
Id: tile.Id,
|
||||
Ref: tile.Ref,
|
||||
Sprite: tile.Sprite,
|
||||
ToggleSprite: tile.ToggleSprite,
|
||||
Solid: tile.Solid,
|
||||
Player: tile.Player,
|
||||
IsPrimary: tile.IsPrimary,
|
||||
Renderable: tile.Renderable,
|
||||
Velocity: tile.Velocity,
|
||||
Collectible: tile.Collectible,
|
||||
Transient: tile.Transient,
|
||||
Destroyable: tile.Destroyable,
|
||||
Tiles: tile.Tiles,
|
||||
TileNames: tile.TileNames,
|
||||
Obstacle: tile.Obstacle,
|
||||
Direction: tile.Direction,
|
||||
Alpha: tile.Alpha,
|
||||
Shader: tile.Shader,
|
||||
Bond: tile.Bond,
|
||||
Door: tile.Door,
|
||||
Switch: tile.Switch,
|
||||
Animation: tile.Animation,
|
||||
}
|
||||
|
||||
return newtile
|
||||
Id byte
|
||||
Sprite *ebiten.Image
|
||||
Class string
|
||||
Solid bool
|
||||
Player bool
|
||||
IsPrimary bool
|
||||
Renderable bool
|
||||
Velocity bool
|
||||
Collectible bool
|
||||
Transient bool
|
||||
Particle int // -1=unused, 0-3 = show image of slice
|
||||
Tiles []*ebiten.Image
|
||||
TileNames []string // same thing, only the names
|
||||
Obstacle bool
|
||||
Direction int // obstacles
|
||||
}
|
||||
|
||||
const (
|
||||
@ -85,52 +44,55 @@ const (
|
||||
Secondary bool = false
|
||||
)
|
||||
|
||||
func GetSprites(class []string) []*ebiten.Image {
|
||||
sprites := []*ebiten.Image{}
|
||||
|
||||
for _, sprite := range class {
|
||||
sprites = append(sprites, Assets[sprite])
|
||||
}
|
||||
|
||||
return sprites
|
||||
}
|
||||
|
||||
func NewTilePlayer(isprimary bool) *Tile {
|
||||
tile := &Tile{
|
||||
Id: 'S',
|
||||
Class: "sphere",
|
||||
Renderable: true,
|
||||
Player: true,
|
||||
Velocity: true,
|
||||
IsPrimary: isprimary,
|
||||
}
|
||||
|
||||
switch isprimary {
|
||||
case Primary:
|
||||
tile.Sprite = Assets["sphere-blue"]
|
||||
case Secondary:
|
||||
tile.Sprite = Assets["sphere-blue-secondary"]
|
||||
tile.Id = 's'
|
||||
}
|
||||
|
||||
// primary sprite is always the first one
|
||||
tile.Tiles = []*ebiten.Image{Assets["sphere"], Assets["sphere-small"]}
|
||||
tile.Tiles = []*ebiten.Image{Assets["sphere-blue"], Assets["sphere-blue-secondary"]}
|
||||
return tile
|
||||
}
|
||||
|
||||
func NewTileBlock() *Tile {
|
||||
func NewTileBlock(class string) *Tile {
|
||||
return &Tile{
|
||||
Id: '#',
|
||||
Sprite: Assets[class],
|
||||
Class: class,
|
||||
Solid: true,
|
||||
Renderable: true,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTileCollectible() *Tile {
|
||||
func NewTileCollectible(class string) *Tile {
|
||||
return &Tile{
|
||||
Id: 'o',
|
||||
Sprite: Assets[class],
|
||||
Class: class,
|
||||
Solid: false,
|
||||
Renderable: true,
|
||||
Collectible: true,
|
||||
Animation: TileAnimation{
|
||||
OnDestruction: true,
|
||||
DestructionSheet: Animations["collectible-detonating"],
|
||||
OnIdle: true,
|
||||
IdleSheet: Animations["collectible-idle"],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func NewTileObstacle(direction int) *Tile {
|
||||
func NewTileObstacle(class string, direction int) *Tile {
|
||||
return &Tile{
|
||||
Id: '+',
|
||||
Sprite: Assets[class],
|
||||
Class: class,
|
||||
Solid: false,
|
||||
Renderable: true,
|
||||
Obstacle: true,
|
||||
@ -139,122 +101,161 @@ func NewTileObstacle(direction int) *Tile {
|
||||
}
|
||||
}
|
||||
|
||||
func NewTileTranswall() *Tile {
|
||||
func NewTileParticle(class []string) *Tile {
|
||||
sprites := []*ebiten.Image{}
|
||||
|
||||
for _, sprite := range class {
|
||||
sprites = append(sprites, Assets[sprite])
|
||||
}
|
||||
|
||||
return &Tile{
|
||||
Id: '*',
|
||||
Class: "particle",
|
||||
Solid: false,
|
||||
Renderable: false,
|
||||
Particle: 0,
|
||||
Tiles: sprites,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTileTranswall(class []string) *Tile {
|
||||
sprites := []*ebiten.Image{}
|
||||
names := []string{}
|
||||
|
||||
for _, sprite := range class {
|
||||
sprites = append(sprites, Assets[sprite])
|
||||
names = append(names, sprite)
|
||||
}
|
||||
|
||||
return &Tile{
|
||||
Id: '*',
|
||||
Class: "transwall",
|
||||
Solid: false,
|
||||
Renderable: true,
|
||||
Transient: true,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTileHiddenDoor(alpha string) *Tile {
|
||||
return &Tile{
|
||||
Solid: false,
|
||||
Renderable: true,
|
||||
Destroyable: true,
|
||||
Alpha: Assets[alpha],
|
||||
Shader: Shaders["destruct"],
|
||||
}
|
||||
}
|
||||
|
||||
func NewTileSwitch() *Tile {
|
||||
return &Tile{
|
||||
Solid: false,
|
||||
Renderable: true,
|
||||
Bond: true,
|
||||
Switch: true,
|
||||
}
|
||||
}
|
||||
|
||||
func NewTileDoor() *Tile {
|
||||
return &Tile{
|
||||
Solid: false,
|
||||
Renderable: true,
|
||||
Bond: true,
|
||||
Door: true,
|
||||
Tiles: sprites,
|
||||
Sprite: sprites[0], // initially use the first
|
||||
TileNames: names,
|
||||
}
|
||||
}
|
||||
|
||||
// used to map level data bytes to actual tiles
|
||||
type TileRegistry map[string]*Tile
|
||||
type TileRegistry map[byte]*Tile
|
||||
|
||||
// holds a raw level spec:
|
||||
//
|
||||
// Name: the name of the level file w/o the .lvl extension
|
||||
// Background: an image name used as game background for this level
|
||||
// Description: text to display on top
|
||||
// Data: a level spec consisting of chars of the above mapping and spaces, e.g.:
|
||||
// ####
|
||||
// # #
|
||||
// ####
|
||||
//
|
||||
// Each level data must be 20 chars wide (= 640 px width) and 15 chars
|
||||
// high (=480 px height).
|
||||
type RawLevel struct {
|
||||
Name string
|
||||
Description string
|
||||
Background *ebiten.Image
|
||||
Data []byte
|
||||
}
|
||||
|
||||
func InitTiles() TileRegistry {
|
||||
return TileRegistry{
|
||||
"floor": {Renderable: false},
|
||||
"default": NewTileBlock(),
|
||||
"solidorange": NewTileBlock(),
|
||||
"PlayerPrimary": NewTilePlayer(Primary),
|
||||
"PlayerSecondary": NewTilePlayer(Secondary),
|
||||
"Collectible": NewTileCollectible(),
|
||||
"ObstacleStar": NewTileObstacle(config.All),
|
||||
"ObstacleNorth": NewTileObstacle(config.North),
|
||||
"ObstacleSouth": NewTileObstacle(config.South),
|
||||
"ObstacleWest": NewTileObstacle(config.West),
|
||||
"ObstacleEast": NewTileObstacle(config.East),
|
||||
"Transient": NewTileTranswall(),
|
||||
"HiddenDoor": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor2": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor3": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor4": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor5": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor6": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor7": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor8": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor9": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor10": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor11": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor12": NewTileHiddenDoor("damage"),
|
||||
"HiddenDoor13": NewTileHiddenDoor("damage"),
|
||||
"Switch": NewTileSwitch(),
|
||||
"Door": NewTileDoor(),
|
||||
' ': {Id: ' ', Class: "floor", Renderable: false},
|
||||
'#': NewTileBlock("block-grey32"),
|
||||
'B': NewTileBlock("block-orange-32"),
|
||||
'S': NewTilePlayer(Primary),
|
||||
's': NewTilePlayer(Secondary),
|
||||
'o': NewTileCollectible("collectible-orange"),
|
||||
'+': NewTileObstacle("obstacle-star", config.All),
|
||||
'^': NewTileObstacle("obstacle-north", config.North),
|
||||
'v': NewTileObstacle("obstacle-south", config.South),
|
||||
'<': NewTileObstacle("obstacle-west", config.West),
|
||||
'>': NewTileObstacle("obstacle-east", config.East),
|
||||
'*': NewTileParticle([]string{
|
||||
//"particle-ring-1",
|
||||
"particle-ring-2",
|
||||
"particle-ring-3",
|
||||
"particle-ring-4",
|
||||
"particle-ring-5",
|
||||
"particle-ring-6",
|
||||
}),
|
||||
't': NewTileTranswall([]string{"transwall", "block-orange-32"}),
|
||||
}
|
||||
}
|
||||
|
||||
// load LDTK project at compile time into ram
|
||||
func LoadLDTK(dir string) *ldtkgo.Project {
|
||||
fd, err := assetfs.Open("levels/openquell.ldtk")
|
||||
// load levels at compile time into ram, creates a slice of raw levels
|
||||
func LoadLevels(dir string) []RawLevel {
|
||||
levels := []RawLevel{}
|
||||
|
||||
// we use embed.FS to iterate over all files in ./levels/
|
||||
entries, err := assetfs.ReadDir(dir)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open LDTK file levels/openquell.ldtk: %s", err)
|
||||
log.Fatalf("failed to read level dir %s: %s", dir, err)
|
||||
}
|
||||
|
||||
sort.Slice(entries, func(i, j int) bool {
|
||||
return entries[i].Name() < entries[j].Name()
|
||||
})
|
||||
|
||||
for _, levelfile := range entries {
|
||||
if levelfile.Type().IsRegular() && strings.Contains(levelfile.Name(), ".lvl") {
|
||||
path := filepath.Join("assets", dir)
|
||||
level := ParseRawLevel(path, levelfile)
|
||||
|
||||
levels = append(levels, level)
|
||||
|
||||
slog.Debug("loaded level", "path", path, "file", levelfile)
|
||||
}
|
||||
}
|
||||
|
||||
return levels
|
||||
}
|
||||
|
||||
func ParseRawLevel(dir string, levelfile fs.DirEntry) RawLevel {
|
||||
fd, err := os.Open(filepath.Join(dir, levelfile.Name()))
|
||||
if err != nil {
|
||||
log.Fatalf("failed to read level file %s: %s", levelfile.Name(), err)
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
fileinfo, err := fd.Stat()
|
||||
if err != nil {
|
||||
log.Fatalf("failed to stat() LDTK file levels/openquell.ldtk: %s", err)
|
||||
}
|
||||
name := strings.TrimSuffix(levelfile.Name(), ".lvl")
|
||||
des := ""
|
||||
background := &ebiten.Image{}
|
||||
data := []byte{}
|
||||
|
||||
filesize := fileinfo.Size()
|
||||
buffer := make([]byte, filesize)
|
||||
scanner := bufio.NewScanner(fd)
|
||||
for scanner.Scan() {
|
||||
// ignore any whitespace
|
||||
line := scanner.Text()
|
||||
|
||||
_, err = fd.Read(buffer)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to read bytes from LDTK file levels/openquell.ldtk: %s", err)
|
||||
}
|
||||
// ignore empty lines
|
||||
if len(line) == 0 {
|
||||
continue
|
||||
}
|
||||
|
||||
project, err := ldtkgo.Read(buffer)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// do some sanity checks
|
||||
properties := []string{"minmoves", "level", "description"}
|
||||
need := len(properties)
|
||||
|
||||
for idx, level := range project.Levels {
|
||||
have := 0
|
||||
|
||||
for _, property := range level.Properties {
|
||||
if util.Contains(properties, property.Identifier) {
|
||||
have++
|
||||
switch {
|
||||
case strings.Contains(line, "Background:"):
|
||||
haveit := strings.Split(line, ": ")
|
||||
if util.Exists(Assets, haveit[1]) {
|
||||
background = Assets[haveit[1]]
|
||||
}
|
||||
}
|
||||
|
||||
if have != need {
|
||||
log.Fatalf("level definition for level %d (%s) invalid: %d missing properties\n required: %s",
|
||||
idx, level.Identifier, need-have, strings.Join(properties, ", "),
|
||||
)
|
||||
case strings.Contains(line, "Description:"):
|
||||
haveit := strings.Split(line, ": ")
|
||||
des = haveit[1]
|
||||
default:
|
||||
// all other non-empty and non-equalsign lines are
|
||||
// level definition matrix data, merge thes into data
|
||||
data = append(data, line+"\n"...)
|
||||
}
|
||||
}
|
||||
|
||||
return project
|
||||
return RawLevel{
|
||||
Name: name,
|
||||
Data: data,
|
||||
Background: background,
|
||||
Description: des,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,49 +0,0 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"log"
|
||||
"log/slog"
|
||||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
type ShaderRegistry map[string]*ebiten.Shader
|
||||
|
||||
var Shaders = LoadShaders("shaders")
|
||||
|
||||
func LoadShaders(dir string) ShaderRegistry {
|
||||
shaders := ShaderRegistry{}
|
||||
|
||||
entries, err := assetfs.ReadDir(dir)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to read shaders dir %s: %s", dir, err)
|
||||
}
|
||||
|
||||
for _, file := range entries {
|
||||
path := path.Join(dir, file.Name())
|
||||
fd, err := assetfs.Open(path)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open shader file %s: %s", file.Name(), err)
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
name := strings.TrimSuffix(file.Name(), ".kg")
|
||||
|
||||
buf := new(bytes.Buffer)
|
||||
buf.ReadFrom(fd)
|
||||
|
||||
shader, err := ebiten.NewShader([]byte(buf.Bytes()))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
shaders[name] = shader
|
||||
|
||||
slog.Debug("loaded shader asset", "path", path)
|
||||
}
|
||||
|
||||
return shaders
|
||||
}
|
||||
@ -1,17 +1,14 @@
|
||||
package assets
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"embed"
|
||||
"encoding/json"
|
||||
"image"
|
||||
_ "image/png"
|
||||
"io/fs"
|
||||
"log"
|
||||
"log/slog"
|
||||
"path"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
@ -19,64 +16,13 @@ import (
|
||||
// Maps image name to image data
|
||||
type AssetRegistry map[string]*ebiten.Image
|
||||
|
||||
// A helper to pass the registry easier around
|
||||
type assetData struct {
|
||||
Registry AssetRegistry
|
||||
}
|
||||
|
||||
// to parse asesprite animation json
|
||||
type AnimationGeo struct {
|
||||
X int `json:"x"`
|
||||
Y int `json:"y"`
|
||||
Width int `json:"w"`
|
||||
Height int `json:"h"`
|
||||
}
|
||||
|
||||
type AnimationFrame struct {
|
||||
Position AnimationGeo `json:"frame"`
|
||||
Duration int `json:"duration"`
|
||||
}
|
||||
|
||||
type AnimationMeta struct {
|
||||
Name string `json:"image"`
|
||||
Geo AnimationGeo `json:"size"`
|
||||
}
|
||||
|
||||
// Needed to thaw sprite set written by asesprite
|
||||
type AnimationJSON struct {
|
||||
Meta AnimationMeta `json:"Meta"`
|
||||
Frames []AnimationFrame `json:"frames"`
|
||||
}
|
||||
|
||||
// used to store Animation data
|
||||
type AnimationSprite struct {
|
||||
Sprite *ebiten.Image
|
||||
Duration time.Duration
|
||||
}
|
||||
|
||||
type AnimationSet struct {
|
||||
Width, Height int
|
||||
Sprites []AnimationSprite
|
||||
File string
|
||||
}
|
||||
|
||||
// names in the registry match the sprite set png file name, the JSON
|
||||
// file names are irrelevant as they point to the matching file using
|
||||
// the "image" field.
|
||||
type AnimationRegistry map[string]AnimationSet
|
||||
|
||||
//go:embed sprites/*.png fonts/*.ttf levels/*.ldtk shaders/*.kg sprites/*.json
|
||||
//go:embed levels/*.lvl sprites/*.png fonts/*.ttf
|
||||
var assetfs embed.FS
|
||||
|
||||
// Called at build time, creates the global asset and animation registries
|
||||
var Assets, Animations = LoadImages()
|
||||
var Assets = LoadImages("sprites")
|
||||
|
||||
// load pngs and json files
|
||||
func LoadImages() (AssetRegistry, AnimationRegistry) {
|
||||
dir := "sprites"
|
||||
imagedata := &assetData{}
|
||||
imagedata.Registry = AssetRegistry{}
|
||||
rawanimations := []AnimationJSON{}
|
||||
func LoadImages(dir string) AssetRegistry {
|
||||
images := AssetRegistry{}
|
||||
|
||||
// we use embed.FS to iterate over all files in ./assets/
|
||||
entries, err := assetfs.ReadDir(dir)
|
||||
@ -85,93 +31,24 @@ func LoadImages() (AssetRegistry, AnimationRegistry) {
|
||||
}
|
||||
|
||||
for _, imagefile := range entries {
|
||||
path := path.Join(dir, imagefile.Name())
|
||||
|
||||
fd, err := assetfs.Open(path)
|
||||
path := filepath.Join("assets", dir, imagefile.Name())
|
||||
fd, err := os.Open(path)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to open file %s: %s", imagefile.Name(), err)
|
||||
log.Fatalf("failed to open image file %s: %s", imagefile.Name(), err)
|
||||
}
|
||||
defer fd.Close()
|
||||
|
||||
switch {
|
||||
case strings.HasSuffix(path, ".png"):
|
||||
name, image := ReadImage(imagefile, fd)
|
||||
imagedata.Registry[name] = image
|
||||
name := strings.TrimSuffix(imagefile.Name(), ".png")
|
||||
|
||||
case strings.HasSuffix(path, ".json"):
|
||||
animationjson := ReadJson(imagefile, fd)
|
||||
rawanimations = append(rawanimations, animationjson)
|
||||
img, _, err := image.Decode(fd)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to decode image %s: %s", imagefile.Name(), err)
|
||||
}
|
||||
|
||||
images[name] = ebiten.NewImageFromImage(img)
|
||||
|
||||
slog.Debug("loaded asset", "path", path)
|
||||
}
|
||||
|
||||
// preprocess animation sprites
|
||||
animations := ProcessAnimations(rawanimations, imagedata)
|
||||
|
||||
return imagedata.Registry, animations
|
||||
}
|
||||
|
||||
func ReadImage(imagefile fs.DirEntry, fd fs.File) (string, *ebiten.Image) {
|
||||
name := strings.TrimSuffix(imagefile.Name(), ".png")
|
||||
|
||||
img, _, err := image.Decode(fd)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to decode image %s: %s", imagefile.Name(), err)
|
||||
}
|
||||
|
||||
image := ebiten.NewImageFromImage(img)
|
||||
|
||||
return name, image
|
||||
}
|
||||
|
||||
func ReadJson(imagefile fs.DirEntry, fd fs.File) AnimationJSON {
|
||||
buf := new(bytes.Buffer)
|
||||
buf.ReadFrom(fd)
|
||||
|
||||
animationjson := AnimationJSON{}
|
||||
|
||||
err := json.Unmarshal(buf.Bytes(), &animationjson)
|
||||
if err != nil {
|
||||
log.Fatalf("failed to parse JSON: %s", err)
|
||||
}
|
||||
|
||||
return animationjson
|
||||
}
|
||||
|
||||
// turn a raw JSON from Asesprite into something we can use better
|
||||
// internally we also load all the sprites of an animation by using
|
||||
// image.SubImage() on the spriteset matching the animation name.
|
||||
// so, if the animation JSON is called "player-idle.json", then we
|
||||
// expect to receive the spriteset in a file "player-idle.png", which
|
||||
// has of course already been loaded at this stage. These spritesets
|
||||
// must contain a row of sprites. We get the measurements from the JSON.
|
||||
func ProcessAnimations(rawanimations []AnimationJSON, imagedata *assetData) AnimationRegistry {
|
||||
animations := AnimationRegistry{}
|
||||
|
||||
for _, animation := range rawanimations {
|
||||
animationset := AnimationSet{}
|
||||
|
||||
animationset.File = strings.TrimSuffix(animation.Meta.Name, ".png")
|
||||
|
||||
for _, frame := range animation.Frames {
|
||||
sprite := imagedata.Registry[animationset.File].SubImage(
|
||||
image.Rect(
|
||||
frame.Position.X,
|
||||
frame.Position.Y,
|
||||
frame.Position.X+frame.Position.Width,
|
||||
frame.Position.Y+frame.Position.Height,
|
||||
)).(*ebiten.Image)
|
||||
|
||||
animationset.Sprites = append(animationset.Sprites,
|
||||
AnimationSprite{Sprite: sprite, Duration: time.Duration(frame.Duration)})
|
||||
}
|
||||
|
||||
animationset.Width = animationset.Sprites[0].Sprite.Bounds().Dx()
|
||||
animationset.Height = animationset.Sprites[0].Sprite.Bounds().Dy()
|
||||
|
||||
animations[animationset.File] = animationset
|
||||
}
|
||||
|
||||
return animations
|
||||
return images
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
@ -1,164 +0,0 @@
|
||||
{ "frames": [
|
||||
{
|
||||
"filename": "collectible-detonating 0.ase",
|
||||
"frame": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 1.ase",
|
||||
"frame": { "x": 64, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 2.ase",
|
||||
"frame": { "x": 128, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 3.ase",
|
||||
"frame": { "x": 192, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 4.ase",
|
||||
"frame": { "x": 256, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 5.ase",
|
||||
"frame": { "x": 320, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 6.ase",
|
||||
"frame": { "x": 384, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 7.ase",
|
||||
"frame": { "x": 448, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 8.ase",
|
||||
"frame": { "x": 512, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 9.ase",
|
||||
"frame": { "x": 576, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 10.ase",
|
||||
"frame": { "x": 640, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 11.ase",
|
||||
"frame": { "x": 704, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 12.ase",
|
||||
"frame": { "x": 768, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 13.ase",
|
||||
"frame": { "x": 832, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible-detonating 14.ase",
|
||||
"frame": { "x": 896, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "http://www.aseprite.org/",
|
||||
"version": "1.x-dev",
|
||||
"image": "collectible-detonating.png",
|
||||
"format": "RGBA8888",
|
||||
"size": { "w": 960, "h": 64 },
|
||||
"scale": "1",
|
||||
"frameTags": [
|
||||
],
|
||||
"layers": [
|
||||
{ "name": "Yellow Sphere", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 8", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 7", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 6", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 5", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 4", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 3", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 2", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 1", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Blitz Outer", "opacity": 70, "blendMode": "normal" },
|
||||
{ "name": "Blitz Middle", "opacity": 84, "blendMode": "normal" },
|
||||
{ "name": "Blitz Inner", "opacity": 97, "blendMode": "normal" }
|
||||
],
|
||||
"slices": [
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 6.6 KiB |
|
Before Width: | Height: | Size: 647 B |
|
Before Width: | Height: | Size: 689 B |
|
Before Width: | Height: | Size: 472 B |
|
Before Width: | Height: | Size: 325 B |
|
Before Width: | Height: | Size: 179 B |
|
Before Width: | Height: | Size: 179 B |
|
Before Width: | Height: | Size: 109 B |
|
Before Width: | Height: | Size: 716 B |
|
Before Width: | Height: | Size: 783 B |
|
Before Width: | Height: | Size: 802 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 909 B |
|
Before Width: | Height: | Size: 924 B |
|
Before Width: | Height: | Size: 937 B |
|
Before Width: | Height: | Size: 876 B |
|
Before Width: | Height: | Size: 577 B |
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 271 B |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 1.7 KiB |
@ -1,2 +0,0 @@
|
||||
#!/bin/sh
|
||||
montage -tile 4x0 -geometry +0+0 block* collectible-orange.png obstacle-* sphere-blue* transwall.png map.png && okular map.png
|
||||
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 5.3 KiB |
|
Before Width: | Height: | Size: 132 KiB |
|
Before Width: | Height: | Size: 503 B |
|
Before Width: | Height: | Size: 543 B |
|
Before Width: | Height: | Size: 141 KiB |
|
Before Width: | Height: | Size: 1.2 KiB |
@ -1,36 +0,0 @@
|
||||
// Copyright 2020 The Ebiten Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
//go:build ignore
|
||||
|
||||
//kage:unit pixels
|
||||
|
||||
package main
|
||||
|
||||
var Damaged int
|
||||
|
||||
const HP float = 0
|
||||
|
||||
func Fragment(_ vec4, texCoord vec2, _ vec4) vec4 {
|
||||
wallpx := imageSrc0At(texCoord) // A pixel from the wall tile
|
||||
mask := imageSrc1At(texCoord) // A pixel from the damage mask image
|
||||
|
||||
if Damaged == 1 && (wallpx.a != 0.0 && mask.a != 0.0) {
|
||||
alpha := clamp(HP+(1.0-mask.a), 0.0, 1.0)
|
||||
// Create a darker pixel if it's inside a damage mask.
|
||||
return vec4(wallpx.r*alpha, wallpx.g*alpha, wallpx.b*alpha, wallpx.a)
|
||||
}
|
||||
|
||||
return wallpx // Otherwise, leave a pixel color as is
|
||||
}
|
||||
@ -1,45 +0,0 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
42
|
||||
0 0 0
|
||||
0 0 0
|
||||
14 14 14
|
||||
29 29 29
|
||||
51 51 51
|
||||
80 80 80
|
||||
99 99 99
|
||||
122 122 122
|
||||
167 167 167
|
||||
192 192 192
|
||||
228 228 228
|
||||
251 245 239
|
||||
242 211 171
|
||||
255 227 160
|
||||
255 216 117
|
||||
255 202 60
|
||||
255 168 36
|
||||
255 141 0
|
||||
73 77 126
|
||||
63 69 136
|
||||
54 61 145
|
||||
44 52 155
|
||||
35 44 164
|
||||
26 36 173
|
||||
39 39 68
|
||||
31 31 76
|
||||
27 27 80
|
||||
22 22 85
|
||||
17 17 90
|
||||
14 14 93
|
||||
139 109 156
|
||||
142 98 167
|
||||
145 86 179
|
||||
150 68 197
|
||||
154 52 213
|
||||
158 36 229
|
||||
198 159 165
|
||||
204 153 161
|
||||
212 145 155
|
||||
221 136 149
|
||||
230 127 143
|
||||
241 116 135
|
||||
@ -1,33 +0,0 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
30
|
||||
242 211 171
|
||||
236 199 134
|
||||
230 193 96
|
||||
224 176 50
|
||||
205 142 32
|
||||
198 159 165
|
||||
186 140 144
|
||||
180 129 129
|
||||
172 115 115
|
||||
147 87 98
|
||||
139 109 156
|
||||
118 93 138
|
||||
97 80 118
|
||||
82 68 100
|
||||
62 51 75
|
||||
73 77 126
|
||||
61 61 106
|
||||
51 48 83
|
||||
37 33 56
|
||||
27 21 37
|
||||
39 39 68
|
||||
39 39 68
|
||||
39 39 68
|
||||
39 39 68
|
||||
39 39 68
|
||||
251 245 239
|
||||
223 207 198
|
||||
194 178 174
|
||||
171 157 155
|
||||
146 134 130
|
||||
@ -1,42 +0,0 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
39
|
||||
32 0 59
|
||||
63 0 83
|
||||
108 0 108
|
||||
146 0 124
|
||||
187 0 151
|
||||
236 0 178
|
||||
255 19 186
|
||||
255 64 190
|
||||
255 113 213
|
||||
255 147 231
|
||||
255 186 253
|
||||
245 220 255
|
||||
255 255 255
|
||||
0 0 0
|
||||
12 12 12
|
||||
26 26 26
|
||||
39 39 39
|
||||
54 54 54
|
||||
71 71 71
|
||||
86 86 86
|
||||
99 99 99
|
||||
118 118 118
|
||||
133 133 133
|
||||
153 153 153
|
||||
177 177 177
|
||||
205 205 205
|
||||
42 2 0
|
||||
52 9 0
|
||||
71 24 0
|
||||
94 46 0
|
||||
131 71 0
|
||||
165 96 0
|
||||
201 106 0
|
||||
243 119 0
|
||||
255 165 41
|
||||
255 186 82
|
||||
255 239 169
|
||||
255 250 211
|
||||
255 255 247
|
||||
|
Before Width: | Height: | Size: 12 KiB |
@ -1,49 +0,0 @@
|
||||
JASC-PAL
|
||||
0100
|
||||
46
|
||||
23 32 56
|
||||
37 58 94
|
||||
60 94 139
|
||||
79 143 186
|
||||
115 190 211
|
||||
164 221 219
|
||||
25 51 45
|
||||
37 86 46
|
||||
70 130 50
|
||||
117 167 67
|
||||
168 202 88
|
||||
208 218 145
|
||||
77 43 50
|
||||
122 72 65
|
||||
173 119 87
|
||||
192 148 115
|
||||
215 181 148
|
||||
231 213 179
|
||||
52 28 39
|
||||
96 44 44
|
||||
136 75 43
|
||||
190 119 43
|
||||
222 158 65
|
||||
232 193 112
|
||||
36 21 39
|
||||
65 29 49
|
||||
117 36 56
|
||||
165 48 48
|
||||
207 87 60
|
||||
218 134 62
|
||||
30 29 57
|
||||
64 39 81
|
||||
122 54 123
|
||||
162 62 140
|
||||
198 81 151
|
||||
223 132 165
|
||||
9 10 20
|
||||
16 20 31
|
||||
21 29 40
|
||||
32 46 55
|
||||
57 74 80
|
||||
87 114 119
|
||||
129 151 150
|
||||
168 181 178
|
||||
199 207 204
|
||||
235 237 233
|
||||
|
Before Width: | Height: | Size: 145 KiB After Width: | Height: | Size: 145 KiB |
BIN
assets/sprites/background-orange.png
Normal file
|
After Width: | Height: | Size: 152 KiB |
|
Before Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB |
@ -1,181 +0,0 @@
|
||||
{ "frames": [
|
||||
{
|
||||
"filename": "backgroundstars 0.ase",
|
||||
"frame": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 2000
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 1.ase",
|
||||
"frame": { "x": 640, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 2.ase",
|
||||
"frame": { "x": 1280, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 3.ase",
|
||||
"frame": { "x": 1920, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 4.ase",
|
||||
"frame": { "x": 2560, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 2000
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 5.ase",
|
||||
"frame": { "x": 3200, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 6.ase",
|
||||
"frame": { "x": 3840, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 7.ase",
|
||||
"frame": { "x": 4480, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 8.ase",
|
||||
"frame": { "x": 5120, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 2000
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 9.ase",
|
||||
"frame": { "x": 5760, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 10.ase",
|
||||
"frame": { "x": 6400, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 11.ase",
|
||||
"frame": { "x": 7040, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 12.ase",
|
||||
"frame": { "x": 7680, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 2000
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 13.ase",
|
||||
"frame": { "x": 8320, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 14.ase",
|
||||
"frame": { "x": 8960, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 15.ase",
|
||||
"frame": { "x": 9600, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 16.ase",
|
||||
"frame": { "x": 10240, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "backgroundstars 17.ase",
|
||||
"frame": { "x": 10880, "y": 0, "w": 640, "h": 384 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 640, "h": 384 },
|
||||
"sourceSize": { "w": 640, "h": 384 },
|
||||
"duration": 2000
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "http://www.aseprite.org/",
|
||||
"version": "1.x-dev",
|
||||
"image": "backgroundstars-animated.png",
|
||||
"format": "RGBA8888",
|
||||
"size": { "w": 11520, "h": 384 },
|
||||
"scale": "1",
|
||||
"frameTags": [
|
||||
],
|
||||
"layers": [
|
||||
{ "name": "background", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "stars", "opacity": 124, "blendMode": "normal" }
|
||||
],
|
||||
"slices": [
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 52 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
BIN
assets/sprites/block-grey.png
Normal file
|
After Width: | Height: | Size: 584 B |
|
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
@ -1,156 +0,0 @@
|
||||
{ "frames": [
|
||||
{
|
||||
"filename": "collectible #Detonation 0.ase",
|
||||
"frame": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 20
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 1.ase",
|
||||
"frame": { "x": 64, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 20
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 2.ase",
|
||||
"frame": { "x": 128, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 20
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 3.ase",
|
||||
"frame": { "x": 192, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 20
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 4.ase",
|
||||
"frame": { "x": 256, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 5.ase",
|
||||
"frame": { "x": 320, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 6.ase",
|
||||
"frame": { "x": 384, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 7.ase",
|
||||
"frame": { "x": 448, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 8.ase",
|
||||
"frame": { "x": 512, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 9.ase",
|
||||
"frame": { "x": 576, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 10.ase",
|
||||
"frame": { "x": 640, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 11.ase",
|
||||
"frame": { "x": 704, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 12.ase",
|
||||
"frame": { "x": 768, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
},
|
||||
{
|
||||
"filename": "collectible #Detonation 13.ase",
|
||||
"frame": { "x": 832, "y": 0, "w": 64, "h": 64 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 64, "h": 64 },
|
||||
"sourceSize": { "w": 64, "h": 64 },
|
||||
"duration": 100
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "http://www.aseprite.org/",
|
||||
"version": "1.x-dev",
|
||||
"image": "collectible-detonating.png",
|
||||
"format": "I8",
|
||||
"size": { "w": 896, "h": 64 },
|
||||
"scale": "1",
|
||||
"frameTags": [
|
||||
{ "name": "Detonation", "from": 1, "to": 14, "direction": "forward" }
|
||||
],
|
||||
"layers": [
|
||||
{ "name": "Yellow Sphere", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 8", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 7", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 6", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 5", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 4", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 3", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 2", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Layer 1", "opacity": 255, "blendMode": "normal" },
|
||||
{ "name": "Blitz Outer", "opacity": 70, "blendMode": "normal" },
|
||||
{ "name": "Blitz Middle", "opacity": 84, "blendMode": "normal" },
|
||||
{ "name": "Blitz Inner", "opacity": 97, "blendMode": "normal" }
|
||||
],
|
||||
"slices": [
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
@ -1,54 +0,0 @@
|
||||
{ "frames": [
|
||||
{
|
||||
"filename": "collectible-idle 0.ase",
|
||||
"frame": { "x": 0, "y": 0, "w": 32, "h": 32 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
|
||||
"sourceSize": { "w": 32, "h": 32 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "collectible-idle 1.ase",
|
||||
"frame": { "x": 32, "y": 0, "w": 32, "h": 32 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
|
||||
"sourceSize": { "w": 32, "h": 32 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "collectible-idle 2.ase",
|
||||
"frame": { "x": 64, "y": 0, "w": 32, "h": 32 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
|
||||
"sourceSize": { "w": 32, "h": 32 },
|
||||
"duration": 200
|
||||
},
|
||||
{
|
||||
"filename": "collectible-idle 3.ase",
|
||||
"frame": { "x": 96, "y": 0, "w": 32, "h": 32 },
|
||||
"rotated": false,
|
||||
"trimmed": false,
|
||||
"spriteSourceSize": { "x": 0, "y": 0, "w": 32, "h": 32 },
|
||||
"sourceSize": { "w": 32, "h": 32 },
|
||||
"duration": 200
|
||||
}
|
||||
],
|
||||
"meta": {
|
||||
"app": "http://www.aseprite.org/",
|
||||
"version": "1.x-dev",
|
||||
"image": "collectible-idle.png",
|
||||
"format": "RGBA8888",
|
||||
"size": { "w": 128, "h": 32 },
|
||||
"scale": "1",
|
||||
"frameTags": [
|
||||
],
|
||||
"layers": [
|
||||
{ "name": "Layer 1", "opacity": 255, "blendMode": "normal" }
|
||||
],
|
||||
"slices": [
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 931 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 448 B |
|
Before Width: | Height: | Size: 615 B |
|
Before Width: | Height: | Size: 357 B |