Welcome, Guest. Please login or register.

Login with username, password and session length

 
Advanced search

1411275 Posts in 69323 Topics- by 58380 Members - Latest Member: bob1029

March 28, 2024, 05:51:40 AM

Need hosting? Check out Digital Ocean
(more details in this thread)
TIGSource ForumsCommunityDevLogsSpace Cabrón (previously Back to Earth)
Pages: 1 ... 3 4 [5]
Print
Author Topic: Space Cabrón (previously Back to Earth)  (Read 15548 times)
Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #80 on: May 05, 2014, 03:38:03 PM »

2lazy2recolor
Logged
Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #81 on: May 07, 2014, 06:02:50 PM »

Ever wanted to be a sombrero-wearing robot pistolero shooting aliens in space? You got that.  Cool
Logged
sam_suite
Level 1
*



View Profile WWW
« Reply #82 on: May 07, 2014, 06:19:24 PM »

Ever wanted to be a sombrero-wearing robot pistolero shooting aliens in space?


...have you read my dream journal?
Logged

mirrorfish
Level 1
*


?!?! ... It's just a box.


View Profile WWW
« Reply #83 on: May 07, 2014, 06:31:24 PM »

Yes to sombrero. Also yes to procedural shmup pixel vibes. Very cool stuff. I do music, let me know if you need some (some tracks in sig link).
Logged

Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #84 on: May 08, 2014, 04:06:55 AM »

Ever wanted to be a sombrero-wearing robot pistolero shooting aliens in space?


...have you read my dream journal?

You can live it now, babe.  Tiger

Yes to sombrero. Also yes to procedural shmup pixel vibes. Very cool stuff. I do music, let me know if you need some (some tracks in sig link).

Thanks, dude. A friend is already taking care of the music, but I appreciate your offer. Your music is super cool.
Logged
Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #85 on: May 25, 2014, 05:41:39 PM »

This is me shamelessly god-moding through a boss' prototype:
https://www.youtube.com/watch?v=lULeLcomQ3g&feature=youtu.be
Logged
AD1337
Level 9
****


Lucas Molina


View Profile WWW
« Reply #86 on: May 26, 2014, 01:28:00 PM »

oh my god, that's good stuff!   Toast LeftSmiley
Logged

SolarLune
Level 10
*****


It's been eons


View Profile WWW
« Reply #87 on: June 10, 2014, 06:17:10 AM »

Ah, this game's RIP now? Sad

Too bad. Hope you can get back to it sometime, Gaeb!
Logged

Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #88 on: February 02, 2015, 06:06:06 PM »

So, I've decided to finish the game. I've also decided to plan a little more regarding the game's loop and cut some features that wouldn't add to it in any major way.

The game's main loop now would be something like this (beware, terrible digital-handwriting):

Note: the spawn boss node actually means spawn and kill boss.

The game starts with enemies being randomly spawned inside certain constraints established by how far you are, with a full timer and an empty threshold bar. The threshold bar is increased based on the number of the enemies you kill (or the time you can maintain a combo, I might play a bit with both) and the timer simply decreases as a way of building tension and motivating the player not to ignore enemies and simply dodge stuff for ever. The lower the timer, the more enemies are spawned. Once the threshold is reached, enemy spawning slows down to a halt until the player pushes the button that makes the boss spawn. After the boss dies, there is some cutscene or something that lets the player relax for a moment and then the cycle restarts.

What I'm trying to achieve here is something that allows the player to breath between moments of tension without being too intrusive (although cutscenes can be the complete opposite of non-intrusive). Something like this:


This is a plot to show you how serious I am.

With this in mind, I decided to completely rewrite the game, and it is funny how now that I know where to go, progress seems to be quite faster than before. I have about 4 days of lazy work and this is the current state of the game with some placeholder UI stuff:


There are no animations or juice so far, and I intend to keep it that way until I have a well established loop and at least a couple of bosses to test the game as a whole.
I have 3 different areas ready to be put into the game from the previous project, but I will wait for now.

I've decided to remove all of the robot upgrade stuff and decided to make the hacking mechanic a way of trading threshold for lives and use it as well as a way of building different bosses, such as the old prototype posted before.
Old prototype in question: https://www.youtube.com/watch?v=lULeLcomQ3g&feature=youtu.be

Since I've decided to scrap robot upgrades, I have no excuse to put my robot-pistolero-in-space skin in the game, but I will probably leave it as an unlockable skin or something.

Anyways, I encourage you to criticize and suggest stuff you think would make sense. The objective here is to a make a simple, fun game and if you think I'm deviating too much from this, feel free to call me stupid. Thanks, guys. The next post will probably be something along the lines of incorporating Binding of Isaac's way of increasing it's size each time you finish the game or how the hacking mechanic fits with the game.
Logged
AD1337
Level 9
****


Lucas Molina


View Profile WWW
« Reply #89 on: February 03, 2015, 04:56:04 AM »

Cool.

So the game loops forever?
Logged

Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #90 on: February 03, 2015, 05:06:20 AM »

That is something to consider. I was thinking of a Binding-of-Isaac-esque approach where you have a number of iterations on this loop and then the game ends, but giving the player the ability to go on infinitely seems like a good idea. I'll have to think about it.
Logged
Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #91 on: February 10, 2015, 03:56:06 PM »

Been working on a couple of things this past week, but most of them are not visible. I've rewritten the hacking system and figured out it would be nice to verbalize what I'm planning, to see if it makes sense and how it can help balance the fact that the player has no lives per se, but the amount of retries are proportional to the amount of drones he has.


Hacking an animationless enemy.

So, the basics of the mechanic is that you have the ability to hack drones with some green wave things and once succeeded, the hacked object explodes and a drone is spawned. Drones follow the player and shoot, but their main advantage is that they are used as "extra lives" when the player dies. When it happens, the player will spawn at the position of a drone without any upgrade he might have obtained throughout the game. Or, if the player has no drones left when he dies, he reaches the game's losing condition. (This is totally up for change, if testing proves this is not appropriate).

The basic exchange for hacking is the the number that says how close you are to obtaining the ability to spawn a boss (the threshold), so, playing in a safe way, i.e., hacking a lot, will require of you to be much more quick when dealing  with enemies as to reach the threshold before the timer reaches zero. Right now, each wave spawned by hacking decreases by 1 the current threshold level.

Another thing I have planned that might make the mechanic more balanced is having different levels of drone resistance based on the time it takes to hack the enemy. Each level increases the resistance of the drone in question, as well as its fire rate. The third level in the picture, activates its own little shield when you activate yours.


Possible drone level based on difficulty.

Hacking might also be used to carry objects, but that mechanic is only used when fighting bosses and threshold isn't a problem, and I will cover it when time comes. (The second boss prototype video shows how it works.)

There are one more planned for drones: consuming them to randomly upgrade your robot, but that as well will not be implemented yet, as I plan to have a playable build of the game's core by the end of the month (or the next one).
Logged
Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #92 on: July 13, 2015, 01:08:34 PM »

I've been working lazily on the game for the past couple of weeks and trying to regain motivation to finish it by addressing interesting problems I need to solve and putting them higher on my priorities list.

I'm almost finished porting the backgrounds to the new project. There's the space one left because it relies heavily on background props and I'm not done with them yet.

One nice thing I've made to optimize the difference between normal enemies and resistant enemies is to move the visual distinction to shaders using some texture lookup stuff.

What was done before was kinda unnecessarily complex and it used two different animation states, one for each type: normal and resistant; which made for setting up new enemies a pain in the ass.

What is done now is basically this:

Every enemy sprite sheet (or anything that needs a custom palette) must be colored with its red channel being a code to a color inside the custom palette and by doing a texture lookup with the value on the red channel on the palette, we find the target color.

Since I didn't want to have 256x1 palette textures and organize the colors precisely on the right pixel, I've made palettes look like this:


Three different palettes: The first is the palette used in enemies to be recolored, the second is for normal enemies and the third is for resistant enemies

And by having each red channel being a multiple of an arbitrary number, I can easily find the color in the palette texture.

In the palettes above we have 6 different colors. One of the problems of this method is that I need a single transparent pixel at the start of each palette, to be picked when the R is 0. So, each different gray color in this case is a multiple of 30 (just an arbitrary number that fits inside 256 and the number of colors we have, in this case 7). Thus, the red channel (as well as unnecessarily the green and the blue) have the following values:



By taking Unity's default sprite shader and modifying it a little bit, this is the resulting fragment shader:

Code:
fixed4 frag(v2f IN) : SV_Target
{
// get the grayscale color with coordinates for the color inside the palette
fixed4 colorCoordinates = tex2D(_MainTex, IN.texcoord);
colorCoordinates.rgb *= colorCoordinates.a;

// calculate the uv on the palette to be picked.
float targetPaletteColor = ((colorCoordinates.r * 256) / _TextureChannelDivisor) / _PaletteNColors;

// get the color
fixed4 c = tex2D(_Palette, float2(targetPaletteColor, 0 )) * IN.color;
c.rgb *= c.a;

return c;
}

Where _TextureChannelDivisor is the number every channel is a multiple of, in this case 30. And _PaletteNColors is the number of colors inside the palette, 7 counting the first transparent pixel.

When looking for the color, tex2D(_MainTex, IN.texcoord) will return the color of that specific fragment inside the sprite sheet colored with the grayscale colors. We take that, multiply the red channel by 256 (the resulting vector from tex2D is normalized), resulting in the "code number" for that color. Then we divide it by the _TextureChannelDivisor so we have an index of where in the texture this color is, then we divide it by the number of colors so we have a normalized coordinate to be used as an UV inside the second tex2D call with the _Palette itself.

Here's it working (sorry for the low fps):



I'm sure there's some optimization to be made here, I can already think of some stuff, but I will wrap my head around it later.
Logged
AD1337
Level 9
****


Lucas Molina


View Profile WWW
« Reply #93 on: July 13, 2015, 02:18:03 PM »

WOW  Grin

Great to see this again! Really think this should be finished, it would be a great portfolio piece.
Logged

Jonesvg
Level 0
*


View Profile WWW
« Reply #94 on: August 07, 2015, 12:29:50 PM »

WOW, very good Gaeb, it's great see you are back in this project friend.
Logged

See some of my works in jonesvg.carbonmade.com
Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #95 on: August 24, 2015, 01:01:12 PM »

WOW, very good Gaeb, it's great see you are back in this project friend.

WOW  Grin

Great to see this again! Really think this should be finished, it would be a great portfolio piece.

Thank you, guys.

Soon after implementing the palette swapping shader, I realized what a pain in the ass it is to draw the sprites and swap their colors manually, so Python and OpenCV saved my life. Here’s a script that takes 3 images: The original image, its palette and the final palette, then swaps them.

Code:
import sys
import numpy as np
import cv2

#
# This script is used to convert colored spritesheets to
# their grayscale counterpart provided two different
# palettes: the image's palette and the grayscale.
#

class Pixel:

r = 0
g = 0
b = 0
a = 0

def __init__(self, r, g, b, a):
if a == 0: # if the pixel is transparent, no need to set values
return

self.r = r
self.g = g
self.b = b
self.a = a

def __hash__(self):
return hash(self.r) + hash(self.g) + hash(self.b) + hash(self.a)

def __eq__(self, other):
return self.r == other.r and self.g == other.g and self.b == other.b and self.a == other.a

def __str__(self):
return str(self.r) + ', ' + str(self.g) + ', ' + str(self.b) + ', ' + str(self.a)

class PaletteSwapper:

def load_images(self, imagePath, colorPalettePath, grayPalettePath):
return cv2.imread(imagePath, -1), cv2.imread(colorPalettePath, -1), cv2.imread(grayPalettePath, -1)

def create_palettes_dict(self, colors, gray_colors):
color_dict = {}

for i in range(len(colors)):
color_dict[colors[i]] = gray_colors[i]
print '[', colors[i], '] : [', gray_colors[i], ']'

return color_dict

#s = set(colors) & set(gray_colors)
#print s

# iterates over an image and returns an array with the colors from that palette
def get_colors_from_palette(self, img):
colors = []

n_rows = img.shape[0]
n_cols = img.shape[1]

for y in range(n_rows):
for x in range(n_cols):
color = img[y,x]
pxl = Pixel(color.item(0), color.item(1), color.item(2), color.item(3))

colors.append(pxl)

return colors

def swap_palette(self, original_img, palette_dict, result_filename):
height, width, channels = original_img.shape

for y in range(height):
for x in range(width):
try:
# Get temporary pixel
pxl = original_img[y, x]
temp_pxl = Pixel(pxl.item(0), pxl.item(1), pxl.item(2), pxl.item(3))
equivalent_pxl = palette_dict[temp_pxl]

original_img[y,x] = [equivalent_pxl.r, equivalent_pxl.g, equivalent_pxl.b, equivalent_pxl.a]

except KeyError as e:
print e.message

cv2.imwrite(result_filename, original_img)
print 'Image saved to ', result_filename

def main(argv):
# It is needed three filenames: imagePath, colorPalettePath, grayPalettePath
if len(argv) < 4:
print 'Parameters needed: <image_path> <color_palette_path> <gray_palette_path> <desired_filename> (optional)'
return 0

final_filename = 'swapped.png'
if len(argv) == 5:
final_filename = argv[4]

palette_swapper = PaletteSwapper()

print 'Loading images...'
img, colorPalette, grayPalette = palette_swapper.load_images(argv[1], argv[2], argv[3])

print 'Grabbing palettes...'
gray_colors = palette_swapper.get_colors_from_palette(grayPalette)
colors = palette_swapper.get_colors_from_palette(colorPalette)

print 'Creating palette dict...'
color_dict = palette_swapper.create_palettes_dict(colors, gray_colors)

print 'Swapping palette...'
palette_swapper.swap_palette(img, color_dict, final_filename)


if __name__ == '__main__':
main(sys.argv)
« Last Edit: December 08, 2015, 03:55:41 PM by Gueib » Logged
Gueib
Level 1
*


don't be jealous of my boogie


View Profile WWW
« Reply #96 on: December 08, 2015, 04:01:55 PM »

The game is far from abandoned, even though it's been a while since my last post. A lot happened since my last post (including getting hired by a local game studio, hurray), but my absence is more related to laziness to post here than lack of work on the game.

This is a gif of today's addition to the game.

Logged
Pages: 1 ... 3 4 [5]
Print
Jump to:  

Theme orange-lt created by panic