You are browsing as a guest. Sign up (or log in) to start making projects!

City Defenders TD

  • 8 Devlogs
  • 54 Total hours

Tower Defense Game About Defending Medieval Cities

Open comments for this post

6h 53m 6s logged

Quite a bit of progress!

  • Pixel art revamp: The pixel art has generally improved massively. I actually took the time to get some inspiration from Google and worked on the tileset. It now includes a lake and also generally just looks better, with borders around the paths. It did take a lot of time, though. I also implemented animations for this, for the slime, and perhaps for the crossbow too. I also made a little card container for the top 2 stats.
  • Waves: I added waves! It’s now technically a fully playable tower defense game, I guess. As of right now it’s going to crash as soon as it gets farther than Wave 3 because I don’t have anything to do after it, but soon I will add another scene for that.
1
0
163
Open comments for this post

7h 16m 19s logged

Lots of progress again! This one was slightly more in the background, as I started a little bit of housekeeping:

  • Transition from Rects to FRects: FRects are the same thing as normal Rects, except that they allow for floats. This didn’t really have an impact on the game other than making it easier to work with vectors for positioning, as they also use floats.
  • UI Changes: I changed the positioning aspect of the UI. I recreated the Rect placement system of pygame, where you can select a point (eg. top left, center, midbottom, etc.) to use to position the rect. This is very flexible, and I copied it. Now, I can do things like place text with much more ease. I also changed the colors of the UI to make it darker and overall nicer. I made it so that the user had to select a turret and then go to a menu to see the cost and other attributes of it, which will be better for the future.
  • Coins: I added coins, which will be the temporary currency when inside the game. This will be used to buy towers and such. Outside the main game, I am planning to create another one that is used to buy skills and stuff, just to make it more realistic.
0
0
17
Open comments for this post

7h 4m 38s logged

It took a while, but there have been some pretty big improvements.

  • Transition to 1440x960px: I eventually found that being limited to 360x240 was going to be very limiting, specially with text because at low resolutions it looked like a jumbled mess. Thus I embarked on a pretty hard journey (not hard in retrospect) to figure out how to change the resolution but also keep the pixelated style without having to draw sprites at 4 times the resolution. The solution I ended up finding was to store a scale factor of 4 (360x4=1440, 240x4=960), and then scaling a separate surface to that resolution. Now, a surface is created with the same dimensions as the map, and everything is drawn to that surface instead of the map (I used to draw enemies, turrets, bullets, etc. onto the map because they moved together), and then that surface gets scaled. This allows me to keep the pixelated graphics on the actual game, and have crisp text on the GUI. For the offsets, I just moved the function that translated the screen coordinates to map ones from the map to the scene, and then adjusted it to take in the scale factor. Everything else works pretty much the same, as its only the image and mouse clicks getting scaled instead of rectangles. I scaled the button sprites to 32x32 to make them easier to draw, and then I have it in the config to scale them to 64x64. I decided to do that mostly for ease, because most of the other sprites are around that resolution anyway.
  • Turret placement: I added more buttons to the GUI and added turret placement. The GUI itself is always going to be kind of janky. I moved it into its own class so as to sort of clean up the code in the main scene, but now the GUI manager does weird things like self.scene.game.screen.width which isn’t very pretty. It’ll do, though. I track a variable storing the turret to be placed (None if it’s not in that state) and a variable that stores whether it can be placed. I check for collisions between the path tiles (I knew it would be useful!) and the sprite to check if it can be placed. I also modified the draw function of the turret to make it red or green depending on it.
    GUI: Generally, for the GUI, I keep a state from an Enum (basically a fancy way of storing a string for a state), and then change the UI according to that state. I designed it in a way where it only rebuilds it on command, so it won’t rebuild the whole thing every frame, in hopes to save some sort of performance.

Overall, some very good progress, even if it’s not 100% visible!

0
0
18
Open comments for this post

6h 47m 51s logged

I decided to just write the GUI from scratch. This is kind of uncharted territory for me. I tried using pygame_gui but it felt really restrictive and the use of a json file for customization is absurd to me. I made a basic element abstract class so that all elements must have an update and draw method. I then made a button class and a container class. All elements have an ID, and when a button is clicked it sends out a pygame event, which is a feature I did like from pygame_gui. I think I will end up eventually making an UI manager class, as handling the state within the scene is getting clunky and weird.

0
0
17
Open comments for this post

6h 17m 37s logged

I’ve probably progressed more in these ~6.25 hours than the rest of the project combined.

  • Fixed the map dragging boundary checks. This was just a matter of separating the if statement into one for each axis. Now, even if the map won’t move on the y-axis, it can move on the x-axis, for example.
  • I added an enemy. This was also pretty simple. They take in a path instead of a position, and their initial position is just the first index of the path (the path is a list of coordinates that they walk to). Vector math made this much easier, as I could just subtract the current position of the enemy from the target, and multiply it with movement speed to move it. The enemy is actually a parent class, and the specific slime in the video is a very simple subclass of it that just has some stats. Default enemy behavior is handled in that parent class.
    • I made a customizable health bar class. The cool part about it is that it uses linear interpolation to change its color as the health changes relative to the maximum.
  • I made a ballistic projectile parent class and an arrow subclass. It takes a position and a target, as well as other stats, and uses vector math to move to the target. When it hits an enemy it takes health from the enemy and then ceases to exist.
  • There is a turret class and a crossbow. The turret takes a projectile class (the crossbow takes the arrow, for example). It will make a new instance of the projectile when shooting. It has a circle for a range of effect, and it will point to and shoot at enemies within the circle.
    • The r key will toggle between drawing the areas and not.

Quite a lot of progress!

0
0
70
Open comments for this post

7h 13m 26s logged

I decided to give up on the isometry because I wasn’t really getting anything done. I have gone back to using a 2d map instead.|

  • The map is made with the Tiled Map Editor (https://thorbjorn.itch.io/tiled) and saved as a JSON file.
    • Tiled is good for visually building maps but a pain to work with. I’d much rather write a map editor from scratch, genuinely. I might do it at some point, honestly.
    • The map is actually split up into 3 layers: the ground, where turrets can be placed; the path tiles, where enemies will walk; and the path polygon, which is a line that the enemies will follow. This allows me to have separate path and ground groups which will simplify turret-path collisions later. In theory, I will be able to make the enemies follow the polygon, too.
    • I had to write a whole function just to parse the map JSON files. It organizes the layers into a dictionary of keys and 2-dimensional Numpy arrays. For the path polygon, it converts it from a list of dicts to tuples. It also removes any other inconsistencies with the original file and only keeps the important stuff.
  • I made the map bigger than the screen itself so that it is draggable. The checks for boundaries are kind of buggy but it’ll do for now. This was just a matter of keeping a variable to track if the map is being dragged, keeping an offset, checking for boundaries, and checking for mouse movements.

I know this was kind of a setback, but real progress can be made now!

0
0
100
Open comments for this post

5h 22m 44s logged

Turns out, rendering isometric grids is pretty hard! I followed a tutorial by DaFluffyPotato on isometric rendering which let me understand the drawing part, but there are going to be some issues with the grid system in the future. I had an issue in which the grid wouldn’t draw half of itself, and it was because it was drawing everything to the right of the top tile outside it. I got it to work by multiplying the grid width by 2 and then adding an offset, but it’s kind of a band-aid and I want to research more into how to actually solve it. I did actually draw the sprites myself, though, and I have a grass block that looks really nice but that’ll be for later.

2
0
105
Open comments for this post

6h 50m 44s logged

I’ve been working for a while, mostly on backwards-facing stuff about the general project structure:

  • A basic game class is used for the actual game instance, letting me manage variables and such and then pass them around.
  • A scene manager class manages different screens in the game.
    • Abstract methods are used to make sure scenes will always handle events, update, and render by making sure the methods are always implemented.
    • Each scene is a class object with several methods.
  • A config manager takes in a bunch of dataclasses and allows accessing the config like globals.
  • Tests check to make sure that an error is raised if a wrong key is accessed, and other stuff.
  • Player ships all inherit from one overall base ship class, and so do turret from their base turret class.
    • Turrets have an attachment point and player ships have points to attach to.
    • Both sprites are joined at the points so as to create a mounting system in which the same ship can use different turret configurations.

The next thing to work on is to allow the turret to rotate as if it was on top of the ship, and to handle ship movement, having it rotate to face where it is moving.

The following image is actually 2 different sprites: the turret (green) and the ship (below). It draws them by blitting the turret on top of the ship sprite.

I have decided to change the theme of the project. The vast majority of the time in this devlog was the background, and luckily I didn’t have much progress on the actual game part. It will now be a tower defense game.

0
0
88

Delete project?

Are you sure you want to permanently delete this project? This action cannot be undone.

All devlogs, followers, and associated data will be removed.

Followers

Loading…