Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
430 changes: 66 additions & 364 deletions LUA/asteroids/asteroids.lua

Large diffs are not rendered by default.

91 changes: 91 additions & 0 deletions LUA/asteroids/modules/asteroid.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
--
-- Астероїд, який рухається по екрану
--

local data = require("modules.data")

Asteroid = {
x = 0,
y = 0,
speed_x = 0,
speed_y = 0,
size = 0,
--- @type table|nil
sprite = nil,
offscreen = false,
killed_at = -1,
dead = false,
}

function Asteroid:new(x, y, speed_x, speed_y)
local size = math.random(1, 4)
local sprite
if size == 1 then
sprite = data.ASTEROID_16_SPRITES[math.random(1, 8)]
elseif size == 2 then
sprite = data.ASTEROID_32_SPRITES[math.random(1, 8)]
elseif size == 3 then
sprite = data.ASTEROID_48_SPRITES[math.random(1, 8)]
else
sprite = data.ASTEROID_64_SPRITES[math.random(1, 8)]
end
local o = {
x = x,
y = y,
speed_x = speed_x,
speed_y = speed_y,
size = size,
sprite = sprite,
offscreen = x < sprite.width / 2 or x > display.width - sprite.width / 2 or y < sprite.width / 2 or
y > display.height - sprite.height / 2,
}
setmetatable(o, self)
self.__index = self
return o
end

function Asteroid:update(delta)
self.x = self.x + self.speed_x * delta
self.y = self.y + self.speed_y * delta
if self.offscreen then
self.offscreen = self.x < self.sprite.width / 2 or self.x > display.width - self.sprite.width / 2 or
self.y < self.sprite.width / 2 or self.y > display.height - self.sprite.height / 2
else
self.x = self.x % display.width
self.y = self.y % display.height
end
end

function Asteroid:kill()
self.killed_at = util.time()
self.dead = true
end

function Asteroid:draw()
if self.dead then
local time_since_death = util.time() - self.killed_at
-- Малюємо коло, яке збільшується та зменшується впродовж 1 секунди
if time_since_death < 1 then
local radius = math.sin(time_since_death * 2 * math.pi) * self.sprite.width / 2
display.fill_circle(self.x, self.y, radius, WHITE)
end
else
local cx = self.x - self.sprite.width / 2
local cy = self.y - self.sprite.height / 2
display.draw_image(self.sprite, cx, cy)
if not self.offscreen then
if cx < 0 then
display.draw_image(self.sprite, cx + display.width, cy)
elseif cx + self.sprite.width > display.width then
display.draw_image(self.sprite, cx - display.width, cy)
end
if cy < 0 then
display.draw_image(self.sprite, cx, cy + display.height)
elseif cy + self.sprite.height > display.height then
display.draw_image(self.sprite, cx, cy - display.height)
end
end
end
end

return Asteroid
51 changes: 51 additions & 0 deletions LUA/asteroids/modules/bullet.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
--
-- Куля, якою стріляє корабель
--

Bullet = {
x = 0,
y = 0,
speed_x = 0,
speed_y = 0,
distance_traveled = 0,
dead = false,

radius = 1,
max_distance = math.sqrt(display.width * display.width + display.height * display.height) / 2,
}

function Bullet:new(x, y)
local o = { x = x, y = y }
setmetatable(o, self)
self.__index = self
return o
end

function Bullet:update(delta)
if self.dead then
return
end
local dx = self.speed_x * delta
local dy = self.speed_y * delta
self.x = self.x + dx
self.y = self.y + dy
-- Якщо куля виходить за межі екрану, вона з'являється на протилежному боці
self.x = self.x % display.width
self.y = self.y % display.height

-- Коли куля долає велику відстань, вона вмирає
self.distance_traveled = self.distance_traveled + math.sqrt(dx * dx + dy * dy)
if self.distance_traveled > self.max_distance then
self.dead = true
end
end

function Bullet:kill()
self.dead = true
end

function Bullet:draw()
display.fill_circle(self.x, self.y, self.radius, WHITE)
end

return Bullet
92 changes: 92 additions & 0 deletions LUA/asteroids/modules/data.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
ROOT = 'resources/'

data = {
ASTEROID_16_SPRITES = { resources.load_image(ROOT .. "asteroid_16.bmp", MAGENTA) },
ASTEROID_32_SPRITES = { resources.load_image(ROOT .. "asteroid_32.bmp", MAGENTA) },
ASTEROID_48_SPRITES = { resources.load_image(ROOT .. "asteroid_48.bmp", MAGENTA) },
ASTEROID_64_SPRITES = { resources.load_image(ROOT .. "asteroid_64.bmp", MAGENTA) },

SHIP_SPRITE = resources.load_image(ROOT .. "ship.bmp", MAGENTA),
SHIP_FORWARD_SPRITE = resources.load_image(ROOT .. "ship_forward.bmp", MAGENTA),
SHIP_BACKWARD_SPRITE = resources.load_image(ROOT .. "ship_backward.bmp", MAGENTA),

BANNER = {},
PRESS_START = resources.load_image(ROOT .. "press_start.bmp"),
YOU_ARE_DEAD = resources.load_image(ROOT .. "game_over.bmp"),

SHOOT_SOUND = resources.load_audio(ROOT .. "shoot.mp3"),
BOOM_SOUND = resources.load_audio(ROOT .. "boom.mp3"),
DEATH_SOUND = resources.load_audio(ROOT .. "death.mp3"),

SHOOT_MELODY = {
{ 880, 8 },
{ 784, 8 },
{ 698, 8 },
{ 659, 8 },
{ 587, 8 },
{ 523, 8 },
{ 440, 8 },
{ 392, 8 },
{ 349, 8 },
{ 330, 8 },
{ 294, 8 },
{ 262, 8 },
},

BOOM_MELODY = {
{ 440, 8 },
{ 392, 8 },
{ 349, 8 },
{ 330, 8 },
{ 294, 8 },
{ 262, 8 },
{ 220, 8 },
{ 196, 8 },
{ 175, 8 },
{ 165, 8 },
{ 147, 8 },
{ 131, 8 },
{ 123, 8 },
{ 110, 8 },
{ 98, 8 },
{ 88, 8 },
},

-- Low-pitch (100-200 Hz) noise.
DEATH_MELODY = {
{ 200, 8 },
{ 100, 8 },
{ 150, 8 },
{ 200, 8 },
{ 100, 8 },
{ 150, 8 },
{ 100, 8 },
{ 150, 8 },
{ 100, 8 },
{ 150, 8 },
{ 50, 8 },
{ 100, 8 },
{ 50, 8 },
{ 100, 8 },
{ 50, 8 },
{ 100, 8 },
{ 50, 8 },
{ 100, 8 },
{ 50, 8 },
{ 100, 8 },
{ 50, 8 },
},
}

for i = 2, 8 do
data.ASTEROID_16_SPRITES[i] = resources.rotate_image(data.ASTEROID_16_SPRITES[1], i * 45, MAGENTA)
data.ASTEROID_32_SPRITES[i] = resources.rotate_image(data.ASTEROID_32_SPRITES[1], i * 45, MAGENTA)
data.ASTEROID_48_SPRITES[i] = resources.rotate_image(data.ASTEROID_48_SPRITES[1], i * 45, MAGENTA)
data.ASTEROID_64_SPRITES[i] = resources.rotate_image(data.ASTEROID_64_SPRITES[1], i * 45, MAGENTA)
end

for i = 1, 4 do
data.BANNER[i] = resources.load_image(ROOT .. "banner" .. i .. ".bmp")
end

return data
124 changes: 124 additions & 0 deletions LUA/asteroids/modules/ship.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
--
-- Корабель, яким керує гравець
--

local data = require("modules.data")


Ship = {
x = display.width / 2,
y = display.height / 2,
width = data.SHIP_SPRITE.width, -- Розмір спрайту
height = data.SHIP_SPRITE.height,
sprite = data.SHIP_SPRITE,
forward_sprite = data.SHIP_FORWARD_SPRITE,
backward_sprite = data.SHIP_BACKWARD_SPRITE,
current_sprite = nil,
current_rotation_index = nil,
current_sprite_set_index = nil,
rotation = 270, -- Кут обороту корабля в градусах за годинниковою стрілкою
speed_x = 0,
speed_y = 0,
accel_forward = 0,
angular_speed = 0,
max_speed_x = display.width / 2,
max_speed_y = display.height / 2,
killed_at = -1,
dead = false,
-- accel_y = 0,
}
function Ship:new(o)
o = o or {}
setmetatable(o, self)
self.__index = self
return o
end

function Ship:set_forward_acceleration(accel)
self.accel_forward = accel
end

function Ship:set_angular_speed(speed)
self.angular_speed = speed
end

function Ship:kill()
self.killed_at = util.time()
self.dead = true
end

function Ship:update(delta)
local dir_x, dir_y = math.rotate(1, 0, self.rotation)

self.speed_x = self.speed_x + self.accel_forward * delta * dir_x
self.speed_y = self.speed_y + self.accel_forward * delta * dir_y

self.speed_x = math.clamp(self.speed_x, -self.max_speed_x, self.max_speed_x)
self.speed_y = math.clamp(self.speed_y, -self.max_speed_y, self.max_speed_y)

self.x = self.x + self.speed_x * delta
self.y = self.y + self.speed_y * delta

self.x = self.x % display.width
self.y = self.y % display.height

self.rotation = (self.rotation + self.angular_speed * delta) % 360
end

function Ship:draw()
if self.dead then
local time_since_death = util.time() - self.killed_at
-- Малюємо коло, яке збільшується та зменшується впродовж 1 секунди
if time_since_death < 1 then
local radius = math.sin(time_since_death * 2 * math.pi) * 32
display.fill_circle(self.x, self.y, radius, WHITE)
end
else
local rotation_index = math.floor(self.rotation / ANGLE_STEP) + 1
-- Координати верхнього лівого кута спрайту
local cx = self.x - self.width / 2
local cy = self.y - self.height / 2

local sprite_set_index
if self.accel_forward > 0 then
sprite_set_index = 1
elseif self.accel_forward < 0 then
sprite_set_index = -1
else
sprite_set_index = 0
end

if self.current_sprite_set_index ~= sprite_set_index or self.current_rotation_index ~= rotation_index then
if self.current_sprite ~= nil then
resources.delete(self.current_sprite)
end

self.current_sprite_set_index = sprite_set_index
self.current_rotation_index = rotation_index

local angle = (rotation_index - 1) * ANGLE_STEP
if sprite_set_index == 1 then
self.current_sprite = resources.rotate_image(self.forward_sprite, angle, MAGENTA)
elseif sprite_set_index == -1 then
self.current_sprite = resources.rotate_image(self.backward_sprite, angle, MAGENTA)
else
self.current_sprite = resources.rotate_image(self.sprite, angle, MAGENTA)
end
end

display.draw_image(self.current_sprite, cx, cy)
-- Якщо ми біля краю екрану, малюємо корабель ще раз на протилежному боці
if cx < 0 then
display.draw_image(self.current_sprite, cx + display.width, cy)
elseif cx + self.width > display.width then
display.draw_image(self.current_sprite, cx - display.width, cy)
end
if cy < 0 then
display.draw_image(self.current_sprite, cx, cy + display.height)
elseif cy + self.height > display.height then
display.draw_image(self.current_sprite, cx, cy - display.height)
end
end
end

return Ship
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file added LUA/asteroids/resources/boom.mp3
Binary file not shown.
Binary file added LUA/asteroids/resources/death.mp3
Binary file not shown.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Binary file added LUA/asteroids/resources/shoot.mp3
Binary file not shown.
Binary file removed LUA/asteroids/splash.xcf
Binary file not shown.