First post, Two months into development

Published May 07, 2017
Advertisement

To start off, the reason I'm creating this journal is because this will be my first "complete" game I've made. Years ago I made a shell of a survival game in XNA and that was the closest I ever got to a finished project. My goal for this post and future posts is to hopefully share some knowledge about LibGDX and get feedback about terrible my programming practices :P

Lets jump right into it!

The premise of this game is pretty simple. You play as some dude whose image is based off of a character in one of my favorite books. +10 to anyone who can guess which book.

9NxsaLg.png

There really isn't a story yet, although the goal of the game is to journey through 7 dungeons, or the 7 layers of hell, defeat the bosses, and then kill satan possibly? I haven't thought of an ending yet. When you first start off in the town area, youll notice all the NPCs are ghosts and you can't interact with them, the exception being a single priest in the giant tower. As you finish each dungeon, more and more NPCs return to their original form.

Although this sounds fairly linear, I'm trying to move away from it by incorporating a "purgatory" system when the player dies. Instead of a game over, the player is sent to purgatory where he has the option to descend the layers of hell with the current skills available, or return to the surface via rising from a grave to acquire better skills and potions.

Weapon and armor equips won't be a part of the game at this point. I have much love for the way the Witcher 3 handles their potion system, so I'm using inspiration from that to make the player stronger. As the player defeats monsters, items will be picked up. At the end of the day you have an option to make camp and create and consume up to 2 or 3 potions which buff you for the whole day afterwards.

Obviously a lot of this hasn't been implemented yet, but it's nice to have goals to work on.

The title of the post says two months worth of development, it may be more like 4 or 5. It's only been 2 months since I've put my project onto Github. I was wanting to start a journal earlier, but the artwork was so terrible that I felt too ashamed to share it. Look at these awesome slimes!

7HGFRzx.png

So far my biggest struggle is moving forward has been the artwork. I am by no means a good artist, and to make things worse I chose to use pixel style art. But I've limited myself to a maximum of 2 hours a day working on the art so I don't get frustrated and give up. The world feels bland and boring without trees and bushes, so wandering around at this point is useless.

Ni31AXh.png

The map at this point right now is huge, maybe too huge. You can see the areas I've outlined as different biomes and areas for the dungeons. My greatest challenge I feel will be to make this world feel alive and vibrant.

Now on to code things.

I've used LibGDX before for smaller projects like your basic pong and breakout clones, but this is the first time I've delved so far into the library. Right now I have something like 15 enemies planned for the world, and I use a class called EnemyFactory for creation. public Enemy createEnemy(EnemyType type, Vector2 position){ Enemy enemy = null; String id; switch (type){ case SLIME: id = "slime" + idNumber; enemy = new Enemy(position, id); enemy.isEnemy = true; enemy.sprite = new Sprite(new Texture("slime.png")); enemy.createBody(position, enemy.sprite.getTexture()); enemy.health = 10; enemy.enemyType = EnemyType.SLIME; enemy.itemToDrop = Item.SLIME_GOO; enemy.attackCount = 0; enemy.attackTimer = 0.2f;

Eventually this will be put into a json or xml file, but I don't know anything about those languages yet so this works for now. Enemies are spawned using tiled map objects like so:for(MapObject object : tiledMap.getLayers().get("SpawnLayer").getObjects().getByType(RectangleMapObject.class)){ Rectangle rect = ((RectangleMapObject)object).getRectangle(); if(object.getProperties().containsKey("slime")){ mapEntities.add(MainGame.enemyFactory.createEnemy(Enemy.EnemyType.SLIME, new Vector2(rect.getX() / MainGame.PPM, rect.getY() / MainGame.PPM))); }

This was one of my biggest reasons for using LibGDX. Using tiled map data has made things like teleporting to different maps and spawning enemies so much easier. Another reason for using this library is Box2D. I hate math and hard-coding values for collisions, so Box2D was a godsend for what I needed. In LibGDX you have a class called ContactListener which handles all collisions in your world. public void beginContact(Contact contact) { Fixture fixtureA = contact.getFixtureA(); Fixture fixtureB = contact.getFixtureB(); Player player; Entity entity; Projectile projectile; if(fixtureA == null || fixtureB == null)return; if(fixtureA.getBody().getUserData() == null || fixtureB.getBody().getUserData() == null)return; if(isProjectileHitEnemy(fixtureA, fixtureB)){ entity = fixtureB.getBody().getUserData() instanceof Entity ? (Enemy)fixtureB.getBody().getUserData() : (Enemy)fixtureA.getBody().getUserData(); projectile = fixtureA.getBody().getUserData().equals(Statics.PLAYER_PROJECTILE) ? (Projectile)fixtureA.getUserData() : (Projectile)fixtureB.getUserData(); subject.notify(projectile, entity, Event.ENEMY_DAMAGE);// projectile.isActive = false; System.out.println("PROJECTILE HIT ENEMY"); }

This is nice because it allows you to use the user data from a Box2D body to see what is hitting what.

A day/night cycle has been implemented as well. Box2DLights is another great option that LibGDX offers. With dynamic hard and soft shadows, you really can't go wrong with it. public void updateLight(DayNightCycle dayNightCycle, Camera camera){ if(dayNightCycle.getHours() == 6){ ambientB = 0.3f; ambientR = 0.8f; ambientG = 0.35f; } if(dayNightCycle.getHours() == 7){ ambientG = 0.65f; ambientR = 0.9f; ambientB = 0.01f; } if(dayNightCycle.getHours() == 8){ ambientB = 1; ambientG = 1; ambientR = 1; } if(dayNightCycle.getHours() == 17){ ambientR = 1; ambientG = 0.8f; ambientB = 0; } if(dayNightCycle.getHours() == 19){ ambientR = 1; ambientG = 0.5f; ambientB = 0; } if(dayNightCycle.getHours() == 20){ ambientR = 1; ambientB = 0.3f; ambientG = 0.3f; } if(dayNightCycle.getHours() == 21){ ambientG = 0.2f; ambientB = 0.7f; ambientR = 0.3f; } if(dayNightCycle.getHours() == 22){ ambientR = 0.2f; ambientG = 0.15f; ambientB = 0.4f; ambientA = 0.3f; } rayHandler.setAmbientLight(ambientR, ambientG, ambientB, ambientA); playerLight.setPosition(MainGame.player.sprite.getX(), MainGame.player.sprite.getY()); rayHandler.setCombinedMatrix(camera.combined); rayHandler.updateAndRender(); }

Holy if statements! Maybe one day I'll figure out how to make a smooth transition from daylight to darkness, but it is not this day. There really isn't anything more to Box2DLights than the initialization of the light and the update method! How great is that?

Here are a couple of gifs of the lighting and combat system in action:

http://imgur.com/unkOjMK

http://imgur.com/QIqmgax

I'll try to make more frequent posts as I implement more of my ideas into this project, and hopefully with better artwork so there's something nice to look at. Feel free to give advice or ask questions! I feel like a have a decent understanding of LibGDX at this point and I highly recommend it to anyone who wants to make a game in Java :)

7 likes 6 comments

Comments

Aardvajk
Looks cool. I like these projects with realistic scope.
May 07, 2017 09:51 AM
Azokah
The name of the wind? by Patrick Rothfuss.. maybe?
May 07, 2017 10:28 PM
imontheverge
Nope but that's a favorite of mine! It's an older series.
May 08, 2017 04:46 AM
ferrous

My first thought upon seeing that if/else chain was to move to an array of control points (hour/rgb value pairs), and then using something like a catmull-rom interpolation to come up with the current RGB value for the light.

May 10, 2017 04:33 PM
imontheverge
I've never heard of catmull rom but it looks like what I need! Thanks :)
May 11, 2017 02:56 AM
ferrous

Yeah, Catmull Rom is a great thing to have in your toolbox, it's a way to interpolate along a spline, and yet you are guaranteed to hit all the control points along your interpolation. Makes it easy to understand, and it's fairly easy to implement.

If you get it working, it'd be neat to see a timelapse GIF =)

May 12, 2017 09:27 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement
Advertisement