mirror of
https://github.com/doukutsu-rs/doukutsu-rs
synced 2025-11-26 14:17:08 +00:00
failed refactoring lol
This commit is contained in:
parent
ff5962d97e
commit
ccadb98a8a
|
|
@ -10,9 +10,12 @@ panic = 'abort'
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
byteorder = "1.3"
|
byteorder = "1.3"
|
||||||
|
gfx_device_gl = "0.16"
|
||||||
ggez = { git = "https://github.com/ggez/ggez", rev = "4f4bdebff463881c36325c7e10520c9a4fd8f75c" }
|
ggez = { git = "https://github.com/ggez/ggez", rev = "4f4bdebff463881c36325c7e10520c9a4fd8f75c" }
|
||||||
imgui = "0.4.0"
|
imgui = "0.4.0"
|
||||||
imgui-ext = "0.3.0"
|
imgui-ext = "0.3.0"
|
||||||
|
imgui-gfx-renderer = "0.4.0"
|
||||||
|
imgui-winit-support = {version = "0.4.0", default-features = false, features = ["winit-19"] }
|
||||||
image = {version = "0.22", default-features = false, features = ["png_codec", "pnm", "bmp"] }
|
image = {version = "0.22", default-features = false, features = ["png_codec", "pnm", "bmp"] }
|
||||||
itertools = "0.9.0"
|
itertools = "0.9.0"
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
|
|
@ -25,3 +28,4 @@ rodio = { version = "0.11", default-features = false, features = ["flac", "vorbi
|
||||||
strum = "0.18.0"
|
strum = "0.18.0"
|
||||||
strum_macros = "0.18.0"
|
strum_macros = "0.18.0"
|
||||||
owning_ref = "0.4.1"
|
owning_ref = "0.4.1"
|
||||||
|
winit = { version = "0.19.3" }
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
use ggez::{Context, GameResult};
|
use ggez::{Context, GameResult};
|
||||||
|
|
||||||
use crate::frame::Frame;
|
use crate::engine_constants::EngineConstants;
|
||||||
use crate::SharedGameState;
|
use crate::game_state::GameState;
|
||||||
|
use crate::GameContext;
|
||||||
|
|
||||||
pub trait GameEntity {
|
pub trait GameEntity {
|
||||||
fn tick(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult;
|
fn init(&mut self, _state: &GameState, _game_ctx: &mut GameContext, _ctx: &mut Context) -> GameResult { Ok(()) }
|
||||||
|
|
||||||
fn draw(&self, state: &mut SharedGameState, ctx: &mut Context, frame: &Frame) -> GameResult;
|
fn tick(&mut self, state: &GameState, constants: &EngineConstants, ctx: &mut Context) -> GameResult;
|
||||||
|
|
||||||
|
fn draw(&self, state: &GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
src/frame.rs
19
src/frame.rs
|
|
@ -1,6 +1,5 @@
|
||||||
use crate::player::Player;
|
use crate::player::Player;
|
||||||
use crate::stage::Stage;
|
use crate::stage::Stage;
|
||||||
use crate::SharedGameState;
|
|
||||||
|
|
||||||
pub struct Frame {
|
pub struct Frame {
|
||||||
pub x: isize,
|
pub x: isize,
|
||||||
|
|
@ -9,32 +8,32 @@ pub struct Frame {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Frame {
|
impl Frame {
|
||||||
pub fn update(&mut self, state: &SharedGameState, player: &Player, stage: &Stage) {
|
pub fn update(&mut self, player: &Player, stage: &Stage, canvas_size: (f32, f32)) {
|
||||||
if (stage.map.width - 1) * 16 < state.canvas_size.0 as usize {
|
if (stage.map.width - 1) * 16 < canvas_size.0 as usize {
|
||||||
self.x = -(((state.canvas_size.0 as isize - ((stage.map.width - 1) * 16) as isize) * 0x200) / 2);
|
self.x = -(((canvas_size.0 as isize - ((stage.map.width - 1) * 16) as isize) * 0x200) / 2);
|
||||||
} else {
|
} else {
|
||||||
self.x += (player.target_x - (state.canvas_size.0 as isize * 0x200 / 2) - self.x) / self.wait;
|
self.x += (player.target_x - (canvas_size.0 as isize * 0x200 / 2) - self.x) / self.wait;
|
||||||
|
|
||||||
if self.x < 0 {
|
if self.x < 0 {
|
||||||
self.x = 0;
|
self.x = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let max_x = (((stage.map.width as isize - 1) * 16) - state.canvas_size.0 as isize) * 0x200;
|
let max_x = (((stage.map.width as isize - 1) * 16) - canvas_size.0 as isize) * 0x200;
|
||||||
if self.x > max_x {
|
if self.x > max_x {
|
||||||
self.x = max_x;
|
self.x = max_x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stage.map.height - 1) * 16 < state.canvas_size.1 as usize {
|
if (stage.map.height - 1) * 16 < canvas_size.1 as usize {
|
||||||
self.y = -(((state.canvas_size.1 as isize - ((stage.map.height - 1) * 16) as isize) * 0x200) / 2);
|
self.y = -(((canvas_size.1 as isize - ((stage.map.height - 1) * 16) as isize) * 0x200) / 2);
|
||||||
} else {
|
} else {
|
||||||
self.y += (player.target_y - (state.canvas_size.1 as isize * 0x200 / 2) - self.y) / self.wait;
|
self.y += (player.target_y - (canvas_size.1 as isize * 0x200 / 2) - self.y) / self.wait;
|
||||||
|
|
||||||
if self.y < 0 {
|
if self.y < 0 {
|
||||||
self.y = 0;
|
self.y = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
let max_y = (((stage.map.height as isize - 1) * 16) - state.canvas_size.1 as isize) * 0x200;
|
let max_y = (((stage.map.height as isize - 1) * 16) - canvas_size.1 as isize) * 0x200;
|
||||||
if self.y > max_y {
|
if self.y > max_y {
|
||||||
self.y = max_y;
|
self.y = max_y;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
101
src/game_state.rs
Normal file
101
src/game_state.rs
Normal file
|
|
@ -0,0 +1,101 @@
|
||||||
|
use ggez::{Context, GameResult};
|
||||||
|
use log::info;
|
||||||
|
|
||||||
|
use crate::bitfield;
|
||||||
|
use crate::entity::GameEntity;
|
||||||
|
use crate::frame::Frame;
|
||||||
|
use crate::GameContext;
|
||||||
|
use crate::player::Player;
|
||||||
|
use crate::scene::game_scene::GameScene;
|
||||||
|
use crate::stage::Stage;
|
||||||
|
|
||||||
|
bitfield! {
|
||||||
|
pub struct KeyState(u16);
|
||||||
|
impl Debug;
|
||||||
|
pub left, set_left: 0;
|
||||||
|
pub right, set_right: 1;
|
||||||
|
pub up, set_up: 2;
|
||||||
|
pub down, set_down: 3;
|
||||||
|
pub map, set_map: 4;
|
||||||
|
pub jump, set_jump: 5;
|
||||||
|
pub fire, set_fire: 6;
|
||||||
|
pub weapon_next, set_weapon_next: 7;
|
||||||
|
pub weapon_prev, set_weapon_prev: 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitfield! {
|
||||||
|
pub struct GameFlags(u32);
|
||||||
|
impl Debug;
|
||||||
|
pub flag_x01, set_flag_x01: 0;
|
||||||
|
pub control_enabled, set_control_enabled: 1;
|
||||||
|
pub flag_x04, set_flag_x04: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct GameState {
|
||||||
|
pub tick: usize,
|
||||||
|
pub stage: Stage,
|
||||||
|
pub frame: Frame,
|
||||||
|
pub flags: GameFlags,
|
||||||
|
pub key_state: KeyState,
|
||||||
|
pub key_trigger: KeyState,
|
||||||
|
player: Player,
|
||||||
|
key_old: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GameState {
|
||||||
|
pub fn new(game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult<Self> {
|
||||||
|
Ok(Self {
|
||||||
|
tick: 0,
|
||||||
|
stage: Stage::empty(),
|
||||||
|
player: Player::new(&game_ctx.constants, ctx)?,
|
||||||
|
frame: Frame {
|
||||||
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
wait: 16,
|
||||||
|
},
|
||||||
|
flags: GameFlags(0),
|
||||||
|
key_state: KeyState(0),
|
||||||
|
key_trigger: KeyState(0),
|
||||||
|
key_old: 0,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn player(&self) -> &Player {
|
||||||
|
&self.player
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn player_mut(&mut self) -> &mut Player {
|
||||||
|
&mut self.player
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update_key_trigger(&mut self) {
|
||||||
|
let trigger = self.key_state.0 & (self.key_state.0 ^ self.key_old);
|
||||||
|
self.key_old = self.key_state.0;
|
||||||
|
self.key_trigger = KeyState(trigger);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn switch_to_stage(&mut self, id: usize, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
|
let stage = Stage::load(ctx, &game_ctx.base_path, &game_ctx.stages[id])?;
|
||||||
|
info!("Loaded stage: {}", stage.data.name);
|
||||||
|
info!("Map size: {}x{}", stage.map.width, stage.map.height);
|
||||||
|
|
||||||
|
game_ctx.next_scene = Some(Box::new(GameScene::new(self, game_ctx, ctx)?));
|
||||||
|
self.stage = stage;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn init(&mut self, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
|
self.tick = 0;
|
||||||
|
self.player = Player::new(&game_ctx.constants, ctx)?;
|
||||||
|
|
||||||
|
self.player.x = 700 * 0x200;
|
||||||
|
self.player.y = 1000 * 0x200;
|
||||||
|
|
||||||
|
self.flags.set_flag_x01(true);
|
||||||
|
self.flags.set_control_enabled(true);
|
||||||
|
|
||||||
|
//game_ctx.sound_manager.play_song(ctx)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/live_debugger.rs
Normal file
38
src/live_debugger.rs
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
use ggez::{Context, GameResult};
|
||||||
|
use imgui::{Condition, im_str, Window};
|
||||||
|
|
||||||
|
use crate::game_state::GameState;
|
||||||
|
use crate::GameContext;
|
||||||
|
|
||||||
|
pub struct LiveDebugger {
|
||||||
|
selected_item: i32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LiveDebugger {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
selected_item: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn run(&mut self, state: &mut GameState, game_ctx: &GameContext, ctx: &mut Context, ui: &mut imgui::Ui) -> GameResult {
|
||||||
|
Window::new(im_str!("Live Debugger"))
|
||||||
|
.size([300.0, 100.0], Condition::FirstUseEver)
|
||||||
|
.build(ui, || {
|
||||||
|
ui.text(format!(
|
||||||
|
"Player position: ({:.1},{:.1})",
|
||||||
|
state.player().x as f32 / 512.0,
|
||||||
|
state.player().y as f32 / 512.0,
|
||||||
|
));
|
||||||
|
});
|
||||||
|
|
||||||
|
Window::new(im_str!("Stages"))
|
||||||
|
.size([240.0, 320.0], Condition::FirstUseEver)
|
||||||
|
.build(ui, || {
|
||||||
|
ui.list_box(im_str!("Stage table"), &mut self.selected_item,
|
||||||
|
&[im_str!("Null"), im_str!("Egg Corridor")], 10);
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
139
src/main.rs
139
src/main.rs
|
|
@ -7,7 +7,7 @@ use std::path;
|
||||||
|
|
||||||
use ggez::{Context, ContextBuilder, event, filesystem, GameResult};
|
use ggez::{Context, ContextBuilder, event, filesystem, GameResult};
|
||||||
use ggez::conf::{WindowMode, WindowSetup};
|
use ggez::conf::{WindowMode, WindowSetup};
|
||||||
use ggez::event::{KeyCode, KeyMods};
|
use ggez::event::KeyCode;
|
||||||
use ggez::event::winit_event::{ElementState, Event, KeyboardInput, WindowEvent};
|
use ggez::event::winit_event::{ElementState, Event, KeyboardInput, WindowEvent};
|
||||||
use ggez::graphics;
|
use ggez::graphics;
|
||||||
use ggez::graphics::DrawParam;
|
use ggez::graphics::DrawParam;
|
||||||
|
|
@ -18,17 +18,25 @@ use log::*;
|
||||||
use pretty_env_logger::env_logger::Env;
|
use pretty_env_logger::env_logger::Env;
|
||||||
|
|
||||||
use crate::engine_constants::EngineConstants;
|
use crate::engine_constants::EngineConstants;
|
||||||
|
use crate::entity::GameEntity;
|
||||||
|
use crate::game_state::GameState;
|
||||||
|
use crate::game_state::KeyState;
|
||||||
|
use crate::live_debugger::LiveDebugger;
|
||||||
|
use crate::scene::game_scene::GameScene;
|
||||||
use crate::scene::loading_scene::LoadingScene;
|
use crate::scene::loading_scene::LoadingScene;
|
||||||
use crate::scene::Scene;
|
use crate::scene::Scene;
|
||||||
use crate::sound::SoundManager;
|
use crate::sound::SoundManager;
|
||||||
use crate::stage::StageData;
|
use crate::stage::{Stage, StageData};
|
||||||
use crate::texture_set::TextureSet;
|
use crate::texture_set::TextureSet;
|
||||||
|
use crate::ui::UI;
|
||||||
|
|
||||||
mod common;
|
mod common;
|
||||||
mod engine_constants;
|
mod engine_constants;
|
||||||
mod entity;
|
mod entity;
|
||||||
mod enemy;
|
mod enemy;
|
||||||
mod frame;
|
mod frame;
|
||||||
|
mod game_state;
|
||||||
|
mod live_debugger;
|
||||||
mod map;
|
mod map;
|
||||||
mod player;
|
mod player;
|
||||||
mod player_hit;
|
mod player_hit;
|
||||||
|
|
@ -37,40 +45,18 @@ mod stage;
|
||||||
mod sound;
|
mod sound;
|
||||||
mod text_script;
|
mod text_script;
|
||||||
mod texture_set;
|
mod texture_set;
|
||||||
|
mod ui;
|
||||||
bitfield! {
|
|
||||||
pub struct KeyState(u16);
|
|
||||||
impl Debug;
|
|
||||||
left, set_left: 0;
|
|
||||||
right, set_right: 1;
|
|
||||||
up, set_up: 2;
|
|
||||||
down, set_down: 3;
|
|
||||||
map, set_map: 4;
|
|
||||||
jump, set_jump: 5;
|
|
||||||
fire, set_fire: 6;
|
|
||||||
weapon_next, set_weapon_next: 7;
|
|
||||||
weapon_prev, set_weapon_prev: 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
bitfield! {
|
|
||||||
pub struct GameFlags(u32);
|
|
||||||
impl Debug;
|
|
||||||
pub flag_x01, set_flag_x01: 0;
|
|
||||||
pub control_enabled, set_control_enabled: 1;
|
|
||||||
pub flag_x04, set_flag_x04: 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Game {
|
struct Game {
|
||||||
scene: Option<Box<dyn Scene>>,
|
scene: Option<Box<dyn Scene>>,
|
||||||
state: SharedGameState,
|
state: Option<GameState>,
|
||||||
|
ctx: GameContext,
|
||||||
|
ui: UI,
|
||||||
scaled_matrix: ColumnMatrix4<f32>,
|
scaled_matrix: ColumnMatrix4<f32>,
|
||||||
def_matrix: ColumnMatrix4<f32>,
|
def_matrix: ColumnMatrix4<f32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SharedGameState {
|
pub struct GameContext {
|
||||||
pub flags: GameFlags,
|
|
||||||
pub key_state: KeyState,
|
|
||||||
pub key_trigger: KeyState,
|
|
||||||
pub texture_set: TextureSet,
|
pub texture_set: TextureSet,
|
||||||
pub base_path: String,
|
pub base_path: String,
|
||||||
pub stages: Vec<StageData>,
|
pub stages: Vec<StageData>,
|
||||||
|
|
@ -80,16 +66,6 @@ pub struct SharedGameState {
|
||||||
pub canvas_size: (f32, f32),
|
pub canvas_size: (f32, f32),
|
||||||
pub screen_size: (f32, f32),
|
pub screen_size: (f32, f32),
|
||||||
pub next_scene: Option<Box<dyn Scene>>,
|
pub next_scene: Option<Box<dyn Scene>>,
|
||||||
key_old: u16,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl SharedGameState {
|
|
||||||
pub fn update_key_trigger(&mut self) {
|
|
||||||
let mut trigger = self.key_state.0 ^ self.key_old;
|
|
||||||
trigger = self.key_state.0 & trigger;
|
|
||||||
self.key_old = self.key_state.0;
|
|
||||||
self.key_trigger = KeyState(trigger);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Game {
|
impl Game {
|
||||||
|
|
@ -112,14 +88,8 @@ impl Game {
|
||||||
|
|
||||||
let s = Game {
|
let s = Game {
|
||||||
scene: None,
|
scene: None,
|
||||||
scaled_matrix: DrawParam::new()
|
state: None,
|
||||||
.scale(Vector2::new(scale, scale))
|
ctx: GameContext {
|
||||||
.to_matrix(),
|
|
||||||
def_matrix: DrawParam::new().to_matrix(),
|
|
||||||
state: SharedGameState {
|
|
||||||
flags: GameFlags(0),
|
|
||||||
key_state: KeyState(0),
|
|
||||||
key_trigger: KeyState(0),
|
|
||||||
texture_set: TextureSet::new(base_path),
|
texture_set: TextureSet::new(base_path),
|
||||||
base_path: str!(base_path),
|
base_path: str!(base_path),
|
||||||
stages: Vec::new(),
|
stages: Vec::new(),
|
||||||
|
|
@ -129,16 +99,24 @@ impl Game {
|
||||||
screen_size,
|
screen_size,
|
||||||
canvas_size,
|
canvas_size,
|
||||||
next_scene: None,
|
next_scene: None,
|
||||||
key_old: 0,
|
|
||||||
},
|
},
|
||||||
|
ui: UI::new(ctx)?,
|
||||||
|
scaled_matrix: DrawParam::new()
|
||||||
|
.scale(Vector2::new(scale, scale))
|
||||||
|
.to_matrix(),
|
||||||
|
def_matrix: DrawParam::new().to_matrix(),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(s)
|
Ok(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, ctx: &mut Context) -> GameResult {
|
fn update(&mut self, ctx: &mut Context) -> GameResult {
|
||||||
if self.scene.is_some() {
|
if self.state.is_none() {
|
||||||
self.scene.as_mut().unwrap().tick(&mut self.state, ctx)?;
|
self.state = Some(GameState::new(&mut self.ctx, ctx)?);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.scene.is_some() && self.state.is_some() {
|
||||||
|
self.scene.as_mut().unwrap().tick(self.state.as_mut().unwrap(), &mut self.ctx, ctx)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
@ -148,23 +126,24 @@ impl Game {
|
||||||
graphics::set_transform(ctx, self.scaled_matrix);
|
graphics::set_transform(ctx, self.scaled_matrix);
|
||||||
graphics::apply_transformations(ctx)?;
|
graphics::apply_transformations(ctx)?;
|
||||||
|
|
||||||
if self.scene.is_some() {
|
if let (Some(scene), Some(state)) = (self.scene.as_mut(), self.state.as_mut()) {
|
||||||
self.scene.as_ref().unwrap().draw(&mut self.state, ctx)?;
|
scene.draw(state, &mut self.ctx, ctx)?;
|
||||||
|
|
||||||
graphics::set_transform(ctx, self.def_matrix);
|
graphics::set_transform(ctx, self.def_matrix);
|
||||||
graphics::apply_transformations(ctx)?;
|
graphics::apply_transformations(ctx)?;
|
||||||
self.scene.as_ref().unwrap().overlay_draw(&mut self.state, ctx)?;
|
|
||||||
|
self.ui.draw(state, &mut self.ctx, ctx, scene)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics::present(ctx)?;
|
graphics::present(ctx)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn key_down_event(&mut self, _ctx: &mut Context, key_code: KeyCode, _key_mod: KeyMods, repeat: bool) {
|
fn key_down_event(&mut self, _ctx: &mut Context, key_code: KeyCode, repeat: bool) {
|
||||||
if repeat { return; }
|
if repeat { return; }
|
||||||
|
|
||||||
// todo: proper keymaps?
|
// todo: proper keymaps?
|
||||||
let state = &mut self.state;
|
if let Some(state) = self.state.as_mut() {
|
||||||
match key_code {
|
match key_code {
|
||||||
KeyCode::Left => { state.key_state.set_left(true) }
|
KeyCode::Left => { state.key_state.set_left(true) }
|
||||||
KeyCode::Right => { state.key_state.set_right(true) }
|
KeyCode::Right => { state.key_state.set_right(true) }
|
||||||
|
|
@ -177,10 +156,11 @@ impl Game {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fn key_up_event(&mut self, _ctx: &mut Context, key_code: KeyCode, _key_mod: KeyMods) {
|
fn key_up_event(&mut self, _ctx: &mut Context, key_code: KeyCode) {
|
||||||
let state = &mut self.state;
|
if let Some(state) = self.state.as_mut() {
|
||||||
match key_code {
|
match key_code {
|
||||||
KeyCode::Left => { state.key_state.set_left(false) }
|
KeyCode::Left => { state.key_state.set_left(false) }
|
||||||
KeyCode::Right => { state.key_state.set_right(false) }
|
KeyCode::Right => { state.key_state.set_right(false) }
|
||||||
|
|
@ -193,6 +173,7 @@ impl Game {
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main() -> GameResult {
|
pub fn main() -> GameResult {
|
||||||
|
|
@ -215,40 +196,35 @@ pub fn main() -> GameResult {
|
||||||
.add_resource_path(resource_dir);
|
.add_resource_path(resource_dir);
|
||||||
|
|
||||||
let (ctx, event_loop) = &mut cb.build()?;
|
let (ctx, event_loop) = &mut cb.build()?;
|
||||||
let state = &mut Game::new(ctx)?;
|
let game = &mut Game::new(ctx)?;
|
||||||
state.state.next_scene = Some(Box::new(LoadingScene::new()));
|
game.ctx.next_scene = Some(Box::new(LoadingScene::new()));
|
||||||
|
|
||||||
while ctx.continuing {
|
while ctx.continuing {
|
||||||
ctx.timer_context.tick();
|
ctx.timer_context.tick();
|
||||||
event_loop.poll_events(|event| {
|
event_loop.poll_events(|event| {
|
||||||
ctx.process_event(&event);
|
ctx.process_event(&event);
|
||||||
|
game.ui.handle_events(ctx, &event);
|
||||||
|
|
||||||
match event {
|
match event {
|
||||||
Event::WindowEvent { event, .. } => match event {
|
Event::WindowEvent { event, .. } => match event {
|
||||||
WindowEvent::CloseRequested => event::quit(ctx),
|
WindowEvent::CloseRequested => event::quit(ctx),
|
||||||
WindowEvent::KeyboardInput {
|
WindowEvent::KeyboardInput {
|
||||||
input:
|
input: KeyboardInput {
|
||||||
KeyboardInput {
|
|
||||||
state: ElementState::Pressed,
|
|
||||||
virtual_keycode: Some(keycode),
|
virtual_keycode: Some(keycode),
|
||||||
modifiers,
|
state: input_state,
|
||||||
..
|
..
|
||||||
},
|
},
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
|
match input_state {
|
||||||
|
ElementState::Pressed => {
|
||||||
let repeat = keyboard::is_key_repeated(ctx);
|
let repeat = keyboard::is_key_repeated(ctx);
|
||||||
state.key_down_event(ctx, keycode, modifiers.into(), repeat);
|
game.key_down_event(ctx, keycode, repeat);
|
||||||
|
}
|
||||||
|
ElementState::Released => {
|
||||||
|
game.key_up_event(ctx, keycode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
WindowEvent::KeyboardInput {
|
|
||||||
input:
|
|
||||||
KeyboardInput {
|
|
||||||
state: ElementState::Released,
|
|
||||||
virtual_keycode: Some(keycode),
|
|
||||||
modifiers,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
..
|
|
||||||
} => {
|
|
||||||
state.key_up_event(ctx, keycode, modifiers.into());
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
},
|
},
|
||||||
|
|
@ -256,14 +232,13 @@ pub fn main() -> GameResult {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
state.update(ctx)?;
|
game.update(ctx)?;
|
||||||
state.draw(ctx)?;
|
game.draw(ctx)?;
|
||||||
|
|
||||||
if state.state.next_scene.is_some() {
|
if game.ctx.next_scene.is_some() && game.state.is_some() {
|
||||||
mem::swap(&mut state.scene, &mut state.state.next_scene);
|
mem::swap(&mut game.scene, &mut game.ctx.next_scene);
|
||||||
state.state.next_scene = None;
|
game.ctx.next_scene = None;
|
||||||
|
game.scene.as_mut().unwrap().init(game.state.as_mut().unwrap(), &mut game.ctx, ctx)?;
|
||||||
state.scene.as_mut().unwrap().init(&mut state.state, ctx)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ use num_traits::clamp;
|
||||||
|
|
||||||
use crate::bitfield;
|
use crate::bitfield;
|
||||||
use crate::common::{Direction, Rect};
|
use crate::common::{Direction, Rect};
|
||||||
use crate::engine_constants::PhysicsConsts;
|
use crate::engine_constants::{EngineConstants, PhysicsConsts};
|
||||||
use crate::entity::GameEntity;
|
use crate::entity::GameEntity;
|
||||||
use crate::frame::Frame;
|
use crate::game_state::GameState;
|
||||||
use crate::SharedGameState;
|
use crate::GameContext;
|
||||||
use crate::str;
|
use crate::str;
|
||||||
|
|
||||||
bitfield! {
|
bitfield! {
|
||||||
|
|
@ -103,12 +103,8 @@ pub struct Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
pub fn new(state: &mut SharedGameState, ctx: &mut Context) -> GameResult<Player> {
|
pub fn new(constants: &EngineConstants, ctx: &mut Context) -> GameResult<Player> {
|
||||||
let constants = &state.constants;
|
|
||||||
|
|
||||||
let tex_player_name = str!("MyChar");
|
let tex_player_name = str!("MyChar");
|
||||||
state.texture_set.ensure_texture_loaded(ctx, constants, &tex_player_name)?;
|
|
||||||
|
|
||||||
Ok(Player {
|
Ok(Player {
|
||||||
x: 0,
|
x: 0,
|
||||||
y: 0,
|
y: 0,
|
||||||
|
|
@ -146,7 +142,7 @@ impl Player {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick_normal(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult<()> {
|
fn tick_normal(&mut self, state: &GameState, constants: &EngineConstants) -> GameResult<()> {
|
||||||
if self.cond.cond_x02() {
|
if self.cond.cond_x02() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
@ -224,23 +220,23 @@ impl Player {
|
||||||
if state.key_state.up() {
|
if state.key_state.up() {
|
||||||
self.boost_sw = 2;
|
self.boost_sw = 2;
|
||||||
self.xm = 0;
|
self.xm = 0;
|
||||||
self.ym = state.constants.booster.b2_0_up;
|
self.ym = constants.booster.b2_0_up;
|
||||||
} else if state.key_state.left() {
|
} else if state.key_state.left() {
|
||||||
self.boost_sw = 2;
|
self.boost_sw = 2;
|
||||||
self.xm = 0;
|
self.xm = 0;
|
||||||
self.ym = state.constants.booster.b2_0_left;
|
self.ym = constants.booster.b2_0_left;
|
||||||
} else if state.key_state.right() {
|
} else if state.key_state.right() {
|
||||||
self.boost_sw = 2;
|
self.boost_sw = 2;
|
||||||
self.xm = 0;
|
self.xm = 0;
|
||||||
self.ym = state.constants.booster.b2_0_right;
|
self.ym = constants.booster.b2_0_right;
|
||||||
} else if state.key_state.down() {
|
} else if state.key_state.down() {
|
||||||
self.boost_sw = 2;
|
self.boost_sw = 2;
|
||||||
self.xm = 0;
|
self.xm = 0;
|
||||||
self.ym = state.constants.booster.b2_0_down;
|
self.ym = constants.booster.b2_0_down;
|
||||||
} else {
|
} else {
|
||||||
self.boost_sw = 2;
|
self.boost_sw = 2;
|
||||||
self.xm = 0;
|
self.xm = 0;
|
||||||
self.ym = state.constants.booster.b2_0_up_nokey;
|
self.ym = constants.booster.b2_0_up_nokey;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -455,11 +451,11 @@ impl Player {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick_stream(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult<()> {
|
fn tick_stream(&mut self, state: &GameState, constants: &EngineConstants) -> GameResult<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick_animation(&mut self, state: &SharedGameState) {
|
fn tick_animation(&mut self, state: &GameState, constants: &EngineConstants) {
|
||||||
if self.cond.cond_x02() {
|
if self.cond.cond_x02() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -524,10 +520,10 @@ impl Player {
|
||||||
|
|
||||||
match self.direction {
|
match self.direction {
|
||||||
Direction::Left => {
|
Direction::Left => {
|
||||||
self.anim_rect = state.constants.my_char.animations_left[self.anim_num];
|
self.anim_rect = constants.my_char.animations_left[self.anim_num];
|
||||||
}
|
}
|
||||||
Direction::Right => {
|
Direction::Right => {
|
||||||
self.anim_rect = state.constants.my_char.animations_right[self.anim_num];
|
self.anim_rect = constants.my_char.animations_right[self.anim_num];
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -537,7 +533,12 @@ impl Player {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameEntity for Player {
|
impl GameEntity for Player {
|
||||||
fn tick(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult<()> {
|
fn init(&mut self, state: &GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
|
game_ctx.texture_set.ensure_texture_loaded(ctx, &game_ctx.constants, &self.tex_player_name)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn tick(&mut self, state: &GameState, constants: &EngineConstants, ctx: &mut Context) -> GameResult {
|
||||||
if !self.cond.visible() {
|
if !self.cond.visible() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
@ -559,31 +560,31 @@ impl GameEntity for Player {
|
||||||
// AirProcess(); // todo
|
// AirProcess(); // todo
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tick_normal(state, ctx)?;
|
self.tick_normal(state, constants)?;
|
||||||
}
|
}
|
||||||
1 => {
|
1 => {
|
||||||
self.tick_stream(state, ctx)?;
|
self.tick_stream(state, constants)?;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.cond.set_cond_x20(false);
|
self.cond.set_cond_x20(false);
|
||||||
self.tick_animation(state);
|
self.tick_animation(state, constants);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, state: &mut SharedGameState, ctx: &mut Context, frame: &Frame) -> GameResult<()> {
|
fn draw(&self, state: &GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
if !self.cond.visible() || self.cond.cond_x02() {
|
if !self.cond.visible() || self.cond.cond_x02() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo draw weapon
|
// todo draw weapon
|
||||||
|
|
||||||
if let Some(batch) = state.texture_set.tex_map.get_mut(&self.tex_player_name) {
|
if let Some(batch) = game_ctx.texture_set.tex_map.get_mut(&self.tex_player_name) {
|
||||||
batch.add_rect(
|
batch.add_rect(
|
||||||
(((self.x - self.view.left as isize) / 0x200) - (frame.x / 0x200)) as f32,
|
(((self.x - self.view.left as isize) / 0x200) - (state.frame.x / 0x200)) as f32,
|
||||||
(((self.y - self.view.top as isize) / 0x200) - (frame.y / 0x200)) as f32,
|
(((self.y - self.view.top as isize) / 0x200) - (state.frame.y / 0x200)) as f32,
|
||||||
&self.anim_rect,
|
&self.anim_rect,
|
||||||
);
|
);
|
||||||
batch.draw(ctx)?;
|
batch.draw(ctx)?;
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,13 @@
|
||||||
use num_traits::clamp;
|
use num_traits::clamp;
|
||||||
|
|
||||||
|
use crate::game_state::GameState;
|
||||||
use crate::player::Player;
|
use crate::player::Player;
|
||||||
use crate::stage::Stage;
|
|
||||||
use crate::SharedGameState;
|
|
||||||
|
|
||||||
const OFF_X: &[isize; 4] = &[0, 1, 0, 1];
|
const OFF_X: &[isize; 4] = &[0, 1, 0, 1];
|
||||||
const OFF_Y: &[isize; 4] = &[0, 0, 1, 1];
|
const OFF_Y: &[isize; 4] = &[0, 0, 1, 1];
|
||||||
|
|
||||||
impl Player {
|
impl Player {
|
||||||
fn judge_hit_block(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_block(&mut self, x: isize, y: isize, state: &GameState) {
|
||||||
// left wall
|
// left wall
|
||||||
if (self.y - self.hit.top as isize) < (y * 0x10 + 4) * 0x200
|
if (self.y - self.hit.top as isize) < (y * 0x10 + 4) * 0x200
|
||||||
&& self.y + self.hit.bottom as isize > (y * 0x10 - 4) * 0x200
|
&& self.y + self.hit.bottom as isize > (y * 0x10 - 4) * 0x200
|
||||||
|
|
@ -82,7 +81,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn judge_hit_triangle_a(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_triangle_a(&mut self, x: isize, y: isize) {
|
||||||
if self.x < (x * 0x10 + 8) * 0x200
|
if self.x < (x * 0x10 + 8) * 0x200
|
||||||
&& self.x > (x * 0x10 - 8) * 0x200
|
&& self.x > (x * 0x10 - 8) * 0x200
|
||||||
&& (self.y - self.hit.top as isize) < (y * 0x10 * 0x200) - (self.x - x * 0x10 * 0x200) / 2 + 0x800
|
&& (self.y - self.hit.top as isize) < (y * 0x10 * 0x200) - (self.x - x * 0x10 * 0x200) / 2 + 0x800
|
||||||
|
|
@ -101,7 +100,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn judge_hit_triangle_b(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_triangle_b(&mut self, x: isize, y: isize) {
|
||||||
if self.x < (x * 0x10 + 8) * 0x200
|
if self.x < (x * 0x10 + 8) * 0x200
|
||||||
&& self.x > (x * 0x10 - 8) * 0x200
|
&& self.x > (x * 0x10 - 8) * 0x200
|
||||||
&& (self.y - self.hit.top as isize) < (y * 0x10 * 0x200) - (self.x - x * 0x10 * 0x200) / 2 - 0x800
|
&& (self.y - self.hit.top as isize) < (y * 0x10 * 0x200) - (self.x - x * 0x10 * 0x200) / 2 - 0x800
|
||||||
|
|
@ -120,7 +119,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn judge_hit_triangle_c(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_triangle_c(&mut self, x: isize, y: isize) {
|
||||||
if self.x < (x * 0x10 + 8) * 0x200
|
if self.x < (x * 0x10 + 8) * 0x200
|
||||||
&& self.x > (x * 0x10 - 8) * 0x200
|
&& self.x > (x * 0x10 - 8) * 0x200
|
||||||
&& (self.y - self.hit.top as isize) < (y * 0x10 * 0x200) + (self.x - x * 0x10 * 0x200) / 2 - 0x800
|
&& (self.y - self.hit.top as isize) < (y * 0x10 * 0x200) + (self.x - x * 0x10 * 0x200) / 2 - 0x800
|
||||||
|
|
@ -139,7 +138,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn judge_hit_triangle_d(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_triangle_d(&mut self, x: isize, y: isize) {
|
||||||
if (self.x < (x * 0x10 + 8) * 0x200)
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
||||||
&& (self.x > (x * 0x10 - 8) * 0x200)
|
&& (self.x > (x * 0x10 - 8) * 0x200)
|
||||||
&& (self.y - self.hit.top as isize) < (y * 0x10 * 0x200) + (self.x - x * 0x10 * 0x200) / 2 + 0x800
|
&& (self.y - self.hit.top as isize) < (y * 0x10 * 0x200) + (self.x - x * 0x10 * 0x200) / 2 + 0x800
|
||||||
|
|
@ -158,7 +157,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn judge_hit_triangle_e(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_triangle_e(&mut self, x: isize, y: isize) {
|
||||||
self.flags.set_flag_x10000(true);
|
self.flags.set_flag_x10000(true);
|
||||||
|
|
||||||
if (self.x < (x * 0x10 + 8) * 0x200)
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
||||||
|
|
@ -180,7 +179,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn judge_hit_triangle_f(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_triangle_f(&mut self, x: isize, y: isize) {
|
||||||
self.flags.set_flag_x20000(true);
|
self.flags.set_flag_x20000(true);
|
||||||
|
|
||||||
if (self.x < (x * 0x10 + 8) * 0x200)
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
||||||
|
|
@ -202,7 +201,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn judge_hit_triangle_g(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_triangle_g(&mut self, x: isize, y: isize) {
|
||||||
self.flags.set_flag_x40000(true);
|
self.flags.set_flag_x40000(true);
|
||||||
|
|
||||||
if (self.x < (x * 0x10 + 8) * 0x200)
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
||||||
|
|
@ -224,7 +223,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn judge_hit_triangle_h(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_triangle_h(&mut self, x: isize, y: isize) {
|
||||||
self.flags.set_flag_x80000(true);
|
self.flags.set_flag_x80000(true);
|
||||||
|
|
||||||
if (self.x < (x * 0x10 + 8) * 0x200)
|
if (self.x < (x * 0x10 + 8) * 0x200)
|
||||||
|
|
@ -246,7 +245,7 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn judge_hit_water(&mut self, state: &SharedGameState, x: isize, y: isize) {
|
fn judge_hit_water(&mut self, x: isize, y: isize) {
|
||||||
if (self.x - self.hit.right as isize) < (x * 0x10 + 5) * 0x200
|
if (self.x - self.hit.right as isize) < (x * 0x10 + 5) * 0x200
|
||||||
&& (self.x + self.hit.right as isize) > (x * 0x10 - 5) * 0x200
|
&& (self.x + self.hit.right as isize) > (x * 0x10 - 5) * 0x200
|
||||||
&& (self.y - self.hit.top as isize) < (y * 0x10 + 5) * 0x200
|
&& (self.y - self.hit.top as isize) < (y * 0x10 + 5) * 0x200
|
||||||
|
|
@ -255,55 +254,55 @@ impl Player {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tick_map_collisions(&mut self, state: &SharedGameState, stage: &Stage) {
|
pub fn tick_map_collisions(&mut self, state: &GameState) {
|
||||||
let x = clamp(self.x / 0x10 / 0x200, 0, stage.map.width as isize);
|
let x = clamp(self.x / 0x10 / 0x200, 0, state.stage.map.width as isize);
|
||||||
let y = clamp(self.y / 0x10 / 0x200, 0, stage.map.height as isize);
|
let y = clamp(self.y / 0x10 / 0x200, 0, state.stage.map.height as isize);
|
||||||
|
|
||||||
for (ox, oy) in OFF_X.iter().zip(OFF_Y) {
|
for (ox, oy) in OFF_X.iter().zip(OFF_Y) {
|
||||||
let attrib = stage.map.get_attribute((x + *ox) as usize, (y + *oy) as usize);
|
let attrib = state.stage.map.get_attribute((x + *ox) as usize, (y + *oy) as usize);
|
||||||
match attrib {
|
match attrib {
|
||||||
// Block
|
// Block
|
||||||
0x02 | 0x60 => {
|
0x02 | 0x60 => {
|
||||||
self.judge_hit_water(state, x + *ox, y + *oy);
|
self.judge_hit_water(x + *ox, y + *oy);
|
||||||
}
|
}
|
||||||
0x05 | 0x41 | 0x43 | 0x46 => {
|
0x05 | 0x41 | 0x43 | 0x46 => {
|
||||||
self.judge_hit_block(state, x + *ox, y + *oy);
|
self.judge_hit_block(x + *ox, y + *oy, state);
|
||||||
}
|
}
|
||||||
0x50 | 0x70 => {
|
0x50 | 0x70 => {
|
||||||
self.judge_hit_triangle_a(state, x + *ox, y + *oy);
|
self.judge_hit_triangle_a(x + *ox, y + *oy);
|
||||||
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
if attrib & 0x20 != 0 { self.judge_hit_water(x + *ox, y + *oy); }
|
||||||
}
|
}
|
||||||
0x51 | 0x71 => {
|
0x51 | 0x71 => {
|
||||||
self.judge_hit_triangle_b(state, x + *ox, y + *oy);
|
self.judge_hit_triangle_b(x + *ox, y + *oy);
|
||||||
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
if attrib & 0x20 != 0 { self.judge_hit_water(x + *ox, y + *oy); }
|
||||||
}
|
}
|
||||||
0x52 | 0x72 => {
|
0x52 | 0x72 => {
|
||||||
self.judge_hit_triangle_c(state, x + *ox, y + *oy);
|
self.judge_hit_triangle_c(x + *ox, y + *oy);
|
||||||
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
if attrib & 0x20 != 0 { self.judge_hit_water(x + *ox, y + *oy); }
|
||||||
}
|
}
|
||||||
0x53 | 0x73 => {
|
0x53 | 0x73 => {
|
||||||
self.judge_hit_triangle_d(state, x + *ox, y + *oy);
|
self.judge_hit_triangle_d(x + *ox, y + *oy);
|
||||||
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
if attrib & 0x20 != 0 { self.judge_hit_water(x + *ox, y + *oy); }
|
||||||
}
|
}
|
||||||
0x54 | 0x74 => {
|
0x54 | 0x74 => {
|
||||||
self.judge_hit_triangle_e(state, x + *ox, y + *oy);
|
self.judge_hit_triangle_e(x + *ox, y + *oy);
|
||||||
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
if attrib & 0x20 != 0 { self.judge_hit_water(x + *ox, y + *oy); }
|
||||||
}
|
}
|
||||||
0x55 | 0x75 => {
|
0x55 | 0x75 => {
|
||||||
self.judge_hit_triangle_f(state, x + *ox, y + *oy);
|
self.judge_hit_triangle_f(x + *ox, y + *oy);
|
||||||
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
if attrib & 0x20 != 0 { self.judge_hit_water(x + *ox, y + *oy); }
|
||||||
}
|
}
|
||||||
0x56 | 0x76 => {
|
0x56 | 0x76 => {
|
||||||
self.judge_hit_triangle_g(state, x + *ox, y + *oy);
|
self.judge_hit_triangle_g(x + *ox, y + *oy);
|
||||||
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
if attrib & 0x20 != 0 { self.judge_hit_water(x + *ox, y + *oy); }
|
||||||
}
|
}
|
||||||
0x57 | 0x77 => {
|
0x57 | 0x77 => {
|
||||||
self.judge_hit_triangle_h(state, x + *ox, y + *oy);
|
self.judge_hit_triangle_h(x + *ox, y + *oy);
|
||||||
if attrib & 0x20 != 0 { self.judge_hit_water(state, x + *ox, y + *oy); }
|
if attrib & 0x20 != 0 { self.judge_hit_water(x + *ox, y + *oy); }
|
||||||
}
|
}
|
||||||
0x61 => {
|
0x61 => {
|
||||||
self.judge_hit_water(state, x + *ox, y + *oy);
|
self.judge_hit_water(x + *ox, y + *oy);
|
||||||
self.judge_hit_block(state, x + *ox, y + *oy);
|
self.judge_hit_block(x + *ox, y + *oy, state);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,18 @@
|
||||||
use ggez::{Context, GameResult};
|
use ggez::{Context, GameResult};
|
||||||
|
use ggez::GameError::EventLoopError;
|
||||||
use ggez::nalgebra::clamp;
|
use ggez::nalgebra::clamp;
|
||||||
use log::info;
|
|
||||||
use num_traits::abs;
|
|
||||||
|
|
||||||
use crate::common::Rect;
|
use crate::common::Rect;
|
||||||
use crate::entity::GameEntity;
|
use crate::entity::GameEntity;
|
||||||
use crate::frame::Frame;
|
use crate::game_state::GameState;
|
||||||
use crate::player::Player;
|
use crate::GameContext;
|
||||||
use crate::scene::Scene;
|
use crate::scene::Scene;
|
||||||
use crate::SharedGameState;
|
use crate::stage::BackgroundType;
|
||||||
use crate::stage::{BackgroundType, Stage};
|
|
||||||
use crate::str;
|
use crate::str;
|
||||||
|
use crate::live_debugger::LiveDebugger;
|
||||||
|
|
||||||
pub struct GameScene {
|
pub struct GameScene {
|
||||||
pub tick: usize,
|
debugger: LiveDebugger,
|
||||||
pub stage: Stage,
|
|
||||||
pub frame: Frame,
|
|
||||||
pub player: Player,
|
|
||||||
tex_tileset_name: String,
|
tex_tileset_name: String,
|
||||||
tex_background_name: String,
|
tex_background_name: String,
|
||||||
tex_hud_name: String,
|
tex_hud_name: String,
|
||||||
|
|
@ -38,28 +34,17 @@ pub enum Alignment {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameScene {
|
impl GameScene {
|
||||||
pub fn new(state: &mut SharedGameState, ctx: &mut Context, id: usize) -> GameResult<Self> {
|
pub fn new(state: &GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult<Self> {
|
||||||
let stage = Stage::load(ctx, &state.base_path, &state.stages[id])?;
|
let tex_tileset_name = str!(["Stage/", &state.stage.data.tileset.filename()].join(""));
|
||||||
info!("Loaded stage: {}", stage.data.name);
|
let tex_background_name = state.stage.data.background.filename();
|
||||||
info!("Map size: {}x{}", stage.map.width, stage.map.height);
|
|
||||||
|
|
||||||
let tex_tileset_name = ["Stage/", &stage.data.tileset.filename()].join("");
|
|
||||||
let tex_background_name = stage.data.background.filename();
|
|
||||||
let tex_hud_name = str!("TextBox");
|
let tex_hud_name = str!("TextBox");
|
||||||
|
|
||||||
state.texture_set.ensure_texture_loaded(ctx, &state.constants, &tex_tileset_name)?;
|
game_ctx.texture_set.ensure_texture_loaded(ctx, &game_ctx.constants, &tex_tileset_name)?;
|
||||||
state.texture_set.ensure_texture_loaded(ctx, &state.constants, &tex_background_name)?;
|
game_ctx.texture_set.ensure_texture_loaded(ctx, &game_ctx.constants, &tex_background_name)?;
|
||||||
state.texture_set.ensure_texture_loaded(ctx, &state.constants, &tex_hud_name)?;
|
game_ctx.texture_set.ensure_texture_loaded(ctx, &game_ctx.constants, &tex_hud_name)?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
tick: 0,
|
debugger: LiveDebugger::new(),
|
||||||
stage,
|
|
||||||
player: Player::new(state, ctx)?,
|
|
||||||
frame: Frame {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
wait: 16,
|
|
||||||
},
|
|
||||||
tex_tileset_name,
|
tex_tileset_name,
|
||||||
tex_background_name,
|
tex_background_name,
|
||||||
tex_hud_name,
|
tex_hud_name,
|
||||||
|
|
@ -68,8 +53,8 @@ impl GameScene {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_number(&self, x: f32, y: f32, val: usize, align: Alignment, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn draw_number(&self, x: f32, y: f32, val: usize, align: Alignment, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
let set = state.texture_set.tex_map.get_mut(&self.tex_hud_name);
|
let set = game_ctx.texture_set.tex_map.get_mut(&self.tex_hud_name);
|
||||||
if set.is_none() {
|
if set.is_none() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
@ -87,12 +72,11 @@ impl GameScene {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_hud(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn draw_hud(&self, state: &GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
let set = state.texture_set.tex_map.get_mut(&self.tex_hud_name);
|
let set = game_ctx.texture_set.tex_map.get_mut(&self.tex_hud_name);
|
||||||
if set.is_none() {
|
if set.is_none() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let batch = set.unwrap();
|
let batch = set.unwrap();
|
||||||
|
|
||||||
// todo: max ammo display
|
// todo: max ammo display
|
||||||
|
|
@ -114,30 +98,30 @@ impl GameScene {
|
||||||
&Rect::<usize>::new_size(0, 40, 64, 8));
|
&Rect::<usize>::new_size(0, 40, 64, 8));
|
||||||
// bar
|
// bar
|
||||||
batch.add_rect(40.0, 40.0,
|
batch.add_rect(40.0, 40.0,
|
||||||
&Rect::<usize>::new_size(0, 32, ((self.life_bar as usize * 40) / self.player.max_life as usize) - 1, 8));
|
&Rect::<usize>::new_size(0, 32, ((self.life_bar as usize * 40) / state.player().max_life as usize) - 1, 8));
|
||||||
// life
|
// life
|
||||||
batch.add_rect(40.0, 40.0,
|
batch.add_rect(40.0, 40.0,
|
||||||
&Rect::<usize>::new_size(0, 24, ((self.player.life as usize * 40) / self.player.max_life as usize) - 1, 8));
|
&Rect::<usize>::new_size(0, 24, ((state.player().life as usize * 40) / state.player().max_life as usize) - 1, 8));
|
||||||
|
|
||||||
batch.draw(ctx)?;
|
batch.draw(ctx)?;
|
||||||
|
|
||||||
self.draw_number(40.0, 40.0, self.life_bar as usize, Alignment::Right, state, ctx)?;
|
self.draw_number(40.0, 40.0, self.life_bar as usize, Alignment::Right, game_ctx, ctx)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_background(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn draw_background(&self, state: &GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
let set = state.texture_set.tex_map.get_mut(&self.tex_background_name);
|
let set = game_ctx.texture_set.tex_map.get_mut(&self.tex_background_name);
|
||||||
if set.is_none() {
|
if set.is_none() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
let batch = set.unwrap();
|
let batch = set.unwrap();
|
||||||
|
|
||||||
match self.stage.data.background_type {
|
match state.stage.data.background_type {
|
||||||
BackgroundType::Stationary => {
|
BackgroundType::Stationary => {
|
||||||
let count_x = state.canvas_size.0 as usize / batch.width() + 1;
|
let count_x = game_ctx.canvas_size.0 as usize / batch.width() + 1;
|
||||||
let count_y = state.canvas_size.1 as usize / batch.height() + 1;
|
let count_y = game_ctx.canvas_size.1 as usize / batch.height() + 1;
|
||||||
|
|
||||||
for y in 0..count_y {
|
for y in 0..count_y {
|
||||||
for x in 0..count_x {
|
for x in 0..count_x {
|
||||||
|
|
@ -146,11 +130,11 @@ impl GameScene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BackgroundType::MoveDistant => {
|
BackgroundType::MoveDistant => {
|
||||||
let off_x = self.frame.x as usize / 2 % (batch.width() * 0x200);
|
let off_x = state.frame.x as usize / 2 % (batch.width() * 0x200);
|
||||||
let off_y = self.frame.y as usize / 2 % (batch.height() * 0x200);
|
let off_y = state.frame.y as usize / 2 % (batch.height() * 0x200);
|
||||||
|
|
||||||
let count_x = state.canvas_size.0 as usize / batch.width() + 2;
|
let count_x = game_ctx.canvas_size.0 as usize / batch.width() + 2;
|
||||||
let count_y = state.canvas_size.1 as usize / batch.height() + 2;
|
let count_y = game_ctx.canvas_size.1 as usize / batch.height() + 2;
|
||||||
|
|
||||||
for y in 0..count_y {
|
for y in 0..count_y {
|
||||||
for x in 0..count_x {
|
for x in 0..count_x {
|
||||||
|
|
@ -164,27 +148,27 @@ impl GameScene {
|
||||||
BackgroundType::Black => {}
|
BackgroundType::Black => {}
|
||||||
BackgroundType::Autoscroll => {}
|
BackgroundType::Autoscroll => {}
|
||||||
BackgroundType::OutsideWind | BackgroundType::Outside => {
|
BackgroundType::OutsideWind | BackgroundType::Outside => {
|
||||||
let offset = (self.tick % 640) as isize;
|
let offset = (state.tick % 640) as isize;
|
||||||
|
|
||||||
batch.add_rect(((state.canvas_size.0 - 320.0) / 2.0).floor(), 0.0,
|
batch.add_rect(((game_ctx.canvas_size.0 - 320.0) / 2.0).floor(), 0.0,
|
||||||
&Rect::<usize>::new_size(0, 0, 320, 88));
|
&Rect::<usize>::new_size(0, 0, 320, 88));
|
||||||
|
|
||||||
for x in ((-offset / 2)..(state.canvas_size.0 as isize)).step_by(320) {
|
for x in ((-offset / 2)..(game_ctx.canvas_size.0 as isize)).step_by(320) {
|
||||||
batch.add_rect(x as f32, 88.0,
|
batch.add_rect(x as f32, 88.0,
|
||||||
&Rect::<usize>::new_size(0, 88, 320, 35));
|
&Rect::<usize>::new_size(0, 88, 320, 35));
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in ((-offset % 320)..(state.canvas_size.0 as isize)).step_by(320) {
|
for x in ((-offset % 320)..(game_ctx.canvas_size.0 as isize)).step_by(320) {
|
||||||
batch.add_rect(x as f32, 123.0,
|
batch.add_rect(x as f32, 123.0,
|
||||||
&Rect::<usize>::new_size(0, 123, 320, 23));
|
&Rect::<usize>::new_size(0, 123, 320, 23));
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in ((-offset * 2)..(state.canvas_size.0 as isize)).step_by(320) {
|
for x in ((-offset * 2)..(game_ctx.canvas_size.0 as isize)).step_by(320) {
|
||||||
batch.add_rect(x as f32, 146.0,
|
batch.add_rect(x as f32, 146.0,
|
||||||
&Rect::<usize>::new_size(0, 146, 320, 30));
|
&Rect::<usize>::new_size(0, 146, 320, 30));
|
||||||
}
|
}
|
||||||
|
|
||||||
for x in ((-offset * 4)..(state.canvas_size.0 as isize)).step_by(320) {
|
for x in ((-offset * 4)..(game_ctx.canvas_size.0 as isize)).step_by(320) {
|
||||||
batch.add_rect(x as f32, 176.0,
|
batch.add_rect(x as f32, 176.0,
|
||||||
&Rect::<usize>::new_size(0, 176, 320, 64));
|
&Rect::<usize>::new_size(0, 176, 320, 64));
|
||||||
}
|
}
|
||||||
|
|
@ -196,34 +180,34 @@ impl GameScene {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw_tiles(&self, state: &mut SharedGameState, ctx: &mut Context, layer: TileLayer) -> GameResult {
|
fn draw_tiles(&self, layer: TileLayer, state: &GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
if let Some(batch) = state.texture_set.tex_map.get_mut(&self.tex_tileset_name) {
|
if let Some(batch) = game_ctx.texture_set.tex_map.get_mut(&self.tex_tileset_name) {
|
||||||
let mut rect = Rect::<usize>::new(0, 0, 16, 16);
|
let mut rect = Rect::<usize>::new(0, 0, 16, 16);
|
||||||
|
|
||||||
let tile_start_x = clamp(self.frame.x / 0x200 / 16, 0, self.stage.map.width as isize) as usize;
|
let tile_start_x = clamp(state.frame.x / 0x200 / 16, 0, state.stage.map.width as isize) as usize;
|
||||||
let tile_start_y = clamp(self.frame.y / 0x200 / 16, 0, self.stage.map.height as isize) as usize;
|
let tile_start_y = clamp(state.frame.y / 0x200 / 16, 0, state.stage.map.height as isize) as usize;
|
||||||
let tile_end_x = clamp((self.frame.x / 0x200 + 8 + state.canvas_size.0 as isize) / 16 + 1, 0, self.stage.map.width as isize) as usize;
|
let tile_end_x = clamp((state.frame.x / 0x200 + 8 + game_ctx.canvas_size.0 as isize) / 16 + 1, 0, state.stage.map.width as isize) as usize;
|
||||||
let tile_end_y = clamp((self.frame.y / 0x200 + 8 + state.canvas_size.1 as isize) / 16 + 1, 0, self.stage.map.height as isize) as usize;
|
let tile_end_y = clamp((state.frame.y / 0x200 + 8 + game_ctx.canvas_size.1 as isize) / 16 + 1, 0, state.stage.map.height as isize) as usize;
|
||||||
|
|
||||||
for y in tile_start_y..tile_end_y {
|
for y in tile_start_y..tile_end_y {
|
||||||
for x in tile_start_x..tile_end_x {
|
for x in tile_start_x..tile_end_x {
|
||||||
let tile = *self.stage.map.tiles
|
let tile = *state.stage.map.tiles
|
||||||
.get((y * self.stage.map.width) + x)
|
.get((y * state.stage.map.width) + x)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
match layer {
|
match layer {
|
||||||
TileLayer::Background => {
|
TileLayer::Background => {
|
||||||
if self.stage.map.attrib[tile as usize] >= 0x20 {
|
if state.stage.map.attrib[tile as usize] >= 0x20 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TileLayer::Foreground => {
|
TileLayer::Foreground => {
|
||||||
let attr = self.stage.map.attrib[tile as usize];
|
let attr = state.stage.map.attrib[tile as usize];
|
||||||
if attr < 0x40 || attr >= 0x80 {
|
if attr < 0x40 || attr >= 0x80 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
TileLayer::All => {}
|
||||||
}
|
}
|
||||||
|
|
||||||
rect.left = (tile as usize % 16) * 16;
|
rect.left = (tile as usize % 16) * 16;
|
||||||
|
|
@ -231,7 +215,7 @@ impl GameScene {
|
||||||
rect.right = rect.left + 16;
|
rect.right = rect.left + 16;
|
||||||
rect.bottom = rect.top + 16;
|
rect.bottom = rect.top + 16;
|
||||||
|
|
||||||
batch.add_rect((x as f32 * 16.0 - 8.0) - (self.frame.x / 0x200) as f32, (y as f32 * 16.0 - 8.0) - (self.frame.y / 0x200) as f32, &rect);
|
batch.add_rect((x as f32 * 16.0 - 8.0) - (state.frame.x / 0x200) as f32, (y as f32 * 16.0 - 8.0) - (state.frame.y / 0x200) as f32, &rect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -242,35 +226,30 @@ impl GameScene {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene for GameScene {
|
impl Scene for GameScene {
|
||||||
fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn init(&mut self, state: &mut GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
state.sound_manager.play_song(ctx)?;
|
|
||||||
self.player.x = 700 * 0x200;
|
|
||||||
self.player.y = 1000 * 0x200;
|
|
||||||
//self.player.equip.set_booster_2_0(true);
|
|
||||||
state.flags.set_flag_x01(true);
|
|
||||||
state.flags.set_control_enabled(true);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn tick(&mut self, state: &mut GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
state.update_key_trigger();
|
state.update_key_trigger();
|
||||||
|
|
||||||
if state.flags.flag_x01() {
|
/*if state.flags.flag_x01() {
|
||||||
self.player.tick(state, ctx)?;
|
state.player_mut().tick(state, &game_ctx.constants, ctx)?;
|
||||||
|
state.player_mut().flags.0 = 0;
|
||||||
|
state.player_mut().tick_map_collisions(state);
|
||||||
|
state.frame.update(state.player(), &state.stage, game_ctx.canvas_size);
|
||||||
|
}*/
|
||||||
|
|
||||||
self.player.flags.0 = 0;
|
state.tick = state.tick.wrapping_add(1);
|
||||||
self.player.tick_map_collisions(state, &self.stage);
|
//state.tick(game_ctx, ctx)?;
|
||||||
|
|
||||||
self.frame.update(state, &self.player, &self.stage);
|
|
||||||
}
|
|
||||||
|
|
||||||
if state.flags.control_enabled() {
|
if state.flags.control_enabled() {
|
||||||
// update health bar
|
// update health bar
|
||||||
if self.life_bar < self.player.life as usize {
|
if self.life_bar < state.player().life as usize {
|
||||||
self.life_bar = self.player.life as usize;
|
self.life_bar = state.player().life as usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.life_bar > self.player.life as usize {
|
if self.life_bar > state.player().life as usize {
|
||||||
self.life_bar_count += 1;
|
self.life_bar_count += 1;
|
||||||
if self.life_bar_count > 30 {
|
if self.life_bar_count > 30 {
|
||||||
self.life_bar -= 1;
|
self.life_bar -= 1;
|
||||||
|
|
@ -280,20 +259,21 @@ impl Scene for GameScene {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tick = self.tick.wrapping_add(1);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn draw(&self, state: &GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
self.draw_background(state, ctx)?;
|
self.draw_background(state, game_ctx, ctx)?;
|
||||||
self.draw_tiles(state, ctx, TileLayer::Background)?;
|
self.draw_tiles(TileLayer::Background, state, game_ctx, ctx)?;
|
||||||
self.player.draw(state, ctx, &self.frame)?;
|
state.player().draw(state, game_ctx, ctx)?;
|
||||||
self.draw_tiles(state, ctx, TileLayer::Foreground)?;
|
self.draw_tiles(TileLayer::Foreground, state, game_ctx, ctx)?;
|
||||||
|
self.draw_hud(state, game_ctx, ctx)?;
|
||||||
|
|
||||||
self.draw_hud(state, ctx)?;
|
Ok(())
|
||||||
self.draw_number(16.0, 50.0, abs(self.player.x) as usize, Alignment::Left, state, ctx)?;
|
}
|
||||||
self.draw_number(16.0, 58.0, abs(self.player.y) as usize, Alignment::Left, state, ctx)?;
|
|
||||||
|
|
||||||
|
fn overlay_draw(&mut self, state: &mut GameState, game_ctx: &mut GameContext, ctx: &mut Context, ui: &mut imgui::Ui) -> GameResult {
|
||||||
|
self.debugger.run(state, game_ctx, ctx, ui)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
use ggez::{Context, GameResult};
|
use ggez::{Context, GameResult};
|
||||||
|
|
||||||
use crate::scene::game_scene::GameScene;
|
use crate::game_state::GameState;
|
||||||
|
use crate::GameContext;
|
||||||
use crate::scene::Scene;
|
use crate::scene::Scene;
|
||||||
use crate::SharedGameState;
|
|
||||||
use crate::stage::StageData;
|
use crate::stage::StageData;
|
||||||
|
|
||||||
pub struct LoadingScene {
|
pub struct LoadingScene {
|
||||||
|
|
@ -18,30 +18,32 @@ impl LoadingScene {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Scene for LoadingScene {
|
impl Scene for LoadingScene {
|
||||||
fn init(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn init(&mut self, state: &mut GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
state.texture_set.ensure_texture_loaded(ctx, &state.constants, "Loading")?;
|
game_ctx.texture_set.ensure_texture_loaded(ctx, &game_ctx.constants, "Loading")?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tick(&mut self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn tick(&mut self, state: &mut GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
// deferred to let the loading image draw
|
// deferred to let the loading image draw
|
||||||
if self.tick == 1 {
|
if self.tick == 1 {
|
||||||
let stages = StageData::load_stage_table(ctx, &state.base_path)?;
|
let stages = StageData::load_stage_table(ctx, &game_ctx.base_path)?;
|
||||||
state.stages = stages;
|
game_ctx.stages = stages;
|
||||||
state.next_scene = Some(Box::new(GameScene::new(state, ctx, 53)?));
|
} else if self.tick == 2 {
|
||||||
|
state.init(game_ctx, ctx)?;
|
||||||
|
state.switch_to_stage(53, game_ctx, ctx)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.tick += 1;
|
self.tick += 1;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn draw(&self, state: &mut SharedGameState, ctx: &mut Context) -> GameResult {
|
fn draw(&self, state: &GameState, game_ctx: &mut GameContext, ctx: &mut Context) -> GameResult {
|
||||||
let loading = state.texture_set.tex_map.get_mut("Loading");
|
let loading = game_ctx.texture_set.tex_map.get_mut("Loading");
|
||||||
|
|
||||||
if loading.is_some() {
|
if loading.is_some() {
|
||||||
let img = loading.unwrap();
|
let img = loading.unwrap();
|
||||||
img.add(((state.canvas_size.0 - img.width() as f32) / 2.0).floor(),
|
img.add(((game_ctx.canvas_size.0 - img.width() as f32) / 2.0).floor(),
|
||||||
((state.canvas_size.1 - img.height() as f32) / 2.0).floor());
|
((game_ctx.canvas_size.1 - img.height() as f32) / 2.0).floor());
|
||||||
img.draw(ctx)?;
|
img.draw(ctx)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
use ggez::{Context, GameResult};
|
use ggez::{Context, GameResult};
|
||||||
|
|
||||||
use crate::SharedGameState;
|
use crate::GameContext;
|
||||||
|
use crate::game_state::GameState;
|
||||||
|
|
||||||
pub mod game_scene;
|
pub mod game_scene;
|
||||||
pub mod loading_scene;
|
pub mod loading_scene;
|
||||||
|
|
||||||
pub trait Scene {
|
pub trait Scene {
|
||||||
fn init(&mut self, _state: &mut SharedGameState, _ctx: &mut Context) -> GameResult { Ok(()) }
|
fn init(&mut self, _state: &mut GameState, _game_ctx: &mut GameContext, _ctx: &mut Context) -> GameResult { Ok(()) }
|
||||||
|
|
||||||
fn tick(&mut self, _state: &mut SharedGameState, _ctx: &mut Context) -> GameResult { Ok(()) }
|
fn tick(&mut self, _state: &mut GameState, _game_ctx: &mut GameContext, _ctx: &mut Context) -> GameResult { Ok(()) }
|
||||||
|
|
||||||
fn draw(&self, _state: &mut SharedGameState, _ctx: &mut Context) -> GameResult { Ok(()) }
|
fn draw(&self, _state: &GameState, _game_ctx: &mut GameContext, _ctx: &mut Context) -> GameResult { Ok(()) }
|
||||||
|
|
||||||
fn overlay_draw(&self, _state: &mut SharedGameState, _ctx: &mut Context) -> GameResult { Ok(()) }
|
fn overlay_draw(&mut self, _state: &mut GameState, _game_ctx: &mut GameContext, _ctx: &mut Context, _ui: &mut imgui::Ui) -> GameResult { Ok(()) }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::io::{Cursor, Read};
|
use std::io::Cursor;
|
||||||
|
|
||||||
use ggez::{Context, GameResult};
|
use ggez::{Context, GameResult};
|
||||||
|
|
||||||
|
|
|
||||||
22
src/stage.rs
22
src/stage.rs
|
|
@ -8,6 +8,7 @@ use ggez::GameError::ResourceLoadError;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
|
||||||
use crate::map::Map;
|
use crate::map::Map;
|
||||||
|
use crate::str;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash)]
|
#[derive(Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct NpcType {
|
pub struct NpcType {
|
||||||
|
|
@ -374,6 +375,27 @@ pub struct Stage {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stage {
|
impl Stage {
|
||||||
|
pub fn empty() -> Self {
|
||||||
|
Self {
|
||||||
|
map: Map {
|
||||||
|
attrib: [0u8; 256],
|
||||||
|
height: 16,
|
||||||
|
width: 16,
|
||||||
|
tiles: vec![0u8; 16 * 16],
|
||||||
|
},
|
||||||
|
data: StageData {
|
||||||
|
map: str!("0"),
|
||||||
|
name: str!("Null"),
|
||||||
|
background: Background::new("bk0"),
|
||||||
|
background_type: BackgroundType::Black,
|
||||||
|
tileset: Tileset::new("0"),
|
||||||
|
boss_no: 0,
|
||||||
|
npc1: NpcType::new("0"),
|
||||||
|
npc2: NpcType::new("0"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn load(ctx: &mut Context, root: &str, data: &StageData) -> GameResult<Self> {
|
pub fn load(ctx: &mut Context, root: &str, data: &StageData) -> GameResult<Self> {
|
||||||
let map_file = filesystem::open(ctx, [root, "Stage/", &data.map, ".pxm"].join(""))?;
|
let map_file = filesystem::open(ctx, [root, "Stage/", &data.map, ".pxm"].join(""))?;
|
||||||
let attrib_file = filesystem::open(ctx, [root, "Stage/", &data.tileset.name, ".pxa"].join(""))?;
|
let attrib_file = filesystem::open(ctx, [root, "Stage/", &data.tileset.name, ".pxa"].join(""))?;
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ use ggez::graphics::{Drawable, DrawParam, FilterMode, Image, Rect};
|
||||||
use ggez::graphics::spritebatch::SpriteBatch;
|
use ggez::graphics::spritebatch::SpriteBatch;
|
||||||
use ggez::nalgebra::{Point2, Vector2};
|
use ggez::nalgebra::{Point2, Vector2};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use log::{debug, info};
|
use log::info;
|
||||||
|
|
||||||
use crate::common;
|
use crate::common;
|
||||||
use crate::engine_constants::EngineConstants;
|
use crate::engine_constants::EngineConstants;
|
||||||
|
|
|
||||||
104
src/ui.rs
Normal file
104
src/ui.rs
Normal file
|
|
@ -0,0 +1,104 @@
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use ggez::{Context, GameResult, graphics};
|
||||||
|
use ggez::GameError::RenderError;
|
||||||
|
use imgui::{FontConfig, FontSource};
|
||||||
|
use imgui_gfx_renderer::{Renderer, Shaders};
|
||||||
|
use imgui_gfx_renderer::gfx::format::Rgba8;
|
||||||
|
use imgui_gfx_renderer::gfx::handle::RenderTargetView;
|
||||||
|
use imgui_gfx_renderer::gfx::memory::Typed;
|
||||||
|
use imgui_winit_support::{HiDpiMode, WinitPlatform};
|
||||||
|
|
||||||
|
use crate::scene::Scene;
|
||||||
|
use crate::GameContext;
|
||||||
|
use crate::game_state::GameState;
|
||||||
|
|
||||||
|
mod types {
|
||||||
|
pub type Device = gfx_device_gl::Device;
|
||||||
|
pub type Factory = gfx_device_gl::Factory;
|
||||||
|
pub type Resources = gfx_device_gl::Resources;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct UI {
|
||||||
|
pub imgui: imgui::Context,
|
||||||
|
pub platform: WinitPlatform,
|
||||||
|
pub renderer: Renderer<Rgba8, types::Resources>,
|
||||||
|
main_color: RenderTargetView<types::Resources, Rgba8>,
|
||||||
|
last_frame: Instant,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl UI {
|
||||||
|
pub fn new(ctx: &mut Context) -> GameResult<Self> {
|
||||||
|
let mut imgui = imgui::Context::create();
|
||||||
|
imgui.set_ini_filename(None);
|
||||||
|
imgui.fonts().add_font(&[
|
||||||
|
FontSource::DefaultFontData {
|
||||||
|
config: Some(FontConfig::default()),
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
imgui.style_mut().use_dark_colors();
|
||||||
|
|
||||||
|
let mut platform = WinitPlatform::init(&mut imgui);
|
||||||
|
platform.attach_window(imgui.io_mut(), graphics::window(ctx), HiDpiMode::Rounded);
|
||||||
|
|
||||||
|
let (factory, dev, _, _, color) = graphics::gfx_objects(ctx);
|
||||||
|
let shaders = {
|
||||||
|
let version = dev.get_info().shading_language;
|
||||||
|
if version.is_embedded {
|
||||||
|
if version.major >= 3 {
|
||||||
|
Shaders::GlSlEs300
|
||||||
|
} else {
|
||||||
|
Shaders::GlSlEs100
|
||||||
|
}
|
||||||
|
} else if version.major >= 4 {
|
||||||
|
Shaders::GlSl400
|
||||||
|
} else if version.major >= 3 {
|
||||||
|
if version.minor >= 2 {
|
||||||
|
Shaders::GlSl150
|
||||||
|
} else {
|
||||||
|
Shaders::GlSl130
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Shaders::GlSl110
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let renderer = Renderer::init(&mut imgui, factory, shaders)
|
||||||
|
.map_err(|e| RenderError(e.to_string()))?;
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
imgui,
|
||||||
|
platform,
|
||||||
|
renderer,
|
||||||
|
main_color: RenderTargetView::new(color),
|
||||||
|
last_frame: Instant::now(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn handle_events(&mut self, ctx: &mut Context, event: &winit::Event) {
|
||||||
|
self.platform.handle_event(self.imgui.io_mut(), graphics::window(ctx), &event);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn draw(&mut self, state: &mut GameState, game_ctx: &mut GameContext, ctx: &mut Context, scene: &mut Box<dyn Scene>) -> GameResult {
|
||||||
|
{
|
||||||
|
let io = self.imgui.io_mut();
|
||||||
|
self.platform.prepare_frame(io, graphics::window(ctx)).map_err(|e| RenderError(e))?;
|
||||||
|
|
||||||
|
io.update_delta_time(self.last_frame);
|
||||||
|
self.last_frame = Instant::now();
|
||||||
|
}
|
||||||
|
let mut ui = self.imgui.frame();
|
||||||
|
|
||||||
|
scene.overlay_draw(state, game_ctx, ctx, &mut ui)?;
|
||||||
|
|
||||||
|
self.platform.prepare_render(&ui, graphics::window(ctx));
|
||||||
|
let draw_data = ui.render();
|
||||||
|
let (factory, dev, encoder, _, _) = graphics::gfx_objects(ctx);
|
||||||
|
self.renderer
|
||||||
|
.render(factory, encoder, &mut self.main_color, draw_data)
|
||||||
|
.map_err(|e| RenderError(e.to_string()))?;
|
||||||
|
|
||||||
|
encoder.flush(dev);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue