Very much WIP using some of the graphical style/themes from Mint in a Vampire Survivors style game.
WIP has:
- 2 characters with different modifiers
- 6 weapons and 1 passive item. weapons and passives have level upgrade modifiers
- A wave spawner (but it spawns the same stuff every wave - need more mob types)
- Boss mobs drop a chest that will drop a random upgrade to an item in your inventory
- Standard mobs drop xp, hitting the target xp for the level triggers a shop where you are offered 3 items (with some weighting towards items you already own)
"O" button does everything.
TODO:
- refactor for performance, I think I can improve collision handling
- a proper map, thinking an infinite map like vampire survivors
- scaling of mobs with XP
- more items
- more enemy types
- probably refactor how I am doing classes, it's getting messy.
- bugs, probably lots of them
- everything else
Hello, I have this code that circles an object around the player position.
It works well if the player stands still, but if the player moves the trajectory of the object goes a bit wonky. it sort of stops, or looks like it wants to go in the other direction for a bit.
How can I make it smoothly rotate around the player?
local player = self.game_context.player local orbit_radius = 40 -- Distance from player to orbiting projectile local orbit_speed = self.speed -- Normalized speed of orbit; consider this as fraction of a circle per frame for p in all(self.projectiles) do p.angle += orbit_speed if (p.angle > 360) p.angle = 0 p.x = player.x + (player.attributes.w / 2) + orbit_radius * cos(p.angle/360) p.y = player.y + (player.attributes.h / 2) + orbit_radius * sin(p.angle/360) -- Handle projectile duration and collision p.duration -= 1 end |
Hello,
I feel like I am being a bit thick this morning.
I have a 128 x 128 sprite sheet as a .png.
I've tried importpng and the pictron exporter from asesprite. both exhibit the same behaviour, when I paste from the clipboard the whole image fills sprite 0 and sets its size to 128 x 128, I'm expecting the image to start at sprite 0 and fill outwards. Am I missing something obvious?
thanks in advance
Hello, considering the following:
Trying to remake Vampire Survivors and a fun project
I have a character class
Characters have effects that are applied to a target. In this example my target = player
I have a character that is an instance of that class. Let's call him "Antonio"
I have a "run", Antonio is copied into run.player
I set player to be run.player
My problem is that I have to initiate the character class and Antonio before I create "player". But player is not yet created so player referenced on the character class is nil.
I hope this makes sense, I have a workaround but it feels clunky and I'm wondering if there are other solutions.
Here is my code before the workaround:
character = {} character.__index = character function character:new(name) local o = setmetatable({}, character) o.name = name o.x = 0 o.y = 0 o.sp_scale = 1 o.w = 16 o.h = 16 o.effects = effects o.original_invincibility_frames = 10 o.invincibility_frames = 0 o.max_health = 100 o.health = 20 o.recovery = 0 o.armor = 0 o.move_speed = 1 o.might = 1 o.weapon_projectile_speed = 0 o.weapon_duration = 0 o.weapon_area = 0 o.weapon_cooldown = 0 o.weapon_projectiles_amount = 0 o.revival = 0 o.magnet = 0 o.luck = 0 o.growth = 0 o.greed = 0 o.curse = 0 o.reroll = 0 o.skip = 0 o.banish = 0 return o end function character:set_effects(effects) self.effects = effects end function character:apply_effects(level) local effects = self.effects for _, effect in pairs(effects) do if level % effect.level_increment == 0 and level <= effect.max_level_increment then local target = effect.target if effect.mode == "percent" then target[effect.stat] += (target[effect.stat] or 0) * effect.value else target[effect.stat] = (target[effect.stat] or 0) + effect.value end end end end antonio = character:new("antonio") antonio.recovery = 0.5 antonio:set_effects( { { description="Gains 10% Might every 2 Levels", stat = "might", value = 1, target = player, -- here is the problem, player doesn't exist level_increment = 2, max_level_increment = 10, mode = "percent" }, { description="Gains 0.5 Recovery every 1 level", stat = "recovery", value = 0.5, target = player, level_increment = 1, max_level_increment = 5 } } ) function _init() t = 0 run = {} run.player = {} run.level = 1 add(run.player, deepcopy(antonio)) player = run.player[1] end function _update() if t % 60 == 0 then player.health += player.recovery end if btnp(4) then run.level += 1 player:apply_effects(run.level) end t += 1 end function _draw() local y = 0 cls(0) for entry in all(run.player) do for k, v in pairs(entry) do if type(v) == "number" then print(k..":"..v, 0, y) y += 8 end end end local y = 0 print("Level: "..run.level, 240, y) end function deepcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in next, orig, nil do copy[deepcopy(orig_key)] = deepcopy(orig_value) end setmetatable(copy, getmetatable(orig)) else -- for numbers, strings, booleans, etc copy = orig end return copy end |
And here is my code with the workaround, in short, once player is created I go and apply player as the target of the effects: player:update_effects_target(player)
character = {} character.__index = character function character:new(name) local o = setmetatable({}, character) o.name = name o.x = 0 o.y = 0 o.sp_scale = 1 o.w = 16 o.h = 16 o.effects = effects o.original_invincibility_frames = 10 o.invincibility_frames = 0 o.max_health = 100 o.health = 20 o.recovery = 0 o.armor = 0 o.move_speed = 1 o.might = 1 o.weapon_projectile_speed = 0 o.weapon_duration = 0 o.weapon_area = 0 o.weapon_cooldown = 0 o.weapon_projectiles_amount = 0 o.revival = 0 o.magnet = 0 o.luck = 0 o.growth = 0 o.greed = 0 o.curse = 0 o.reroll = 0 o.skip = 0 o.banish = 0 return o end function character:set_effects(effects) self.effects = effects end function character:update_effects_target(target) for _, effect in pairs(self.effects) do effect.target = target end end function character:apply_effects(level) local effects = self.effects for _, effect in pairs(effects) do if level % effect.level_increment == 0 and level <= effect.max_level_increment then local target = effect.target if effect.mode == "percent" then target[effect.stat] += (target[effect.stat] or 0) * effect.value else target[effect.stat] = (target[effect.stat] or 0) + effect.value end end end end antonio = character:new("antonio") antonio.recovery = 0.5 antonio:set_effects( { { description="Gains 10% Might every 2 Levels", stat = "might", value = 1, target = player, -- here is the problem, player doesn't exist level_increment = 2, max_level_increment = 10, mode = "percent" }, { description="Gains 0.5 Recovery every 1 level", stat = "recovery", value = 0.5, target = player, level_increment = 1, max_level_increment = 5 } } ) function _init() t = 0 run = {} run.player = {} run.level = 1 add(run.player, deepcopy(antonio)) player = run.player[1] player:update_effects_target(player) end function _update() if t % 60 == 0 then player.health += player.recovery end if btnp(4) then run.level += 1 player:apply_effects(run.level) end t += 1 end function _draw() local y = 0 cls(0) for entry in all(run.player) do for k, v in pairs(entry) do if type(v) == "number" then print(k..":"..v, 0, y) y += 8 end end end local y = 0 print("Level: "..run.level, 240, y) end function deepcopy(orig) local orig_type = type(orig) local copy if orig_type == 'table' then copy = {} for orig_key, orig_value in next, orig, nil do copy[deepcopy(orig_key)] = deepcopy(orig_value) end setmetatable(copy, getmetatable(orig)) else -- for numbers, strings, booleans, etc copy = orig end return copy end |
Hello,
For fun, I'm building a Vampire Survivors style game. There will be a lot of mobs on screen, so I've built a grid partitioning system and each weapon only checks for collisions with mobs nearby.
The grid size is 30, so that's a 16 x 9 grid.
My question is this, currently, I'm initialising the grid on every frame and re-populating all the mob positions into their grids.
Should I move to initialising just once and updating mob positions in the grid on every frame? I'm not sure whether that will actually be quicker because I will have to delete the mob from one grid position and add it to another.
Also, that seems hard to implement :-)
Thanks in advance
Russ
Knuckle Dice v1.3
Knuckle Dice is an attempt to recreate Knuckle Bones from Cult of the Lamb. This is my first programming project ever so there's no AI yet - it's two player only to begin with.
In the future I will try to add:
- CPU AI (DONE)
- I want to experiment with perfect information. In other words, remove the randomness and tell the player exactly what the opponent is about to play.
Controls
- z to start/restart
- x to play a dice
Rules/Game Logic
- Maximum 3 dice in one column
- Playing a die in a column that matches dice in the opposing player's column removes all instances of that dice
- When nine dice are played by either player the game ends
Scoring
- You receive points equivalent to the die played multiplied by the number of instances of that dice. (e.g a 5 played twice in one column will give you twenty points - 2*(5+5)
- The player with the most points wins
v1.1 Updates
- Changed GFX to more of a 1bit style
v1.3 Updates
- Now it's a single player game with some rudimentary AI for P2