瀏覽代碼

Initial 2P prototype

Eiyeron Fulmincendii 9 年之前
父節點
當前提交
a2ccbb4ad0
共有 11 個文件被更改,包括 397 次插入33 次删除
  1. 二進制
      data/pacman.wrf
  2. 二進制
      data/wip_data.wrf
  3. 3 30
      src/engine/main.cpp
  4. 3 2
      src/input/Input.cpp
  5. 1 1
      src/map/Map.cpp
  6. 229 0
      src/pacman/GameState.cpp
  7. 34 0
      src/pacman/GameState.h
  8. 65 0
      src/pacman/Player.cpp
  9. 47 0
      src/pacman/Player.h
  10. 5 0
      src/pacman/static_data.cpp
  11. 10 0
      src/pacman/static_data.h

二進制
data/pacman.wrf


二進制
data/wip_data.wrf


+ 3 - 30
src/engine/main.cpp

@@ -10,6 +10,8 @@
 #include "piaf/Archive.h"
 #include "utility/misc.h"
 
+#include "pacman/GameState.h"
+
 using namespace WalrusRPG;
 using WalrusRPG::PIAF::Archive;
 using WalrusRPG::Graphics::Texture;
@@ -27,36 +29,9 @@ int main(int argc, char *argv[])
     Quirks::init(argv[0]);
 
     Text::init();
-    Archive arc("data/wip_data.wrf");
-    Texture tex(arc.get("ov.png"));
-    WalrusRPG::PIAF::File f1 = arc.get("l1.bin");
-    WalrusRPG::PIAF::File f2 = arc.get("l2.bin");
-
-    const uint8_t *l1 = f1.get();
-    const uint8_t *l2 = f2.get();
-
-    // TODO better map reading.
-    uint16_t *dungeonTest = new uint16_t[f1.file_size / 2 + 1];
-    uint16_t *dungeonTest2 = new uint16_t[f1.file_size / 2 + 1];
-
-    for (unsigned i = 0; i < f1.file_size / 2; i++)
-    {
-        dungeonTest[i] = read_big_endian_value<uint16_t>(&l1[i * 2]);
-        dungeonTest2[i] = read_big_endian_value<uint16_t>(&l2[i * 2]);
-    }
-
-    Map map(20, 20, dungeonTest, dungeonTest2, tex);
-    tinystl::vector<Frame> stripe21;
-    tinystl::vector<Frame> stripe22;
-    stripe21.push_back({21, 23});
-    stripe21.push_back({22, 31});
-    stripe22.push_back({22, 37});
-    stripe22.push_back({21, 41});
-    map.anim.add_animation(21, {stripe21, true, 0});
-    map.anim.add_animation(22, {stripe22, true, 0});
 
     StateMachine::init();
-    StateMachine::push(new States::StateMap(0, 0, map));
+    StateMachine::push(new Pacman::GameState());
     StateMachine::run();
 
     Logger::log("WalrusRPG Deinit");
@@ -67,8 +42,6 @@ int main(int argc, char *argv[])
     Timing::deinit();
     Graphics::deinit();
     Status::deinit();
-    delete[] dungeonTest;
-    delete[] dungeonTest2;
     Logger::log("WalrusRPG Exit");
     Graphics::deinit();
 

+ 3 - 2
src/input/Input.cpp

@@ -23,8 +23,9 @@ struct KeyBuffer key_states[Key::K_SIZE] = {{false, false}};
 #ifdef TARGET_SFML
 using sf::Keyboard;
 InputMap key_map[] = {
-    {Key::K_A, Keyboard::W},          {Key::K_B, Keyboard::X},
-    {Key::K_L, Keyboard::Q},          {Key::K_R, Keyboard::S},
+    // Edit for Pacman
+    {Key::K_A, Keyboard::Z},          {Key::K_B, Keyboard::S},
+    {Key::K_L, Keyboard::Q},          {Key::K_R, Keyboard::D},
 
     {Key::K_UP, Keyboard::Up},        {Key::K_DOWN, Keyboard::Down},
     {Key::K_LEFT, Keyboard::Left},    {Key::K_RIGHT, Keyboard::Right},

+ 1 - 1
src/map/Map.cpp

@@ -14,7 +14,7 @@ using WalrusRPG::Graphics::Texture;
 Map::Map(int width, int height, uint16_t *layer0, uint16_t *layer1, Texture &tex)
     : anim(), tex(tex)
 {
-    this->renderer = new TileRenderer(tex, 16, 16);
+    this->renderer = new TileRenderer(tex, 8, 8);
     this->width = width;
     this->height = height;
     this->layer0 = layer0;

+ 229 - 0
src/pacman/GameState.cpp

@@ -0,0 +1,229 @@
+#include "GameState.h"
+#include "piaf/Archive.h"
+#include "input/Input.h"
+#include "render/Text.h"
+#include "Graphics.h"
+#include "Logger.h"
+
+#include "Player.h"
+#include "static_data.h"
+
+using Pacman::GameState;
+using Pacman::Player;
+using Pacman::ButtonInput;
+using Pacman::MoveIntent;
+using WalrusRPG::PIAF::Archive;
+using WalrusRPG::PIAF::File;
+using WalrusRPG::Utils::Rect;
+using namespace WalrusRPG;
+using namespace WalrusRPG::Graphics;
+using namespace WalrusRPG::Input;
+using WalrusRPG::Input::Key;
+
+uint16_t map_data[] = {
+	5,3,3,3,3,3,3,3,3,3,3,3,3,13,14,3,3,3,3,3,3,3,3,3,3,3,3,6,
+1,0,0,0,0,0,0,0,0,0,0,0,0,18,17,0,0,0,0,0,0,0,0,0,0,0,0,2,
+1,0,9,15,15,10,0,9,15,15,15,10,0,18,17,0,9,15,15,15,10,0,9,15,15,10,0,2,
+1,0,18,0,0,17,0,18,0,0,0,17,0,18,17,0,18,0,0,0,17,0,18,0,0,17,0,2,
+1,0,11,16,16,12,0,11,16,16,16,12,0,11,12,0,11,16,16,16,12,0,11,16,16,12,0,2,
+1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
+1,0,9,15,15,10,0,9,10,0,9,15,15,15,15,15,15,10,0,9,10,0,9,15,15,10,0,2,
+1,0,11,16,16,12,0,18,17,0,11,16,16,24,23,16,16,12,0,18,17,0,11,16,16,12,0,2,
+1,0,0,0,0,0,0,18,17,0,0,0,0,18,17,0,0,0,0,18,17,0,0,0,0,0,0,2,
+7,4,4,4,4,10,0,18,25,15,15,10,0,18,17,0,9,15,15,26,17,0,9,4,4,4,4,8,
+0,0,0,0,0,1,0,18,23,16,16,12,0,11,12,0,11,16,16,24,17,0,2,0,0,0,0,0,
+0,0,0,0,0,1,0,18,17,0,0,0,0,0,0,0,0,0,0,18,17,0,2,0,0,0,0,0,
+0,0,0,0,0,1,0,18,17,0,19,4,4,31,31,4,4,20,0,18,17,0,2,0,0,0,0,0,
+3,3,3,3,3,12,0,11,12,0,2,0,0,0,0,0,0,1,0,11,12,0,11,3,3,3,3,3,
+0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,
+4,4,4,4,4,10,0,9,10,0,2,0,0,0,0,0,0,1,0,9,10,0,9,4,4,4,4,4,
+0,0,0,0,0,1,0,18,17,0,21,3,3,3,3,3,3,22,0,18,17,0,2,0,0,0,0,0,
+0,0,0,0,0,1,0,18,17,0,0,0,0,0,0,0,0,0,0,18,17,0,2,0,0,0,0,0,
+0,0,0,0,0,1,0,18,17,0,9,15,15,15,15,15,15,10,0,18,17,0,2,0,0,0,0,0,
+5,3,3,3,3,12,0,11,12,0,11,16,16,24,23,16,16,12,0,11,12,0,11,3,3,3,3,6,
+1,0,0,0,0,0,0,0,0,0,0,0,0,18,17,0,0,0,0,0,0,0,0,0,0,0,0,2,
+1,0,9,15,15,10,0,9,15,15,15,10,0,18,17,0,9,15,15,15,10,0,9,15,15,10,0,2,
+1,0,11,16,24,17,0,11,16,16,16,12,0,11,12,0,11,16,16,16,12,0,18,23,16,12,0,2,
+1,0,0,0,18,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,18,17,0,0,0,2,
+27,15,10,0,18,17,0,9,10,0,9,15,15,15,15,15,15,10,0,9,10,0,18,17,0,9,15,29,
+28,16,12,0,11,12,0,18,17,0,11,16,16,24,23,16,16,12,0,18,17,0,11,12,0,11,16,30,
+1,0,0,0,0,0,0,18,17,0,0,0,0,18,17,0,0,0,0,18,17,0,0,0,0,0,0,2,
+1,0,9,15,15,15,15,26,25,15,15,10,0,18,17,0,9,15,15,26,25,15,15,15,15,10,0,2,
+1,0,11,16,16,16,16,16,16,16,16,12,0,11,12,0,11,16,16,16,16,16,16,16,16,12,0,2,
+1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,
+7,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,8,
+};
+
+const uint8_t gums_model[] = {
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,
+0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,
+0,2,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,2,0,
+0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,
+0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
+0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,
+0,1,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,1,0,
+0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,
+0,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,0,
+0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,
+0,1,0,0,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,0,0,1,0,
+0,2,1,1,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,2,0,
+0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,
+0,0,0,1,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,0,
+0,1,1,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,0,0,1,1,1,1,1,1,0,
+0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,
+0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,1,0,
+0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,
+0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
+};
+
+
+GameState::GameState() : level(1), map(28, 31, map_data, nullptr, map_texture), cam(-(320-28*8)/2,4),
+	p1(4,4), p2(204,228)
+
+{
+	p1.up = new ButtonInput(K_A);
+	p1.down = new ButtonInput(K_B);
+	p1.left = new ButtonInput(K_L);
+	p1.right = new ButtonInput(K_R);
+	
+	p2.up = new ButtonInput(K_UP);
+	p2.down = new ButtonInput(K_DOWN);
+	p2.left = new ButtonInput(K_LEFT);
+	p2.right = new ButtonInput(K_RIGHT);
+
+
+	set_gums();
+}
+
+GameState::~GameState()
+{
+
+}
+
+void GameState::update(unsigned dt)
+{
+	map.update(dt);
+	p1.update(dt);
+	p2.update(dt);
+	move_player(p1);
+	move_player(p2);
+}
+
+void GameState::render(unsigned dt)
+{
+	// Map
+	map.render(cam, dt);
+	// Gums
+	for (int y = 0; y < 31; ++y)
+	{
+		for (int x = 0; x < 28; ++x)
+		{
+			if(gums[y][x] == Pacgum::NORMAL)
+				put_rectangle({8*x - cam.get_x()+3, 8*y - cam.get_y()+3,2,2}, White);
+			if(gums[y][x] == Pacgum::SUPER)
+				put_rectangle({8*x - cam.get_x()+1, 8*y - cam.get_y()+1,6,6}, Yellow);
+		}
+	}
+	// Enemy Door
+	put_rectangle({104-cam.get_x(), 101-cam.get_y(), 16, 2}, Red);
+
+
+	// Player Character
+	// render_player(j1);
+	// render_player(j2);
+
+	p1.render(dt, cam);
+	p2.render(dt, cam);
+	// Borders
+	
+	put_rectangle({0, 0, 0u-cam.get_x(), 320}, DarkGray);
+	put_rectangle({320+cam.get_x(), 0, 0u-cam.get_x(), 320}, DarkGray);
+	put_rectangle({-cam.get_x(),0, 1, 240}, White);
+	put_rectangle({320+cam.get_x(),0, 1, 240}, White);
+
+}
+
+void GameState::set_gums()
+{
+	for (int y = 0; y < 31; ++y)
+	{
+		for (int x = 0; x < 28; ++x)
+		{
+			gums[y][x] = (Pacgum)gums_model[28*y + x];
+		}
+	}
+}
+
+/**
+ * Does a corner-based collision check for a small Rect.
+ * Assumes that said Rect as big or smaller than a tile
+ * (8 x 8 pixels).
+ * Also assumes that a corner outside the map doesn't collide anything.
+ * Assumes that you lost the game and any tile != 0 is solid. 
+ */
+bool GameState::does_collide_a_wall(Rect r)
+{
+	struct Corner{int x; int y;};
+
+	Corner top_left{r.x, r.y};
+	Corner top_right{(r.x+(int)r.width-1), r.y};
+	Corner bottom_left{r.x, (r.y+(int)r.height-1)};
+	Corner bottom_right{(r.x+(int)r.width-1), (r.y+(int)r.height-1)};
+	return (is_inside_map(top_left.x, top_left.y) && (map.is_tile_solid(top_left.x/8, top_left.y/8) != 0))
+			|| (is_inside_map(top_right.x, top_right.y) && (map.is_tile_solid(top_right.x/8, top_right.y/8) != 0))
+			|| (is_inside_map(bottom_right.x, bottom_right.y) && (map.is_tile_solid(bottom_right.x/8, bottom_right.y/8) != 0))
+			|| (is_inside_map(bottom_left.x, bottom_left.y) && (map.is_tile_solid(bottom_left.x/8, bottom_left.y/8) != 0));
+}
+
+void GameState::move_player(Player &p)
+{
+	if(p.intent == UP) {
+		if(!does_collide_a_wall({p.x+4, p.y+4-1, 8, 8})){
+			p.vy = -1;
+			p.vx = 0;
+		}
+	}
+	if(p.intent == DOWN) {
+		if(!does_collide_a_wall({p.x+4, p.y+4+1, 8, 8})){
+			p.vy = 1;
+			p.vx = 0;
+		}
+	}
+	if(p.intent == LEFT) {
+		if(!does_collide_a_wall({p.x+4-1, p.y+4, 8, 8})){
+			p.vx = -1;
+			p.vy = 0;
+		}
+	}
+	if(p.intent == RIGHT) {
+		if(!does_collide_a_wall({p.x+4+1, p.y+4, 8, 8})){
+			p.vx = 1;
+			p.vy = 0;
+		}
+	}
+
+	if(does_collide_a_wall({p.x+4+p.vx, p.y+4+p.vy, 8, 8})){
+		p.vy = 0;
+		p.vx = 0;
+	}
+
+	p.x += p.vx;
+	p.y += p.vy;
+
+	if(p.x < -8)
+		p.x = 224-8;
+	if(p.x+16 > 232)
+		p.x = 0;
+}

+ 34 - 0
src/pacman/GameState.h

@@ -0,0 +1,34 @@
+#ifndef INCLUDE_GAMESTATE_h
+#define INCLUDE_GAMESTATE_h
+#include "engine/State.h"
+#include "map/Map.h"
+#include "render/Camera.h"
+#include "utility/Rect.h"
+#include "Player.h"
+
+namespace Pacman
+{
+	enum Pacgum:uint8_t {NOTHING, NORMAL, SUPER};
+	
+	class GameState : public WalrusRPG::States::State {
+	private:
+		unsigned level;
+		WalrusRPG::Map map;
+		Pacgum gums[31][28];
+		WalrusRPG::Camera cam;
+		Player p1;
+		Player p2;
+	public:
+		GameState();
+		~GameState();
+        void update(unsigned dt) override;
+        void render(unsigned dt) override;
+        void set_gums();
+        inline bool is_inside_map(int x, int y) { return x >= 0 && x < 224 && y >= 0 && y < 248;}
+        bool does_collide_a_wall(WalrusRPG::Utils::Rect r);
+        void move_player(Player &p);
+        void render_player(WalrusRPG::Utils::Rect r);
+	};
+}
+
+#endif

+ 65 - 0
src/pacman/Player.cpp

@@ -0,0 +1,65 @@
+#include "Player.h"
+#include "Graphics.h"
+
+using Pacman::Player;
+using Pacman::ButtonInput;
+using Pacman::MoveIntent;
+using WalrusRPG::Camera;
+using namespace WalrusRPG::Graphics;
+using namespace WalrusRPG::Input;
+
+ButtonInput::ButtonInput(Key key): key(key)
+{
+}
+ButtonInput::~ButtonInput()
+{
+}
+
+
+bool ButtonInput::operator()()
+{
+	printf("key %d => %d\n", key, key_down(key));
+	return key_down(key);
+}
+
+Player::Player(int x, int y) : x(x), y(y), up(nullptr), down(nullptr), left(nullptr), right(nullptr),
+	intent(MoveIntent::NONE), vx(0), vy(0)
+{
+}
+
+Player::~Player()
+{
+	if(up != nullptr)
+		delete up;
+	if(down != nullptr)
+		delete down;
+	if(left != nullptr)
+		delete left;
+	if(right != nullptr)
+		delete right;
+}
+
+void Player::update(unsigned dt)
+{
+	if(up != nullptr && (*up)()){
+		intent = UP;
+	}
+	if(down != nullptr && (*down)()) {
+		intent = DOWN;
+	}
+	if(left != nullptr && (*left)()){
+		intent = LEFT;
+	}
+	if(right != nullptr && (*right)()){
+		intent = RIGHT;
+	}
+}
+
+void Player::render(unsigned dt, Camera& cam)
+{
+	put_rectangle({x-cam.get_x(), y-cam.get_y(),16,16}, Yellow);
+	if(x < 0)
+	put_rectangle({x-cam.get_x()+224, y-cam.get_y(),16,16}, Yellow);
+	if(x > 232)
+	put_rectangle({x-cam.get_x()-224, y-cam.get_y(),16,16}, Yellow);
+}

+ 47 - 0
src/pacman/Player.h

@@ -0,0 +1,47 @@
+#ifndef INCLUDE_PLAYER_H
+#define INCLUDE_PLAYER_H
+
+#include "input/Input.h"
+#include "render/Camera.h"
+
+namespace Pacman
+{
+	class VButtonInput
+	{
+	public:
+		virtual bool operator()() = 0;
+		VButtonInput() {};
+		virtual ~VButtonInput() {};
+	};
+
+	class ButtonInput : public VButtonInput {
+		private:
+			WalrusRPG::Input::Key key;
+		public:
+		ButtonInput(WalrusRPG::Input::Key key);
+		~ButtonInput();
+		bool operator()() override;
+	};
+
+	enum MoveIntent{NONE, UP, DOWN, LEFT, RIGHT};
+
+	class Player
+	{
+	public:
+		int x;
+		int y;
+		int vx;
+		int vy;
+		MoveIntent intent;
+		VButtonInput *up;
+		VButtonInput *down;
+		VButtonInput *left;
+		VButtonInput *right;
+
+		Player(int x, int y);
+		~Player();
+		void render(unsigned dt, WalrusRPG::Camera& cam);
+		void update(unsigned dt);
+	};
+}
+#endif

+ 5 - 0
src/pacman/static_data.cpp

@@ -0,0 +1,5 @@
+#include "static_data.h"
+
+
+WalrusRPG::PIAF::Archive game_data("data/pacman.wrf");
+WalrusRPG::Graphics::Texture map_texture(game_data.get("mapset.png"));

+ 10 - 0
src/pacman/static_data.h

@@ -0,0 +1,10 @@
+#ifndef INCLUDE_STATIC_DATA
+#define INCLUDE_STATIC_DATA
+
+#include "piaf/Archive.h"
+#include "Texture.h"
+
+extern WalrusRPG::PIAF::Archive game_data;
+extern WalrusRPG::Graphics::Texture map_texture;
+
+#endif