Organize project
This commit is contained in:
parent
d6143951d8
commit
6993054d63
7 changed files with 368 additions and 327 deletions
58
src/animation.odin
Normal file
58
src/animation.odin
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
package game
|
||||
|
||||
import rl "vendor:raylib"
|
||||
|
||||
Animation :: struct {
|
||||
texture: rl.Texture2D,
|
||||
num_frames: int,
|
||||
frame_timer: f32,
|
||||
current_frame: int,
|
||||
frame_length: f32,
|
||||
flip: bool,
|
||||
loop: bool,
|
||||
done: bool,
|
||||
offset: rl.Vector2,
|
||||
}
|
||||
|
||||
update_animation :: proc(a: ^Animation) {
|
||||
a.frame_timer += rl.GetFrameTime()
|
||||
|
||||
if a.frame_timer > a.frame_length && !a.done {
|
||||
a.current_frame += 1
|
||||
a.frame_timer = 0
|
||||
|
||||
if a.current_frame == a.num_frames {
|
||||
if a.loop {
|
||||
a.current_frame = 0
|
||||
} else {
|
||||
a.current_frame += -1
|
||||
a.done = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
draw_animation :: proc(a: Animation, pos: rl.Vector2) {
|
||||
width := f32(a.texture.width)
|
||||
height := f32(a.texture.height)
|
||||
|
||||
source := rl.Rectangle {
|
||||
x = f32(a.current_frame) * width / f32(a.num_frames),
|
||||
y = 0,
|
||||
width = width / f32(a.num_frames),
|
||||
height = height,
|
||||
}
|
||||
|
||||
if a.flip {
|
||||
source.width = -source.width
|
||||
}
|
||||
|
||||
dest := rl.Rectangle {
|
||||
x = pos.x + a.offset.x,
|
||||
y = pos.y + a.offset.y,
|
||||
width = width / f32(a.num_frames),
|
||||
height = height,
|
||||
}
|
||||
|
||||
rl.DrawTexturePro(a.texture, source, dest, {dest.width / 2, dest.height}, 0, rl.WHITE)
|
||||
}
|
||||
5
src/constants.odin
Normal file
5
src/constants.odin
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
package game
|
||||
|
||||
GAME_SCREEN_WIDTH: f32 = 480
|
||||
GAME_SCREEN_HEIGHT: f32 = 270
|
||||
TILE_SIZE :: 16
|
||||
144
src/entity.odin
Normal file
144
src/entity.odin
Normal file
|
|
@ -0,0 +1,144 @@
|
|||
package game
|
||||
|
||||
import "core:math"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
EntityKind :: enum {
|
||||
Player,
|
||||
Tile,
|
||||
Item,
|
||||
}
|
||||
|
||||
PlayerData :: struct {
|
||||
animation: Animation,
|
||||
}
|
||||
|
||||
ItemData :: struct {
|
||||
id: int,
|
||||
count: int,
|
||||
texture: rl.Texture2D,
|
||||
}
|
||||
|
||||
TileData :: struct {
|
||||
has_plant: bool,
|
||||
is_watered: bool,
|
||||
plant_id: int,
|
||||
animation: Animation,
|
||||
plant_grown: bool,
|
||||
}
|
||||
|
||||
EntityData :: union {
|
||||
PlayerData,
|
||||
TileData,
|
||||
ItemData,
|
||||
}
|
||||
|
||||
Entity :: struct {
|
||||
pos: rl.Vector2,
|
||||
kind: EntityKind,
|
||||
handle: EntityHandle,
|
||||
flags: bit_set[EntityFlags],
|
||||
data: EntityData,
|
||||
}
|
||||
latest_entity_handle: int
|
||||
|
||||
EntityHandle :: int
|
||||
EntityFlags :: enum {
|
||||
nil,
|
||||
Allocated,
|
||||
}
|
||||
|
||||
create_entity :: proc(entity: Entity) -> ^Entity {
|
||||
for &e in entities {
|
||||
if .Allocated not_in e.flags {
|
||||
e = entity
|
||||
e.flags = {.Allocated}
|
||||
latest_entity_handle += 1
|
||||
return &e
|
||||
}
|
||||
}
|
||||
assert(false, "Failed to allocate entity, not enough space!!!!")
|
||||
return nil
|
||||
}
|
||||
|
||||
destroy_entity :: proc(e: ^Entity) {
|
||||
e^ = Entity{}
|
||||
}
|
||||
|
||||
handle_to_entity :: proc(handle: EntityHandle) -> ^Entity {
|
||||
for &e in entities {
|
||||
if handle == e.handle && .Allocated in e.flags {
|
||||
return &e
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
update_entities :: proc() {
|
||||
for &e in entities {
|
||||
if .Allocated not_in e.flags {continue}
|
||||
|
||||
#partial switch &data in e.data {
|
||||
case TileData:
|
||||
update_tile(e, &data)
|
||||
case PlayerData:
|
||||
update_animation(&data.animation)
|
||||
case ItemData:
|
||||
//rl.DrawTextureV(data.texture, e.pos + {0, t * 3}, rl.WHITE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_tile :: proc(e: Entity, data: ^TileData) {
|
||||
update_animation(&data.animation)
|
||||
if data.has_plant && data.animation.done && data.plant_grown == false {
|
||||
data.plant_grown = true
|
||||
data.has_plant = false
|
||||
rl.PlaySound(pickup_sound)
|
||||
item := create_entity(
|
||||
Entity {
|
||||
pos = e.pos,
|
||||
kind = .Item,
|
||||
data = ItemData{id = data.plant_id, count = 3, texture = tomato_texture},
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
draw_entities :: proc() {
|
||||
for e in entities {
|
||||
if .Allocated not_in e.flags {continue}
|
||||
|
||||
switch &data in e.data {
|
||||
case TileData:
|
||||
draw_tile(e)
|
||||
case PlayerData:
|
||||
draw_player(e)
|
||||
case ItemData:
|
||||
draw_item(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entity_to_handle :: proc(e: Entity) -> EntityHandle {
|
||||
return e.handle
|
||||
}
|
||||
|
||||
draw_player :: proc(e: Entity) {
|
||||
data, ok := e.data.(PlayerData)
|
||||
draw_animation(data.animation, e.pos)
|
||||
}
|
||||
draw_tile :: proc(e: Entity) {
|
||||
data, ok := e.data.(TileData)
|
||||
//rl.DrawRectangle(auto_cast e.pos.x, auto_cast e.pos.y, TILE_SIZE, TILE_SIZE, rl.BLACK)
|
||||
rl.DrawTextureV(tile_dirt_dry_texture, e.pos, rl.WHITE)
|
||||
if data.has_plant {
|
||||
draw_animation(data.animation, e.pos)
|
||||
}
|
||||
}
|
||||
draw_item :: proc(e: Entity) {
|
||||
data, ok := e.data.(ItemData)
|
||||
t := f32(math.sin(rl.GetTime() * 5))
|
||||
rl.DrawTextureV(data.texture, e.pos + {0, t * 3}, rl.WHITE)
|
||||
//draw_animation(data.animation, e.pos + {0, t * 3})
|
||||
}
|
||||
29
src/globals.odin
Normal file
29
src/globals.odin
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package game
|
||||
|
||||
import t "../tween"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
SELL_BUTTON_POS :: rl.Vector2{432, 16}
|
||||
|
||||
game_camera := rl.Camera2D {
|
||||
zoom = 1,
|
||||
}
|
||||
ui_camera := rl.Camera2D {
|
||||
zoom = 1,
|
||||
}
|
||||
game_render_buffer: rl.RenderTexture2D
|
||||
screen_game_area: rl.Rectangle
|
||||
game_render_buffer_area := rl.Rectangle{0, 0, GAME_SCREEN_WIDTH, -GAME_SCREEN_HEIGHT}
|
||||
screen_scale: f32
|
||||
|
||||
world_mouse: rl.Vector2
|
||||
|
||||
player_handle: EntityHandle
|
||||
|
||||
tiles: [dynamic]Tile
|
||||
animations: [dynamic]^Animation
|
||||
|
||||
entities: [256]Entity
|
||||
|
||||
tween_ctx_f32: t.TweenContext(f32)
|
||||
tween_ctx_vec2: t.TweenContext([2]f32)
|
||||
382
src/main.odin
382
src/main.odin
|
|
@ -8,75 +8,11 @@ import "core:math/linalg"
|
|||
import "core:slice"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
GAME_SCREEN_WIDTH: f32 = 480
|
||||
GAME_SCREEN_HEIGHT: f32 = 270
|
||||
|
||||
SELL_BUTTON_POS :: rl.Vector2{432, 16}
|
||||
|
||||
TILE_SIZE :: 16
|
||||
game_render_buffer: rl.RenderTexture2D
|
||||
game_camera := rl.Camera2D {
|
||||
zoom = 1,
|
||||
}
|
||||
ui_camera := rl.Camera2D {
|
||||
zoom = 1,
|
||||
}
|
||||
|
||||
screen_scale: f32
|
||||
world_mouse: rl.Vector2
|
||||
screen_game_area: rl.Rectangle
|
||||
game_render_buffer_area := rl.Rectangle{0, 0, GAME_SCREEN_WIDTH, -GAME_SCREEN_HEIGHT}
|
||||
|
||||
pickup_sound: rl.Sound
|
||||
pickup_sound_data: []u8 : #load("../assets/sounds/pickup_sound.mp3")
|
||||
|
||||
player_spritesheet_sprite: []u8 : #load("../assets/player.png")
|
||||
tomato_spritesheet_sprite: []u8 : #load("../assets/tomato.png")
|
||||
tomato_item_sprite: []u8 : #load("../assets/tomato_item.png")
|
||||
sell_button_sprite: []u8 : #load("../assets/sell_button.png")
|
||||
background_sprite: []u8 : #load("../assets/background.png")
|
||||
tile_dirt_dry_sprite: []u8 : #load("../assets/tile_dirt_dry.png")
|
||||
tile_dirt_wet_sprite: []u8 : #load("../assets/tile_dirt_wet.png")
|
||||
|
||||
load_texture_from_memory :: proc(data: []u8) -> (texture: rl.Texture2D) {
|
||||
img := rl.LoadImageFromMemory(".png", raw_data(data), auto_cast len(data))
|
||||
defer rl.UnloadImage(img)
|
||||
texture = rl.LoadTextureFromImage(img)
|
||||
return texture
|
||||
}
|
||||
|
||||
load_sound_from_memory :: proc(
|
||||
data: []u8,
|
||||
sound_extension: cstring = ".mp3",
|
||||
) -> (
|
||||
sound: rl.Sound,
|
||||
) {
|
||||
wav := rl.LoadWaveFromMemory(sound_extension, raw_data(data), auto_cast len(data))
|
||||
defer rl.UnloadWave(wav)
|
||||
sound = rl.LoadSoundFromWave(wav)
|
||||
return
|
||||
}
|
||||
|
||||
sell_button_texture: rl.Texture2D
|
||||
background_texture: rl.Texture2D
|
||||
tile_dirt_dry_texture: rl.Texture2D
|
||||
tile_dirt_wet_texture: rl.Texture2D
|
||||
tomato_texture: rl.Texture2D
|
||||
|
||||
player_animation: Animation
|
||||
tomato_animation: Animation
|
||||
|
||||
player_handle: EntityHandle
|
||||
|
||||
tiles: [dynamic]Tile
|
||||
animations: [dynamic]^Animation
|
||||
|
||||
entities: [256]Entity
|
||||
|
||||
tween_ctx_f32: t.TweenContext(f32)
|
||||
tween_ctx_vec2: t.TweenContext([2]f32)
|
||||
|
||||
main :: proc() {
|
||||
run()
|
||||
}
|
||||
|
||||
run :: proc() {
|
||||
rl.SetConfigFlags({.VSYNC_HINT, .WINDOW_RESIZABLE, .MSAA_4X_HINT})
|
||||
rl.InitWindow(1280, 720, "Raylib Minimal")
|
||||
rl.SetTargetFPS(rl.GetMonitorRefreshRate(rl.GetCurrentMonitor()))
|
||||
|
|
@ -88,57 +24,17 @@ main :: proc() {
|
|||
fmt.println("Audio borked!")
|
||||
}
|
||||
|
||||
pickup_sound = load_sound_from_memory(pickup_sound_data)
|
||||
|
||||
game_render_buffer = rl.LoadRenderTexture(
|
||||
auto_cast GAME_SCREEN_WIDTH,
|
||||
auto_cast GAME_SCREEN_HEIGHT,
|
||||
)
|
||||
rl.SetTextureFilter(game_render_buffer.texture, rl.TextureFilter.POINT) // Texture scale filter to use
|
||||
|
||||
tween_ctx_f32 = t.context_init(f32)
|
||||
tween_ctx_vec2 = t.context_init([2]f32)
|
||||
defer t.context_destroy(tween_ctx_f32)
|
||||
defer t.context_destroy(tween_ctx_vec2)
|
||||
|
||||
player_animation = Animation {
|
||||
texture = load_texture_from_memory(player_spritesheet_sprite),
|
||||
num_frames = 2,
|
||||
frame_length = 0.5,
|
||||
loop = true,
|
||||
}
|
||||
tomato_animation = Animation {
|
||||
texture = load_texture_from_memory(tomato_spritesheet_sprite),
|
||||
num_frames = 4,
|
||||
frame_length = 0.1,
|
||||
loop = false,
|
||||
offset = {TILE_SIZE / 2, TILE_SIZE},
|
||||
}
|
||||
tomato_texture = load_texture_from_memory(tomato_item_sprite)
|
||||
sell_button_texture = load_texture_from_memory(sell_button_sprite)
|
||||
background_texture = load_texture_from_memory(background_sprite)
|
||||
tile_dirt_dry_texture = load_texture_from_memory(tile_dirt_dry_sprite)
|
||||
tile_dirt_wet_texture = load_texture_from_memory(tile_dirt_wet_sprite)
|
||||
|
||||
e := create_entity(
|
||||
Entity {
|
||||
pos = {GAME_SCREEN_WIDTH / 2, GAME_SCREEN_HEIGHT / 2},
|
||||
kind = .Player,
|
||||
data = PlayerData{animation = player_animation},
|
||||
},
|
||||
)
|
||||
player_handle = entity_to_handle(e^)
|
||||
|
||||
load_resources()
|
||||
rl.SetSoundVolume(pickup_sound, 0.1)
|
||||
rl.PlaySound(pickup_sound)
|
||||
|
||||
if true {for !rl.WindowShouldClose() {
|
||||
free_all(context.temp_allocator)
|
||||
update()
|
||||
draw()
|
||||
}
|
||||
|
||||
for !rl.WindowShouldClose() {
|
||||
free_all(context.temp_allocator)
|
||||
update()
|
||||
draw()
|
||||
}
|
||||
rl.UnloadRenderTexture(game_render_buffer) // Unload render texture
|
||||
|
||||
free_resources()
|
||||
rl.CloseAudioDevice()
|
||||
rl.CloseWindow()
|
||||
}
|
||||
|
|
@ -232,227 +128,59 @@ draw :: proc() {
|
|||
rl.EndDrawing()
|
||||
}
|
||||
|
||||
Animation :: struct {
|
||||
texture: rl.Texture2D,
|
||||
num_frames: int,
|
||||
frame_timer: f32,
|
||||
current_frame: int,
|
||||
frame_length: f32,
|
||||
flip: bool,
|
||||
loop: bool,
|
||||
done: bool,
|
||||
offset: rl.Vector2,
|
||||
}
|
||||
load_resources :: proc() {
|
||||
tween_ctx_f32 = t.context_init(f32)
|
||||
tween_ctx_vec2 = t.context_init([2]f32)
|
||||
|
||||
update_animation :: proc(a: ^Animation) {
|
||||
a.frame_timer += rl.GetFrameTime()
|
||||
game_render_buffer = rl.LoadRenderTexture(
|
||||
auto_cast GAME_SCREEN_WIDTH,
|
||||
auto_cast GAME_SCREEN_HEIGHT,
|
||||
)
|
||||
rl.SetTextureFilter(game_render_buffer.texture, rl.TextureFilter.POINT) // Texture scale filter to use
|
||||
|
||||
if a.frame_timer > a.frame_length && !a.done {
|
||||
a.current_frame += 1
|
||||
a.frame_timer = 0
|
||||
|
||||
if a.current_frame == a.num_frames {
|
||||
if a.loop {
|
||||
a.current_frame = 0
|
||||
} else {
|
||||
a.current_frame += -1
|
||||
a.done = true
|
||||
}
|
||||
}
|
||||
player_animation = Animation {
|
||||
texture = load_texture_from_memory(player_spritesheet_sprite),
|
||||
num_frames = 2,
|
||||
frame_length = 0.5,
|
||||
loop = true,
|
||||
}
|
||||
}
|
||||
|
||||
draw_animation :: proc(a: Animation, pos: rl.Vector2) {
|
||||
width := f32(a.texture.width)
|
||||
height := f32(a.texture.height)
|
||||
|
||||
source := rl.Rectangle {
|
||||
x = f32(a.current_frame) * width / f32(a.num_frames),
|
||||
y = 0,
|
||||
width = width / f32(a.num_frames),
|
||||
height = height,
|
||||
tomato_animation = Animation {
|
||||
texture = load_texture_from_memory(tomato_spritesheet_sprite),
|
||||
num_frames = 4,
|
||||
frame_length = 0.1,
|
||||
loop = false,
|
||||
offset = {TILE_SIZE / 2, TILE_SIZE},
|
||||
}
|
||||
|
||||
if a.flip {
|
||||
source.width = -source.width
|
||||
}
|
||||
tomato_texture = load_texture_from_memory(tomato_item_sprite)
|
||||
sell_button_texture = load_texture_from_memory(sell_button_sprite)
|
||||
background_texture = load_texture_from_memory(background_sprite)
|
||||
tile_dirt_dry_texture = load_texture_from_memory(tile_dirt_dry_sprite)
|
||||
tile_dirt_wet_texture = load_texture_from_memory(tile_dirt_wet_sprite)
|
||||
pickup_sound = load_sound_from_memory(pickup_sound_data)
|
||||
|
||||
dest := rl.Rectangle {
|
||||
x = pos.x + a.offset.x,
|
||||
y = pos.y + a.offset.y,
|
||||
width = width / f32(a.num_frames),
|
||||
height = height,
|
||||
}
|
||||
|
||||
rl.DrawTexturePro(a.texture, source, dest, {dest.width / 2, dest.height}, 0, rl.WHITE)
|
||||
e := create_entity(
|
||||
Entity {
|
||||
pos = {GAME_SCREEN_WIDTH / 2, GAME_SCREEN_HEIGHT / 2},
|
||||
kind = .Player,
|
||||
data = PlayerData{animation = player_animation},
|
||||
},
|
||||
)
|
||||
player_handle = entity_to_handle(e^)
|
||||
}
|
||||
|
||||
Tile :: struct {
|
||||
id: int,
|
||||
pos: rl.Vector2,
|
||||
animation: Animation,
|
||||
}
|
||||
free_resources :: proc() {
|
||||
t.context_destroy(tween_ctx_f32)
|
||||
t.context_destroy(tween_ctx_vec2)
|
||||
|
||||
spawn_tile_under_mouse :: proc() {
|
||||
tile_position := get_tile_position(world_mouse)
|
||||
old_tile: bool
|
||||
for e in entities {
|
||||
if .Allocated not_in e.flags {continue}
|
||||
if e.kind == .Tile && e.pos == tile_position {
|
||||
old_tile = true
|
||||
}
|
||||
}
|
||||
if !old_tile {
|
||||
create_entity(
|
||||
Entity {
|
||||
pos = tile_position,
|
||||
kind = .Tile,
|
||||
data = TileData{has_plant = true, plant_id = 0, animation = tomato_animation},
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
rl.UnloadSound(pickup_sound)
|
||||
|
||||
get_tile_position :: proc(wpos: rl.Vector2) -> rl.Vector2 {
|
||||
return {math.floor(wpos.x / TILE_SIZE) * TILE_SIZE, math.floor(wpos.y / TILE_SIZE) * TILE_SIZE}
|
||||
}
|
||||
rl.UnloadTexture(tomato_texture)
|
||||
rl.UnloadTexture(sell_button_texture)
|
||||
rl.UnloadTexture(background_texture)
|
||||
rl.UnloadTexture(tile_dirt_dry_texture)
|
||||
rl.UnloadTexture(tile_dirt_wet_texture)
|
||||
|
||||
EntityKind :: enum {
|
||||
Player,
|
||||
Tile,
|
||||
Item,
|
||||
}
|
||||
|
||||
PlayerData :: struct {
|
||||
animation: Animation,
|
||||
}
|
||||
|
||||
ItemData :: struct {
|
||||
id: int,
|
||||
count: int,
|
||||
texture: rl.Texture2D,
|
||||
}
|
||||
|
||||
TileData :: struct {
|
||||
has_plant: bool,
|
||||
is_watered: bool,
|
||||
plant_id: int,
|
||||
animation: Animation,
|
||||
plant_grown: bool,
|
||||
}
|
||||
|
||||
EntityData :: union {
|
||||
PlayerData,
|
||||
TileData,
|
||||
ItemData,
|
||||
}
|
||||
|
||||
Entity :: struct {
|
||||
pos: rl.Vector2,
|
||||
kind: EntityKind,
|
||||
handle: EntityHandle,
|
||||
flags: bit_set[EntityFlags],
|
||||
data: EntityData,
|
||||
}
|
||||
latest_entity_handle: int
|
||||
|
||||
EntityHandle :: int
|
||||
EntityFlags :: enum {
|
||||
nil,
|
||||
Allocated,
|
||||
}
|
||||
|
||||
create_entity :: proc(entity: Entity) -> ^Entity {
|
||||
for &e in entities {
|
||||
if .Allocated not_in e.flags {
|
||||
e = entity
|
||||
e.flags = {.Allocated}
|
||||
latest_entity_handle += 1
|
||||
return &e
|
||||
}
|
||||
}
|
||||
assert(false, "Failed to allocate entity, not enough space!!!!")
|
||||
return nil
|
||||
}
|
||||
|
||||
destroy_entity :: proc(e: ^Entity) {
|
||||
e^ = Entity{}
|
||||
}
|
||||
|
||||
handle_to_entity :: proc(handle: EntityHandle) -> ^Entity {
|
||||
for &e in entities {
|
||||
if handle == e.handle && .Allocated in e.flags {
|
||||
return &e
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
update_entities :: proc() {
|
||||
for &e in entities {
|
||||
if .Allocated not_in e.flags {continue}
|
||||
|
||||
#partial switch &data in e.data {
|
||||
case TileData:
|
||||
update_tile(e, &data)
|
||||
case PlayerData:
|
||||
update_animation(&data.animation)
|
||||
case ItemData:
|
||||
//rl.DrawTextureV(data.texture, e.pos + {0, t * 3}, rl.WHITE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_tile :: proc(e: Entity, data: ^TileData) {
|
||||
update_animation(&data.animation)
|
||||
if data.has_plant && data.animation.done && data.plant_grown == false {
|
||||
data.plant_grown = true
|
||||
data.has_plant = false
|
||||
rl.PlaySound(pickup_sound)
|
||||
item := create_entity(
|
||||
Entity {
|
||||
pos = e.pos,
|
||||
kind = .Item,
|
||||
data = ItemData{id = data.plant_id, count = 3, texture = tomato_texture},
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
draw_entities :: proc() {
|
||||
for e in entities {
|
||||
if .Allocated not_in e.flags {continue}
|
||||
|
||||
switch &data in e.data {
|
||||
case TileData:
|
||||
draw_tile(e)
|
||||
case PlayerData:
|
||||
draw_player(e)
|
||||
case ItemData:
|
||||
draw_item(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
entity_to_handle :: proc(e: Entity) -> EntityHandle {
|
||||
return e.handle
|
||||
}
|
||||
|
||||
draw_player :: proc(e: Entity) {
|
||||
data, ok := e.data.(PlayerData)
|
||||
draw_animation(data.animation, e.pos)
|
||||
}
|
||||
draw_tile :: proc(e: Entity) {
|
||||
data, ok := e.data.(TileData)
|
||||
//rl.DrawRectangle(auto_cast e.pos.x, auto_cast e.pos.y, TILE_SIZE, TILE_SIZE, rl.BLACK)
|
||||
rl.DrawTextureV(tile_dirt_dry_texture, e.pos, rl.WHITE)
|
||||
if data.has_plant {
|
||||
draw_animation(data.animation, e.pos)
|
||||
}
|
||||
}
|
||||
draw_item :: proc(e: Entity) {
|
||||
data, ok := e.data.(ItemData)
|
||||
t := f32(math.sin(rl.GetTime() * 5))
|
||||
rl.DrawTextureV(data.texture, e.pos + {0, t * 3}, rl.WHITE)
|
||||
//draw_animation(data.animation, e.pos + {0, t * 3})
|
||||
rl.UnloadRenderTexture(game_render_buffer) // Unload render texture
|
||||
}
|
||||
|
|
|
|||
43
src/resources.odin
Normal file
43
src/resources.odin
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
package game
|
||||
|
||||
import rl "vendor:raylib"
|
||||
|
||||
pickup_sound_data: []u8 : #load("../assets/sounds/pickup_sound.mp3")
|
||||
|
||||
player_spritesheet_sprite: []u8 : #load("../assets/player.png")
|
||||
tomato_spritesheet_sprite: []u8 : #load("../assets/tomato.png")
|
||||
tomato_item_sprite: []u8 : #load("../assets/tomato_item.png")
|
||||
sell_button_sprite: []u8 : #load("../assets/sell_button.png")
|
||||
background_sprite: []u8 : #load("../assets/background.png")
|
||||
tile_dirt_dry_sprite: []u8 : #load("../assets/tile_dirt_dry.png")
|
||||
tile_dirt_wet_sprite: []u8 : #load("../assets/tile_dirt_wet.png")
|
||||
|
||||
load_texture_from_memory :: proc(data: []u8) -> (texture: rl.Texture2D) {
|
||||
img := rl.LoadImageFromMemory(".png", raw_data(data), auto_cast len(data))
|
||||
defer rl.UnloadImage(img)
|
||||
texture = rl.LoadTextureFromImage(img)
|
||||
return texture
|
||||
}
|
||||
|
||||
load_sound_from_memory :: proc(
|
||||
data: []u8,
|
||||
sound_extension: cstring = ".mp3",
|
||||
) -> (
|
||||
sound: rl.Sound,
|
||||
) {
|
||||
wav := rl.LoadWaveFromMemory(sound_extension, raw_data(data), auto_cast len(data))
|
||||
defer rl.UnloadWave(wav)
|
||||
sound = rl.LoadSoundFromWave(wav)
|
||||
return
|
||||
}
|
||||
|
||||
pickup_sound: rl.Sound
|
||||
|
||||
sell_button_texture: rl.Texture2D
|
||||
background_texture: rl.Texture2D
|
||||
tile_dirt_dry_texture: rl.Texture2D
|
||||
tile_dirt_wet_texture: rl.Texture2D
|
||||
tomato_texture: rl.Texture2D
|
||||
|
||||
player_animation: Animation
|
||||
tomato_animation: Animation
|
||||
34
src/tile.odin
Normal file
34
src/tile.odin
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
package game
|
||||
|
||||
import "core:math"
|
||||
import rl "vendor:raylib"
|
||||
|
||||
Tile :: struct {
|
||||
id: int,
|
||||
pos: rl.Vector2,
|
||||
animation: Animation,
|
||||
}
|
||||
|
||||
spawn_tile_under_mouse :: proc() {
|
||||
tile_position := get_tile_position(world_mouse)
|
||||
old_tile: bool
|
||||
for e in entities {
|
||||
if .Allocated not_in e.flags {continue}
|
||||
if e.kind == .Tile && e.pos == tile_position {
|
||||
old_tile = true
|
||||
}
|
||||
}
|
||||
if !old_tile {
|
||||
create_entity(
|
||||
Entity {
|
||||
pos = tile_position,
|
||||
kind = .Tile,
|
||||
data = TileData{has_plant = true, plant_id = 0, animation = tomato_animation},
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
get_tile_position :: proc(wpos: rl.Vector2) -> rl.Vector2 {
|
||||
return {math.floor(wpos.x / TILE_SIZE) * TILE_SIZE, math.floor(wpos.y / TILE_SIZE) * TILE_SIZE}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue