Now that we created the spawn method and wired everything up, let's make the spawn method do something useful and create the player's dungeon heart.
Every player spawns with 4 imps, 4 creatures, and 1 dungeon heart. To distinguish the different entities, we'll add more textures by setting more component values of the Texture component.
Next, let's extend the spawn method. The first step is to check that the caller hasn't spawned yet by verifying there are no entities owned by the caller. Then we add a 3x3 area of mined tiles and place entities on it.
As we've learned, entities are just a collection of various components:
In the new spawn method, we verify each of the 9 coordinates is empty, and then create the different entities by setting the respective component values.
After the spawn method is implemented, we can click on any empty area of the map and observe 18 entities being created (9 mined tiles, 4 creatures, 4 imps, 1 dungeon heart).
|
@@ -24,7 +24,10 @@ struct Components {
|
|
|
24
24
|
TupleComponent life;
|
|
25
25
|
}
|
|
26
26
|
enum Texture {
|
|
27
|
-
Imp
|
|
27
|
+
Imp,
|
|
28
|
+
Creature,
|
|
29
|
+
Heart,
|
|
30
|
+
Ground
|
|
28
31
|
}
|
|
29
32
|
|
|
30
33
|
contract Game {
|
|
@@ -50,7 +53,17 @@ contract Game {
|
|
|
50
53
|
componentList = _componentList;
|
|
51
54
|
|
|
52
55
|
string memory imp = 'https://imagedelivery.net/kiVB3FlOmd8gwoTJWblSOA/ef4adf50-0e0d-4959-9917-439de7ed9500/public';
|
|
56
|
+
string
|
|
57
|
+
memory creature = 'https://imagedelivery.net/kiVB3FlOmd8gwoTJWblSOA/e77e4f90-5047-4c82-7c4d-80057d12f200/public';
|
|
58
|
+
string
|
|
59
|
+
memory heart = 'https://imagedelivery.net/kiVB3FlOmd8gwoTJWblSOA/62e3c547-6d33-4df0-3da5-2f965875ae00/public';
|
|
60
|
+
string
|
|
61
|
+
memory ground = 'https://imagedelivery.net/kiVB3FlOmd8gwoTJWblSOA/47011e62-ea03-44df-51b7-441f42588a00/public';
|
|
62
|
+
|
|
53
63
|
c.texture.set(uint256(Texture.Imp), imp);
|
|
64
|
+
c.texture.set(uint256(Texture.Creature), creature);
|
|
65
|
+
c.texture.set(uint256(Texture.Heart), heart);
|
|
66
|
+
c.texture.set(uint256(Texture.Ground), ground);
|
|
54
67
|
}
|
|
55
68
|
|
|
56
69
|
/**
|
|
@@ -62,9 +75,53 @@ contract Game {
|
|
|
62
75
|
}
|
|
63
76
|
}
|
|
64
77
|
|
|
65
|
-
function
|
|
66
|
-
uint256
|
|
67
|
-
c.position.set(
|
|
68
|
-
c.
|
|
78
|
+
function mine(Coord memory coord) internal {
|
|
79
|
+
uint256 tile = World(world).getNumEntities();
|
|
80
|
+
c.position.set(tile, coord);
|
|
81
|
+
c.mined.set(tile);
|
|
82
|
+
c.appearance.set(tile, uint256(Texture.Ground));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function spawn(Coord memory center) public {
|
|
86
|
+
// Check player is not spawned yet
|
|
87
|
+
require(c.ownedBy.getEntitiesWithValue(msg.sender).length == 0, 'already spawned');
|
|
88
|
+
|
|
89
|
+
// Create player entity (to indicate spawn)
|
|
90
|
+
uint256 playerEntity = World(world).getNumEntities();
|
|
91
|
+
c.ownedBy.set(playerEntity, msg.sender);
|
|
92
|
+
|
|
93
|
+
// Check spawn area is empty, then mine
|
|
94
|
+
for (uint256 dx; dx < 3; dx++) {
|
|
95
|
+
for (uint256 dy; dy < 3; dy++) {
|
|
96
|
+
Coord memory coord = Coord(center.x - 1 + dx, center.y - 1 + dy);
|
|
97
|
+
require(c.position.getEntitiesWithValue(coord).length == 0, 'invalid spawn pos');
|
|
98
|
+
mine(coord);
|
|
99
|
+
|
|
100
|
+
// Spawn entities
|
|
101
|
+
uint256 entity = World(world).getNumEntities();
|
|
102
|
+
c.position.set(entity, coord);
|
|
103
|
+
c.ownedBy.set(entity, msg.sender);
|
|
104
|
+
|
|
105
|
+
// Put heart at the center
|
|
106
|
+
if (dx == 1 && dy == 1) {
|
|
107
|
+
c.heart.set(entity);
|
|
108
|
+
c.life.set(entity, 10, 10);
|
|
109
|
+
c.attack.set(entity, 1);
|
|
110
|
+
c.appearance.set(entity, uint256(Texture.Heart));
|
|
111
|
+
} else if ((dx + dy) % 2 == 0) {
|
|
112
|
+
// Put creatures at diagonal positions
|
|
113
|
+
c.life.set(entity, 10, 10);
|
|
114
|
+
c.attack.set(entity, 3);
|
|
115
|
+
c.movable.set(entity);
|
|
116
|
+
c.appearance.set(entity, uint256(Texture.Creature));
|
|
117
|
+
} else {
|
|
118
|
+
// Put imps at vertical/horizontal positions
|
|
119
|
+
c.life.set(entity, 5, 5);
|
|
120
|
+
c.movable.set(entity);
|
|
121
|
+
c.miner.set(entity);
|
|
122
|
+
c.appearance.set(entity, uint256(Texture.Imp));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
}
|
|
69
126
|
}
|
|
70
127
|
}
|