Hi, thanks for the interest. At this time, I doubt we'll be adding additional control schemes, as it was designed to be played with mouse or a touch device.
Roaring Cat Games
Creator of
Recent community posts
Hey, this game is great! Fun challenge with two people. The controls are kind of awkward on a single keyboard (laptop) but it's still fun.
Our game has a very similar mechanic where you have to plant trees on asteroids to calm them down. (check it out! Our Game Planetary Planet )
Man, that soundtrack! I simply can't get enough of it! Especially the song when the ship lands in the city. The hip-hop sound reminded me of Samurai Champloo, A LOT! If those are original, great job!
While simple, the music and role-playing mechanics had me intrigued and glued to the game the whole time. At one point I managed to collect 100+ artifacts but forgot to save and died shortly due to greed.
Great job! I'm gonna have to hit up the nostalgia soundtrack!
This is my favorite entry so far. Everything was polished, the beginning gives you just enough to frustrate you to try again. I'm glad you added a save feature, as this would have been a painful "rougue-like" puzzle adventure. I really wanted to use the bomb on the big alien though...Neila is a jerk.
Over the last few days we've been working on solidifying the weapon select experience, and in the meantime we ran into an unexpected bug that led me (@barryrowe) down a bit of a refactoring rabbit hole.
The bug had to do with converting touch events to world units properly. This is a common issue as its often better to work in "World Units" instead of pixels so that you can better manage units relative to your game world rather than whatever device might happen to be running the game. Even better, being a common practice, most engines and libraries provide a quick way to do this via your camera object(s). LibGDX is no exception and the Camera API provides both project() and unproject() methods
//Based on working in a Screen of 640x960 pixels //Our desired width and Height in world units private static final float WORLD_WIDTH = 20f; private static final float WORDL_HEIGHT = 30f; private Vector3 screenPoint = new Vector3(320f, 480f, 0f); private Vector3 worldPoint = new Vector3(10f, 15f, 0f); Camera cam = new OrthographicCamera(WORLD_WIDTH, WORLD_HEIGHT); //World to Screen
cam.project(worldPoint); //worldPoint is updated to have values [320f, 480f, 0f] //Screen to World cam.unproject(screenPoint); //screenPoint is updated to have values [10f, 15f, 0f]
This is pretty straight forward, and so we were passing in the camera to our System(s) that needed to handle user input, and we just use camera.unproject() to get the world units, and from there find what was touched. Right? Well, we made the mistake of thinking this was all we would ever need to do, and didn't account for the viewport (Read up on libgdx viewports if you're interested). It turns out that if the viewport comes into play for resizing (we are using a FitViewport currently), the camera doesn't necessarily know about this adjustment when calling unproject(). Instead, we really needed to have access to the viewport object itself, and use Viewport.unproject(), otherwise we would end up with world units that don't match up to the adjusted viewport and we found that on odd device screens tapping to select a weapon was just completely broken.
The bigger problem this uncovered, was that we had written the kitten2d RenderingSystem to create the camera for the game. Looking back, this shouldn't have been the job of the rendering system. The RenderingSystem definitely needs a reference to the camera, but it shouldn't be responsible for creating it and exposing said camera to other systems/events that need it. Now in the future, it's probably the right call to make cameras an Entity with a CameraComponent, but for now we just moved this responsibility up to the Game implementation itself. We then make the Game implement IGameProcessor which can then expose the camera and viewport objects. We're free to pass the IGameProcessor reference to our Screens (which can provide the camera, viewport, gameProcessor, whatever is needed, on down to the systems that screen adds to its Ashley Engine.
You can see the bulk of this refactor in this commit (b4fbfb6a5). Feel free to laugh at how many cameras were being generated for some reason...it's kind of embarrassing.
Anyway, now that we knocked out this big adjustment, we're ready to start knocking out the final sets of features before the #kentuckyfriedpixels deadline.
Hopefully we finish strong and produce something at least a few people find fun.
Over the last week we have been working on determining the bg music feel and designing out the weapon select UI.
The original plan for the weapon select UI was to have 3 little plant pods that would "bloom" when you selected one to activate a weapon. That sounded really good, but in practice it was pretty confusing. The biggest issue was that each of the pods would need to somehow indicate to the player which weapon they contained BEFORE they were selected and opened. We discussed using different colors, or somehow etching an icon on the outside, but nothing felt right.
On top of being confusing for the player, having to design a proper state transition to "bloom" and "un-bloom" the selections was becoming fairly annoying to keep track of with the animation system we currently have in place. (NOTE: this is a limitation of our animation and state system, and not really a problem with the approach)
Lastly, these blooms also lacked a way to indicate to the user how many upgrade levels each weapon has obtained. To stick with the aesthetic we would have to either place some colorful leaves around the bloom, or "grow" some small flowers below them. Nothing we could come up with felt like it would be a useful indicator to the player, and would just look like over-designed animation on the gui.
What we fell back to was a simple circular button system, with a three-section ring around each indicator. Each of the sections will "light-up" as the weapon is upgraded (no upgrades: all three grayed out, and each upgrade fills in a grayed-out section). To indicate the current weapon selection, we have a "rotating coin" style animation on the button so that it is clear which item is active.
Loi has only created assets for the Pollen Aura weapon, but here is a rough screenshot of the layout:
We are still working on the BG music but we've nailed down a good direction, and Nathan ( @TheLucidBard) has worked up a great draft for us. You can catch one of our favorite riffs from the track in the vine below (as well as seeing the weapon UI in action). We've been playing with the tempo on the track a little and found that the play style so far is nice with the speed throttled to about 70% tempo.
Tonight we've been working on the weapon switching mechanic. The goal is to implement it so that:
- When the player releases their finger (touchUp) we go into an "options" or "passive" mode that allows the player a chance to switch to another available weapon
- When in "options" mode everything is dramatically slowed down, but not fully paused.
- When the player touches back down, if they touch one of the open weapons, the player's weapon is reset
- When the player touches down if it's not on one of the weapon selects, the game resumes and goes back to full speed
- The weapon selections will be plant pods that close/open when selected or deselected (not implemented yet)
For this we have a single System: WeaponChangeSystem, and a global flag for whether the app is slowed or not App.isSlowed().
To achieve our goal we need WeaponChangeSystem to extend EntitySystem, and implement InputProcessor
public class WeaponChangeSystem extends EntitySystem implements InputProcessor { ...
When the system is added to the Engine we need to perform our setup: Creating the entities needed to represent the weapon switching buttons, and register the system with the game's inputMultiplexer. (NOTE: this code shows some basic examples of generating entities with the Kitten2d Ashley Extension components). In our game we also keep a static accessor to our root Game object. This is fragile and frowned upon in a larger game, but effective for easy access to globally managed resources like the inputMultiplexer and game state with a small game like this.
@Override public void addedToEngine(Engine engine) { super.addedToEngine(engine); App.game.multiplexer.addProcessor(this); PooledEngine pEngine = (PooledEngine)engine; if(seedSelect == null){ seedSelect = pEngine.createEntity(); seedSelect.add(TransformComponent.create(pEngine) .setPosition(App.W/4f, 0f, Z.weaponSelect) .setHidden(true)); seedSelect.add(BoundsComponent.create(pEngine) .setBounds(0f, 0f, 2f, 2f)); seedSelect.add(TextureComponent.create(pEngine)); seedSelect.add(StateComponent.create(pEngine).setLooping(false).set("DEFAULT")); seedSelect.add(AnimationComponent.create(pEngine) .addAnimation("DEFAULT", Animations.getSeedPod()) .addAnimation("SELECTED", Animations.getSeedPodOpening())); pEngine.addEntity(seedSelect); } if(helicpoterSelect == null){ helicpoterSelect = pEngine.createEntity(); helicpoterSelect.add(TransformComponent.create(pEngine) .setPosition(2f * (App.W / 4f), 0f, Z.weaponSelect) .setHidden(true)); helicpoterSelect.add(BoundsComponent.create(pEngine) .setBounds(0f, 0f, 2f, 2f)); helicpoterSelect.add(TextureComponent.create(pEngine)); helicpoterSelect.add(StateComponent.create(pEngine).setLooping(false).set("DEFAULT")); helicpoterSelect.add(AnimationComponent.create(pEngine) .addAnimation("DEFAULT", Animations.getHelicopterPod()) .addAnimation("SELECTED", Animations.getHelicopterPodOpening())); pEngine.addEntity(helicpoterSelect); } if(auraSelect == null){ auraSelect = pEngine.createEntity(); auraSelect.add(TransformComponent.create(pEngine) .setPosition(3f*(App.W/4f), 0f, Z.weaponSelect) .setHidden(true)); auraSelect.add(BoundsComponent.create(pEngine) .setBounds(0f, 0f, 2f, 2f)); auraSelect.add(StateComponent.create(pEngine).setLooping(false).set("DEFAULT")); auraSelect.add(AnimationComponent.create(pEngine) .addAnimation("DEFAULT", Animations.getAuraPod()) .addAnimation("SELECTED", Animations.getAuraPodOpening())); auraSelect.add(TextureComponent.create(pEngine)); pEngine.addEntity(auraSelect); } }
Now that we have our system setup when the engine is added we need to handle when the player touches or stops touching. On touchUp we want to setup our "options" mode state. This is very basic right now, and will be expanded to activate the different animation states of the weaponSelect buttons, but for now it just shows them all and sets the "isSlowed" flag on the application.
@Override public boolean touchUp(int screenX, int screenY, int pointer, int button) { if(App.getState() != GameState.GAME_OVER && !App.isSlowed()) { App.setSlowed(true); K2ComponentMappers.transform.get(seedSelect).setHidden(false); K2ComponentMappers.transform.get(auraSelect).setHidden(false); K2ComponentMappers.transform.get(helicpoterSelect).setHidden(false); } return false; }
The next thing we need to do is capture touchDown and either switch to the new weapon or resume into normal playing mode. To do this we simply unproject the touchpoint, and check if it falls within the bounds of any of our buttons. (notice we aren't creating a new Vector3 object here, but reusing a class-level instance to reduce additional garbage collection over time):
@Override public boolean touchDown(int screenX, int screenY, int pointer, int button) { if(App.isSlowed()){ touchPoint.set(screenX, screenY, 0f); this.cam.unproject(touchPoint); BoundsComponent seedBounds = K2ComponentMappers.bounds.get(seedSelect); BoundsComponent helicopterBounds = K2ComponentMappers.bounds.get(helicpoterSelect); BoundsComponent auraBounds = K2ComponentMappers.bounds.get(auraSelect); if(seedBounds.bounds.contains(touchPoint.x, touchPoint.y)){ switchWeapon(WeaponType.GUN_SEEDS); }else if(helicopterBounds.bounds.contains(touchPoint.x, touchPoint.y)){ switchWeapon(WeaponType.HELICOPTER_SEEDS); }else if(auraBounds.bounds.contains(touchPoint.x, touchPoint.y)){ switchWeapon(WeaponType.POLLEN_AURA); }else{ App.setSlowed(false); } } return false; }
The last thing we need to do is make sure our render method knows to throttle the detlaTime sent to the Engine when App.isSlowed() is true. So in our SpaceScreen we update the update() method like so:
@Override protected void update(float deltaChange) { float deltaToApply = Math.min(deltaChange, App.MAX_DELTA_TICK); if(App.isSlowed()){ if(App.isSlowed()) { deltaToApply *= App.SLOW_SCALE; } } engine.update(deltaToApply); ...
With these changes in place, we get the effect you can see in this vine of gameplay. All of the enemies and animations slow down while in "options" mode, and you can switch weapons by clicking/tapping on one of the weapon select 'buttons'. (I was unaware of the background conversation at the time, but it oddly fits..)
Game: GalaxSeed
Jam Entry: Existing Project, expanding and polishing features.
Gameplay: It's an arcade shooter that would fall well into the "bullet hell" category. You control a ship that has various planting mechanisms (weapons) to spread life on the incoming asteroids and comets. You have to dodge your way through the obstacles. Successfully planting trees slows down fragments and subdues angry asteroids, but planted or not, you must avoid everything so navigate carefully.
Tools: libGDX (Java), Ashley (An entity component system built to work with libGDX), IntelliJ (IDE), Adobe Illustrator, Spriter
Team: @Barryrowe (code cat), @loilemix (art cat), Nathan Hutchens joining the team for this project on music and sound design
Background:
We started GalaxSeed a while back as part of the libgdx jam, and at the time we called it Planetary Planter. We had never participated in a month-long Jam before, and our end product was far less than complete. We procrastinated more than we worked on the game and it showed.
Since the end of libgdx jam, we put in quite a bit more effort to create at least a full play cycle experience (Menu, Start Game, Play, Game Over, Repeat). During this time we really added features and generic systems to a sibling project: Kitten2d Ashley Extensions. All of the documentation needs to be updated, and plenty of performance and general code clean-up needs to be done, but between January and Mid-May we made a lot of progress to make this extension library useful for jumpstarting a libGDX-Ashley based project.
We showed the game at an event in Louisville right as we had gotten the first draft ready to what we THOUGHT we were going to release. Based on feedback at the event, and that of other developers, we realized we really needed to re-think a lot of things. The game needed more variety, and needed to decide what it was going to be: Classic Shooter or full-on Bullet Hell?
With Kentucky Fried Pixels right around the corner we decided to take Planetary Planter, and re-work the majority of the game and use this jam as the time-box to finish those changes.
Features Planned for the Jam:
- Implement multiple weapons instead of a single seed gun
- Implement weapon upgrades
- Design enemy spawn timings and paths rather than procedural generation
- Focus on dodging, and make that fun
- Implement "touch-up" menu/pause system based on passive mode of Squadron and Squadron 1945
- Implement single-charge special weapon
- All new music and sounds
- Fix the player control for high DPI screens and allow switching between "normal" and "enhanced" movement
Kickoff Jam Accomplishments:
- We implemented mechanics and visuals for all three of the planned player weapons
- Implement all of the upgrades for each of the new weapons
- Began brainstorming music design
- Resolved a bug causing rotated textures to lose quality
Above: Shot of the new pollen aura weapon. It slows down anything that is inside of the field, and slowly pollenates it to grow trees. Slowed items are indicated with a yellow shade while they are being pollenated.
Above:Example of the difference between using Nearest and Linear openGL texture filters for our rotated textures.
Next Steps:
- Weapon Selection and loss
- Right now in the post-jam version, you switch weapons every-time a "touchDown" event fires (mouse-click or tap). What we want to implement is when you lift your finger on mobile (or release mouse on desktop) the game "slows-down" and you get a weapon-pod system where you can select which weapon you wish to switch to. This will also be where we can pause the game.
- Design the introduction "levels" from Pluto up to Saturn
- Implement a proper options and Credits screen
Work on our game has been a lot slower than we'd have liked this last week, but we've re-kindled the gamedev fire, and are getting excited about the next steps moving forward. I (Barry) have been working on some backend pieces, and designing out some things that can be extracted out into AshleyExtensions later on.
Today I finished up a "RemainInBoundsSystem" that supports multiple modes, and works with Axis-Aligned rectangles. You can view the System code in the project here:
RemainInBoundsSystem in Life In Space
The modes are
- CONTAINED: The entity bounds must remain completely inside of the system bounds
- CENTER: The entity origin must stay within the system bounds
- EDGE: The entity bounds may pass outside of the system bounds, but the outer-edge must always stay in or on the system bounds.
These mode look like:
Today we also added in some initial ship animations, (idle, left and right), and seed bullets with varied animation states. Here's a screenshot:
In the next few days we'll be adding in systems to:
- allow entities follow other entities with offsets that will account for rotations
- allow bounds calculations to handle circle bounds as well as rectangles
- Introduce the enemies
- Introduce bullet hits with sprouting
- Damage and collision
Getting time and motivation over the holiday break was pretty rough. However, I did receive "2D Game Collision Detection" from http://collisiondetection2d.net for Christmas and have put it to good use.
Tonight I added proper offset support for our AshleyExtensions' BoundsSystem and DebugSystem. I say proper, because the offset no properly adjusts based on position AND rotation:
Today we released v0.0.1 of Kitten2d AshleyExtensions for libGDX.
I have the extension pulled in from the sonatype nexus repo into our LifeInSpace project with a test set of systems working on an Entity. The Ludum Dare fog is wearing off, and we're ready to get going on this game!
We having nailed it all down, but our game is going to be a tribute to all of the Jam games we've made with libGDX, and all about Boss fights!
You can follow our progress in code here: https://github.com/RoaringCatGames/libgdxjam-2015
While we're brainstorming our ideas for the game, we've been splitting out some Ashley ECS systems into a more generic library. Hopefully we'll be able to provide easy-to-use installation instructions and code samples by the end of the jam for others to use these simple, generic systems as well.
The OSS project for these ashley gdx extensions is here: https://github.com/RoaringCatGames/kitten2d-ashley-extensions
Hi everyone,
I am Barry Rowe, the programmer for a studio (in name at least) in Louisville KY, Roaring Cat Games. We're just coming off of a weekend of jamming on Ludum Dare 34, and looking forward to another jam. The other half of our team is Loi LeMix who will be providing all of the Art, and with the extended time frame possible our music.
We'll most likely be using Ashley ECS, and some of the systems and components we've developed over the last couple of game jams (Movement, Basic Gravity, Rendering, DebugRendering, Health/Damage). Hopefully by the end of this weekend I'll have those systems up as a library for others to use as well. We've been looking for a way to give back to the libGDX community, and it seems like some basic starter systems for Ashley ECS is something a lot of people might like to see. We created a box2d-AshleyECS example project before LD34 you can check out here: https://github.com/RoaringCatGames/libgdx-ashley-box2d-example
For tooling we'll be using IntelliJ, Adobe Illustrator, Spriter2D, Adobe Photoshop, Audacity, and Git.
Looking forward to seeing what all comes out of the Jam!