Theo dõi kênh: Tại đây
Sẽ có cập nhật trong tương lai 🥰 !!!
Video Hướng Dẫn Chi Tiết Phần 1: Xem tại đây
Video Hướng Dẫn Chi Tiết Phần 2 (Đa người chơi) Mới: Xem tại đây
Xem Tài Liệu Đa Người Chơi: Xem tại đây
Website: Xem tại đây
Tài liệu sẽ được cập nhật định kì và thông báo trong group nên các bạn chú ý nhen .
Các khóa học khác xem tại : 8 Sync Dev
Hoặc liên hệ trực tiếp qua fb: Kevin Nguyễn để được hỗ trợ
src
├── settings
│ └── settings.py
├── resources
│ └── load_textures.py
├── entity
│ ├── event
│ │ ├── evt_pick.py
│ │ └── evt_distance.py
│ ├── scene
│ │ ├── block.py
│ │ ├── sky.py
│ │ └── hand.py
│ ├── genmap/
│ └── character/
└── main.py
Để minh họa trực quan, đây là cách tổ chức cấu trúc thư mục của dự án:
- Thư mục gốc
src:- Thư mục
settings:settings.py: Chứa các cài đặt và cấu hình cho dự án.
- Thư mục
resources:load_textures.py: Tải các tài nguyên và kết cấu cần thiết cho trò chơi.
- Thư mục
entity:- Thư mục
event:evt_pick.py: Xử lý sự kiện chọn.evt_distance.py: Xử lý sự kiện khoảng cách.
- Thư mục
scene:block.py: Định nghĩa khối trong trò chơi.sky.py: Định nghĩa bầu trời trong trò chơi.hand.py: Định nghĩa bàn tay trong trò chơi.
genmap.py: Tạo bản đồ trong trò chơi.character.py: Định nghĩa nhân vật trong trò chơi.
- Thư mục
main.py: Tệp chính để chạy ứng dụng.
- Thư mục
frompathlibimportPathBASE_DIR=Path(__file__).resolve().parent.parent.parentMODEL_PATH=str(BASE_DIR/'assets'/'models')
SFX_PATH=str(BASE_DIR/'assets'/'sfx')
TEXTURE_PATH=str(BASE_DIR/'assets'/'textures')fromursinaimportload_texture, Audiofromsrc.settingsimportTEXTURE_PATH, SFX_PATH# Load texturesgrass_texture=load_texture(f'{TEXTURE_PATH}\\Grass_Block.png')
stone_texture=load_texture(f'{TEXTURE_PATH}\\Stone_Block.png')
brick_texture=load_texture(f'{TEXTURE_PATH}\\Brick_Block.png')
dirt_texture=load_texture(f'{TEXTURE_PATH}\\Dirt_Block.png')
wood_texture=load_texture(f'{TEXTURE_PATH}\\Wood_Block.png')
sky_texture=load_texture(f'{TEXTURE_PATH}\\Skybox.png')
arm_texture=load_texture(f'{TEXTURE_PATH}\\Arm_Texture.png')
# Load soundspunch_sound=Audio(f'{SFX_PATH}\\Punch_sound.wav', loop=False, autoplay=False)fromursinaimportheld_keysfromsrc.entity.sceneimporthand, Blockdefevt_pick():
ifheld_keys['left mouse'] orheld_keys['right mouse']:
hand.active()
else:
hand.passive()
ifheld_keys['1']: Block.block_pick=1ifheld_keys['2']: Block.block_pick=2ifheld_keys['3']: Block.block_pick=3ifheld_keys['4']: Block.block_pick=4ifheld_keys['5']: Block.block_pick=5fromsrc.entity.genmapimportvoxel, noisefromsrc.entity.characterimportcharacterfromsrc.entity.sceneimportBlockdistance=10defevt_distance():
player_x=int(character.position.x)
player_z=int(character.position.z)
forzinrange(player_z-distance, player_z+distance):
forxinrange(player_x-distance, player_x+distance):
if (x, z) notinvoxel:
y=int(noise([x*0.1, z*0.1]) *10)
block=Block(position=(x, y, z))
voxel[(x, z)] =blockfromperlin_noiseimportPerlinNoisefromsrc.entity.sceneimportBlockimportrandomnoise=PerlinNoise(octaves=3, seed=random.randint(0, 100000000))
voxel= {}
defgen_map():
forzinrange(20):
forxinrange(20):
y=int(noise([x*0.1, z*0.1]) *10)
block=Block(position=(x, y, z))
voxel[(x, z)] =blockfromursinaimportButton, destroy, scene, color, mouseimportrandomfromsrc.resourcesimportgrass_texture, stone_texture, brick_texture, dirt_texture, wood_texture, punch_soundfromsrc.settingsimportMODEL_PATHclassBlock(Button):
block_pick=1def__init__(self, position=(0, 0, 0), texture=grass_texture):
super().__init__(
parent=scene,
position=position,
model=f'{MODEL_PATH}\\Block',
origin_y=0.5,
texture=texture,
color=color.color(0, 0, random.uniform(0.9, 1.0)),
scale=0.5
)
definput(self, key):
ifself.hovered:
ifkey=='left mouse down':
punch_sound.play()
destroy(self)
elifkey=='right mouse down':
punch_sound.play()
ifBlock.block_pick==1:
voxel=Block(position=self.position+mouse.normal, texture=grass_texture)
elifBlock.block_pick==2:
voxel=Block(position=self.position+mouse.normal, texture=stone_texture)
elifBlock.block_pick==3:
voxel=Block(position=self.position+mouse.normal, texture=brick_texture)
elifBlock.block_pick==4:
voxel=Block(position=self.position+mouse.normal, texture=dirt_texture)
elifBlock.block_pick==5:
voxel=Block(position=self.position+mouse.normal, texture=wood_texture)fromursinaimportEntity, scenefromsrc.resourcesimportsky_textureclassSky(Entity):
def__init__(self):
super().__init__(
parent=scene,
model='Sphere',
texture=sky_texture,
scale=150,
double_sided=True
)
sky=Sky()fromursinaimportEntity, camera, Vec3, Vec2fromsrc.resourcesimportarm_texturefromsrc.settingsimportMODEL_PATHclassHand(Entity):
def__init__(self):
self.passive_pos=Vec2(0.3, -0.6)
self.active_pos=Vec2(0.3, -0.5)
super().__init__(
parent=camera.ui,
model=f'{MODEL_PATH}\\Arm',
texture=arm_texture,
scale=0.2,
rotation=Vec3(150, -10, 0),
position=self.passive_pos
)
defactive(self):
self.position=self.active_posdefpassive(self):
self.position=self.passive_poshand=Hand()fromursina.prefabs.first_person_controllerimportFirstPersonControllercharacter=FirstPersonController()fromursinaimportUrsinafromsrc.resourcesimport*# Tải tất cả các tài nguyênfromsrc.entity.sceneimportsky, hand, Blockfromsrc.entity.genmapimportgen_mapfromsrc.entity.characterimportcharacterfromsrc.entity.eventimportupdateapp=Ursina()
gen_map()
app.run()